Git:从一个分支的给定文件中删除所有更改的最佳方法

Ste*_*ett 12 git git-merge git-rebase git-branch

我有一个混乱的分支,有20个左右的提交,我正准备合并回主人.我已经把它从主人那里重新定位,并且仔细观察,我意识到有些文件正在以与这个分支完全无关的方式进行修改,而且还没有准备好提交.对这些文件的更改不仅限于特定的提交.

所以基本上,如果可能的话,我不想要将这些文件包含在这个分支中.有没有好办法解决这个问题?我的后退位置#1显然只是复制每个文件的最新副本然后提交.但是历史仍然会包含变化,而Git Gods会对我不满.

退回位置#2是做同样的事情,然后将整个分支历史压缩到一个提交.

对这些有什么改进?

Gre*_*con 18

说你的历史是

$ git lola
* 6473d7f (master) Update
| * 9bcfa7e (HEAD, topic) Munge a, b, and c
| * 99af942 Munge b and c
| * 8383e2c Munge a and b
|/
* d1363f4 Baseline

注意:lola是一个非标准但有用的别名.

提交修改了三个不同的文件.

$ git log --decorate=short --pretty=oneline --name-status topic
9bcfa7e946a92c226ad50ce430a9e4ae55b32490 (HEAD, topic)
M       a
M       b
M       c
99af942dbb922effcad8a72e96bec9ee9afcc437 Munge b and c
M       b
M       c
8383e2c8d6092550fec13d3c888c037b3a68af15 Munge a and b
M       a
M       b
d1363f4fba67d94999b269b51bdb50a8a68ba27a Baseline
A       a
A       b
A       c

对文件的更改b是您要保留的,并且您要放弃对a和的所有更改c.一种方法是这样做git filter-branch.

$ git checkout -b tmp topic
Switched to a new branch 'tmp'

$ git merge-base topic master
d1363f4fba67d94999b269b51bdb50a8a68ba27a

$ git filter-branch --tree-filter 'git checkout d1363f -- a c' master..tmp
Rewrite 8383e2c8d6092550fec13d3c888c037b3a68af15 (1/3)
Rewrite 99af942dbb922effcad8a72e96bec9ee9afcc437 (2/3)
Rewrite 9bcfa7e946a92c226ad50ce430a9e4ae55b32490 (3/3)
Ref 'refs/heads/tmp' was rewritten

上面的树过滤器检查命名范围中的提交并恢复文件ac"合并基础"中的内容,即topic分支离开的提交master.

现在tmp已经进行了所有topic更改,b但没有更改任何其他文件.

$ git log --decorate --pretty=oneline --name-status tmp
9ee7e2bd2f380cc338b0264686bcd6f071eb1087 (HEAD, tmp) Munge a, b, and c
M       b
226c22f150af1ddc1f9adc19f97fc4f220851ada Munge b and c
M       b
45e706f7b22c37ee2025ee0d04c651135e7b31cd Munge a and b
M       b
d1363f4fba67d94999b269b51bdb50a8a68ba27a Baseline
A       a
A       b
A       c

作为安全措施,git filter-branch存储原始参考的备份.如果您对更改感到满意并想要删除备份tmp,请运行

$ git update-ref -d refs/original/refs/heads/tmp

  • +1优秀的答案.一旦你将头部包裹起来,使用filter-branch就是一个非常了不起的工具. (3认同)