我应该把主人变成一个被推的分支吗?

时间:2016-01-21 08:00:29

标签: git git-branch git-rebase

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

[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

通常在这一点上,我看到一个干净的工作目录,然后我可以在那里签出master并合并我的功能分支。唉,在这个rebase之后,来自responsive的提交就在那里, responsive中的新提交正确地跟在他们之后,但这是正确的方法吗?我应该如何处理,还是应该使用其他方法让master与{{1}}保持同步?

编辑:我已经制作了一张图片来更好地说明我的工作流程:

1 个答案:

答案 0 :(得分:4)

TLDR

  

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

不,你应该遵循一般规则 - never rewrite the public history(=永远不会推销已经被推的分支)。

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

对于responsive分支,它是公共的并且被许多开发人员使用。 所以你不能在master之上重新定义它,为这个分支做常规合并。

注意:正如评论中所提到的,您的帖子中有一些令人困惑的术语。所以我假设...we first rebase master on to it [feature branch]...实际上意味着相反,你在主服务器上重新设置功能分支。

说明

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

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

重新基础的流程:

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分支分叉(参见我blog中的解释)。

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

如果您确定没有人拥有从responsive派生的活动分支,那么您可以执行此强制更新,然后每个人都需要更新其本地回购。

但我不建议这样做,因为你无法保证没有活跃的子分支,有一天你肯定会发现你的存储库搞砸了。 我认为非常线性的历史不值得您花费在解决这些问题上的时间。