如何将更改的文件添加到 Git 中较旧的(不是最后一次)提交

发布于 2024-08-30 05:38:11 字数 953 浏览 5 评论 0原文

在过去的一个小时里,我改变了几件事,并一步步提交它们,但我刚刚意识到我忘记在一些提交之前添加更改的文件(例如,标记为 a0865... 如下)。

日志看起来像这样:

GIT TidyUpRequests u:1 d:0> git log 
commit fc6734b6351f6c36a587dba6dbd9d5efa30c09ce 
Author: David Klein <> 
Date:   Tue Apr 27 09:43:55 2010 +0200

    The Main program now tests both Webservices at once

commit 8a2c6014c2b035e37aebd310a6393a1ecb39f463 
Author: David Klein <>
Date:   Tue Apr 27 09:43:27 2010 +0200

    ISBNDBQueryHandler now uses the XPath functions from XPath.fs too

commit 06a504e277fd98d97eed4dad22dfa5933d81451f 
Author: David Klein <> 
Date:   Tue Apr 27 09:30:34 2010 +0200

    AmazonQueryHandler now uses the XPath Helper functions defined in XPath.fs

commit a0865e28be35a3011d0b6091819ec32922dd2dd8 <--- changed file should go here
Author: David Klein <> 
Date:   Tue Apr 27 09:29:53 2010 +0200

    Factored out some common XPath Operations

有什么想法吗?

I have changed several things over the last hour and committed them step by step, but I just realized I've forgot to add a changed file some commits ago (for example, the commit marked as a0865... below).

The Log looks like this:

GIT TidyUpRequests u:1 d:0> git log 
commit fc6734b6351f6c36a587dba6dbd9d5efa30c09ce 
Author: David Klein <> 
Date:   Tue Apr 27 09:43:55 2010 +0200

    The Main program now tests both Webservices at once

commit 8a2c6014c2b035e37aebd310a6393a1ecb39f463 
Author: David Klein <>
Date:   Tue Apr 27 09:43:27 2010 +0200

    ISBNDBQueryHandler now uses the XPath functions from XPath.fs too

commit 06a504e277fd98d97eed4dad22dfa5933d81451f 
Author: David Klein <> 
Date:   Tue Apr 27 09:30:34 2010 +0200

    AmazonQueryHandler now uses the XPath Helper functions defined in XPath.fs

commit a0865e28be35a3011d0b6091819ec32922dd2dd8 <--- changed file should go here
Author: David Klein <> 
Date:   Tue Apr 27 09:29:53 2010 +0200

    Factored out some common XPath Operations

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

我一直都在从未离去 2024-09-06 05:38:11

使用 git rebase。具体来说:

  1. 使用 git stash 来存储您要添加的更改。
  2. 使用 git rebase -i HEAD~10 (或者您想查看的任何提交)。
  3. 通过将行开头的单词 pick 更改为 edit,将有问题的提交 (a0865...) 标记为编辑。不要删除其他行,因为这会删除提交。[^vimnote]
  4. 保存 rebase 文件,git 将返回到 shell 并等待您修复该提交。
  5. 使用 git stash pop 弹出存储。
  6. 使用 git add 添加文件。
  7. 使用 git commit --amend --no-edit 修改提交。
  8. 执行 git rebase --Continue ,这将根据新提交重写其余提交。
  9. 如果您已标记多个提交进行编辑,请从步骤 2 开始重复。
  10. 如果您之前已将修改后的提交推送到其他任何地方,那么您将必须再次推送 --force 才能在远程更新它们。但是,有关使用 --force 的常见警告适用,如果您不小心并事先与他们协调,您很容易会丢失其他人的工作。

[^vimnote]:如果您使用 vim,则必须按 Insert 键进行编辑,然后按 Esc 并输入 :wq 保存文件、退出编辑器并应用更改。或者,您可以配置用户友好的 git commit 编辑器,带有 git config --global core.editor "nano"

