在依赖于正在审查的另一个分支的分支上工作


65

git如何帮助解决以下情况:

我的任务分为两部分:后端任务和前端任务。我提出合并请求,以合并后端更改并等待其合并(和地址反馈)。在等待期间,我无法真正处理前端更改,因为它取决于后端更改,而这些更改在master分支上尚不可用。

在仍在审阅中时,从后端更改分支将更改引入到前端更改分支的最佳方法是什么?


14
通常,应该清楚地定义后端项目的接口。因此,在开始前端实现时,如果后端逻辑仍然得到检查,它就不会打扰您,因为您可以使用模型。
Derb先生

17
@HerrDerb噢,甜蜜的夏日孩子……
gardenhead

4
您为什么不能针对尚未审查的后端代码编写它?
immibis

您的团队是否具有某种商定的技术来处理这种情况?如果不是,也许您应该就这样的事情达成共识,因为这是相当普遍的情况。
Radu Murzea

空无一人。这就是我问这个问题的原因。我有很好的建议。我将尝试这些建议,看看它们如何为我解决。
sul4bh

Answers:


42

我有时也有这个问题。Git非常灵活。这是您可以做到的一种方法。

您的第一个分支featureA正在审核中。

您的第二个分支featureB正在开发中,并且取决于分支中的代码featureA

featureA分支合并到featureB分支中。

如果对featureA分支进行更改,则应再次将分支合并featureAfeatureB分支中以合并更改。

您还应该确保首先合并featureA到主干中,否则当您合并featureB到主干中时,您也会无意中也合并了featureA。一旦featureA合并到主干中,您就可以摆脱featureA分支,因为featureB现在仅依赖于主干。

当我的功能分支彼此不依赖但有时相互依赖并且您不得不顺其自然时,我更喜欢它。


这很有道理。这是否允许撤消的合并featureAfeatureB如果需要的话?
sul4bh

8
没有撤消操作,但正如@ 9000所述,您可以创建一个新分支,并从中选择所需的提交(featureA如果必须重新开始)。最好将Git分支视为一次性的。它们既便宜又容易,您随时可以建立新的分支机构。featureB如果您想使用不确定的内容,甚至可以在分支上创建一个测试分支,然后在无法解决的情况下将其废弃,或者将其合并回您的featureB分支。
马特

9
合并将造成一团糟,将很难(并非不可能)回滚。我会选择摘樱桃或重新设置基础(即:在FeatureB的基础上樱桃摘FeatureA中的所有内容)。请参阅9000的答案。
Pierre.Sassoulas

1
这创建了一个复杂的历史记录,每当有人想了解featureA和featureB更改了什么代码时,这将是很多年的问题
Ian

2
如果FeatureA已更新,则应该重新建立FeatureB的基础,不要合并
Lyndon White

38

稍等,跳过合并

对于这种方法,你希望将合并feature_afeature_b反复。

在其他答案中也提到过重新定级,但仅适用于将事物重新定级到master。您要执行的操作是:

  • 启动您feature_bfeature_a,即:

    git checkout feature_a
    git checkout -b feature_b
    
  • 每当feature_a它在等待时的变化得到合并到master,你变基 feature_b就可以了:

    ... commit something onto feature_a ...
    git checkout feature_b
    git rebase feature_a
    
  • 最终,一旦feature_a被合并到中master,您只需获取新的masterfeature_a在上一次重新建立基础:

    git checkout master
    git pull origin master
    git checkout feature_b
    git rebase --onto master feature_a feature_b
    

    这个最终的基础将移植到所有与提交悬而未决的feature_a提交(现在已经无关紧要,因为它已经被合并到其中master)直接移植到上master。您feature_b现在是一个简单的标准分支,从开始master

编辑:从评论中得到启发,一点点提醒:如果您需要进行一些影响到这两个功能的更改,请确保进行更改feature_a(然后按所示进行变基)。千万不能让它在两个不同的提交在两个分支,即使可能是很有诱惑力; 作为feature_a的历史的一部分,feature_b在两个不同的提交中进行一次更改将在语义上是错误的,并可能在以后导致不必要代码的冲突或“复活”。


