Lyn*_*nax 6 git merge release version merge-conflict-resolution
想象一下,我们使用Gitflow,从中分离出一个发布分支develop,最终将合并到 和main中develop。只有release质量的改进。其中大多数需要部署到集成阶段,因此它们的版本有多个pom.xml(多模块),并且package.json在分支上更新和标记release。
上面develop有针对未来版本的常规(不稳定)功能开发,并且版本已相应设置。有时,来自 的改进release会合并回develop. 我们会遇到合并冲突,在下图中用 X 标记。
main ----------------------o----
/
release o---o-----o-o-o
/ \ \ \
develop ----o---o---x--o--x-o-x----
^
we are here |
Run Code Online (Sandbox Code Playgroud)
例子:
release版本号是1.0.0-SNAPSHOT。develop版本号是1.1.0-SNAPSHOT分支之后的。develop,版本号保持不变。release偶尔会增加(并标记)为1.0.1、1.0.2等1.0.3。$ git checkout develop
$ git merge --no-commit --no-ff release
Auto-merging pom.xml
CONFLICT (content): Merge conflict in pom.xml
...
Auto-merging client/package.json
CONFLICT (content): Merge conflict in client/package.json
Automatic merge failed; fix conflicts and then commit the result.
Run Code Online (Sandbox Code Playgroud)
我们正在寻找解决这种情况的想法。一些研究表明这并不是一个罕见的问题,因此我找到了一些建议。大多数情况下,据说只是手动解决冲突。但我仍然渴望找到一种可以在脚本中自动化的方法。也许有一些 Git 魔法可以提供帮助?也许我们一开始就很糟糕?
下面的讨论给它带来了一个更好的形象,我们现在处于“仅错误修复!”:
方法 0 -- 不这样做?
自从我们的团队开始进行这种版本增量和标记以来,我一直不确定这是否是一个好的做法。但它基本上是有效的,我们一起定义了工作流程的细节,我们的客户、合作伙伴和测试团队要求我们提供候选版本,就好像它是实际版本一样。当版本 xyz 测试成功后,它会原封不动地进入生产环境,然后release合并到main. 但问题仍然存在:一旦在 中进行了修补程序main并且应该向后移植到develop,我们将再次遇到版本冲突。
方法一——采摘樱桃?
抱歉,我不会这样做。我经常读到樱桃采摘是邪恶的。他们会反对 Gitflow。
方法 2 -- 接受手动解决吗?
这就是我们现在所做的。该过程不是自动化的。每次release更改版本号时,后续合并都会产生冲突,必须手动解决。我们接受它,但对此并不满意。
方法 3 ——不要那么频繁地合并?
我想这将是不好的做法。我们希望将质量改进合并到我们所有的分支机构。
方法 4——使用合并选项--ours或类似选项?
问题在于,据我所知,合并冲突的自动“解决”是基于文件的,而不是基于行或块的。我们需要保留版本号develop,但这些文件中的其他更改pom.xml或package.json可能在任一侧,并且不要盲目覆盖,因此我们希望手动查看和解决此类冲突。不过,我愿意接受这方面的任何建议!
方法 5 -- 将版本号移动到单独的文件中?
通过这种方式,我们可以将冲突减少到一个位置,可以使用 轻松解决冲突--ours。虽然较新的 Maven 版本似乎可以实现,但我不知道package.json引用外部定义的版本号的方法。有没有人在这方面取得了良好的经验并建议以这种方式走得更远?
方法 6 - 准备并重置版本develop?
我看到这种行为已经jgitflow-maven-plugin六年多没有维持了。我们可以在 中进行提交develop,将release版本写入文件中,然后合并,并将版本更改回原始版本。
我不喜欢出现与实际开发无关的额外提交,而且我认为不可能清理 Git 历史记录。
所以这将是一个有趣的后续问题:我知道我可以将 D 变基/压缩为 C,但我不知道如何将 A 或 B 变基/压缩为 C。还有其他人吗?
-----B---------
\
---A---C---D---
Run Code Online (Sandbox Code Playgroud)
方法 7 - 在 中准备版本release?
与之前的方法类似,我们可以在 中进行提交release,写入目标版本,然后合并到develop而不发生冲突。然后,我们不需要恢复提交,release而只需将分支指针移回和git reset --hard HEAD^/或简单地不推送它,因此此准备提交将位于两个分支“之间”。
-----B-----------
\
B'
\
---A-----C---D---
Run Code Online (Sandbox Code Playgroud)
下面的文章描述了使用中间分支的类似事情(以满足拉取请求的要求),但它是几个手动步骤并不能解决我的挑战。
方法 8——准备版本而不提交?
我最喜欢的解决方案是只在本地编写目标版本develop而不提交,然后合并release到该版本......但git merge不允许这样做。我没有看到任何开关来覆盖此行为并忽略未合并的
error: Your local changes to the following files would be overwritten by merge:
client/package.json
...
pom.xml
Please commit your changes or stash them before you merge.
Aborting
Run Code Online (Sandbox Code Playgroud)
搜索网络告诉我隐藏本地更改,但这当然不是一个选项。
方法9——编写程序来解决冲突?
我认为这些冲突结构良好,甚至可以完全预测,因此应该可以编写一个小 shell 脚本来 grep/sed 冲突,以便自动解决并提交合并。但我犹豫是否要在这里付出很大的努力,希望得到其他人的启发!
注意:像这样的事情的“最佳实践”很难定义,因为每个人的情况可能都不同。
话虽这么说,我们的一个项目与您的情况类似:我们使用 Git Flow,并且我们的develop分支构建号始终与分支构建号不同release。我们潜在的理想解决方案尚未实现,但可能类似于您建议的方法 8,我们将版本注入到构建管道中,而不在提交中进行硬编码(即甚至不修改版本文件全部)。但这样做的缺点是,您无法仅根据代码知道特定提交代表什么版本。但是您可以使用特定版本来标记提交,如果我们实现了这一点,这可能就是我们要做的。我们还可以将提交 ID 与版本信息一起烘焙到工件元数据中,以便于查找。
我们目前使用的解决方案是方法 4、5 和 7 的组合。我们分离版本文件(您的方法 5),每次创建release(或hotfix) 分支时,第一次提交仅将版本文件更改为即将发布的版本版本(您的方法 7)。我们确保release 始终有 的提示main,以便每当我们部署release到生产环境时,我们都可以干净地合并release到main. (请注意,我们仍然--no-ff按照 Git Flow 的建议使用,但重点是如果我们愿意的话,我们可以快进。)
现在,在您完成release分支到后main,Git Flow 建议合并release回develop,但我们发现合并main回develop稍微更高效,因此 的提示main也在 上develop,但有时,如果 上出现重要的错误修复,我们也会合并release回部署之前。无论哪种方式,这两个合并都将始终与 上的版本文件发生冲突,我们使用您的方法 4 自动选择这些文件的版本。这使得合并回能够完全自动化,但是,有时仍然存在其他冲突需要手动解决,就像正常开发过程同时发生一样。但至少它通常是干净的。developreleasedevelopdevelopdevelopdeveloprelease
请注意,我们方法的一个副作用是我们的版本文件在和 上始终不同,这对我们来说没问题。developmain
| 归档时间: |
|
| 查看次数: |
1831 次 |
| 最近记录: |