我可以在GIT中进行部分还原吗


156

是否可以仅还原单个文件或在多文件提交中还原文件中的某些更改?

全文 我提交了一堆文件。一些提交之后,一个将保持匿名的人(JACK !!!)将文件复制到他的存储库中,并提交了几个文件,覆盖了我所做的某些更改。我想还原一个被破坏或更严重的文件,请进入并还原该文件中的两个更改。由于它已被拉入和推入,因此必须是单独的还原提交。


布莱恩让我走上了正轨。我最终使用了git add --patch,然后使用patch中的edit函数来获取我想要的东西。
离合器

2
我玩游戏已经很晚了,但是我认为我找到了“正确”的答案
ntc2

@ ntc2奇怪的是,被接受的答案对我来说比您链接的要好得多-它创建了合并冲突供我解决,而不仅仅是无法应用补丁。
Iiridayn

@liridayn你看完我的全部答案吗?在“变体”部分中,我声称添加--3way结果会导致合并冲突,而不是无法应用补丁。
ntc2

Answers:


204

您可以通过添加'--no-commit'选项来还原提交而无需创建新提交。这会将所有还原的文件留在登台区域中。从那里,我将执行软重置并添加我真正想要的更改。对于示例工作流:

git revert <sha-of-bad-commit> --no-commit
git reset   // This gets them out of the staging area
<edit bad file to look like it should, if necessary>
git add <bad-file>
git checkout . // This wipes all the undesired reverts still hanging around in the working copy
git commit

42
软重置后,您还git add -p可以启动一个交互式会话,该会话允许您选择性地添加文件块,而不是整个文件。(还有git reset -p选择性地取消变更的步骤。很高兴知道,但在这种情况下可能不是您想要的。)
StéphanKochen

1
这正是我在寻找的内容:恢复为工作副本,以交互方式选择大块,然后提交。您值得为此而
大声疾呼

这个灵感来自另一种解决办法是revertresetstash -p(藏“取消,我不想actualy化妆”),add其余部分commit
西里尔CHAPON

82

您可以使用以下checkout命令以交互方式应用文件的旧版本。

例如,如果您知道COMMIT添加回去的代码在哪里被删除,则可以运行以下命令:

git checkout -p COMMIT^ -- FILE_TO_REVERT

Git将提示您重新添加当前文件版本中缺少的块。您可以e先创建更改补丁,然后再应用更改。


如果只想还原部分文件,则非常有用!基本上,是要从头上git checkout -p path/to/file
拿走

40

您只需使用即可手动检出要还原的文件的旧旧内容git checkout。例如,如果您想还原my-important-file到version中的版本abc123,则可以执行

git checkout abc123 -- my-important-file

现在您有了my-important-fileback 的旧内容,甚至可以根据需要对其进行编辑,然后像往常一样提交以进行提交,以恢复他所做的更改。如果您只想还原其提交的某些部分,请使用git add -p,从您提交的补丁中仅选择一些块。


19
这不是revert,您只是在取回文件的旧版本。适当的人员revert将删除文件中的错误提交修改,即使自该错误提交以来已对其进行了多次修改,并且您也不想丢失这些修改。
Totor

2
托尔,看我的答案。您可以使用'-p'保存修改。答案实际上与这一答案非常接近。
cmcginty

1
或者您可以将其合并为git checkout -p
Lao Lam 2015年

31

我在Git邮件列表中找到了一种方法:

git show <commit> -- <path> | git apply --reverse

来源:http//git.661346.n2.nabble.com/Revert-a-single-commit-in-a-single-file-td6064050.html#a6064406

变化

如果补丁不能很好地应用,那么该命令将失败(不进行任何更改),但是与--3way您相反,您将遇到冲突,可以手动解决(在这种情况下,Casey的回答可能更实际):

git show <commit> -- <path> | git apply --reverse --3way

您还可以使用它来部分还原多个提交,例如:

git log -S<string> --patch | git apply --reverse

恢复<string>任何提交中具有匹配更改的文件。这正是我在用例中所需要的(一些单独的提交对不同的文件进行了类似的更改,并以我不想还原的无关方式更改了其他文件)。

如果已diff.noprefix=true设置,~/.gitconfig则需要添加-p0git apply命令,例如

git show <commit> -- <path> | git apply -p0 --reverse

这个答案比公认的答案要好得多:“更好,请进入并还原该文件中的两个更改”。
重写

我只想还原提交的一部分,所以我做了:(1) git show ... > foo.txt (2)编辑foo.txt以删除差异,我不想还原(3) git apply --reverse foo.txt还原仍在中列出的差异foo.txt
cxw

在git show part中添加--binary --full-index也可能是一个有用的变化
Laurynas Biveinis
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.