git - 撤消旧提交中对特定文件的更改,不留下任何痕迹

标签 git version-control git-revert

我有一个分支,我在几个提交中对几个文件做了一些更改。有一次,前一段时间,我开始对这些文件的一个子集进行一些工作,并 checkin 了一些更改。之后,我们决定将这些文件删除,作为在另一个分支中完成的工作的一部分。因此,我想“取消”那些文件——它们与我在我的分支中所做的不再相关,我不想因此与其他地方删除的文件造成任何 merge 冲突。

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

更具体地说:

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

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,但一直没能想出一种方法来做到这一点而不创建新的提交,这会重置旧提交所做的更改。我知道我也可以通过简单地删除我的分支中的文件来避免 merge 冲突,但这感觉像是一个“丑陋”的解决方案,这次有效但下一次可能无效(如果另一个分支中的更改不是删除,怎么办,但修改?),所以如果有更简洁的方法,我想学习它。

最佳答案

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

首先,我使用 git rebase -i master 进行了交互式 rebase 。 .这打开了我的文本编辑器(我碰巧将 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

接着是一些关于如何编辑文件的评论。我所做的是用我想更改的提交更改行

...
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 - 撤消旧提交中对特定文件的更改,不留下任何痕迹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17531238/

相关文章:

xcode - 多个 git 帐户不适用于 Xcode

java - 我应该将 SQL 文件放在我的 Java 项目中的什么位置?

git - 如何还原多个 Git 提交?

git - git恢复到某些提交,而不更改历史记录并创建一个新的提交,如git revert

git - 查看 Git 忽略或排除的所有内容的命令?

git - 如果 merge 两个具有相同提交的分支会发生什么?

混帐 : empty ident name (for <>) not allowed

eclipse - 如何在分支之间正确合并,从不同版本的主干分支?

linux - 如何对 git 和 gitolite 钩子(Hook)进行版本控制?

git - 推送后重做错误的 git 冲突解决