Git 从另一个分支创建分支。为两者发送拉取请求?

Git create branch from another branch. Send pull requests for both?

  1. 我创建了一个分支并针对这些更改发送了拉取请求,我们称它为分支 A。
  2. 然后我还在我的分支A上创建了一个分支B。经过一些更改,我想为这些更改发送一个pull request,看到了分支A的提交(我发送了一个pull request)在分支 B 的最新提交中。

我该如何处理?

我想在创建另一个分支以开发新功能之前,我通常应该确保我再次处于 master 上,这样它就不会再次发生?

我也可以为分支 B 发送拉取请求吗?会不会有副作用?

我们来画一张图

X --- X --- X --- X <--(master)
       \
        A1 -- A2 <--(A)
          \
           B1 -- B2 -- B3 <--(B)

我假设 A 的 PR 仍然很出色,所以 A1masterB 之间的区别。如果 B 中没有任何内容依赖于 A1,那么这在概念上是不好的;您不希望 B 的 approval/merge 依赖 acceptance/potential 过早发布 A1.

中的更改

现在,如果 A 的 PR 获得批准,那么合并后 A1 将不再是一个差异;你可以争论"no harm, no foul";但如果独立分支独立于 master.

仍然是最好的

我是否可以将最后一次主合并的提交变基并将提交重命名为分支 B 上更改的名称?这是否也会删除我发送拉取请求的分支 A 上的提交?

先看第二部分:变基不会从 repo 中删除提交;这是一个(看似普遍的)误解。因为 A1 可以从分支 A 到达,它不会受到 B 变基的影响。 但是,您在变基时应该小心,避免创建 A1 提交的副本,因为这会破坏变基的目的。

git rebase --onto master A B

应该给你

                      B1' -- B2' -- B3' <--(B)
                    /
X --- X --- X --- X <--(master)
       \
        A1 -- A2 <--(A)
         \
          B1 --- B2 --- B3

(请注意,为了清楚起见,我在此图中显示了 B1B2B3,以强调变基 不会删除提交。由于没有 refs 指向它们,除非您知道如何查找它们,否则您将看不到它们,并且它们将被排除在 push 操作等之外;最终它们可能会变成垃圾收集。但是在 rebase 之后,在你的本地 repo 中你可以做类似 git log B@{1} 的事情,然后看到它们仍然存在)

请记住,如果 B 曾经被推送过,这可能会给其他开发人员带来问题(因为虽然没有提交从 repo 中删除,但这确实使提交 曾经是 B 可访问变为 B 不再可访问 ,这并不好。

请参阅 git rebase 文档中的 "recovering from upstream rebase",如果这似乎不是问题,那么您可以变基。请记住,您需要重新测试 rebased B,因为它的树处于独特的新状态。 (IMO 最佳实践也是重新测试中间提交。)

如果我需要在接受 pull request 之前对分支 A 进行其他更改,我是否仍然可以 rebase/squash 分支 A 的提交而不影响分支 B?

这个问题至少有几个变体。

如果您没有A变基B,那么任何重写或替换A1的变基操作可能会让您离开处于意外状态,因为 B 仍将指向 A1 (不是在 rebase 中创建的 A1',或者在壁球的情况下是 A1A2,或其他) .

如果你 已经 A 重新设置了 B 的基点,那么你可以对 A 做任何你想做的事,而不会进一步影响 B。再次注意重写已推送的历史记录的风险。

终于找到另一种我很喜欢的方式,就是cherry-picking

  1. 对来自 master (A) 的分支执行拉取请求。
  2. 获取不基于master(B)的分支的commit hash。

    git log --pretty=format:"%h - %an, %ar : %s"
    
  3. (可选)删除旧分支(B)如果要保持同名:

    git branch -D B
    
  4. 从master新建一个分支:

    git checkout -b B
    
  5. Cherry 选择更改(将更改合并到新分支):

    git cherry-pick HASH_OF_B (noted in step 2)
    
  6. 有冲突就合并,然后结束cherry-pick:

    git cherry-pick --continue
    
  7. 正确地基于 master 为这个新分支发送拉取请求。

我喜欢这个的一点是 master 分支保持完美的状态(非常干净),而且操作起来非常简单。我们也可以放心地压缩分支中的提交。