git使用—rebase还是merge

转载自:https://segmentfault.com/q/1010000007704573/

我猜现实中的情况是这样的:

使用 git 的人群中,不会用 rebase(哪怕是基础功能的)的至少一半(这个估计恐怕很保守了)
剩下一半里真正理解何时应该正确 rebase 的恐怕也就一半……
merge 还是 rebase 并不是一个二者选其一的问题,而是应该根据具体情况来选择使用,而这个“具体情况”在现实中实在是不好一一列举出来了,对于大多数开发者来说在团队中的职能比较单一,也不是经常有机会遇到,所以在这里我只总结两个人人都应该理解并遵守的准则:

当你从 remote 去 pull 的时候,永远使用 rebase(除了一个例外,后面会讲)
当你完成了一个功能(假定你是单独开本地分支去做的)后打算合并到主干分支的时候,永远使用 merge
开发者应当理解:不同的合并策略影响的或许不是最终的代码结果,但却会影响 git 如何记录提交的历史(尽管很多时候这种理解只对个别人受益,而对自己没有什么影响)。其他的人在使用这些历史的时候(比如 code review 的时候,或者 bisect 的时候等等)会因为过去你做过的事情而感到无比幸福或痛苦。

第二点比较容易理解,把开发一个功能的具体细节隐藏在本地分支中,而把最终的结果作为一条完整的记录合并(merge)到主干分支去。

关键是第一点。大多数情况下大家会选择默认的 pull,也就是 fetch + merge,于是我们会看到主干上不停的出现 Merge commit xxx into xxx 之类的干扰信息。如果所有的人都图方便这么干,那就永远都别想有干净漂亮的历史树了,取而代之是类似这样的东西:

这里写图片描述

如果你去 clone 一个正确使用 git 的项目,你绝对不会看到上图这样乱七八糟的 master。为什么呢?答案就是:git pull –rebase,这条命令会使用 rebase 来代替默认的 pull 对合并的历史树进行变基处理,就可以避免因为无法快进(fast forward)而产生的额外合并记录。

现在绝大多数的 git 客户端都允许设置 git pull 的默认行为是 –rebase,所以掌握了这个诀窍可以让大部分的日常拉取操作都产生清爽漂亮的历史记录,但这并不是完美的结局。有一种例外是这样的:

在你使用 git merge 完成了一个功能分支向主干分支的合并之后(当然是 –no-ff 的)
在你运行 git fetch 发现远程主干又领先你若干提交
此时你若 git pull –rebase,你会发现你刚才合并功能分支的记录没了……
这是因为变基会忽略合并记录,因此变基命令会有一个特别的参数叫做:–preserve-merges 用于重建被忽略的合并记录。所以比 git pull –rebase 更好的方案就是用 git fetch + git rebase -p 代替之。

当然这个仅针对上面提到的特殊情况,随着 git 的升级说不好哪一天就不存在这种问题了也不一定。我一般都不会遇到这种情况,因为我都是这么做的:

完成功能分支之后先不 merge,而是回到主干分支去 git pull –rebase
如果主干有更新,rebase 更新的内容到功能分支来预检一下,看看在加入了最近别人的改动之后我的功能是否依然 OK(在这个过程中可能会有冲突处理,别怪我没提醒哦)
一切就绪之后再次 git fetch 主干看看有没有变动(因为在第二步的进行期间没准又有人 push 了新的变化),有的话重复第二步,没有则——
合并功能分支到主干然后 push,收工。
我这么做可以避免前面提到的意外,看似复杂了些但其实做熟练了之后也没什么难度,更重要的原因是 git rebase -p 是有缺陷的:

不能和 git pull 连用,一条命令分成俩,怎么都觉得“亏”了(虽说你可以写脚本,但最好不要因为习惯了之后反而有时候会害了你)
由于无法和 git pull 配合使用,所以你必须指明目标分支给 rebase,这一点比较烦人,特别是很多 GUI 客户端压根不支持 git rebase -p 的时候(我经常会在 CLI/GUI 之间切换环境使用 git)
ORIG_HEAD 会被破坏。
ORIG_HEAD 在很多情形下非常有用,比如说你可以用 git log -p -reverse ORIG_HEAD 来回看最近一次合并所产生的所有变化等等。–preserve-merges 会让它失去本来应该指向的位置,你不得不先找到正确的 hash 来代替它,这会有点烦。

以上答案最终说明一件事情,现实的复杂性永远超出你在菜鸟时期所能做出的想象,真想把 git 用好那就要在日常工作的基础上好好理解 git 的工作原理吧,可以去看官方网站电子书(中文版),里面的 git internal 一节仔细看懂之后,该用什么命令心里就有数了。

补充一点:如果你的团队不在乎主干分支上有很多不重要的干扰提交记录,那你可以始终使用 rebase,这样至少可以不会出现很多分岔,处理得当也可以得到干净(但是啰嗦)的主干分支历史记录。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/450151.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

淘宝网轮播图

转载于:https://www.cnblogs.com/wxwxwx/p/10264370.html

atob和btoa的趣谈

2019独角兽企业重金招聘Python工程师标准>>> 不了解的人突然看到window对象的atob和btoa 函数,估计会认为哪个臭小子添加全局函数了。 你如果告诉他这是原生函数,他一定会怒骂:哪个脑残给api起个这样的名子。 你能猜出来这两个函数…

