我有一个本地git存储库,在Github中有一个远程上游。我在本地存储库中为正在使用的新功能创建了branchA,然后为该分支提交了请求请求。在等待此PR在上游合并时,我想使用基于branchA的其他功能。因此,我从branchA创建了一个新的branchA1,并对该分支进行了一些更改。
现在我的branchA的PR是壁球,并合并到Github的远程上游,我想为我的branchA1提交PR。我所做的是,我首先从远程上游获取了对本地master分支的更改。然后,我尝试在branchA1中执行git rebase master
,但是此命令似乎正在删除我在branchA1中所做的所有更改。
如果我想从branchA1提交PR,最好的做法是什么?
如果我在工作流程中做错了什么,那么等待父分支的PR合并时使用新功能的正确方法是什么?
答案 0 :(得分:3)
TL; DR:您可能想要git rebase --onto
(需要一些额外的参数)。
当您-或其他人时;我将在此处使用“他们”,并假设有人—在您原始的拉取请求中进行了“压榨并合并”,他们用他们认为比自己更好的一个新提交来替换您的提交您的原始提交。
但是,您仍然拥有原始提交。现在,您的工作是使用git rebase
仅复制您的A1
上的良好提交,而不复制两个{{1} }和A1
,现在仅在A
上。
您以图片的形式表示,例如:
A1
每个大写字母代表一个提交,其中...--o--o--A <-- master, origin/master
\
B--C--D <-- branch-A
\
E--F--G <-- branch-A1
是 在您的A
的尖端的提交的哈希ID。开始时,master
是您对B
所做的第一次提交,依此类推。
然后他们说:好的,我们喜欢您的branch-A
提交。但是我们将通过进行新的提交B-C-D
来“改善”它们,这是合并 H
+ B
+ C
的结果进行一次大提交,我们将在D
(您的master
)结尾处放置。他们可能同时也可能没有在他们的origin/master
中进行更多的提交,因此,我们抽一轮master
来代表任何这种无趣的提交。一旦运行o
,您就将他们的 新提交(您已经有旧的)提交到您的存储库中,进行更新您的git fetch origin
:
origin/master
如果您 o--H <-- origin/master
/
...--o--o--A <-- master
\
B--C--D <-- branch-A
\
E--F--G <-- branch-A1
和git checkout master
,则将自己的git merge origin/master
向前移动以匹配您的master
:
origin/master
您的...--o--o--A--o--H <-- master, origin/master
\
B--C--D <-- branch-A
\
E--F--G <-- branch-A1
仍然存在,除非您专门删除了它。但是,即使删除了它,也仍然有branch-A
项提交:
B-C-D
如果您现在...--o--o--A--o--H <-- master, origin/master
\
B--C--D--E--F--G <-- branch-A1
和git checkout branch-A1
–无论您是否仍然有名字git rebase master
指向您的承诺branch-A
,他们都放弃了他们的{{ 1}} –您的Git现在将尝试在D
上方复制所有六个提交H
,以尝试产生以下内容:
B-C-D-E-F-G
但是在H
上复制 B'-C'-D'-E'-F'-G' <-- branch-A1 (rebased)
/
...--o--o--A--o--H <-- master, origin/master
\
B--C--D--E--F--G [abandoned]
的操作并不顺利:它将与自身冲突,并且还需要移除B
和H
的效果 。因此,这看起来就像您在尝试删除自己的代码,只是在将C
复制到D
之后再将C
复制到C'
时才再次放回代码。在任何情况下,这 all 都是没用的。
此时,您要告诉Git的不是:将我在D
上所有不在D'
上的所有提交复制到{{1 }},位于branch-A1
的顶端,而:仅复制我在master
上提交但未在{{1}上提交的部分 },在H
的顶端跟随master
。在此特定示例中,您要复制的提交集为branch-A1
。您要结束:
master
方法告诉Git使用H
,它接受两个参数而不是一个。您想将*基础设为master
,并且要排除提交E-F-G
和更早的内容( E'-F'-G' <-- branch-A1 (rebased)
/
...--o--o--A--o--H <-- master, origin/master
\
B--C--D--E--F--G [abandoned]
,git rebase --onto
,master
和所有无聊的提交D
的左侧)。因此,如果您做仍具有C
来标识提交B
的名称,则可以使用:
A
如果不名称为A
,则可以使用原始提交哈希ID代替名称branch-A
作为限制符,或者可以运行{ {1}}和删除不需要的D
命令;或者,您可以运行git checkout branch-A1 # make sure you're on the right branch
git rebase --onto master branch-A # tell Git: copy only commits after branch-A
并计算提交次数(或者您需要的任何次数)以找到提交。
请注意,重新基准化后,您会拥有一个 new branch-A
(即使之前的三个提交, history 与您之前的branch-A
完全无关)复制以具有相同的效果)。因此,您将需要将其强制推到用于处理请求请求的任何Web服务(显然是GitHub)。如果您担心其他人可能会在GitHub服务器上向您的git rebase -i master
添加提交,则可以使用pick
。