假设您有以下 Git 存储库:
- 您的私人仓库,位于您的工作计算机上;
- 您的公共回购
you
,托管在某处;
- 一个主要的 repo,
origin
它是主要的开发树。
你正在做某事并做了两个提交 A 和 B。你将它们发布到你的公共仓库。同时,origin
还有另一个提交 Z。
/-A-B master, you/master
o-o-o
\-Z origin/master
现在假设一位同事需要您的两次提交才能开始一项新功能。他从您的公共回购中拉出您的分支,并在此基础上进行一些提交。
/-C-D-E colleague/master
/-A-B master, you/master
o-o-o
\-Z origin/master
您现在想要在origin/master
. 您从中获取origin
并进行变基(相当于git pull --rebase
或git pull
带有 pull.rebase 选项集)。这会创建两个新的提交。您将它们推送到您的公共回购和origin
. 更复杂的是,假设origin
在此之后推送了一个新的提交 F。
/-A-B-C-D-E colleague/master
o-o-o
\-Z-A'-B'-F master, you/master, origin/master
现在的问题是你的同事有一些基于两个“弃用”提交的工作,并且为了避免进一步的复杂性(合并时的冲突,弄乱历史),他必须将他的分支重新设置在 B' 之上(假设他不想要F)。你需要告诉他这件事,否则他可能不会注意到你做了什么。
/-C-D-E colleague/master
o-o-o-Z-A'-B'-F master, you/master, origin/master
如果你不告诉他,稍后他会将他的分支合并回原点,历史将如下所示:
/-A-B-C-D-E
o-o-o \
\-Z-A'-B'-F-M colleague/master, origin/master
您有两次 A 和 B 提交,但名称不同。历史变得更难阅读,你会遇到可怕的合并冲突。记住这个例子很简单。如果有几十个人在做这个项目,而且origin
进展很快,历史很快就会变得一团糟。
如果只有一位同事,那应该没问题。但是如果你不能确切地知道谁从你那里拉了出来,你就不能知道你必须警告谁。在开源开发中尤其如此。
主要规则是:不要对已经发布的提交进行变基。如果 A 和 B 仅在您的私人仓库中,那么变基很好,并且可能是最好的做法,因为它使历史更简单和有意义。只有当分支有充分的理由存在时(例如,功能分支),分歧的历史才有意义。