我们有以下场景:我们的游戏OpenLieroX有几个基本版本;现在0.57,0.58和0.59。对于每个基本版本,我们都有一个单独的分支。每个这样的基础版本都有几个版本(如0.57 beta1-beta8和rc1,0.58 beta1-beta9)。
当我们正在研究新的东西时,我们正在最高的基础版本分支(现在是0.59)。当我们修复一些报告的错误时,我们会在最早的版本(大多数为0.58)中执行此操作。有时,我们总是将0.58中的所有更改合并到0.59(只要我们仍然维护并对旧分支进行更改)。
这一切都很好,直到我们想要只有0.58而不是0.59的一些变化。这种情况仅发生在目前为止的一个案例中:版本号。我们有一些Version.cpp文件(以及一些其他文件),其中包含版本号。因此,当我们想要推出0.58的新版本时,我们将那里的versionstring更改为“0.58 beta10”(或其他)。现在,当我们通常从0.58合并到0.59时,也会应用此更改。我们现在通过使用正确的版本号再次覆盖它来修复此类情况(或者在其他错误提交的情况下,可能是还原)。
关于这些不必要的变化的细节对我来说似乎有点难看。我们管理这种方式一般是不好/不常见的吗?如何才能最简单的方法来获得相同的结果?樱桃采摘0.59中的所有提交0.58将是更多的工作。
还有一个细节可能会使它变得更复杂:在处理代码时,我必须设置即将推出的版本号。这是因为我们有一个网络引擎,我们可能已经引入了一些新功能,并且代码中有检查,例如'if(client-> version()> = Version(X,Y,Z))......' 。现在,当我们介绍新的东西时,通常它在某些方面也意味着这样的检查。 (但我们正试图避免旧分支中的这些变化。)
另一个问题是我们不只是计算版本(如0.58.1,0.58.2,......),但我们计算如下:0.58 beta1,0.58 beta2,...,0.58 betaX,0.58 rc1,...,0.58,0.58.1,0.58.2,......这是因为我们希望将其标记为开始时的实验(β阶段),然后将其标记为大多数稳定或稳定。在极少数情况下,即使在两个不同的beta版本之间也可能发生严重的变化(可能是网络协议)(当然,我们会尽量避免它们,但有时候不可能没有)。
答案 0 :(得分:5)
在从0.58开始0.59之后,您可以使用单独的“release”分支来获取0.58中的版本号更改。每个版本(最新版本除外)都有自己的“发布”分支,该分支仅包含来自基本分支的合并以及更新外部版本号的更改。分支结构可能如下所示:
A--------o--B 0.58-release
/ /
...--o--o--o--o--o--o--o--o 0.58
\ \ \ \
\ \ \ \ C 0.59-release
\ \ \ \ /
o--o--o--o--o--o--o--o--o--o--o--o 0.59
\ \
o--o--o 0.60
或者,如果您非常严格只更改A,B,C等更改外部版本号(没有重大代码更改,那些属于'基础'分支:0.58,0.59等) ),那么你可以没有“释放”分支。相反,您可以使用分离的HEAD或临时分支(在发布版本后删除)来进行外部版本更新提交并将其保存在标记中。
A B
/ /
...--o--o--o--o--o--o--o--o 0.58
\ \ \ \
\ \ \ \ C
\ \ \ \ /
o--o--o--o--o--o--o--o--o--o--o--o 0.59
\ \
o--o--o 0.60
你也可以研究一下Git自己的版本控制方式。
对于在Git工作树中完成的构建,版本号是从git describe HEAD
的输出生成的。如果版本号发生变化,Makefile知道哪些文件需要重新编译/重建,并且它始终运行GIT-VERSION-GEN脚本以确保它具有最新的版本号。通过包含生成的版本文件,可在Makefile中使用版本号。它通过编译器(-DGIT_VERSION=…
)的参数传递给C文件,并使用 sed 替换为脚本。
有一些规定可以覆盖版本号“刻录到”构建中,但它们通常仅用于在工作树之外完成的构建(例如,从从tar文件中提取的树构建的构建)。
在您的问题的附录中,您声明在开发过程中需要调整版本号。首先,我认为我所描述的“0.58释放”分支方案仍然可以为您服务。分离您的更改只需要更多的纪律。如果您认为* -release分支为“已发布用于内部测试”而不仅仅是“向客户发布(或用于外部测试)”,那么它仍然有意义。总是在基础分支上进行开发(例如“0.58”),并且在进行需要特定版本号的构建之前始终将基本分支合并到发布分支(例如“0.58-release”)(始终从这样的版本编译)合并发行分支)。
如果你坚持将版本号更改和(非合并)代码更改放在同一行历史记录中,那么在我看来,除了你去之外,你别无选择,只能处理冲突。使用git cherry-pick
(根据Damien Wilson或针对git rebase -i
的自动编辑脚本)。
如果您的“版本文件”仅包含版本控制信息,则可以使用.gitattributes
将Version.cpp
文件标记为无法合并,从而简化冲突解决方案。< / p>
包含Version.cpp 的目录中的
/Version.cpp -merge
如果合并分支之间的文件不同,则将其标记为此(与merge=binary
相同)将始终导致冲突。合并后的工作树版本将默认为您已检出的分支的版本(不是您要合并的分支中的版本),因此您只需git add Version.cpp && git commit
即可完成合并(假设所有其他冲突也得到解决)。
答案 1 :(得分:0)
看起来你正在做的是正确的方法(对于这个结果)。但也许你应该重新考虑你的版本系统。
您可以添加构建版本,0.58.1,0.58.2等,这样您可以根据需要添加任意内容,并且您仍然会将其统称为“0.58”,即使它具有构建数字给它。
一旦发布,您可以添加beta,RC,无论如何,但这不是版本控制系统应该关注的内容。
发布“0.58.3(beta1)”仅表示版本0.58.3。 beta1部分是人类信息,而不是版本控制系统。
答案 2 :(得分:0)
如果我理解了这个问题,听起来你想要包含来自不同分支的某个提交子集。如果是这种情况,您可能只需要运行git cherry-pick
并仅应用您想要的提交。
答案 3 :(得分:0)
棘手的部分是将版本标识与底层代码隔离开来。
您可以在发布的代码分支之上浮动指定版本的分支,这样您就可以安全地将该代码的所有从已发布的分支(0.58)合并到主分支(0.59)在任何时候,不要混淆冲突的版本名称。该版本指定分支永远不会合并回已发布的分支;如果要在版本化版本中包含新代码,只需在已发布的分支上重新设置它。
您可以使用 .git / config 文件中的以下条目轻松排列:
[branch "0.58-release"]
remote = .
merge = refs/heads/0.58
rebase = true
这样,您的发布分支称为“0.58”,您可以使用“0.58-release”分支创建版本化版本。在制作发布版本时,您将发出以下命令:
git checkout 0.58-release
git pull
# Edit the version-designating file.
git commit -a -m'Updated version.'
版本指定文件的所有更改仅在“58-release”分支上存在,并且可以使用git rebase
安全地向前移动。或者,如果您希望每次更改到版本指定文件以坚持“0.58”分支中的代码状态,您可以将“0.58”分支合并到“0.58-release”中分支而不是在“0.58”之上重新定位“0.58-release”。