【问题标题】:Undoing changes to specific files in old commits, leaving no trace of them撤消对旧提交中特定文件的更改,不留下任何痕迹
【发布时间】:2013-07-06 01:22:02
【问题描述】:

我有一个分支,我在多个提交中对多个文件进行了一些更改。有一次,不久前,我开始对这些文件的一个子集做一些工作,并检查了一些更改。之后,我们决定删除这些文件,作为在另一个分支中完成的工作的一部分。因此,我想“取消”这些文件 - 它们与我在分支中所做的事情不再相关,并且我不想因此与其他已删除的文件造成任何合并冲突。

我有什么方法可以更新做出这些更改的提交,以使这些文件保持不变,并且在我的分支的历史记录之外

更具体的说法:

考虑以下处于当前状态的源代码树:

src/A.java
src/B.java
src/C.java
src/D.java

在历史记录中大约有 10 次提交,进行了一次提交,以下列方式进行了更改:

M   src/B.java
M   src/C.java
A   src/D.java

有没有办法可以从历史记录中删除对C.java 的更改,这样当您查看上面的提交时,它看起来就像

M   src/B.java
A   src/D.java

如你所见,C.java 从未被我的分支触及过。

我查看了git revert,但在不创建新提交的情况下无法找到一种方法来做到这一点,这会重置旧提交所做的更改。我知道我也可以通过简单地删除我的分支中的文件来避免合并冲突,但这感觉就像一个“丑陋”的解决方案,这一次有效但可能不是下一次(如果另一个分支中的更改不是删除,怎么办?但是修改?),所以如果有更清洁的方法我想学习它。

【问题讨论】:

标签: git version-control git-revert


【解决方案1】:

虽然 the now deleted answer by RyPeck RyPeck linked to a good way of doing this using git filter-branch 在 cmets 中,我以不同的方式解决了它,所以我想我会分享我是如何做到的 - 如果没有其他目的,那么作为参考未来的我(他将不可避免地不得不再次在互联网上问这个问题,可能很快......):

首先,我使用git rebase -i master 进行了交互式变基。这打开了我的文本编辑器(我碰巧将 git 配置为打开 Notepad++),文件类似于:

pick First commit message
pick Second commit message
pick This is where I touched the files I didn't want to touch
pick Another commit
pick This goes on for a while
pick I think you get the point
pick I'll stop now

随后是一些 cmets 关于如何编辑文件的内容。我所做的是用我想要更改的提交更改行

...
edit This is where I touched the files I didn't want to touch
...

然后保存并关闭编辑器。然后发生的事情是 git 应用了三个第一个提交,然后停止并说

Stopped at <hash>... This is where I touched the files I didn't want to touch
You can amend the commit now, with

    git commit --amend

Once you are satisfied with your changes, run

    git rebase --continue

然后,我将文件重置为提交之前的状态,使用类似于

git reset HEAD^ src/C.java # undoes the changes to the file
git add src/C.java         # stages the undoing of the changes
git commit --amend         # amends the undoing to the last commit

之后,提交更改了文件两次——第一次是我所做的更改,然后再次返回——并且 git 将这两组更改压缩为一组,其中它们取消并且什么都不做。我现在跑

git rebase --continue

完成工作。如果我现在查看 src/C.java 的历史记录,这组提交什么都没有。

这种技术非常灵活 - 使用提交的edit 模式,您可以对其进行任何更改。

【讨论】:

  • 这对于大型项目历史来说将是一个巨大的痛苦。只是为了讨论,这与 git filter-branch 最终所做的有多大不同?
  • @IamReck:我不知道——直到我已经这样做了才找到你的答案,所以我没有机会测试git filter-branch 看看会发生什么。如果我有时间,我可能会检查一个虚拟分支并运行一些测试。
  • @IamReck:另外,关于“大型项目历史”:这绝对不是我建议在更大范围内进行的事情,或者在多个开发人员之间共享的任何事情上。在我的例子中,我独自在一个特性分支上工作,并决定一些更改应该真正在他们的分支中,因为它们是不同特性的一部分。所以我的更改都在一个本地的、未发布的分支上——这样的分支历史(希望)永远不会是巨大的......
  • 我没有正确执行 git filter-branch 。我在这里找到了正确的方法。 stackoverflow.com/questions/9751928/…
猜你喜欢
  • 2021-08-31
  • 1970-01-01
  • 2011-01-31
  • 2015-05-29
  • 1970-01-01
  • 1970-01-01
  • 2019-04-28
  • 2011-09-09
  • 1970-01-01
相关资源
最近更新 更多