[英]How can I merge a git branch so that topic commits are orphaned?
I'm still coming up to speed with some of the more advanced features of Git... 我还在加速使用Git的一些更高级的功能......
Given the following history, how can I clean up topic branch merges so they appear in history as a single commit? 鉴于以下历史记录,我如何清理主题分支合并,以便它们作为单个提交出现在历史记录中?
[master] - - - - - - - C - - -
\
[feature] - A - - B - - D -
Ideally, I'd like to rebase [feature] with [master] at D and then merge [feature] into [master], leaving A and B orphaned. 理想情况下,我想在D处使用[master]重新设置[feature],然后将[feature]合并到[master]中,让A和B成为孤儿。
I thought I could do this simply by: 我以为我可以通过以下方式做到这一点:
$ git rebase master # on feature branch
$ git co master
$ git merge --no-ff feature
and then clean up the orphaned commits with 然后清理孤立的提交
$ git gc --prune=now --aggressive
That still leaves A and B in the history though - Am I missing something? 尽管如此,这仍然留下了历史上的A和B - 我错过了什么吗?
If I redraw your diagrams to place the branch markers at the tip of the branch (which reflects the actual representation of branches) your original situation is: 如果我重新绘制图表以将分支标记放在分支的顶端(这反映了分支的实际表示),那么您的原始情况是:
o --- C (master)
\
--- A --- B --- D (feature)
And after rebasing and merging with --no-ff
as you describe, you now have: 在你按照你所描述的变化和--no-ff
合并之后,你现在拥有:
o --- C ------------------ M (master)
\ \ /
\ A' --- B' --- D' (feature)
\
--- A --- B --- D
As I understand it, you now want to make sure that A
, B
and D
disappear from your repository. 据我了解,您现在想确保A
, B
和D
从您的存储库中消失。 Firstly, I would say that I strongly recommend that you don't worry about these commits. 首先,我想说我强烈建议您不要担心这些提交。
However, if you really want to get rid of them, then you will have to make sure that they are truly unreachable, or git gc --prune=now --aggressive
will not remove them. 但是,如果你真的想摆脱它们,那么你必须确保它们真的无法到达,或者git gc --prune=now --aggressive
不会删除它们。 As it is, they will still be pointed to (at least) by the reflog for feature
. 实际上,它们仍将被(至少)指向feature
的reflog。 There are various ways of expiring entries from the reflog, eg with: 有各种方法可以使reflog中的条目到期,例如:
git reflog expire --expire=now feature
... or a safer option should be to set the config variable gc.reflogexpireunreachable
to now
and expire the reflog: ...或者更安全的选项应该是将配置变量 gc.reflogexpireunreachable
设置为now
并使reflog过期:
git config gc.reflogexpireunreachable
git reflog expire feature
In either case, you would then need to run git gc --prune=now --aggressive
afterwards again. 在任何一种情况下,您都需要再次运行git gc --prune=now --aggressive
。
However, to reiterate what I said above, I wouldn't do this - those commits aren't hurting anyone and the reflog is a valuable safety net when using git. 但是,重申我上面所说的,我不会这样做 - 那些提交不会伤害任何人,并且使用git时reflog是一个有价值的安全网。
If you want to "fuse" A, B and D, you can use an interactive rebase. 如果你想“融合”A,B和D,你可以使用交互式rebase。
If your branch feature
is on top of master
(which it will be after you have issued git rebase master
on this branch), do: 如果你的分支feature
在master
之上(在你在这个分支上发布git rebase master
之后它就会出现),请执行以下操作:
git rebase -i master
Then, in the file which will open in an editor, replace the pick
on commits A and B with squash
. 然后,在将在编辑器中打开的文件中,用squash
替换提交A和B的pick
。 Git will then squash A and B into D, and an editor will pop with the commit messages for all squashed commits. 然后Git将A和B压缩到D中,编辑器将弹出所有压缩提交的提交消息。
If you want to collapse the effect of a branch into a single commit, then from master do: 如果要将分支的效果折叠为单个提交,则从master执行:
git merge --squash feature
git commit
although IMHO being able to keep the individual commits on the branch intact is actually a good feature most of the time. 虽然恕我直言,能够保持分支上的个人提交完好无损,但实际上大多数时候都是一个很好的功能。
Alternatively, you could use git rebase -i
on the branch and tell it to squash all the commits together, and then merge the squashed result onto master. 或者,您可以在分支上使用git rebase -i
并告诉它将所有提交压缩在一起,然后将压扁的结果合并到master上。
Why would it remove A and B? 为什么要删除A和B?
The git rebase master
will make feature to be branched off the tip of master and when you commit, all the commits from feature will come to master. git rebase master
将使功能从master的尖端分支出来,当你提交时,所有来自feature的提交都将掌握。 Thus you will see A and B ( actually A' and B') 因此你会看到A和B(实际上是A'和B')
And git gc
doesn't have anything to do with what you see in the history. 而git gc
与您在历史中看到的内容没有任何关系。 It removes dangling commits ( which can be A and B, but you have A' and B' in master now) 它删除了悬空提交(可以是A和B,但你现在拥有A'和B')
If you want them to come as single commit, try the --no-commit
option or look at other alternatives like git rebase -i
( and squash) 如果你想让它们作为单个提交,请尝试--no-commit
选项或查看其他替代方案,如git rebase -i
(和squash)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.