这是我遇到的常见情况,我正在寻找一种干净的解决方案。
my-first-work
)上做一些工作some-further-work
的顶部,开始新的分支(my-first-work
未指定的时间间隔
my-first-work
变基或压榨到master
master
的头部与{{1的头部)相同,git也不会将其视为我所基于的东西}})my-first-work
将git rebase master
移到some-further-work
master
所做的提交都与已经被压榨/合并的内容冲突当前,我通过使用my-first-work
来解决此问题,然后删除直到git rebase -i master
头的所有提交。这样可以干净地重播my-first-work
顶部的其他提交。
是否有更清洁的解决方案?并有一种方法可以使git在发生变基/压扁(如4)时自动识别?
答案 0 :(得分:1)
清洁程序在旁观者/工作人员的眼中(或手?),但是您可以使用git rebase --onto
来分离出要复制的 放置副本的位置。
请记住git rebase
的意思是: 1 我有一个线性的提交链,如图1所示,我想复制到一个新的线性提交链,如下所示:如图2所示。完成复制后,我希望我的分支名称指向上次复制的提交。原始的A-B-C
链即使仍然存在也不再有用。
[drawing 1]
...--o--*--o <-- upstream/master
\
A--B--C <-- topic
[drawing 2]
...--o--*--o <-- upstream/master
\
A'-B'-C' <-- topic
原始提交和副本之间的区别在于,原始提交基于提交*
,之前是upstream/master
的提示。副本基于upstream/master
的(新)提示。短语<基于> 在这里有两个含义:提交A
的父对象是提交*
,而 的父对象>提交A'
是后面的提交,而快照中的提交A
是*
加上一些变化,而快照中的 commit A'
将 same 更改添加到以后提交中。
由于我们使用有光泽的新提交A'
(具有不同的哈希值)来支持旧的呆板A
,因此我们需要将B
复制到B'
,以及C
到C'
,一旦完成,我们需要我们的名字topic
指向的不是最后复制的提交C
,而不是C'
。
纯白的git rebase
正是这样做的。我们说:
git checkout topic; git rebase upstream/master
告诉Git:
C
开始并向后工作的所有提交。那是C
然后B
然后A
然后*
然后*
之前的所有内容。upstream/master
开始并向后工作的所有提交。这是第二个o
,然后是*
,然后是*
之前的所有内容。 *
和所有较早的提交。第二个o
不在第一个列表中,但是没关系:如果被插入,我们将其淘汰,但事实并非如此,因此我们什么也不做。现在,我们的列表为C
,B
和A
。upstream/master
指向的提交开始。因此,这会将A
复制到A'
,将B
复制到B'
,然后{{ 1}}到C
。C'
移出先前的位置,并像往常一样将其粘贴到新的提交链中。因此,这使topic
指向到topic
,而不是C'
。在新情况下,您有:
C
他们在上游没有抓住您的...--o--* <-- upstream/master
\
A--B--C <-- feature1
\
D--E--F--G <-- feature2
连锁店。相反,他们进行了自己的不同的A-B-C
壁球提交。您从上游存储库中获取了它,所以现在有了:
ABC
如果仅运行...--o--*--ABC <-- upstream/master
\
A--B--C <-- feature1
\
D--E--F--G <-- feature2
,则Git将枚举提交git checkout feature2; git rebase upstream/master
,枚举G-F-E-D-C-B-A-*-...
,从第一个中减去第二个,然后留下复制{{1} }链。
发烧友的变基命令是:
ABC-*-...
此操作将 target 参数(Git开始复制的位置)与 limit 参数分开。现在 target 是G-F-E-D-C-B-A
(Git文档将其称为 onto 参数)。现在 limiting 参数为git checkout feature2
git rebase --onto upstream/master feature1
。如果愿意,可以使用提交upstream/master
的原始哈希ID。 Git只需要知道:我从哪里开始我的敲除这些提交枚举?(令人困惑的是,Git文档将此称为 upstream 参数。)
如您所见,这现在剔除feature1
提交,而不仅仅是C
提交,因此在复制之后,您将:
C-B-A-*
现在Git可以将标签*
从 D'-E'-F'-G' [in progress]
/
...--o--*--ABC <-- upstream/master
\
A--B--C <-- feature1
\
D--E--F--G <-- feature2
上剥下来,然后贴在feature2
上。
1 从技术上讲,G
还有很多功能,尤其是现在有了新的G2
选项。但是,这个我有一个线性的提交链仍然是它的 main 用途。
作为一个不错的奖励,rebase通常可以判断他们是否已经采用了您的git rebase
链并将其复制到自己的--rebase-merges
链。但这只是通常。 Rebase永远不会告诉他们他们已经将您的A-B-C
压入自己的A'-B'-C'
中,因此在这种情况下,您会陷入A-B-C
的困境。 / p>