Git分支模型适合您?

HiQ*_* CJ 371 git merge workflow release cherry-pick

我们公司目前正在使用简单的主干/发布/修补程序分支模型,并希望了解哪些分支模型最适合您的公司或开发过程.

  1. 工作流程/分支模型

    以下是我所看到的三个主要描述,但它们彼此部分相互矛盾,或者不足以解决我们遇到的后续问题(如下所述).因此,我们的团队到目前为止默认不是那么好的解决方案.你做得更好吗?

  2. 合并与变基(纠结与连续历史)

    是应该pull --rebase还是等待合并回到主线直到你的任务完成?我个人倾向于合并,因为这保留了一个任务开始和完成的基础的视觉图示,我甚至更喜欢merge --no-ff这个目的.然而,它有其他缺点.还有许多人没有意识到合并的有用属性 - 它不是可交换的(将主题分支合并到master中并不意味着将master合并到主题分支中).

  3. 我正在寻找一个自然的工作流程

    有时会发生错误,因为我们的程序无法通过简单的规则捕获特定情况.例如,早期版本所需的修复当然应该足够下游,以便可以将上游合并到所有必要的分支中(这些术语的使用是否足够清楚?).然而,在开发人员意识到它应该被放置在更下游之前,并且如果已经推送(更糟糕的是,合并或基于它的某些东西)之后,修复使其成为主人,那么剩下的选项就是挑选,其相关的危险.您使用了哪些简单的规则?同样在这包括一个主题分支的尴尬必然排除其他主题分支(假设它们从共同基线分支).开发人员不希望完成一个功能来启动另一个功能,感觉就像他们刚写的代码不再存在

  4. 如何避免创建合并冲突(由于挑选)?

    创建合并冲突的可靠方法似乎是在分支机构之间进行挑选,它们永远不会再次合并?在任一分支中应用相同的提交(如何执行此操作?)可能会解决这种情况?这是我不敢推动基于合并的工作流程的一个原因.

  5. 如何分解成外用分支?

    我们意识到从主题分支组装完成的集成是很棒的,但是我们的开发人员经常工作没有明确定义(有时像"戳"一样简单),如果某些代码已经进入"misc"主题,根据上面的问题,它不能再被带出去了吗?您如何使用定义/批准/毕业/发布您的主题分支?

  6. 代码审查和毕业等适当的程序当然是可爱的.

    但是我们根本无法保持足够的东西来管理这个 - 任何建议?整合分支,插图?

以下是相关问题列表:

还要看看Plastic SCM在任务驱动开发上写的内容,如果不是Plastic的选择,请研究nvie的分支模型及其支持脚本.

Von*_*onC 90

DVCS新开发人员需要意识到的最令人不安的功能是关于发布过程:

  • 您可以导入(获取/拉取)您需要的任何远程仓库
  • 你可以发布(推送)你想要的任何(裸)回购

从那以后,您可以遵守一些规则来简化您的问题:

  • 只有在没有被推动的情况下才重新绑定一个分支(自最后一个rebase以来没有被推送)
  • 只推到一个裸仓库(强制自Git1.7)
  • 遵循Linus关于rebase和merges的建议

现在:

工作流程/分支模型:

每个工作流程都支持发布管理流程,并为每个项目量身定制.
我可以添加到您提到的工作流程中:每个开发人员都不应该创建一个功能分支,只能创建一个"当前开发"分支,因为事实是:开发人员通常不知道他/她的分支将产生什么:一个功能,几个(因为它最终是一个太复杂的功能),没有(因为没有及时准备发布),另一个功能(因为原来的一个"变形"),...

只有"集成商"应该在"中央"仓库上建立官方功能分支,然后开发人员可以获取这些分支来修改/合并适合该功能的部分工作.

合并与变基(纠结与连续历史):

我喜欢你提到的答案(" 内部开发的git用法的工作流程描述 ")

我正在寻找一个自然的工作流程:

