我应该将 master 变基到一个被推送的分支上吗?
Should I rebase master onto a branch that's been pushed?
我们在我们的小开发团队中使用 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 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
并合并我的功能分支。唉,在这个 rebase 之后,来自 master
的提交就在那里, responsive
中的新提交在它们之后,正确地,但这是正确的方法吗?我应该如何进行,或者我应该使用不同的方法使 responsive
与 master
保持同步?
编辑:我做了一张图来更好地说明我的工作流程:
TLDR
Should I rebase master onto a branch that's been pushed?
不,您应该遵循一般规则 - never rewrite the public history
(=永远不要对已推送的分支进行变基)。
对于简单的功能分支,您可以在推送之前对其进行变基(重写历史记录)。或者,至少,如果您遇到 branches have diverged
情况,您可以确保只有一名开发人员使用功能分支并强制推送。
在 responsive
分支的情况下,它是 public 并且被许多开发人员使用。
所以你不能在 master 之上变基,为这个分支做常规合并。
注意:如评论中所述,您的 post 中的术语有点令人困惑。所以我假设 ...we first rebase master on to it [feature branch]...
实际上意味着相反,并且你在 master 之上重新设置功能分支。
说明
具有特征分支的 "normal"(无历史重写)流程如下所示:
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
上工作的开发人员会做什么?他将只有新的上游历史记录,并且必须相应地重写 his-own 本地历史记录。
如果您确定没有人拥有来自 responsive
的活动分支,则可以执行此强制更新,然后每个人都需要更新他们的本地存储库。
但我不推荐这样做,因为你不能保证没有活动的 sub-branches 并且总有一天你肯定会发现你的存储库已经搞砸了。
我认为相当线性的历史不值得您花时间解决这些问题。
我们在我们的小开发团队中使用 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 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
并合并我的功能分支。唉,在这个 rebase 之后,来自 master
的提交就在那里, responsive
中的新提交在它们之后,正确地,但这是正确的方法吗?我应该如何进行,或者我应该使用不同的方法使 responsive
与 master
保持同步?
编辑:我做了一张图来更好地说明我的工作流程:
TLDR
Should I rebase master onto a branch that's been pushed?
不,您应该遵循一般规则 - never rewrite the public history
(=永远不要对已推送的分支进行变基)。
对于简单的功能分支,您可以在推送之前对其进行变基(重写历史记录)。或者,至少,如果您遇到 branches have diverged
情况,您可以确保只有一名开发人员使用功能分支并强制推送。
在 responsive
分支的情况下,它是 public 并且被许多开发人员使用。
所以你不能在 master 之上变基,为这个分支做常规合并。
注意:如评论中所述,您的 post 中的术语有点令人困惑。所以我假设 ...we first rebase master on to it [feature branch]...
实际上意味着相反,并且你在 master 之上重新设置功能分支。
说明
具有特征分支的 "normal"(无历史重写)流程如下所示:
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
上工作的开发人员会做什么?他将只有新的上游历史记录,并且必须相应地重写 his-own 本地历史记录。
如果您确定没有人拥有来自 responsive
的活动分支,则可以执行此强制更新,然后每个人都需要更新他们的本地存储库。
但我不推荐这样做,因为你不能保证没有活动的 sub-branches 并且总有一天你肯定会发现你的存储库已经搞砸了。 我认为相当线性的历史不值得您花时间解决这些问题。