Git:从一个分支的给定文件中删除所有更改的最佳方法 [英] Git: best way to remove all changes from a given file for one branch

查看:268
本文介绍了Git:从一个分支的给定文件中删除所有更改的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有20个左右的提交,我有一个混乱的分支,我正准备合并回主。我已经将它从主机上重新命名,并且仔细观察,我发现有些文件被修改的方式与这个分支完全不相关,并且没有准备好承诺。对这些文件的更改并不局限于特定的提交。



因此,基本上,如果可能的话,我不希望将这些文件包含在此分支中。有没有一个很好的方法来解决这个问题?我的回退位置#1显然是复制每个这些文件的最新副本,然后提交。但是,历史仍然会包含这些变化,而Git Gods会皱眉。

回落位置#2是做同样的事情,然后挤压整个分支历史归结为一次提交。



对这些进行的任何改进?

解决方案

说你的历史是

 $ git lola 
* 6473d7f(master)更新
| * 9bcfa7e(HEAD,主题)Munge a,b和c
| * 99af942 Munge b和c
| * 8383e2c Munge a和b
| /
* d1363f4基线

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



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

 $ git log --decorate = short --pretty = oneline --name-status主题
9bcfa7e946a92c226ad50ce430a9e4ae55b32490(HEAD,主题)
M a
M b
M c
99af942dbb922effcad8a72e96bec9ee9afcc437 Munge b和c
M b
M c
8383e2c8d6092550fec13d3c888c037b3a68af15 Munge a和b
M a
M b
d1363f4fba67d94999b269b51bdb50a8a68ba27a基线
A a
A b
A c

对文件 b 的更改是您想要保留的更改,并且您想放弃对 a c 的所有更改。一种方法是使用 git filter-branch
$ b

 $ git checkout -b tmp主题
切换到新分支'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'被重写

上面的树过滤器检出指定范围内的提交并恢复文件 a c 添加到合并基础中的内容,即 topic master 分支的提交。

现在 tmp 包含所有主题 b 但没有更改任何其他文件。

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

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

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


I have a bit of a messy branch with 20 or so commits, and I'm preparing for a merge back to master. I've rebased it off master, and looking closer, I realise that there are files being modified in ways that are totally irrelevant to this branch, and not ready to be committed. The changes to those files aren't confined to specific commits.

So basically, I don't want anything to do with those files to be included in this branch if possible. Is there a good way to go about this? My fall back position #1 is obviously to just copy over the latest copy of each of those files then commit. But then the history will still contain the changes, and the Git Gods will frown upon me.

Fall back position #2 is to do the same, then squash the whole branch history down to one commit.

Any improvements on these?

解决方案

Say your history is

$ 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

Note: lola is a non-standard but helpful alias.

The commits have modified three different files.

$ 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

The changes to file b are the ones you want to keep, and you want to discard all changes to a and c. One way to do this is with 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

The tree filter above checks out the commits in the named range and restores files a and c to the content at the “merge base,” that is, the commit at which topic branched away from master.

Now tmp has all topic’s changes to b but no changes to any other file.

$ 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

As a safety measure, git filter-branch stores a backup of your original ref. When you’re satisfied with your changes and want to delete the backup tmp, run

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

这篇关于Git:从一个分支的给定文件中删除所有更改的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