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

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

完整故事 我提交了一堆文件。几次提交之后,一个不愿透露姓名的人(Jack!)将一个文件复制到他的存储库中,并提交了几个文件,覆盖了我所做的一些更改。我想恢复一个被破坏的文件,或者更好的是,进入并恢复该文件中的两个更改。这必须是一个单独的恢复提交,因为它是拉入和推送的。

48952 次浏览

您可以通过添加“--no-commit ”选项来恢复提交,而不创建新的提交。这会将所有还原的文件保留在临时区域中。

从那里,我会执行一个混合重置(重置的默认值)来取消暂存文件,并添加我真正想要的更改。然后,提交(如果需要多次提交,您可以添加并提交更多文件),最后,签出当前目录以清除由revert产生的任何未提交和未暂存的修改。对于示例工作流程:

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 commit
git checkout . # This wipes all the undesired reverts still hanging around in the working copy

您可以使用git checkout手动签出要恢复的文件的旧的、完好的内容。例如,如果要将my-important-file恢复为版本abc123中的版本,则可以执行以下操作

git checkout abc123 -- my-important-file

现在,您可以将my-important-file的旧内容恢复,如果您愿意,甚至可以编辑它们,并像往常一样提交以进行提交,这将恢复他所做的更改。如果您只想恢复其提交的某些部分,请使用git add -p从您要提交的修补程序中仅选择几个大块。

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

例如,如果您知道COMMIT,其中删除了要添加回的代码,则可以运行以下命令:

git checkout -p COMMIT^ -- FILE_TO_REVERT

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

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

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

来源:_农行_0

变奏

如果修补程序未完全应用,则该命令将失败(不会导致任何更改),但如果使用--3way,则会出现冲突,然后您可以手动解决这些冲突(在这种情况下,凯西的回答可能更实用):

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

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

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

要在任何提交中恢复具有与<string>相匹配的更改的文件。这正是我在我的用例中所需要的(几个单独的提交引入了对不同文件的类似更改,以及以我不想恢复的不相关方式对其他文件的更改)。

如果您在~/.gitconfig中设置了diff.noprefix=true,则需要将-p0添加到git apply命令中,例如

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