【问题标题】:Should I rebase master onto a branch that's been pushed?我应该将 master 重新定位到已推送的分支上吗?
【发布时间】:2016-01-21 08:00:28
【问题描述】:

我们在小型开发团队中使用feature branch workflow。我们目前正在开发一个大型项目,因此其中一位开发人员已将他们的功能分支推送到 origin,其他人都可以在其中签出自己的本地副本。

[leonard@dev public]$ git branch -avv
  master                        9d53b40 [origin/master] Fix reviews
* responsive                    0c04643 [origin/responsive] Add media queries
  remotes/origin/HEAD           -> origin/master
  remotes/origin/master         9d53b40 Fix reviews
  remotes/origin/responsive     0c04643 Add media queries

在 master 上开发时,我们创建功能分支(即 master_hotfix),然后当我们准备好合并它时,我们首先将 master 重新设置为它,然后再这样做。这给了我们一个我们喜欢的很好的线性历史。我们认为这也是对我们的响应式项目执行此操作的最佳方式,因此我们将基于响应式分支创建一个新分支(即 responsive_some-feature)。同样的git pullgit rebase responsive responsive_some-feature也可以在这里使用。

但是对于我们是否应该(如果应该,在什么时候)将master 重新设置为responsive,我们有点困惑?在responsive 分支被推送到origin 之前,将master 重新设置为基础很简单,但是将master 重新设置为responsive 然后将responsive 重新设置为responsive_some-feature 对吗?当我时,我看到(以及一些冲突):

# On branch responsive
# Your branch and 'origin/responsive' have diverged,
# and have 112 and 109 different commit(s) each, respectively.
#
nothing to commit (working directory clean)

通常此时我会看到一个干净的工作目录,然后我可以在其中签出 master 并将我的功能分支合并到其中。唉,在此 rebase 之后,来自 master 的提交在那里,新的提交在 @ 987654339@ 正确地追随他们,但这是正确的方法吗?我应该如何继续,或者我应该使用不同的方法使responsivemaster 保持同步?

编辑:我制作了一个图表来更好地说明我的工作流程:

【问题讨论】:

  • 如果responsivemaster 的分支,那么你为什么要考虑在responsive 上重新定位master?另外,如果你用图表代替文字,你的问题会更清楚。
  • 我觉得您的问题不是关于变基,而是整理出该功能可能领先于功能功能的可能性,反之亦然。另外,稍微纠正一下你的术语:merge my feature branch in. 如果master 的功能领先,你真的会快进master(从技术上讲,这是一个快进合并,但我不喜欢使用变基上下文中的“合并”一词)。
  • 拥有线性历史很好,但是一旦您有多个开发人员在功能分支上工作并重新定位它们,您就进入了使用 Git 的“大手术”领域。您可能想问自己,为主要分支保留准确的历史记录(而不是线性历史记录)是否会更好地为您服务,并且只使用变基来保持这些主要分支的线性。当您使用准确的历史记录而不是虚构的线性历史记录时,Git 会更容易使用。同样,rebase 非常适合小更改,但对于大更改坚持合并,它更安全、更容易。
  • 我还担心你说你正在将 master 重新定位到你的特性分支上......通常你会做相反的事情,你将你的特性分支重新定位到 master 上。我对你为什么要重新设置 master 感到困惑。
  • 如果你能给我们看一张masterfeaturefeature-feature的样图,也许我们可以给一些针对性的指导。正如@DietrichEpp 所提到的,关于如何变基似乎有点混乱,这本身可能就是你问题的实际来源。

标签: git git-branch git-rebase


【解决方案1】:

TLDR

我应该将 master 重新定位到已推送的分支上吗?

不,您应该遵循一般规则 - never rewrite the public history(= 永远不要对已推送的分支进行变基)。

对于简单的功能分支,您可以在推送之前对它们进行变基(重写历史记录)。或者,至少,您可以确定只有一名开发人员使用功能分支并在您遇到 branches have diverged 情况时强制推送。

