只要你不分享这个分支,你就有几个解决方案。
提交 --amend
如果你刚刚提交了所有文件,你可以这样做
#Restore the file
git checkout HEAD -- my/file.txt
#Fix your commit
git add my/file.txt
git commit --amend
它会在你的文件被修复的情况下重做你的最后一次提交
变基 -i
还有另一种更复杂但更灵活的方法。即使您今天不使用它,它也可能会为您节省一些其他时间。
你可以压缩你的提交。
假设你有
- 您在其中添加了所有文件的一次提交(我们称之为
abc)
- 一次提交,您可以在其中检索您不想更改的文件的旧版本(我们称之为
def)
你可以做git rebase -i HEAD^^。它将打开一个包含您最后两次提交的文本编辑器,例如
pick abc first commit message
pick def second commit message
替换成
pick abc first commit message
fixup def second commit message
然后保存退出,git会合并这两个提交
Edit1:关于第二个解决方案的一些解释,以跟进评论
git rebase -i HEAD^^ 表示“让我更改我的提交树,从HEAD^^ 开始”(而HEAD^^ 表示“the parent of the parent of my current commit”)
然后它将打开一个文本编辑器,其中包含所有涉及的提交的列表,它会让您为每个提交选择一个操作。可能的操作列表显示在文件的底部。
pick,默认操作,意思是“不要更改这个提交。squash 意思是“合并这个提交和前一个”。fixup 是“合并这个提交和前一个,然后重新使用提交消息”
无论如何,如果您不确定自己在做什么,您可以在进行此类操作之前标记初始提交。示例:
git tag safetyNet
git rebase -i HEAD^^
#damned, I screwed up
git checkout safetyNet
Edit2回答其他评论
如果您已经将您的分支推送到远程,并且您是唯一使用它的人,那么这没什么大不了的。但是,您必须“强制”推动。这就是为什么
假设您有以下提交:
A -- B
L newBranch | commit with the file you didn't want to modify
自从您推送以来,这就是您在本地和远程存储库中拥有的内容。
修复后(使用解决方案 1 或 2),您将在本地存储库中拥有
A -- B2
\ L newBranch |fixed commit
\
\- B
L commit with the file you didn't want to modify, not on any branch anymore
如果您尝试git push origin newBranch,它将失败,因为您不能将fast forward 从B 转换为B2。
所以你需要git push -f origin newBranch 告诉 git “我知道我在做什么;继续前进吧”。
阅读http://git-scm.com/book/en/Git-Branching-Remote-Branches 可能有助于澄清这些概念