对于修复,它可以帮助将每个修复与来自错误跟踪的票证相关联,这有助于开发人员记住他/她应该进行此类修改的位置(即在哪个分支,即专用分支"for fixes").
然后钩子可以帮助保护中央仓库免受来自未经验证的错误修复或来自不应该推送的分支的推送.(这里没有具体的解决方案,所有这些都需要适应您的环境)

如何避免创建合并冲突(由于挑选)?

正如JakubNarębski他的回答中所述,樱桃采摘应该保留在需要它的罕见情况下.
如果您的设置涉及大量挑选樱桃(即"它并不罕见"),那么就会出现问题.

将在revert中应用相同的提交(如何做到这一点?)

git revert 应该照顾好,但这并不理想.

如何分解成外用分支?

只要一个分支尚未被推到任何地方,开发人员应该重新组织其提交历史(一旦他/她最终看到开发需要更明确和稳定的形状):

  • 如果需要,可以使用多个分支
  • 一个分支内的一组连贯的提交(参见修剪Git Checkins)

适当的程序,如代码审查和毕业?

集成分支(在专用集成中)repo可以帮助开发人员:

  • 在远程集成分支之上重新开发他/她的开发(pull --rebase)
  • 在当地解决
  • 将开发推向该回购
  • 检查积分器,不会造成混乱;)

  • @UncleCJ上游就是你经常从我的帖子中提取的地方,无论所有提交结束的地方(SVN用语中的发布版本或主干).下游是他们下面的每个人.向上游发送的东西是将它合并到发布回购中的过程(如linux-2.6),下游是从那里出来的变化,或者从你的存储库中发出这样一个功能的经理给你的仆从......我意味着团队. (3认同)
  • @UncleCJ:"我仍然觉得修剪你的签到以实现严格的顺序历史很难":Git1.7和它的`rebase --interactive --autosquash`会更容易,它会自动移动所有提交,而另一个的开头是相同的提交消息.如果这些提交使用票号(例如),即使当时没有按顺序进行与该票相关的那些修复,autosquash也允许快速重新排序这些提交. (2认同)

小智 21

我认为,我可能错了,对git最误解的一个问题是它的分布式性质.这使得以你可以工作的方式说颠覆是非常不同的,尽管你可以根据需要模仿SVN行为.问题几乎是任何工作流程都会做的,这很好但也有误导性.

如果我对内核开发有所了解(我会专注于那个),每个人都有自己的git存储库来开发内核.有一个存储库,linux-2.6.git,由Torvalds负责,作为发布存储库.如果他们希望开始针对"发布"分支开发功能,人们可以从此处克隆.

其他存储库做了一些开发.我们的想法是从linux-2.6克隆,尽可能多地分支出来,直到你有了一个有效的"新"功能.然后,当它准备就绪时,您可以将其提供给被认为可信的人,他将把您的存储库中的这个分支拉到他们的存储库并将其合并到主流中.在Linux内核中,这发生在几个级别(可信赖的副手),直到它到达linux-2.6.git,此时它变成"内核".

现在这里让人感到困惑.分支名称根本不需要在存储库之间保持一致.所以我可以git pull origin master:vanilla-codeorigin我的存储库中的一个分支中获取一个分支vanilla-code.提供我知道发生了什么,它确实无关紧要 - 它是在所有存储库彼此对等的意义上分布的,而不仅仅是像SVN这样的几台计算机共享.

因此,考虑到所有这些:

  1. 我认为每个程序员都应该如何进行分支.您只需要一个用于管理版本等的中央存储库.Trunk可以head.版本可能是标签或分支,而修补程序本身可能是分支.事实上,我可能会发布分支版本,因此您可以继续修补它们.
  2. 我会合并而不是变形.例如,如果你把一个存储库,克隆它,分支,并做一些开发,然后从你的拉origin,你应该在你的资料库,可能使另一个分支和合并的最新masteryourbranch让别人可以拉你的变化尽可能少的努力,为可能.根据我的经验,很少需要真正的变革.
  3. 我认为这是了解Git的工作方式及其可以做的事情.它确实需要一段时间和很多良好的沟通 - 我才真正开始了解当我开始与其他开发人员使用git时会发生什么,甚至现在,我不确定的一些事情.
  4. 合并冲突很有用.我知道,我知道,你希望一切都能正常工作,但事实是代码更改,你需要将结果合并到有效的东西中.合并冲突实际上只是更多的编程.我从来没有找到一个简单的解释,如何处理它们,所以这里是:注意具有合并冲突的文件,然后将它们更改为它们应该是什么,git add .然后git commit.
  5. 但它适合.正如我所说的,每个用户git存储库都是他们自己玩的,而且分支名称不需要相同.例如,如果您有一个临时存储库,则可以强制执行命名模式,但不需要为每个开发人员执行,只需在发布存储库中执行.
  6. 这是合并阶段.当您考虑要审查/通过质量测试的代码时,您只会合并到发布分支等.

