我们在我们的小型开发团队中使用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 pull
,git 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}}保持同步?
编辑:我已经制作了一张图片来更好地说明我的工作流程:
答案 0 :(得分:4)
我应该将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
派生的活动分支,那么您可以执行此强制更新,然后每个人都需要更新其本地回购。
但我不建议这样做,因为你无法保证没有活跃的子分支,有一天你肯定会发现你的存储库搞砸了。 我认为非常线性的历史不值得您花费在解决这些问题上的时间。