git flow vs cherry-picks

时间:2015-12-29 05:13:20

标签: git workflow

我们为生产版本提供了分支 prod ,为正在进行的开发提供了 dev

我们当前的流程:

我们主要在 dev 分支机构工作,客户会不时决定他想要哪些功能/错误修正 prod 和我们挑选它们。

根据我的理解,樱桃选择与 git flow 模型相矛盾。

到目前为止,我还没有看到如何调整我们的流程来避免它 git flow 假设您事先知道更改是否会转到 prod

社区是否看到任何方式?

更新:我发现我的问题需要更好地澄清术语

我们现在使用的是什么

实施问题#12345

git fetch
git checkout origin/dev -B issue-12345 # new branch for issue #12345 from bug tracking system
# ... do many atomic commits
git fetch
git checkout origin/dev -B dev
git merge issue-12345 --no-ff -m "Bug #12345 - Bug title from bug tracking system"
# ... fix merge conflicts if any and commit
git branch -D issue-12345
git push
笔记
  1. 我们使用每次提交的原子提交来明确意图。这简化了审查/责备/平分过程
  2. 我们使用自定义消息进行合并,因为它比默认Merge 'issue-12345' into 'dev'
  3. 更具描述性
  4. 我们强制通过--no-ff进行非快进合并,因为我们希望将所有问题都表示为合并。因此git log dev --first-parent返回已完成任务的高级视图
  5. 我们不使用git merge --squash及其rebase类似物。我们希望保留整个任务历史记录
  6. 当客户决定他想将问题#12345投入生产时

    git fetch
    git checkout origin/prod -B issue-12345
    git log origin/dev --grep "#12345" --oneline --reverse # get all commits that have to be cherry-picked, usually that's only one merge commit (abcd1234)
    git cherry-pick abcd1234 -x -m 1 # '-m 1' required for cherry-picking merge commit
    # ... fix merge conflicts if any and commit
    # ... repeat for other commit if any
    git checkout origin/prod -B prod
    git merge issue-12345-prod --no-ff -m "Bug #12345 - Bug title from bug tracking system"
    # ... fix merge conflicts if any and commit (although that's unlikely for them to occur)
    git branch -D issue-12345
    git push
    

    git flow告诉我们做什么

    有关详细信息,请参阅http://nvie.com/posts/a-successful-git-branching-model/

    就该文章而言,我们的dev分支对应developprod对应master,不使用版本分支

    根据git flow,只有功能分支应基于dev分支,并且永远不会合并到prod

    但是,修补程序分支应基于prod,然后合并到proddev

    为什么git flow不适用于我们

    1. 我们事先不知道该任务是否需要转到prod分支机构。
    2. 如果我们基于dev的功能分支,我们以后将无法将其合并到prod,如果要求的话(可能需要更多时间)
    3. 如果我们基于prod的功能分支,我们将无法从之前完成的其他任务中受益。
    4. 示例1

      假设我们有一个任务#12345来实现新的Contact Us页面。然后我们有一个任务#23456将页面的背景颜色从白色更改为黄色。

      我们基于issue-12345的{​​{1}}分支,然后将其合并到prod并等待批准将其合并到dev

      然后我们开始处理prod并再次基于issue-23456。但是prod代码甚至没有提及prod页面。因此,我们必须先做一些怪癖,例如首先将Contact Us分支合并到issue-12345

      即使是那么简单的情况,这也很复杂。你可以想象,如果你想使用其他任务中引入的一些代码,那将会困难得多。

      示例2

      任务#34567要求实施issue-23456页面。此页面与Feedback页面非常相似,因此它具有类似的css。我们想重复使用它。但是怎么样?说#34567取决于#12345是不公平的。因此Contact Us基于issue-34567是不合逻辑的。所以呢?手动重写代码?复制粘贴?还是樱桃挑选?

      我认为没有任何合理的解决方案。

3 个答案:

答案 0 :(得分:4)

git-flow(见here translated as regular git commands)基于合并分支(功能到dev,dev到master)

git cherry-pick与merge不兼容,因为:

