git - 如何查看一个 git 分支在贡献分支的整个生命周期内对另一个分支的净贡献
问题描述
我们有一个中央 MASTER 分支和多个单独的任务分支,我们的生命周期如下所示:
- 从 MASTER 创建单个任务分支 A
- 做A并完成任务
- 将 A 合并回 MASTER
- ...如果测试确定了 A 中需要的其他更改,则将最新的 MASTER 合并到 A 中(以使 A 恢复与任务 B、C 的速度,....可能已在过渡期间合并到 MASTER 中)
- 修复分支 A 中的问题
- 将 A 合并回 MASTER
- (重复 4 => 6 直到 A 工作结束)
上面的很好,但是我们需要在第 7 步之后做的是识别(通过某种 GIT diff):
在完成上述生命周期后,A 已将净值更改为 MASTER。
因此,我们正在寻找一个单向差异 A => MASTER 来显示在两个分支之间双向发生多次合并后由 A 引入 MASTER 的净变化。
非常感谢我能得到的任何意见 - 谢谢!
解决方案
您的生命周期模型与能够在合并到基线之前查看所有更改的目标相冲突,特别是在完成测试之前将主题分支合并到主分支的步骤。
相反,保留主题分支中的所有更改,直到最终签核后的集成之前。寿命较长的主题分支可能需要从master 进行一些合并,即
git fetch
git merge origin/master
这样,您就可以在主题分支的第 4 步到第 7 步中执行测试和所有其他活动。在最终签核之前,使用简单的方法查看累积更改
git fetch
git diff origin/master
最后,合并的确切机制将取决于您的工作流程。
如果您不介意基线中可能存在混乱的历史记录,只需合并您的主题分支。
git fetch
git checkout master
git merge --ff-only origin/master
git merge topic/fix-potrzebie
如果您的软件质量组织擅长壁球合并
git checkout master
git merge --ff-only origin/master
git merge --squash topic/fix-potrzebie
... fix merge conflicts ...
git commit -m 'PROJ-1234 Fix potrzebie ...'
git push origin master
保留主题分支存在的证据,但将其折叠为单个提交。以艰难和冒险的方式做这件事看起来像
根据最新基线创建主题分支的新最终版本。
git fetch
git checkout -b topic/fix-potrzebie-final origin/master
将开发主题分支折叠到单个提交。
git merge --squash topic/fix-potrzebie
... fix merge conflicts ...
git commit -m 'PROJ-1234 Fix potrzebie ...'
将其合并回基线。
git checkout master
git merge topic/fix-potrzebie-final
git push origin master
但是没有理由再次进行所有的合并,这也带来了风险,您可能会将不同的代码合并到基线中而不是测试的代码中。已经合并并实际测试的代码可寻址为topic/fix-potrzebie^{tree}
,即与主题分支顶端的提交相关联的树对象。用一个代码是最后的树
git fetch
git checkout master
git merge --no-ff -m 'Integrate PROJ-1234' \
$(echo 'PROJ-1234 Fix potrzebie ...' |
git commit-tree topic/fix-potrzebie^{tree} \
-p $(git rev-parse origin/master))
最后一个命令有一点魔法。它创造了形式的历史
$ git lola
* df6bbc7 (HEAD -> master) Integrate PROJ-1234
|\
| * 0c180a8 PROJ-1234 Fix potrzebie ...
|/
| * 0156bc9 (topic/fix-potrzebie) Updates after testing
| * 0ae9d12 Potrzebie changes
|/
* 61993d0 (origin/master) PROJ-1233 Previous history ...
请注意,这git lola
是一个非标准但非常有用的别名
git log --graph --decorate --pretty=oneline --abbrev-commit --all
另请注意,master 的新提示和主题分支之间不存在任何更改
$ git diff master topic/fix-potrzebie
[ no output, indicating no differences ]
但它们实际上是相同的,即它们具有相同的 SHA-1 哈希,因此共享同一棵树。
$ git rev-parse master^{tree} topic/fix-potrzebie^{tree}
9a4fc1bb6230e80bc3a1928a00cb404da6424153
9a4fc1bb6230e80bc3a1928a00cb404da6424153
要理解该命令,请按从右到左的顺序阅读。
echo $MSG2 | git commit-tree $TREE -p $PARENT
是 git 管道,它创建一个新的提交,其树为$TREE
,其父级为$PARENT
,其提交消息为$MSG2
.- 该树与已在主题分支的顶端提交的树相同。
- 父级是
origin/master
,即当前基线,但从人类可读的 refname 转换为 SHA-1 哈希git rev-parse
。 - 的输出
git commit-tree
是新提交的 SHA-1 哈希,它变成$COMMIT_HASH
…
git merge --no-ff -m "$MSG1" $COMMIT_HASH
将新提交合并到master
. 尽管我们将其设计为快进,但该--no-ff
开关仍保留了短暂的发散-然后合并凹凸作为历史上的人工制品。- 这里的解释从单引号变为双引号以保持一致,但我希望不要与来自环境变量的值混淆。
此时,您可以使用以下命令删除现已过时的主题分支
git branch -D topic/fix-potrzebie
产生形式的整洁历史
$ git lola
* df6bbc7 (HEAD -> master) Integrate PROJ-1234
|\
| * 0c180a8 PROJ-1234 Fix potrzebie ...
|/
* 61993d0 (origin/master) PROJ-1233 Previous history ...
最后,通过以下方式与团队其他成员分享
git push origin master
推荐阅读
- typescript - TypeScript - 递归泛型和叶分支问题(终极井字游戏)
- c# - 如何将包含两个列表的模型从视图发送回我的控制器
- openlayers - 如何在 OpenLayers 5.3.0 中剪裁和显示剪裁的矢量几何图形
- python - “AttributeError:‘NoneType’对象没有属性‘get_text’”
- android - 通过移动设备上的 Facebook Native App 登录网络时,会话丢失
- .net - 如何在 dotnet dockerfile 中添加私有 nuget 源?
- java - 为什么要为 REQUEST 以外的 DispatcherType 编写 servlet 过滤器?
- c# - 如何通过脚本(Unity3d)为按钮文本加下划线和加粗
- java - Spring Security中的授权问题
- r - 为滑动窗口编写一个简单的循环