在父分支合并到上游后,从子分支提交拉取请求

  • 本文关键字:分支 提交 请求 合并 git github
  • 更新时间 :
  • 英文 :


我有一个本地 git 存储库,它在 Github 中有一个远程上游。我在本地存储库中为我正在处理的新功能创建了一个分支 A,然后为该分支提交了拉取请求。在等待此 PR 合并到上游时,我想开发更多基于 branchA 的功能。所以我从分支 A 创建了一个新的分支 A1,并在该分支中进行了一些更改。

现在我的分支 A 的 PR 是挤压并合并到 Github 中的远程上游,我想为我的分支 A1 提交一个 PR。我所做的是首先将更改从远程上游获取到我的本地主分支。然后我尝试在 branchA1 中执行git rebase master,但此命令似乎删除了我在 branchA1 中所做的所有更改。

如果我想从 branchA1 提交 PR,现在最好的办法是什么?

如果我在工作流程中做错了什么,那么在等待来自父分支的 PR 合并时处理新功能的正确方法是什么?

TL;DR:你可能想要git rebase --onto(这需要一些额外的参数)。

当您或其他人;我将在这里使用"他们",并假设有人对您的原始拉取请求进行了"挤压和合并",他们用他们认为比原始提交更好的单个新提交替换了您的提交。

但是,您仍然有原始提交。 现在你的工作是使用git rebase只复制你A1上的良好提交,而不是任何在A1A上被替换的更好的提交,现在只在A1上。

以图形形式表示,有,例如:

...--o--o--A   <-- master, origin/master

B--C--D   <-- branch-A

E--F--G   <-- branch-A1

其中每个大写字母代表一个提交,即A是你(和他们)开始时master顶端的提交的哈希ID,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 mastergit 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-A1git rebase master——无论你是否仍然有你的名字branch-A指向他们为了他们的H而扔掉的提交D——你的 Git 现在将尝试复制所有六个提交,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]

但是在H上复制B并不顺利:它会与自身发生冲突,而且它需要C的效果,D消除。 因此,这看起来像您正在尝试删除自己的代码,只是在将C复制到C'然后D复制到D'时将其再次放回。 无论如何,所有这些都是无用的。

此时,你想告诉 Git 的不是:复制我不在masterbranch-A1上的所有提交,以便在master

的尖端进行H,而是:只复制我在branch-A1上的一些不在master上的提交,以便在master的尖端进行H在此特定示例中,要复制的提交集是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的方法是使用git rebase --onto,它需要两个参数而不是一个参数。 你想在master上重定*的基数,并且你想排除提交D和任何更早的东西(CBA,以及A左侧的所有无聊提交)。 因此,如果您仍然具有标识提交Dbranch-A的名称,则可以使用:

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

如果您没有名称branch-A,则可以使用原始提交哈希 ID 作为限制器而不是名称branch-A,或者可以运行git rebase -i master删除不需要的pick命令;或者您可以运行git log --all --decorate --oneline --graph并计数提交或任何您需要的内容来查找提交。

请注意,变基后,您有一个新的branch-A1(与之前的branch-A1完全无关,即使复制了三个提交以具有相同的效果)。 因此,您需要将其强制推送到您用于处理拉取请求的任何 Web 服务(显然是 GitHub)。 如果您担心其他人可能会在 GitHub 服务器上向您branch-A1添加提交,则可以使用--force-with-lease

最新更新