因此,如果您当前基于挑选樱桃的工作流程有效,您应该保留它 但是,如“If you cherry pick, your branch model is wrong”中所述:

  

他们的洞察力是,使用git(或任何基于DAG的SCM),如果您可以预测应用可能/将需要应用的位置,您可以将其放在它自己的分支上,并将其合并到那些不同的地方根据需要。

     

这将使更改应用于所有必需的分支(您可以将其合并到release以及master),但不会导致提交被复制/粘贴。相反,将记录新的合并提交,因此没有新的提交ID和历史记录(这些提交的分支?)在DAG中得到很好的跟踪。

然而:

  

不要挑选的是,你需要事先知道你希望你的提交应用到多个地方,这样你就可以将它放在它自己的分支上。

在您的情况下,这将涉及多个单独的功能分支,仅在客户批准后合并为主。

关于git-flow,它确实不适合你。集成模型更准确:

拥有 integration 分支更简单,该分支从master开始,并且:

  • 具有从integration分支
  • 创建的分支 每次将其他功能合并到integration时,
  • 在更新的integration分支之上重新定位的相同功能分支:这涉及与负责该功能的团队进行通信功能分支,因为他们每次重新定位时都必须重置自己的功能分支副本(因为它的历史记录会发生变化)
  • 从功能合并提交,功能分支合并到integrationcan be reverted at any time if that feature is dropped的结果:尚未合并的所有其他功能分支需要在更新的{{1分支。

integration分支功能完成且已通过用户验收测试后,它将合并到integration(或master

从OP的情况来看,当功能可以随时单独发送时,您不需要proddev

  

第1天。integration = prod = dev

我们在这里只考虑integrationprod,以及功能或问题分支。

  

第2天。问题#1被提出。这很明显。所有分支都是一样的。我们可以integration

     

第3天。问题#1已修复。我们在任何地方合并git checkout prod -B issue-1分支吗?

合并--no-ff到issue-1

  

第4天。问题#2被提出。再次基于集成分支?

此处基于integration。特别是如果它是一个问题(在prod中检测到) 如果它是一项功能,您可以考虑从prod开始,但由于功能将从integration中删除,因此早期集成的好处将不是保证。

  

第5天。问题#2已修复。合并在哪里?

integrationintegration),检查问题2是否适用于问题1.

  

第6天。第2期被批准进入生产阶段。我们做什么?

首先,在merge --no-ff之上重新定位issue-2(如果prod从那时起已经发展) 然后prodmerge --no-ff issue-2

prod重置为integration,并将所有其他功能分支合并回prod,以验证它们是否在新产品(现在包括integration)。

  

第7天。第1期被批准进入生产。我们做什么?

首先,在issue-2之上重新定位issue-1:这将验证prod是否仍然有效,即使基于issue-1(已合并到issue-2之上先前{1}} 然后,合并--no - ff。

请注意使用prod,它会在功能/问题分支的merge --no-ffprod中生成合并提交:如果需要从{{1}删除所述功能/问题您需要做的就是在integrationprod中恢复该唯一合并提交(而不是恢复表示要删除的分支的一系列提交)。

答案 1 :(得分:1)

我只想指出我们的工作流程存在类似问题,并选择了"还原"工作流而不是采摘樱桃。在创建可包含一个或多个功能的版本时,我们会在开发分支中找到我们想要进入版本然后从那里分支的最新功能。然后我们决定合并哪个功能(git log --first-parent)我们不想从中进入并恢复它们。一旦发布完成,我们就可以恢复"通过恢复还原并合并回开发分支。

虽然git cherry和其他一些命令显示" un-revert"作为使代码更改的提交,git blame足够聪明,可以实际跟踪历史记录返回到原始功能提交,还有一些带有ID的提交消息。

答案 2 :(得分:0)

使用cherry-pick是一种非常体面的方式。

但是

"问题"是git flow合并你分支到彼此(完全然后删除它们作为其流程的一部分)所以使用cherry-pickgit-flow是某种滥用 git流

如何向客户提供功能?

在我看来,您应该考虑开发功能切换机制,以选择每个客户打开/关闭哪些功能。