git rebase详解(图解+最简单示例,一次就懂)
git rebase详解(图解+最简单示例,一次就懂)-CSDN博客
一、提交节点图解
首先通过简单的提交节点图解感受一下rebase在干什么
构造两个分支master和feature,其中feature是在提交点B处从master上拉出的分支
master上有一个新提交M,feature上有两个新提交C和D
此时我们切换到feature分支上,执行rebase命令,相当于是想要把master分支合并到feature分支(这一步的场景就可以类比为我们在自己的分支feature上开发了一段时间了,准备从主干master上拉一下最新改动。模拟了git pull --rebase的情形)
# 这两条命令等价于git rebase master feature
git checkout feature
git rebase master
1
2
3
下图为变基后的提交节点图,解释一下其工作原理:
feature:待变基分支、当前分支
master:基分支、目标分支
官方原文解释(如果觉得看不懂可以直接看下一段):当执行rebase操作时,git会从两个分支的共同祖先开始提取待变基分支上的修改,然后将待变基分支指向基分支的最新提交,最后将刚才提取的修改应用到基分支的最新提交的后面。
结合例子解释:当在feature分支上执行git rebase master时,git会从master和featuer的共同祖先B开始提取feature分支上的修改,也就是C和D两个提交,先提取到。然后将feature分支指向master分支的最新提交上,也就是M。最后把提取的C和D接到M后面,注意这里的接法,官方没说清楚,实际是会依次拿M和C、D内容分别比较,处理冲突后生成新的C’和D’。一定注意,这里新C’、D’和之前的C、D已经不一样了,是我们处理冲突后的新内容,feature指针自然最后也是指向D’
通俗解释(重要!!):rebase,变基,可以直接理解为改变基底。feature分支是基于master分支的B拉出来的分支,feature的基底是B。而master在B之后有新的提交,就相当于此时要用master上新的提交来作为feature分支的新基底。实际操作为把B之后feature的提交先暂存下来,然后删掉原来这些提交,再找到master的最新提交位置,把存下来的提交再接上去(接上去是逐个和新基底处理冲突的过程),如此feature分支的基底就相当于变成了M而不是原来的B了。(注意,如果master上在B以后没有新提交,那么就还是用原来的B作为基,rebase操作相当于无效,此时和git merge就基本没区别了,差异只在于git merge会多一条记录Merge操作的提交记录)
上面的例子可抽象为如下实际工作场景:远程库上有一个master分支目前开发到B了,张三从B拉了代码到本地的feature分支进行开发,目前提交了两次,开发到D了;李四也从B拉到本地的master分支,他提交到了M,然后合到远程库的master上了。此时张三想从远程库master拉下最新代码,于是他在feature分支上执行了git pull origin master:feature --rebase(注意要加–rebase参数),即把远程库master分支给rebase下来,由于李四更早开发完,此时远程master上是李四的最新内容,rebase后再看张三的历史提交记录,就相当于是张三是基于李四的最新提交M进行的开发了。(但实际上张三更早拉代码下来,李四拉的晚但提交早)
二、实际git提交示例
我这里严格按照上面的图解,构造了实际的git提交示例(注意,这里重新贴了新图,之前的图逻辑上还是不够清晰)
如下图所示,ABM是master分支线,ABCD是feature分支线。
此时,在feature分支上执行git rebase master后,会提示有冲突,这里是关键,之前没有把这个细节说清楚。冲突其实也简单,因为我们要生成新的C’和D’嘛,那C’的内容如何得到呢?照搬C的?当然不是,C’的内容就是C和M两个节点的内容合并的结果,D’的内容就是D和M两个节点的内容合并的结果。我们手动处理冲突后,执行如下命令即可:
# 先处理完C,会继续报D的冲突,所以下面命令一共会执行两次
git add file
git rebase --continue
1
2
3
变基完成以后如下图所示,ABM还是没变化,ABMC’D’是rebase完成后的feature节点图,私以为讲到这里就还是比较清楚了
三、推荐使用场景
搞来搞去那么多,这其实是最重要的。不同公司,不同情况有不同使用场景,不过大部分情况推荐如下:
拉公共分支最新代码——rebase,也就是git pull -r或git pull --rebase。这样的好处很明显,提交记录会比较简洁。但有个缺点就是rebase以后我就不知道我的当前分支最早是从哪个分支拉出来的了,因为基底变了嘛,所以看个人需求了。总体来说,即使是单机也不建议使用。
往公共分支上合代码——merge。如果使用rebase,那么其他开发人员想看主分支的历史,就不是原来的历史了,历史已经被你篡改了。举个例子解释下,比如张三和李四从共同的节点拉出来开发,张三先开发完提交了两次然后merge上去了,李四后来开发完如果rebase上去(注意,李四需要切换到自己本地的主分支,假设先pull了张三的最新改动下来,然后执行<git rebase 李四的开发分支>,然后再git push到远端),则李四的新提交变成了张三的新提交的新基底,本来李四的提交是最新的,结果最新的提交显示反而是张三的,就乱套了,以后有问题就不好追溯了。
正因如此,大部分公司其实会禁用rebase,不管是拉代码还是push代码统一都使用merge,虽然会多出无意义的一条提交记录“Merge … to …”,但至少能清楚地知道主线上谁合了的代码以及他们合代码的时间先后顺序
四、总结
从项目的维度考量,单人开发,希望提交记录整体简洁清晰,不关注操作顺序——rebase
从人的维度考量,多人开发,希望知道某人在某个时间干了什么以及先后顺序——merge
无论是个人单机开发,还是公司协作开发,只要没有特殊需求,用merge准没错!!!
参考文章:图解 Git 基本命令 merge 和 rebase
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/weixin_42310154/article/details/119004977
【git merge和git rebase的区别, 切记:永远用rebase - 知乎 (zhihu.com)】
git merge和git rebase的区别, 切记:永远用rebase
这一期来谈一下git merge和git rebase的区别。
Git无疑现在已经成为最流行的代码管理工具之一。其中有两个命令,对很多程序员造成了很多的困惑,一个是merge,一个是rebase。
这些困惑主要纠结于到底应该用merge还是用rebase。
在继续深入探讨之前,我先抛出我的观点。如果你想拥有一套稳定的,健壮的代码, 永远要使用rebase。
不为别的,就为了rebase可以给你提供一套清晰的代码历史。
相反的, merge会给你一套乱七八糟的代码历史。当你看到这样的代码历史的时候,我相信你绝对没有心情去研究每一个历史对应的代码。
好,接下来我们就详细分析一下这两个命令的作用。假设我们的repo有这么个主branch: master。
每个程序员在创建自己的代码之前,要首先创建自己的个人分支,然后代码修改开始。
假如你有6个程序员一起工作, 你就会有6个程序员的分支, 如果你使用merge, 你的代码历史树就会有六个branch跟这个主的branch交织在一起。
那个画风我相信对你一定很熟悉。想着那个画风感觉到一切都好无助, 有个词儿比较合适,叫做欲仙欲死。
这就是merge命令下生成的代码分支历史。
那么rebase又能做到什么程度呢?Rebase永远不会导致多个历史分支进行交织。它永远都是一条线。纯洁而又干脆。轻轻爽爽的, 从不拖泥带水。
那为什么会这样呢?
先说一下merge。Merge命令会保留所有commit的历史时间。每个人对代码的提交是各式各样的。尽管这些时间对于程序本身并没有任何意义。但是merge的命令初衷就是为了保留这些时间不被修改。这样也就形成了以merge时间为基准的网状历史结构。每个分支上都会继续保留各自的代码记录, 主分支上只保留merge的历史记录。子分支随时都有可能被删除。子分子删除以后,你能够看到的记录也就是,merge某branch到某branch上了。这个历史记录描述基本上是没有意义的。
还有一个比较有意思的是你不能,也不应该去修改这个历史记录描述。那是因为这个merge记录里面,不仅仅包含你自己的代码,也包含别人的代码。到这里你能想象有多乱吧?
再来说一下rebase, 这个命令会始终把你最新的修改放到最前头。比如你对主branch进行rebase以后, 你的所有修改就会在主branch当前所有的修改之前。你会更有信心保证你的代码运行畅通无阻。通过你自己的测试以后, 你就可以放心的把代码合并到主的branch里面了。
这里值得一提的是,rebase通常是发生在自己的个人branch上的。它的基础就是现有的主branch。这样做的好处就是保证每个人的代码都可以运行在当前最新的主branch的代码上。
-------------
git rebase
和 git merge
都是用于整合分支的工具,但它们的工作方式和适用场景不同。以下是两者的对比:
1. Git Merge
-
功能:将两个分支的历史合并,生成一个新的合并提交。
-
适用场景:
-
需要保留完整的分支历史。
-
适合多人协作或公共分支(如
main
或develop
)。
-
-
优点:
-
保留所有提交历史,便于追踪。
-
操作简单,不易出错。
-
-
缺点:
-
历史记录可能变得复杂,尤其是频繁合并时。
-
-
示例:
git checkout main git merge feature-branch
2. Git Rebase
-
功能:将一个分支的提交重新应用到另一个分支上,形成线性历史。
-
适用场景:
-
希望保持简洁的提交历史。
-
适合个人分支或尚未共享的分支。
-
-
优点:
-
历史记录更清晰,呈线性。
-
便于查看提交顺序。
-
-
缺点:
-
改写历史可能导致冲突,需手动解决。
-
不适用于已共享的分支,可能影响他人工作。
-
-
示例:
git checkout feature-branch git rebase main
3. 选择建议
-
使用
git merge
:-
合并公共分支或需要保留完整历史时。
-
不熟悉
rebase
时,merge
更安全。
-
-
使用
git rebase
:-
希望保持简洁的提交历史时。
-
在个人分支上整理提交记录。
-
4. 注意事项
-
已推送的分支:避免对已推送的分支使用
rebase
,以免影响他人。 -
冲突处理:
rebase
和merge
都可能产生冲突,需手动解决。
总结:merge
适合保留历史,rebase
适合简化历史。根据具体需求选择。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南