我有一个分支,我在几个提交中对几个文件做了一些更改。有一次,前一段时间,我开始对这些文件的一个子集进行一些工作,并 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/