2
随着对重订feature_a多次,你以后可能会碰到的问题,如果feature_a本身已经在此期间被重订。由于运行的结果,git checkout feature_b; git rebase feature_a您可能会发生冲突或一些有趣的提交,其中包含的提交将恢复对的新更改feature_a。这通常可以通过使用--interactive和跳过从另一个分支的旧版本中提交的提交来解决(我最近不得不这样做了几次)。
maaartinus

@maaartinus,感谢您的单挑,我自己还没有遇到过此类问题。除了rebase简单的步骤以外merge,还有更多的个人步骤出现,因此肯定会产生冲突的机会明显增加;另一方面merge,在这种情况下,这样做在语义上是完全错误的。
AnoE

我猜merge可能会有类似或更严重的问题(冲突不如进行不必要的更改那样糟糕)。我将分支视为所需更改的序列,之后是许多不相关的更改(逻辑上属于另一个分支)。当重复使用同一分支进行基础调整时,我总是删除无关的更改,因为我知道它们无论如何都会出现(可能是更新的形状),并且效果很好。
maaartinus

1
@maaartinus,我为此添加了一个小附录(以一致地进行更改,这些更改只需要在基本分支中进行,而不必在两个不同的提交中进行)。
AnoE

好的技术。这也是我一直都这样做的方式。git rebase --ontoFTW:D
Radu Murzea

29

您已经有了一个分支,每个功能分支都依赖于此分支,并且该分支一直在变化。叫做master

功能分支保持同步的典型方法master是保持在其顶部。当master修改,你通常git fetch origin master:master && git rebase master在你的分支的工作目录。

您可以使用另一个功能分支执行相同的操作:继续获取它并在其基础上重新定基础。

如果出于某种原因,您需要将更改移到另一个分支,则可以挑选您的提交,这些提交永远不会与其他分支的提交混合在一起。


但是我认为情况是功能b需要功能a中的代码,从master分支不会很有帮助。我应该从哪里开始?我是否应该从功能部件a分支并保持同步,直到功能部件a与主部件重新集成,然后从主部件重新定位到功能部件b?
Sinaesthetic,

@Sinaesthetic:您当然可以feature-b基于feature-a,并且随着时间的推移feature-a不断变化。这是使大的变化可观察到的典型方法:将其分为part-A(基于关闭master),part-B(基于关闭part-A),以及在需要时进行更多分割。然后对每个零件提出拉动请求,审阅者可以更轻松地查看逻辑上分组的较小零件。
9000

就PR而言,如果我将b部分与a部分相对于master对b部分进行调整,会不会很重要?我只想确保我的更改没有像a部分中的更改那样显示a部分中的更改。另外,如果我合并vs.调整基准,那将如何影响b部分PR?每次我认为我了解效果时,都会得到不同的结果,大声笑
Sinaesthetic

5

在这种情况下,如果前端任务与后端代码有关键的依赖关系,并且您想在后端完成并在master上接受之前开始在前端上工作,那么我将直接启动前端任务,将其作为功能分支从后端分支,而不是在master上分支前端。

寿命足够长的功能分支需要偶尔从master进行合并(以确保您协调所有合并或语义冲突,这是功能分支上开发工作的一部分,而不是“ review,qa,merge-掌握”过程)。因此,您可以在前端分支上进行此操作,并且当您接受了后端工作的掌握之后,您将通过与您相同的方式,自动获得对后端所做的任何细微更改,作为其审核/接受的一部分。在master上获得任何其他代码更改。

如果事实证明后端分支需要做更多的工作,并且合并到母版之前持续一段时间(例如,如果在审阅过程中发现重大问题),它会不断变化,那么您可能希望直接进行定期合并从后端分支到前端分支(因此,您不必使所有前端工作都基于过时的后端代码)。如果您是同时使用这两项功能的唯一开发人员,那么这很容易(因为您知道自己是否进行了重大更改),但是即使最终两项功能都由不同的开发人员并行进行,也应该没问题。您只需要保持沟通即可(无论如何,如果您并行处理一项任务对另一项至关重要的任务,无论如何都需要这样做)。

