我们正在尝试采用git-flow 实现的成功的 Git 分支模型。现在,我们正在开发至少两个发布分支,一个用于最新的稳定版本,一个用于下一个(“预览”)版本。我不明白为什么所有版本似乎都“线性化”到主版本并在那里标记。为什么不在其发布分支中标记发布?为什么是大师?或者为什么要开发分支而不使用master呢?
6 回答
在 git-flow 模型中,您的“最新发布”版本实际上映射到 . master
,而您的“预览版”映射到 git-flowrelease
分支。它是在实际发布发生时分叉develop
并最终合并的。master
然后这将成为您的“最新版本”,您通常会使用 git-flowhotfix
分支仅修复该版本的错误。这样,您master
始终代表您最新发布的版本的最稳定状态。
如果您想修复旧版本的错误或在那里进行任何其他开发,您将从support
适当的提交中分叉一个分支master
(您将在那里创建所有版本)。support
分支仍然是实验性的(根据文档)并且没有很好的记录。但正如您从命令行帮助中看到的:
usage: git flow support [list] [-v]
git flow support start [-F] <version> <base>
这些分支刚刚开始,不打算合并回master
nor develop
。这通常很好,因为对“古老”版本的修复或客户要求在“古老”版本中实现的功能不能或不应该回到master
. 如果您仍然认为,您想将修复移植到您的主要开发线(由master
and表示develop
),只需启动 a hotfix
,挑选您的更改并完成hotfix
.
看起来主要是一个过于强调分支的心智模型。我同意,您可以只标记您发布的提交,而不是将它们合并回 master。
不过画面很漂亮。将所有内容合并回 master 可以清楚地指示按时间顺序发布的版本,而不是在整个图表中散布版本标签。
不过,我认为此模型不适用于旧版本中的错误修复。它打乱了整洁的排序。
- 假设我们发布了 1.0.1 版,后来添加了功能并发布了 1.1.0。
- 我们在 1.0.1 中发现了一个错误,并希望在两个版本中都修复它
- 我们必须在 master 中的 1.1.0 之后添加 1.0.2,然后直接添加(或之前)1.1.1。
回答你的问题:我认为这是一组规则,在某些情况下可以形成一个简单的心理模型。从纯粹的技术角度来看,并非所有规则都有意义,但这并不会使它们变得糟糕。心智模型对人类有好处。
就我而言,我有两个版本的相同软件,基本相同,但每个版本都有一些不同的功能。
所以我创建了两个worktree
,这意味着,在 master 旁边创建两个相关的长期运行的分支。
$git worktree add -b version-silver ..\version-silver master
$git worktree add -b version-gold ..\version-gold master
然后我有:
$git branch
master # base stuff here
version-silver # some normal features
version-gold # some better features
有一个存储库,但对于上面的每个分支,我有 3 个单独的文件夹并排放置。并在master中进行通用更改。然后将其与其他两个版本合并。
cd master
vim basic.cpp
git add .
git commit -m "my common edit on basic.cpp"
cd ..\version-silver
vim silver.cpp
git add .
git commit -m "my specific edit on silver.cpp"
git merge master # here i get the basic.cpp latest changes for silver project
cd ..\version-gold
git merge master # here i get the basic.cpp latest changes for gold project
每个版本的具体改动也会放在对应的文件夹中,每个项目的作品都是独立的,不会混淆IDE。
希望有帮助。
我个人认为提到的 git-flow 过于复杂。
如果您使用的是 GitHub,请尝试GitHub flow
(如 Scott Chacon 所述)。
它对于多个功能、代码审查的协作特别有用,您可以使用Commit Status API
.
更新:The GitHub Flow™ 有一个新的官方网站</a>
更新 2:GitHub Flow™ 有一个新的官方(简化版)GitHub 指南:https ://guides.github.com/introduction/flow/
完全同意@Mot。
很高兴听到同样的问题。
我们的团队还寻找比 Successl 更多的通用分支模型。即如上面提到的@Mot - 主要思想是避免在单独的 *.git 存储库中引入额外的存储库来支持 release-* 分支,例如它是由 kernel.org 为稳定版本完成的。但是 kernel.org 这样做是为了最小化我猜的下载大小。
对我来说,让master作为develop的主线似乎更干净。
在release-* 合并模型中也存在一些冲突以掌握并随后用想法对其进行标记
每次在 master 上提交时,使用 Git 钩子脚本自动构建和推出我们的软件到我们的生产服务器
导致完成(合并和标记)不是原子事务:
$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2
如果 git hook start build 带有自动版本控制支持:
$git describe --tags --long >.ver
那么可能会为以下内容构建错误的版本:
$ git merge --no-ff release-1.2
我知道成功版本中的版本控制引入了一些颠簸版本过程 ,但这不是自动的。
总而言之 - 我们为发布 - * 合并和标记引入的分支模型的主要区别是: - 在创建其分支时标记发布 - 保留发布的分支以便将来维护它们
master 分支应该始终代表您的生产代码库,因此您总是在生产发布后立即将代码合并回 master。
标记用于“记住”进入生产版本的确切代码,以便您稍后可以返回并在出现问题时分析代码。
从理论上讲,在合并回 master 之后,是否在发布分支或 master 分支上标记代码并不重要。我个人更喜欢在发布分支上标记代码,因为这正是进入构建/发布的代码(假设合并可能会出错)。
开发分支概念的问题在于它是单线程的。Brendan 在这个线程中提到了一种可以用于涉及开发分支概念的策略。