如何将更改的文件添加到 Git 中较旧的(不是最后一个)提交
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2719579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add a changed file to an older (not last) commit in Git
提问by leen
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.
在过去的一个小时里,我更改了几件事情并逐步提交,但我刚刚意识到我忘记添加一些提交前的更改文件。
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?
有任何想法吗?
回答by Greg Hewgill
Use git rebase
. Specifically:
使用git rebase
. 具体来说:
- Use
git stash
to store the changes you want to add. - Use
git rebase -i HEAD~10
(or however many commits back you want to see). - Mark the commit in question (
a0865...
) for edit by changing the wordpick
at the start of the line intoedit
. Don't delete the other lines as that would delete the commits.[^vimnote] - Save the rebase file, and git will drop back to the shell and wait for you to fix that commit.
- Pop the stash by using
git stash pop
- Add your file with
git add <file>
. - Amend the commit with
git commit --amend --no-edit
. - Do a
git rebase --continue
which will rewrite the rest of your commits against the new one. - Repeat from step 2 onwards if you have marked more than one commit for edit.
- 使用
git stash
存储您要添加的变化。 - 使用
git rebase -i HEAD~10
(或者你想看到多少次提交)。 - 标记问题(提交
a0865...
的编辑)通过改变字pick
的行成的开始edit
。不要删除其他行,因为这会删除提交。[^vimnote] - 保存 rebase 文件,git 将返回到 shell 并等待您修复该提交。
- 使用弹出存储
git stash pop
- 添加您的文件
git add <file>
。 - 使用
git commit --amend --no-edit
. - 执行一个
git rebase --continue
将针对新提交重写其余提交的操作。 - 如果您标记了多个提交进行编辑,则从第 2 步开始重复。
[^vimnote]: If you are using vim
then you will have to hit the Insertkey to edit, then Escand type in :wq
to save the file, quit the editor, and apply the changes. Alternatively, you can configure a user-friendly git commit editorwith git config --global core.editor "nano"
.
[^vimnote]: 如果您正在使用,vim
则必须按Insert键进行编辑,然后Esc输入:wq
以保存文件,退出编辑器,然后应用更改。或者,您可以配置一个用户友好的git的承诺编辑用git config --global core.editor "nano"
。
回答by Joel Purra
To "fix" an old commit with a small change, without changing the commit message of the old commit, where OLDCOMMIT
is something like 091b73a
:
用一个小的更改“修复”旧提交,而不更改旧提交的提交消息,其中OLDCOMMIT
类似于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.
您还可以使用git commit --squash=OLDCOMMIT
在变基期间编辑旧的提交消息。
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 instructionchanges in the file; just save and quitthe editor (:wq
invim
) to continue with the rebase.--autosquash
will automatically put any--fixup=OLDCOMMIT
commits in the desired order. Note that--autosquash
is only valid when the--interactive
option is used.- The
^
inOLDCOMMIT^
means it's a reference to the commit just beforeOLDCOMMIT
.
git rebase --interactive
将调出一个文本编辑器(可以配置)来确认(或编辑)rebase 指令序列。文件中有关于rebase 指令更改的信息;只需保存并退出编辑器(:wq
invim
)即可继续进行变基。--autosquash
将自动--fixup=OLDCOMMIT
按所需顺序放置任何提交。请注意,--autosquash
仅在使用该--interactive
选项时才有效。- 在
^
中OLDCOMMIT^
意味着它是一个参考之前提交OLDCOMMIT
。
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:
上述步骤适用于验证和/或修改rebase 指令序列,但也可以通过以下方式跳过/自动化交互式 rebase 文本编辑器:
- Setting
GIT_SEQUENCE_EDITOR
to a script. - Creating a git alias to automatically autosquashall queued fixups.
- Creating a git alias to automatically fixupa single commit.
- 设置
GIT_SEQUENCE_EDITOR
为脚本。 - 创建一个git 别名来自动压缩所有排队的修正。
- 创建git 别名以自动修复单个提交。
See git commitand 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).
请参阅git commit和git rebase。与往常一样,在重写 git history 时,您应该只修复或压缩尚未发布给其他任何人(包括随机 Internet 用户和构建服务器)的提交。
回答by knittl
with git 1.7, there's a really easy way using git rebase
:
使用 git 1.7,有一种非常简单的使用方法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!
在主题行中添加前缀(或者squash!
如果您想编辑提交(消息)):
fixup! Factored out some common XPath Operations
use git rebase -i --autosquash
to fixup your commit
用于git rebase -i --autosquash
修复您的提交
回答by VonC
You can try a rebase --interactive
session to amend your old commit (provided you did not already pushthose commits to another repo).
您可以尝试使用rebase --interactive
会话来修改旧提交(前提是您尚未将这些提交推送到另一个存储库)。
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:
有时在 b.2 中固定的东西。不能修改为它修复的不太完美的提交,因为该提交深埋在补丁系列中。
这正是交互式 rebase 的用途:在大量“a”和“b”之后使用它,通过重新排列和编辑提交,并将多个提交压缩为一个。从您要按原样保留的最后一次提交开始:
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.
单行描述纯粹是为了您的乐趣;git rebase 不会查看它们,而是查看提交名称(在此示例中为“deadbee”和“fa1afe1”),因此不要删除或编辑名称。
通过将命令“pick”替换为“edit”命令,您可以告诉 git rebase 在应用该提交后停止,以便您可以编辑文件和/或提交消息、修改提交并继续 rebase。