如果事实证明整个后端分支需要被丢弃并且永远不会被合并(听起来这将是一件非常重要的事情,很少会发生),那么您要么选择将提交提交到新分支,然后再脱离主分支没有后端工作,或者您应用了反向提交,将所有后端代码删除到了前端分支。但是,正如我所看到的,在您弄清楚将要替换的后端将要替换的后端并决定要做什么之前,它更有可能暂停前端工作。


2

我在这里看不到问题。

您的master分支机构每次都已拥有此功能,在开发功能并合并功能时,它会不断更改。

因此,在您的具体示例中,您首先创建feature_xxx_backend分支并开发后端更改。完成此操作后,分支将进行审核,master审核完成后将合并到该分支中。

因此,只需启动另一个分支feature_yyy_frontend。您可能需要直接从进行分支feature_xxx_backend,以便您在branc中已经有了这些更改。然后简单地开发前端功能,就像分支一样master

feature_xxx_backend分支发生更改时(例如,由于在审核过程中需要处理某些事情),只需进行这些更改并将它们合并到feature_yyy_frontend分支中即可。然后继续在前端分支上。

后端分支的审核完成后,将合并到中master。在这一点上,这将是明智的,重订feature_yyy_frontend分支上master,让评审只需要查看的变化,这个分支有利于master,而不是需要重新审核(用于后端所做的更改,其已获得批准)。

当您有两个,三个或更多从属分支时,也可以这样做。如果您有两个依赖的要素分支,则简单地创建一个将两个要素合并到一起的派生分支。从那里分支,开发第三个要素,并在每个要素分支发生变化时合并两个要素分支。当两个功能都完成并合并到派生分支后,请重新建立基础,或者在将它们合并到主分支后,重新建立基础。

变基(如上所述)功能非常强大,并且有助于保持更改的干净日志,从而使审核变得更加容易。


2

如Polygnome所述,您实际上可以将前端分支与后端分支(而不是母版)合并。即使使用现在的当前分支设置,也可以简单地执行以下操作:

git checkout frontend
git merge backend

或简单地

git merge backend frontend

但是请记住,如果不接受后端更改并且需要做更多的工作,则必须将后端的更新合并到前端,以避免冲突。一旦更改被主服务器接受,您就可以将前端重新建立在主服务器上,以摆脱后端合并提交。

从技术上讲,您也可以使用rebase进行所有操作,但这会弄乱您的前端分支的提交历史记录。我来自哪里,这被认为是不好的做法。青年汽车


“奇怪,没有人提到你能实际上后端的分支,而不是主人合并的前端分支:”这已经提到,例如,在我自己的答案。
Polygnome

@Polygnome前端不必直接从后端分支。它们都可以从母版中分支出来,但是您仍然可以合并它们。因此,您的答案实际上并未提及。
Joris Meys

实际上,我的回答并不建议您直接从后端分支,它只是说那可能是要走的路(因为无论如何您将这些更改合并到前端分支中)。
Polygnome

@Polygnome,然后我误解了您的答案。特别为您更新:-)
Joris Meys

我不知道谁对此表示反对,但是请告诉我我错了,这样我也可以学到一些东西。
Joris Meys

1

这里的大多数答案正确地描述了从第二个分支到第一个分支的更改合并过程,但是它们没有解决如何最大程度地减少您可能需要解决的冲突量。

每当您有两组重大更改要单独查看时(例如featureAfeatureB),请创建一个不打算合并的PR,但要收集关于PoC的早期反馈featureA

人们将能够快速对其进行审核(这只是一个PoC),其目的是验证总体设计或方法。

然后,您可以继续处理功能部件A,为其创建拉取请求,然后分支并处理功能部件B。

最大的区别在于,现在您可以期望featureA不会发生根本的改变:设计和方法已经过验证。代码审查和所需的更改可能是微妙的和局部的,而不是“糟糕,您需要一种不同的方法”。这将最大限度地减少你需要做的,后来合并的工作量featureBfeatureA的代码,无论采用哪种方法你选择。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.