Use git rebase. Specifically:

  1. Use git stash to store the changes you want to add.
  2. Use git rebase -i HEAD~10 (or however many commits back you want to see).
  3. Mark the commit in question (a0865...) for edit by changing the word pick at the start of the line into edit. Don't delete the other lines as that would delete the commits.[^vimnote]
  4. Save the rebase file, and git will drop back to the shell and wait for you to fix that commit.
  5. Pop the stash by using git stash pop.
  6. Add your file with git add <file>.
  7. Amend the commit with git commit --amend --no-edit.
  8. Do a git rebase --continue which will rewrite the rest of your commits against the new one.
  9. Repeat from step 2 onwards if you have marked more than one commit for edit.
  10. If you have previously pushed the modified commits anywhere else, then you will have to push --force again to update them on the remote. However, the usual warnings about using --force apply, and you can easily lose other people's work if you are not careful and coordinate with them beforehand.

[^vimnote]: If you are using vim then you will have to hit the Insert key to edit, then Esc and type in :wq to save the file, quit the editor, and apply the changes. Alternatively, you can configure a user-friendly git commit editor with git config --global core.editor "nano".

迷路的信 2024-09-06 05:38:11

要通过小的更改“修复”旧提交,而不更改旧提交的提交消息,其中 OLDCOMMIT 类似于 091b73a

git add <my fixed files>
git commit --fixup=OLDCOMMIT
git rebase --interactive --autosquash OLDCOMMIT^

您还可以使用 git commit --squash=OLDCOMMIT 在变基期间编辑旧的提交消息。

请参阅 git commitgit rebase。一如既往,当重写 git 历史记录时,你应该只修复或压缩提交您尚未发布给其他任何人(包括随机互联网用户和构建服务器)。


详细说明


可选自动化

上述步骤非常适合验证和/或修改变基指令序列,但也可以通过以下方式跳过/自动化交互式变基文本编辑器:

To "fix" an old commit with a small change, without changing the commit message of the old commit, where OLDCOMMIT is something like 091b73a:

git add <my fixed files>
git commit --fixup=OLDCOMMIT
git rebase --interactive --autosquash OLDCOMMIT^

You can also use git commit --squash=OLDCOMMIT to edit the old commit message during rebase.

See documentation for git commit and git rebase. As always, when rewriting git history, you should only fixup or squash commits you have not yet published to anyone else (including random internet users and build servers).


Detailed explanation

  • git commit --fixup=OLDCOMMIT copies the OLDCOMMIT commit message and automatically prefixes fixup! so it can be put in the correct order during interactive rebase. (--squash=OLDCOMMIT does the same but prefixes squash!.)
  • git rebase --interactive will bring up a text editor (which can be configured) to confirm (or edit) the rebase instruction sequence. There is info for rebase instruction changes in the file; just save and quit the editor (:wq in vim) to continue with the rebase.
  • --autosquash will automatically put any --fixup=OLDCOMMIT commits in the correct order. Note that --autosquash is only valid when the --interactive option is used.
  • The ^ in OLDCOMMIT^ means it's a reference to the commit just before OLDCOMMIT. (OLDCOMMIT^ is the first parent of OLDCOMMIT.)

Optional automation

The above steps are good for verification and/or modifying the rebase instruction sequence, but it's also possible to skip/automate the interactive rebase text editor by:

謌踐踏愛綪 2024-09-06 05:38:11

在 git 1.7 中,有一种非常简单的方法来使用 git rebase:

暂存文件:

git add $files

创建一个新的提交并重新使用“损坏的”提交前缀的提交消息

git commit -c master~4

fixup!在主题行中(或 squash! 如果您想编辑提交(消息)):

fixup! Factored out some common XPath Operations

使用 git rebase -i --autosquash 来修复您的提交

with git 1.7, there's a really easy way using git rebase:

stage your files:

git add $files

create a new commit and re-use commit message of your "broken" commit

git commit -c master~4

prepend fixup! in the subject line (or squash! if you want to edit commit (message)):

fixup! Factored out some common XPath Operations

use git rebase -i --autosquash to fixup your commit

说好的呢 2024-09-06 05:38:11

您可以尝试 rebase --interactive< /strong> 会话来修改您的旧提交(前提是 您尚未将这些提交推送到另一个存储库)。

