如何在单个文件上回滚(重置)git 中已提交的更改
How to roll back (reset) a committed change in git on a single file
我在我的功能分支上有一个提交,由 3 个文件组成,其中一个现在与 master 有合并冲突。
我愿意:
- 回滚冲突文件的提交
- 从 master 变基到有冲突的文件
- 手动重新应用我对该文件的回滚更改
我试过还原,但这适用于整个提交而不是单个文件。
我已经尝试检查单个文件(在我想回滚提交之前的修订版)并提交它(实质上恢复单个文件)。然而,当我变基时,冲突仍然发生。
我觉得我需要以某种方式对这个单个文件进行硬重置,但我看不到重置单个文件的方法。
您可以从另一个提交中使用 git checkout
到 get 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
之类的东西回滚,您将撤消 所有 的更改。如果您 rebase
从 master
获取更改,您将从 master 获取 所有 的更改。
这并不意味着你无法到达你想去的地方;你只需要稍微改变一下就可以了。
最简单(也是 IMO 最适合这种情况)的做法是在合并操作期间解决此问题。一旦 get 告诉您存在冲突,您就可以获得一个冲突文件的 master
s 版本
git checkout master -- path/to/conflicting/file
然后您可以使用您正在使用的任何编辑器或 IDE 手动重新应用您的更改。 (如果您需要查看最初所做的更改,您可以随时 git diff HEAD
git merge-base HEAD master-- path/to/conflicting/file
。)然后
git add path/to/conflicting/file
将冲突标记为已解决,并且
git commit
完成合并。
我在我的功能分支上有一个提交,由 3 个文件组成,其中一个现在与 master 有合并冲突。
我愿意:
- 回滚冲突文件的提交
- 从 master 变基到有冲突的文件
- 手动重新应用我对该文件的回滚更改
我试过还原,但这适用于整个提交而不是单个文件。
我已经尝试检查单个文件(在我想回滚提交之前的修订版)并提交它(实质上恢复单个文件)。然而,当我变基时,冲突仍然发生。
我觉得我需要以某种方式对这个单个文件进行硬重置,但我看不到重置单个文件的方法。
您可以从另一个提交中使用 git checkout
到 get 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
之类的东西回滚,您将撤消 所有 的更改。如果您 rebase
从 master
获取更改,您将从 master 获取 所有 的更改。
这并不意味着你无法到达你想去的地方;你只需要稍微改变一下就可以了。
最简单(也是 IMO 最适合这种情况)的做法是在合并操作期间解决此问题。一旦 get 告诉您存在冲突,您就可以获得一个冲突文件的 master
s 版本
git checkout master -- path/to/conflicting/file
然后您可以使用您正在使用的任何编辑器或 IDE 手动重新应用您的更改。 (如果您需要查看最初所做的更改,您可以随时 git diff HEAD
git merge-base HEAD master-- path/to/conflicting/file
。)然后
git add path/to/conflicting/file
将冲突标记为已解决,并且
git commit
完成合并。