esp32使用lvgl,给图片取模显示图片

使用LVGL官方工具。 https://lvgl.io/tools/imageconverter 上传图片,如果想要透明效果,那么选择 输出格式C array,点击Convert进行转换。 下载.c文件放置到工程下使用即可。

音视频即时通讯二次开发

用于二次开发企业即时通讯源码(C/MFC),现在,做一个普通的即时通讯软件不是一件难事,网上有很多很好的这类软件的源代码可以拿来使用。今天就介绍一个我用过,觉得不错的给大家。软件叫 ANYCHAT SDK(以下简称…

Spring Boot 不使用默认的 parent,改用自己的项目的 parent

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 在初学spring boot时,官方示例中,都是让我们继承一个spring的 spring-boot-starter-parent 这个parent&#xff…

软件工程—让软件包自带commit id

软件开发中软件版本号是一个重要的概念,而对于工程师软件版本号所对应的git(svn)commit id则更重要,嵌入式固件,移动端app开发中,理想的情况下是我拿到一个固件包,或者一个嵌入式设备&#xff0…

ASM 判定一个类,实现了指定接口

为什么80%的码农都做不了架构师?>>> ASM 判定一个类,实现了指定接口 技术支持 ASM 中,ClassReader 类:对已存在的进行解析,并提供获取类信息的方法。 通过 ClassReader ,实现对一个类的解析。 …

流媒体数据代理----Anychat

“用户流媒体数据代理功能”,使用该功能可以实现指定用户将其它用户的流媒体数据(音频、视频)做为自己的数据,转发给请求指定用户相关数据的用户。 应用场景:将指定用户(P)设置为其它用户&…

“javax.servlet.http.HttpServlet“ 错误

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 我们在进行java web的开发的时候,新建jsp页面,可能会出现The superclass "javax.servlet.http.HttpServlet…

WeakReference带来了什么

转载自:WeakReference带来了什么 很多人说到:java存在内存泄漏。 我不想反驳,因为我也开始慢慢说了,但我知道:内存泄漏和规范编码是两个完全不同的概念,所以我想说:请规范编码 java的“内存泄…

视频聊天室开发详解

互联网的不断发展,各种新技术的兴起,原本做管理软件的我也逐渐转向从事着互联网相关的运营产品的开发。尤其是目前抄得最火热的音视频互动平台技术,今天我先列出最基本开发流程,适用于开发视频会议系统、语音视频聊天系统、远程教…

Android应用开发—ViewPager FragmentPagerAdapter和FragmentStatePagerAdapter下Fragment的生命周期

ViewPager配合不同的PagerAdapter,对应Fragment的生命周期有着不同的表现,了解这个生命周期机制对于开发者选择合适的PagerAdapter实现不同的效果,有着很大的帮助。 FragmentPagerAdapter和FragmentStatePagerAdapter的区别: Fra…

Bash常用快捷键及其作用

Bash常用快捷键及其作用 在 Bash 中有非常多的快捷键,如果可以熟练地使用这些快捷键,可有效地提高我们的工作效率。只是快捷键相对较多,不太好记忆,这就要多加练习和使用。这些快捷键如表 1 所示。 表 1 Bash 常用快捷键快捷键作 …

Putty(菩提)远程连接服务器教程

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 百度不准直接用其图片,我也懒得去偷,只是记录下原文地址: https://jingyan.baidu.com/article/4543…

V8 中更快的异步函数和 promises

原文作者:Maya Lekova and Benedikt Meurer译者:UC 国际研发 Jothy写在最前:欢迎你来到“UC国际技术”公众号,我们将为大家提供与客户端、服务端、算法、测试、数据、前端等相关的高质量技术文章,不限于原创与翻译。一…

Android应用开发—浅谈MVX模式

MVX模式的文章太多了,这里不会再重述,关键我还不太懂,本文会从自己的一些思考,分析下MVX的分离思想,先占个坑! Android应用架构这篇文章最后讲到: Activity和Fragment变得非常轻量。他们唯一的…

音视频互动平台--P2P通信技术

压缩包可以从这里获得:http://anychat.storage.aliyun.com/AnyChatCoreSDK_Win32(MBCS)_V4.5.zip 下载后,首先将其解压到一个临时文件夹中,然后开始后续工作。 编译后我们获得的是.lib文件。 AnyChat SDK向上层应用开放了内核的P2P连接策略…

pigz 压缩

压缩工具--pigz 压缩: tar cvf - 目录名 | pigz -9 -p 24 > file.tgz pigz:用法-9是压缩比率比较大,-p是指定cpu的核数。 解压: pigz -d file.tgz 这时候是tar包,那么在用 tar -xvf file.tar 解包。 速度比较gz.tar格式的压缩…

exgcd模板

逆元模板P1082 1 #include <cstdio>2 #include <algorithm>3 4 int exgcd(int a, int b, int &x, int &y) {5 if(!b) {6 x 1;7 y 0;8 return a;9 } 10 int g exgcd(b, a % b, x, y); 11 std::swap(x, y); 12 …

有关eclipse for java ee版本遇到的坑( Context initialization failed)

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 这几天把以前网上看的视频的源代码拷贝到eclipse下面进行学习&#xff0c;当时用的是eclipse-jee-neon-M4a-win32-x86_64这个版本的ecli…