撤销 Git 中某些文件的更改

207
在编码时,我在一些文件中添加了打印语句以跟踪发生的情况。
完成后,是否有可能还原某些文件的更改,但提交我实际上正在工作的文件?
比如我在文件A中添加了打印语句,但修改了文件BB 是我要提交的内容,而A应该恢复到旧状态。

6个回答

315

根据您对文件A所做的更改情况,有三种基本方法可供选择。如果您尚未将更改添加到索引或提交它们,则只需使用checkout命令-此操作将更改工作副本的状态以匹配存储库:

git checkout A
如果您已将其添加到索引中,请使用reset:
git reset A
如果你已经提交了它,那么你可以使用revert命令:
# the -n means, do not commit the revert yet
git revert -n <sha1>
# now make sure we are just going to commit the revert to A
git reset B
git commit

如果相反,你已经提交了这个修改,但是这次提交涉及到很多你不想撤销的文件,那么上面的方法可能会涉及很多“重置B”的命令。在这种情况下,你可以使用这种方法:

# revert, but do not commit yet
git revert -n <sha1>
# clean all the changes from the index
git reset
# now just add A
git add A
git commit

另一种方法是使用rebase -i命令。如果您需要编辑多个提交,则此方法可能很有用:

# use rebase -i to cherry pick the commit you want to edit
# specify the sha1 of the commit before the one you want to edit
# you get an editor with a file and a bunch of lines starting with "pick"
# change the one(s) you want to edit to "edit" and then save the file
git rebase -i <sha1>
# now you enter a loop, for each commit you set as "edit", you get to basically redo that commit from scratch
# assume we just picked the one commit with the erroneous A commit
git reset A
git commit --amend
# go back to the start of the loop
git rebase --continue

注意:还原确实会还原所有提交,这可能意味着需要执行许多“reset B”,不是吗?请参见http://gitready.com/intermediate/2009/03/16/rolling-back-changes-with-revert.html的最后评论。(正如https://dev59.com/-nRB5IYBdhLWcg3wXmRI#642809中所述,“负合并”可能更准确)。 - VonC
是的,如果您有许多文件作为提交的一部分被修改,而您不想还原这些修改,那么就需要另一种方法,我将对此进行编辑并提出建议。 - 1800 INFORMATION
1
"git reset A" 相当于 "git checkout HEAD A"。 - Jakub Narębski
在GitGUI中是否有一个快速简便的点击操作可以将文件还原为存储库中的版本?使用Git bash可以解决问题...但如果可以通过点击完成,那会更快一些 :-) - Someone Somewhere
假设我在文件A(状态1)中进行了更改,并且该文件已在主分支上被修改(状态2)。如果我执行git checkout A命令,它会指向哪个状态,之前的状态1还是更新后的状态2..? - Bhavuk Mathur
对于一个特殊情况,当你:
  1. 使用Gerrit(或其他套件)进行代码审查
  2. 已经提交了你的更改
  3. 已经提交了审核
  4. 只想撤销特定文件中的更改
  5. 不想重置并启动全新的审查会话
我发现以下顺序最方便:
  1. 获取特定文件的变更集 git show HEAD [targe_file_name] > path/file.patch
  2. 撤销对特定文件所做的更改 git apply -R path/file.patch
  3. 提交和审查 git add -u git commit --amend git review
- Zhenhua

25

来源: http://git-scm.com/book/zh/v2/Git-基础-撤销操作

使用命令 git checkout -- modifiedfile.java 可以撤销对文件 modifiedfile.java 的修改。


1) 执行命令 git status,你会看到被修改的文件。

2) 执行命令 git checkout -- modifiedfile.java。

3) 再次执行命令 git status。


git checkout -- modifiedfile.java 是一个不错的技巧。谢谢。 - Chris
git checkout 已经完成了任务,谢谢! - ᴍᴇʜᴏᴠ

7
git add B # Add it to the index
git reset A # Remove it from the index
git commit # Commit the index

5

8
RTFM不是一个好的回答。git checkout A会导致错误。 - Ahmed

4
是的。
git commit FILE

将只提交文件。然后你可以使用

git reset --hard

撤销其他文件的本地更改。

可能还有其他方法,我不太清楚...

编辑:或者,如NicDumZ所说,只在想要撤消更改的文件上使用git-checkout(最佳解决方案取决于提交的文件是否更多还是需要撤消的文件是否更多:-)


1
为什么你不能简单地使用 "git add <file>"(甚至是 "git add --interactive" 或者 "git gui",它们都有交互式提交选项)标记你想要在提交中进行的更改,然后使用 "git commit" 而不是 "git commit -a"?
对于你的情况(针对你的示例),应该这样做:
prompt> git add B
prompt> git commit

只有对文件B的更改才会被提交,而文件A将保持“脏”,即在工作区版本中具有这些打印语句。当您想要删除这些打印语句时,只需使用

prompt> git reset A

或者

prompt> git checkout HEAD -- A

回滚到已提交的版本(即来自HEAD的版本,例如“git show HEAD:A”版本)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接