如何在单个文件上回滚(重置)git 中已提交的更改

How to roll back (reset) a committed change in git on a single file

我在我的功能分支上有一个提交,由 3 个文件组成,其中一个现在与 master 有合并冲突。

我愿意:

我试过还原,但这适用于整个提交而不是单个文件。

我已经尝试检查单个文件(在我想回滚提交之前的修订版)并提交它(实质上恢复单个文件)。然而,当我变基时,冲突仍然发生。

我觉得我需要以某种方式对这个单个文件进行硬重置,但我看不到重置单个文件的方法。

您可以从另一个提交中使用 git checkoutget a single file,如下所示:

git checkout <commit> -- path/to/file

为防止冲突,您应该将新提交压缩到之前的(冲突)提交中。


变基将应用列表中的每个提交,一次一个。如果您有冲突,那么每次变基时都必须重新解决该冲突。这就是我更喜欢良好的合并的原因之一。合并发生在堆栈的顶部(因此您的反冲突提交将适用),您所做的任何冲突 运行 只需解决一次。

如果你真的想使用变基,那么你可以 git rebase -i HEAD~N (其中 N 是你需要返回以获取冲突提交的许多提交)然后直接编辑该提交(放置一个 e 在编辑器中它旁边)或将第二个提交压缩到第一个(在新提交旁边放置一个 s)。基本上,您需要更改您的提交历史记录。那么你应该能够从 master 变基。

这里的问题是概念性的:您正在执行适用于提交的命令,并试图将它们应用到文件,这会扭曲您关于如何解决手头问题的推理。

澄清一下:文件不是单独提交的。每个提交都有一个 TREE,代表整个项目内容的状态。您更改了三个文件,这将创建一个新的内容状态;您 git commit,这会创建 一个新的 COMMIT 对象 ,其中 TREE 表示项目的新状态。

也许混淆来自对其他源代码管理工具的熟悉。例如,git 使用的提交模型与 CVS 不同,在 CVS 中,更改会提交到单个版本化文件。

因此,如果您使用 reset 之类的东西回滚,您将撤消 所有 的更改。如果您 rebasemaster 获取更改,您将从 master 获取 所有 的更改。

这并不意味着你无法到达你想去的地方;你只需要稍微改变一下就可以了。

最简单(也是 IMO 最适合这种情况)的做法是在合并操作期间解决此问题。一旦 get 告诉您存在冲突,您就可以获得一个冲突文件的 masters 版本

git checkout master -- path/to/conflicting/file

然后您可以使用您正在使用的任何编辑器或 IDE 手动重新应用您的更改。 (如果您需要查看最初所做的更改,您可以随时 git diff HEADgit merge-base HEAD master-- path/to/conflicting/file。)然后

git add path/to/conflicting/file

将冲突标记为已解决,并且

git commit

完成合并。