responsive 分支的情况下,它是公开的并被许多开发人员使用。 所以你不能在 master 之上 rebase,做这个分支的常规合并。

注意:如 cmets 中所述,您的帖子中有一些令人困惑的术语。所以我假设...we first rebase master on to it [feature branch]...实际上是相反的意思,你将特性分支重新设置在master之上。

说明

带有功能分支的“正常”(无历史重写)流程如下所示:

1) we have a feature branch 

... O ---- O ---- A ---- B  master
                   \
                    C       feature-branch

2) we do the merge, usually with merge commit (D)
   sometimes it can be fast-forward without the merge commit

... O ---- O ---- A -- B -- D -  master
                   \       /
                    -- C --      feature-branch

re-base 的流程:

1) we have a feature branch 

... O ---- O ---- A ---- B  master
                   \
                    C       feature-branch

2) we rebase feature branch on top of master
   note, that we changed the history and have new C' commit on 
   the feature branch

... O ---- O ---- A ---- B  master
                          \
                           C'  branch_xxx (feature branch)

3) we do the merge, master is fast-forwarded since there is nothing new
   on master

... O ---- O ---- A -- B -- C' -  master (fast forwarded)
                        \  /
                         C'      feature-branch

如果只有一名开发人员在功能分支上工作,它会很好。 所以历史重写是安全的。

但是,当您添加 responsive 分支时,据我了解,流程是这样的:

1) we have a feature branch 

... O ---- O ---- A ---- B       master
                   \
                    R1 -- R2     responsive
                           \
                            F1   responsive-feature-branch

2) now see what happens if `responsive-feature-branch` is still active (someone works on it) and we rebase the `responsive` on top of `master`:

... O ---- O ---- A ---- B                master
                  \       \
                   \       R1' -- R2'     responsive'
                    \
                     R1 -- R2             responsive
                            \
                             F1           responsive-feature-branch

你看到问题了吗?现在你有两个不同的responsive 分支(另请参阅我的post 中的解释)。

您可以使用“-f”(强制)标志推送重新定位的responsive',但是在responsive-feature-branch 上工作的开发人员会做什么呢?他只会拥有新的上游历史,并且必须相应地重写自己的本地历史。

如果您确定没有人拥有从 responsive 派生的活动分支,您可以执行此强制更新,并且每个人都需要然后更新他们的本地存储库。

但我不建议这样做,因为您不能保证没有活动的子分支,并且有一天您肯定会发现您的存储库已经搞砸了。 我认为这种相当线性的历史不值得你花时间解决这些问题。

【讨论】:

  • 这似乎有道理。从本质上讲,我不会 rebase master,那么我为什么要 rebase responsive(因为它的行为有点像“master”,因为它被推到了原点)。那么,在这种情况下,您是否建议在所有开发人员都完成响应式分支(和响应式功能分支)时执行git merge?如果 master 的一个特性需要集成到响应式中,例如,在它准备好上线之前呢?或者这只是这里的陷阱之一?
  • @LeonardChalis 您可以将responsive 合并到mastermaster 合并到responsive。如果您进行常规合并,则应该没有问题。一旦您更新了responsive,开发人员就可以更新他们的本地副本并合并到他们的响应式子分支(或在新版本的响应式分支之上重新设置他们的响应式子分支)。
  • @BorisSerebrov 关于 re-base 的流程,因为它快进,我认为它不会创建 D 提交,它只是将 master 的 HEAD 转发到 C
  • @giannischristofakis 对,谢谢,我更新了答案并将 D 更改为 C'。
猜你喜欢
  • 2021-05-12
  • 2016-03-30
  • 1970-01-01
  • 2012-08-23
  • 2017-04-16
  • 2017-02-16
  • 2016-03-23
  • 1970-01-01
相关资源
最近更新 更多