我希望有所帮助.我发现VonC只是发布了一个非常类似的解释......我输入的速度不够快!

编辑关于如何在商业环境中使用git的进一步想法,因为这似乎与评论中的OP相关:

  • 我们称之为发布存储库的product.git是许多负责实际管理产品本身的高级程序员/技术人员.它们类似于维护者在OSS中的作用.
  • 这些程序员可能也部分领导了新版本的开发,因此他们也可能自己编写代码并维护varios存储库.他们可能会管理临时存储库以获取真正的新功能,他们也可能拥有自己的存储库.
  • 他们下面是负责开发个别位的程序员.例如,某人可能负责UI工作.因此,他们管理UI.git存储库.
  • 他们下面是真正的程序员,他们将这些功能发展为日常工作.

那会发生什么?好吧,每个人都在每天的开始从"上游"源,即发布存储库(也可能包含前几天开发的最新资料)中提取.每个人都直接这样做.这将在他们的存储库中的一个分支上进行,可能被称为"master",或者如果你被称为"最新".程序员然后会做一些工作.这项工作可能是他们不确定的事情,所以他们做了一个分支,做了工作.如果它不起作用,他们可以删除分支并返回.如果是这样,他们将必须合并到他们目前正在进行的主分支.我们会说这是一个UI程序员,latest-ui所以他git checkout latest-ui跟着他git merge abc-ui-mywhizzynewfeature.然后他告诉他的技术主管(UI领导)嘿,我已完成这样的任务,从我这里拉.UI领导确实如此git pull user-repo lastest-ui:lastest-ui-suchafeature-abc.UI领导然后在该分支上查看它,并说,实际上,这非常好,我将它合并到ui-latest.然后他可能会告诉他下面的每个人在他们的ui-latest树枝上或他们给他们的名字上拉他,所以这个特征会被开发者探索.如果团队满意,UI主管可能会要求测试负责人从他那里取出并合并更改.这传播给每个人(变更的下游),他们对其进行测试并提交错误报告等.最后,如果该功能通过了测试等,其中一位顶级技术主管可能会将其合并到该程序的当前工作副本中,此时然后将所有更改传播回来.等等.

它不是一种"传统"的工作方式,而是设计为"同伴驱动"而不是像SVN/CVS那样的"等级".从本质上讲,每个人都有提交权限,但只能在本地提交 它可以访问存储库以及您指定为允许您使用层次结构的发布存储库的存储库.


Joh*_*son 9

我使用的模型具有良好的结果如下:

一个"有福"的回购每个人推送和拉出,基本上是客户端 - 服务器拓扑.

没有主分支,所以没有开发人员可以将任何代码推送到"主线".

所有发展都发生在主题分支上.我们将名称命名为容易检测谁负责它:jn/newFeature或jn/issue-1234

白板上的分支和看板/ scrum卡之间也有一对一的映射.

要释放一个分支,它会被推送到受祝福的仓库,并且看板卡会被移动以备审查.

然后,如果审查接受了分支,则它是发布的候选者.

当一组接受的分支合并在一起并用版本号标记时,就会发生一个版本.

通过将新标签推送到受祝福的仓库,新功能有了新的可能基础.

为避免合并冲突,请开发人员将其未发布的分支更新(合并)到最新的发布标记.


归档时间:

查看次数:

64586 次

最近记录:

9 年,11 月 前