当前位置: 首页 > news >正文

git subtree 不断增加的推送时间,解不玩的冲突!这篇文章应该能救你

原生 git 对于公共组件那种类型的子仓库的支持并不怎么好,就是那种某个子文件夹是一个另外的 git 仓库,并被多个 git 父仓库使用的形式。实际使用的感受甚至是“糟糕透了”。

这种并不友好的子仓库支持可能与 git 的设计理念有关,不过,git 的开发者始终在打补丁以稍微优化这样的体验。


本文内容

    • 不断增加的推送时间
    • 永远也解不完的冲突
    • 原因
    • 解决

不断增加的推送时间

如果你曾经在大仓库试过 git subtree push,你一定为下面这张图感到抓狂:

在这里插入图片描述
▲ 不断增加的推送时间

注意到总提交数了吗?注意到正在计算的提交数的变化了吗?你估算一下全部推送完毕需要多久?2~3 小时是跑不了的了。

最令人心痛的是,等待了 2~3 个小时之后,还有机会因为 Non-Fast-Forward 而遭受拒绝。

walterlv@LVYI MINGW64 /c/Users/OpenSource/Walterlv.Demo (temp/migrate)
$ git subtree push --prefix=SubFolder/Walterlv/ demo temp/from-main
git push using:  demo temp/from-main
fatal: ambiguous argument 'cb0580bb6ee76fa96f5bc3c7095303f9a33f5834^0': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
could not rev-parse split hash cb0580bb6ee76fa96f5bc3c7095303f9a33f5834 from commit 691c5a1531ff38d02cb62fa34c99231dbde050b3
To gitlab.gz.cvte.cn:iip-win/cvte-paint.git
 ! [rejected]              1d3913a2e0ec6e4c507dbe2baabae18ef4b8fab9 -> temp/from-main (non-fast-forward)
error: failed to push some refs to 'git@gitlab.gz.cvte.cn:iip-win/cvte-paint.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

永远也解不完的冲突

在下次执行 git subtree pull 的时候,不管两个仓库有什么样的新变化,只要两边的代码不一样——就是冲突。

在这里插入图片描述

原因

每次执行 subtree 的 push 命令的时候,总会重新为子目录生成新的提交。然而这造成了一些很麻烦的问题:

  1. 每个提交都需要重新计算,因此每次推送都需要把主仓库所有的提交计算一遍,非常耗时;
  2. 每次 push 都是重新计算的,因此本地和远端新仓库的提交总是不一样的,关键还没有共同的父级,这导致 git 无法自动为我们解决冲突。

解决

git subtree 提供了 split 命令,官方对此的描述是:

Extract a new, synthetic project history from the history of the subtree. The new history includes only the commits (including merges) that affected , and each of those commits now has the contents of at the root of the project instead of in a subdirectory. Thus, the newly created history is suitable for export as a separate git repository.

After splitting successfully, a single commit id is printed to stdout. This corresponds to the HEAD of the newly created tree, which you can manipulate however you want.

Repeated splits of exactly the same history are guaranteed to be identical (ie. to produce the same commit ids). Because of this, if you add new commits and then re-split, the new commits will be attached as commits on top of the history you generated last time, so ‘git merge’ and friends will work as expected.

Note that if you use ‘–squash’ when you merge, you should usually not just ‘–rejoin’ when you split.

意思是说,当使用了 split 命令后,git subtree 将确保对于相同历史的分割始终是相同的提交号。

于是,当需要 push 的时候,git 将只计算 split 之后的新提交;并且下次 split 的时候,以前相同的历史纪录将得到相同的 git 提交号。

$ git subtree split --rejoin --prefix=Dependencies/Cvte.Paint/ HEAD

参考资料

  • git-subtree pull merge conflict - Stack Overflow
  • git - Reduce increasing time to push a subtree - Stack Overflow
  • git-subtree/git-subtree.txt at master · apenwarr/git-subtree

我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

相关文章:

  • 阻止某个 NuGet 包意外升级
  • 解读 Microsoft.NET.Sdk 的源码,你能定制各种奇怪而富有创意的编译过程
  • 在 Visual Studio 的解决方案资源管理器中隐藏一些文件
  • 长期支持 LTS(Long-term Support)是怎样的一种支持方式
  • .NET Standard 的管理策略
  • 如何在 .NET/C# 代码中安全地结束掉一个控制台应用程序?通过发送 Ctrl+C 信号来结束
  • Windows 10 应用创建模糊背景窗口的三种方法
  • 使用 PInvoke.net Visual Studio Extension 辅助编写 Win32 函数签名
  • 程序员与英语:即时聊天中的英语缩写 lol / lmao / idk
  • 使用 IFTTT 做 RSS 的邮件订阅服务
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • 语法高亮不够漂亮?这里有你想要的 Rouge 主题
  • 理解 UWP 视图的概念,让 UWP 应用显示多个窗口(多视图)
  • UWP 扩展/自定义标题栏的方法,一些概念和一些注意事项
  • 图片点击放大,你的网页也能做到!
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 【5+】跨webview多页面 触发事件(二)
  • 11111111
  • Docker下部署自己的LNMP工作环境
  • es的写入过程
  • HTTP 简介
  • Java 23种设计模式 之单例模式 7种实现方式
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • orm2 中文文档 3.1 模型属性
  • passportjs 源码分析
  • php ci框架整合银盛支付
  • python3 使用 asyncio 代替线程
  • rabbitmq延迟消息示例
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • SpringCloud集成分布式事务LCN (一)
  • Yii源码解读-服务定位器(Service Locator)
  • 二维平面内的碰撞检测【一】
  • 翻译:Hystrix - How To Use
  • 诡异!React stopPropagation失灵
  • 后端_MYSQL
  • 你真的知道 == 和 equals 的区别吗?
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 问题之ssh中Host key verification failed的解决
  • 赢得Docker挑战最佳实践
  • UI设计初学者应该如何入门?
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • #ifdef 的技巧用法
  • $().each和$.each的区别
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • (转)为C# Windows服务添加安装程序