Gitflow实践:如何将代码从原始/开发到本地/feature-x,以获得好看的git历史



我有以下git结构:local/develt,local/feature-x,origin/develt、origin/feature-x、origin/fieature-y。。。每个local都在跟踪其相应的起源,还有另一个开发人员在处理feature-y,并将他的代码推送到origin/feature-y。

当我在feature-x上工作并将我的代码推送到origin/feature-x好几天的时候,另一位开发人员已经向origin/development发出了合并请求,现在,我需要他的代码才能继续我在feature-x上的工作,我有两个选项来更新我的本地/feature-x代码,但每个选项都有一个缺点(请注意,这种情况意味着,当看到原始/开发中的提交历史时,feature-x应该显示为最新的功能):

  1. 合并来源/发展为本地/feature-x->这将重写git历史,并使feature-x提交出现在feature-y提交之后,我希望避免这种情况。

  2. 将本地/feature-x重新设置为源代码/开发代码->这将使local/feature-x的历史记录与其跟踪版本的历史记录(即original/feature-x)不同,然后git将迫使我将origina/feature-x提交到local/feature-x,因此,在local/feature中有重复的提交,使历史记录看起来很难看!

有什么方法可以更新具有有意义的git历史的本地/feature-x分支w-r-t?

首先,Git Flow并没有规定应该如何更新功能分支。是否合并或重新建立基础取决于您和您的团队,因为两者都是兼容的。请注意,GitFlow确实建议您在将功能分支合并到develop中时强制执行合并提交。因此,即使您使用rebase策略来更新特性分支,最终结果也会是完全提前于develop的少量提交。这种策略有时被称为";"半线性合并";或";回扣合并";。

现在进行一些更正:

  1. 如果您选择用merge更新您的功能分支,那么";这将重写git历史记录;。选择合并的主要原因是为了避免重写历史记录,因为有些人更喜欢这样。请注意,当您在origin/develop中合并时,特性分支的提交ID不会更改,这一事实证明了这一点。(顺便说一句,使用merge而不是rebase的第二个原因是,与rebase相比,有时合并时的冲突可能更少,因为使用merge只需解决一次冲突,而使用rebase则可能需要解决多次提交重新写入时的冲突。)
  2. 如果您选择用rebase更新您的功能分支,则";git会强迫我拉";正如您所指出的,这会给您留下重复的提交。当您重新调整功能分支的基础时,应该强制推动分支,而不是拉动。(或者,您可以使用pull --rebase,它将重新建立基础,而不是合并引入的提交。)

至于什么是";最好";,这是一场无休止的辩论,实际上甚至不适合在SO上提问,你会注意到我编辑了这个问题,删除了这个措辞。你需要根据差异自己决定。听起来你更喜欢更干净的历史记录,所以如果你调整工作流程,只需在重新创建基础后强制推送分支,那么你对重新创建基础的选择应该会很好。

附带说明:在我使用过Git Flow的所有公司环境中,我们一直倾向于仅个人功能分支的rebase。我们锁定了任何共享分支,因此不允许强制推送,代码通过Pull Request合并到这些分支中。对于这些PR,我们默认采用半线性合并策略,这样功能分支就可以重新建立基础,然后通过强制合并提交进行合并。但是,在进行Git Flow共享分支合并时,我们从不使用rebase,例如releasedevelopmasterdevelop

顺便说一句:我知道你说的是渴望一个"干净";这个问题的历史,但我想挑剔你使用的一个特定措辞:

具有有意义的git历史

,这意味着重新基础的历史是";有意义的";而合并的历史不是。如果有什么不同的话,则包含合并的历史略多于"合并";有意义的";而不是用rebase重写,因为使用rebase会丢失一些信息。这就是我通常更喜欢使用半线性合并策略的原因之一;与从不重新定基相比,你仍然会有一点信息丢失,但最重要的信息是";哪些提交是该特征的一部分";保留。也许不是";有意义的";您可以使用";看起来更干净";或";具有更易于阅读的git历史";。(我知道你确实在标题问题中说过。)

最新更新