2011-01-25 73 views
96

我想恢复git中的特定提交。不幸的是,我们的组织仍然使用CVS作为标准,所以当我重新回到CVS时,多个git提交被合并为一个。在这种情况下,我很想单独提供原始的git commit,但这是不可能的。使用git恢复提交的一部分

是否有类似于git add --patch的方法,它允许我选择性地编辑差异来决定要恢复的提交的哪些部分?

+0

更多解决方案[here](http://stackoverflow.com/q/5669358/470844),但重点是限制部分恢复到特定文件。 – ntc2 2014-08-26 23:02:04

回答

160

使用--no-commit-n)选项git revert,然后unstage的变化,然后使用git add --patch

$ git revert -n $bad_commit # Revert the commit, but don't commit the changes 
$ git reset HEAD .    # Unstage the changes 
$ git add --patch .   # Add whatever changes you want 
$ git commit     # Commit those changes 

注意:您添加使用Git的文件添加--patch是要恢复这些文件,而不是你想保留的文件。

+12

可能值得添加最后所需的命令,对于那些不熟悉git的人来说:在提交之后,`git reset --hard`放弃您不想恢复的其他更改。 – tremby 2012-09-26 21:03:37

+10

`git reset --hard`对新手来说很危险,因为它可能会丢失想要的编辑。相反,习惯`git status`,这提示`git checkout - FILE..`可以更安全地恢复事物。 – Tino 2013-07-16 10:30:34

+0

`git`有什么大的遗漏; `git revert`应该只需要一个`--patch`参数。 – Kaz 2017-03-31 14:33:28

1

您可以使用git-revert -n,然后使用add --patch选择hunk。

32

我已经成功地使用了以下内容。

首先恢复完全提交(将其放入索引)但不提交。

git revert -n <sha1> # -n is short for --no-commit 

然后交互地从索引中移除

git reset -p   # -p is short for --patch 

的还原GOOD变化然后提交的不良变化反向的diff

git commit -m "Partially revert <sha1>..." 

最后恢复GOOD变化(已不分阶段由重置命令)仍然在工作树中。他们需要清理。如果没有其他未提交的更改都留在了工作树,这可以通过完成

git reset --hard 
4

解决方案:

git revert --no-commit <commit hash> 
git reset -p  # every time choose 'y' if you want keep the change, otherwise choose 'n' 
git commit -m "Revert ..." 
git checkout -- . # Don't forget to use it. 
3

就个人而言,我更喜欢这个版本,其中重用自动生成的提交信息,并给出用户有机会在最终提交之前编辑并粘贴“部分”一词。

# generate a revert commit 
# note the hash printed to console on success 
git revert --no-edit <hash to revert> 

# undo that commit, but not its changes to the working tree 
# (reset index to commit-before-last; that is, one graph entry up from HEAD) 
git reset HEAD~1 

# interactively add reversions 
git add -p 

# commit with pre-filled message 
git commit -c <hash from revert commit, printed to console after first command> 

# reset the rest of the current directory's working tree to match git 
# this will reapply the excluded parts of the reversion to the working tree 
# you may need to change the paths to be checked out 
# be careful not to accidentally overwrite unsaved work 
git checkout -- .