我有一个分支,我在几个提交中对几个文件进行了一些更改。有一段时间,我开始对这些文件的子集做一些工作,并检查了一些更改。之后,我们决定删除这些文件作为另一个分支中正在完成的事情的一部分。因此,我想“解开”那些文件 - 它们与我在分支机构中的操作无关,而且我不希望因此而导致与其他已删除文件发生任何合并冲突。
有没有什么方法可以更新进行这些更改的提交,使这些文件保持不变,并且在我的分支历史之外?
更具体地说:
在当前状态下考虑以下源树:
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
,但是如果没有创建新的提交,那么就无法找到一种方法来实现它,这会重置旧提交所做的更改。我知道我也可以通过简单地删除我的分支中的文件来避免合并冲突,但这感觉就像一个“丑陋”的解决方案,这次工作但可能不是下一个(如果另一个分支的更改不是删除,但修改?),所以如果有更清洁的方式我想学习它。
答案 0 :(得分:1)
虽然在评论中 the now deleted answer by RyPeck RyPeck linked to a good way of doing this using git filter-branch
,但我解决了它的不同,所以我想我会分享我是如何做到的 - 如果没有其他目的,那么作为未来我的参考(谁不可避免地要再次问互联网这个问题,可能很快......):
首先,我使用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
后面是一些关于如何编辑文件的评论。我所做的是用我想改变的提交改变行
...
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
模式,您可以对其进行任何更改。