有时 b.2 中修复的事情。无法修改为它修复的不太完美的提交,因为该提交深深地埋藏在补丁系列中
这正是交互式变基的用途:在大量“a”和“b”之后使用它,通过重新排列和编辑提交,并将多个提交压缩为一个。

从您想要按原样保留的最后一次提交开始:

git rebase -i <after-this-commit>

将启动编辑器,处理当前分支中的所有提交(忽略合并提交),这些提交是在给定提交之后进行的。
您可以根据自己的喜好重新排序此列表中的提交,也可以删除它们。该列表看起来或多或少像这样:

pick deadbee The oneline of this commit
pick fa1afe1 The oneline of the next commit
...

单行描述纯粹是为了您的愉悦; git rebase 不会查看它们,而是查看提交名称(本例中为“deadbee”和“fa1afe1”),因此请勿删除或编辑这些名称。

通过将命令“pick”替换为命令“edit”,您可以告诉 git rebase 在应用该提交后停止,以便您可以编辑文件和/或提交消息、修改提交,并继续变基

You can try a rebase --interactive session to amend your old commit (provided you did not already push those commits to another repo).

Sometimes the thing fixed in b.2. cannot be amended to the not-quite perfect commit it fixes, because that commit is buried deeply in a patch series.
That is exactly what interactive rebase is for: use it after plenty of "a"s and "b"s, by rearranging and editing commits, and squashing multiple commits into one.

Start it with the last commit you want to retain as-is:

git rebase -i <after-this-commit>

An editor will be fired up with all the commits in your current branch (ignoring merge commits), which come after the given commit.
You can reorder the commits in this list to your heart's content, and you can remove them. The list looks more or less like this:

pick deadbee The oneline of this commit
pick fa1afe1 The oneline of the next commit
...

The oneline descriptions are purely for your pleasure; git rebase will not look at them but at the commit names ("deadbee" and "fa1afe1" in this example), so do not delete or edit the names.

By replacing the command "pick" with the command "edit", you can tell git rebase to stop after applying that commit, so that you can edit the files and/or the commit message, amend the commit, and continue rebasing.

绝情姑娘 2024-09-06 05:38:11

这是一个实现 @Greg 答案的函数:

function gitamendoldcommit() {
    printf "\n\nPress any key if you have no changes other than those you want to add to $1."
    printf "(You can commit your unwanted changes and undo later.):\n\n"
    read foo
    printf "\n\nChange 'pick' to 'edit' in front of $1 (top one), save, close the editor & press any key..."
    printf "Resolve any possible conflicts, if any. then: git add .; git rebase --continue\n\n"
    git rebase -i $1^

    git stash pop
    git add .
    git commit --amend --no-edit
    git rebase --continue
}

用法:(仅在暂存中进行预期的更改)gitamendoldcommit $OLDCOMMIT

Here's a function that implements @Greg's answer:

function gitamendoldcommit() {
    printf "\n\nPress any key if you have no changes other than those you want to add to $1."
    printf "(You can commit your unwanted changes and undo later.):\n\n"
    read foo
    printf "\n\nChange 'pick' to 'edit' in front of $1 (top one), save, close the editor & press any key..."
    printf "Resolve any possible conflicts, if any. then: git add .; git rebase --continue\n\n"
    git rebase -i $1^

    git stash pop
    git add .
    git commit --amend --no-edit
    git rebase --continue
}

Usage: (while having only the intended changes in the staging) gitamendoldcommit $OLDCOMMIT

演多会厌 2024-09-06 05:38:11

此外,如果您使用 git rebase -i 并想要转到当前分支的第一次提交,则可以使用 git rebase -i --root 。现在您可以轻松修改您的第一次提交。

Aditionally, if you use git rebase -i and want to go to the first commit of your current branch you can use git rebase -i --root. Now you could easily modify your first commit.

冷了相思 2024-09-06 05:38:11

2023 年,有一些工具可以做到这一点:特别是 gitsorb。它是一个很棒的工具,有可能改变许多尘埃落定的 git 工作流程。

In 2023 there are tools that do this: specifically git absorb. It is a great tool with the potential to change a lot of dusty git workflows.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文