merge和rebase的区别-Git实操

前言

实操git管理工具,主要演示如何实现新建分支,提交分支,合并分支到主干,删除分支,管理分支功能。并且详细了解部分功能的区别。git安装与基础使用

什么是分支?

顾名思义,在git中,分支指的是从主线上分离出来进行另外的操作,既不影响主线,主线又可以继续干它的事,它可用来解决临时需求;当分支做完事后可合并到主线上,而分支的任务完成可以删掉了。

通过分支可以使不同的团队各自作业,在关键节点上合并,平时互不干扰,也可以个人与团队并行作业,亦或者不同功能并行前进。

演示(新建分支,切换分支,合并分支,删除分支)

1、选择新建分支

image.png

2、输入分支名称

image.png
勾选下面的 checkout branch 表示新建分之后直接切换到相应分支。不勾选则默认当前分支

image.png
显示本地存在两个分支

3、提交到远程仓库进行管理

image.png

image.png
选择要远程仓库管理的分支-Push(刚刚我们新建的只存在本地,所以要先提交到远程仓库)

image.png
Push之后,就可以看到本地和远程都有了我们的两个分支;
如果是别人新建的远程分支你要同步到本地,选择Checkout as new local branch即可

4、合并分支
合并指的是另一个分支上的commit作用到当前的分支上来。
比如:我创建的xiaocao分支,原来是和master主分支代码完全相同的,但是我修改了xiaocao分支上的代码,所以需要合并到主分支master上去。

4.1 首先把修改后的代码分支(xiaocao),提交到远程仓库
image.png

4.2 切换到master分支
image.png

4.3 选择merge 进行合并分支
image.png
合并完成,我们就可以在master 本地看到我们改动的代码了;
这只是本地,并没有提交到远程分支,我们还需要再Push 一下。
image.png

image.png

image.png

4、删除分支
image.png
image.png
勾选下面的 Delete tracking local branch xiaocao as well 表示同时删除本地分支

提交成功!演示新建分支,切换分支,合并分支,删除分支就完成了

我想一定有很多人疑惑下面这张图片的命令有哪些作用吧,有帮助请一键三连,就是给我最大的动力。
image.png
Checkout : 顾名思义就是切换当前分支进行开发(例如:目前我在主分支main上,想要切换到uat分支开发,点击Checkout即可)
New Branch from Selected : 从所选分支新建分支(例如:目前我在主分支main上,想要根据uat分支,创建sim分支,这个就可以解决。当然,你也可以切换到uat分支,然后点击New Branch也行)
Copare With Current: 当前分支与所选分支做代码比较 (看做一个对比工具,比如uat分支上提交的一个类,和sim的这个类有哪些改变)
Show Diff with Working Tree :将当前代码与工作树中的代码对比 (指定文件中,查看两个版本之间的差异)
Rebase Current onto Selected :在当前分支做变基(将所选分支提交加入到当前分支)
Merge Selected into Current :合并到当前分支(将所选分支合并到当前分支)
Checkout with Rebase :检出所选分支并做变基。(将当前分支提交加入到所选分支)
Rname :修改所选分支名称
Delete : 删除所选分支

演示(回退版本、分支)

IDEA针对已经merge还未push的git,进行撤销
演示
1.1 右键选择Git->Show History
image.png
或者直接点击下方git即可
image.png

1.2 在Git Log里选择remote(即远程分支上的git操作记录)
image.png

1.3 选择被合并merged的分支->右键->点击Revert Commit
image.png
image.png或者 选择 undo commit,然后再 revert (或者 Rollback(idea高版本叫Rollback))

回退版本
演示:
最简单的方法,在想要回退的地方,点击New Branch,拉出一个新分支后在pull到远端。代码都是合并别人分支前的代码。
image.png

在Log选中你想要回退到到分支,右键选择 Reset Current Branch to Here.
image.png

image.png
git reset --mixed: 回退commit和add信息
git reset --soft:只回退了commit的信息。如果还要提交,直接commit即可
git reset --hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容,慎用!

idea更新代码时的两个选项Merge the incoming changes into the current branch与Rebase the current branch on top of the incoming changes

Merge the incoming changes into the current branch,翻译出来就是:将传入的更改合并到当前分支
Rebase the current branch on top of the incoming changes,翻译出来就是:在传入更改的基础上重新建立当前分支
image.png

结论:

如果只使用rebase,那么Git log记录就是一条直线,看起来很干净的log,而只使用merge的log看起来就很乱。
场景不同,使用方法不同:
一个项目(建立的分支很多,频繁提交),建议合理使用rebase和merge(下面有介绍基本使用原则),同样一个项目(分支很少,甚至自己一个人搞),无所谓,你想咋搞就咋搞,自己开心就好。
网上有很多误导人的言论,比如“健壮的代码,永远要使用rebase”。准确的说,就是很多人平日可能仅用merge,而忽略了rebase。
rebase最大好处并不是消除merge,而是避免merge交织。
我个人一般在pull request里面还是采用普通的merge,关键就是合理利用rebase和merge来避免git历史提交里无意义的“交织”。

使用 rebase 和 merge 的基本原则:
下游分支更新上游分支内容的时候使用 rebase
上游分支合并下游分支内容的时候使用 merge
更新当前分支的内容时一定要使用 --rebase 参数
例如现有上游分支 master,基于 master 分支拉出来一个开发分支 dev,在 dev 上开发了一段时间后要把 master 分支提交的新内容更新到 dev 分支,此时切换到 dev 分支,使用 git rebase master。
等 dev 分支开发完成了之后,要合并到上游分支 master 上的时候,切换到 master 分支,使用 git merge dev

逻辑原理
参考链接
merge逻辑图片:
image.png
merge的原理是找到这两个分支的祖先commit,在两个分支最新的commit进行三方对比合并。
例如上图,共同的祖先commit2,master最新commit6,develop最新commit5,merge会基于2,5,6这三个commit进行对比。
1、commit6和commit2对比,如果文件的哈希值不一样,同时commit5和commit2对比,发现一样,说明只有commit6修改了这个文件,这种情况直接合并,不会提示
2、commit6和commit2对比,如果文件的哈希值不一样,同时commit5和commit2对比,哈希值不一样,说明两个分支都对同一个文件修改了,则提示冲突,需要我们手动merge
最后合并完后会生成一个新的commit7

rebase逻辑图片:
image.png
重新基于一个分支上进行commit,就是会把当前分支从祖先的commit后提交的commit都撤销掉,放到一个缓存里面去,然后基于一个分支的后面,把缓存的commit再按顺序一个个新增到这个分支后面
例如上图,在develop分支进行rebase master分支,则会把develop分支上的基于和master共同的祖先分支commit2的后面的commit4,5撤销掉,在master的最新的commit6后面重新增加commit4,5上去,这时候develop相当于在master最新的commit上逐步提交了两个commit4,5。
注意:这里新增了commit4,5,在merge时有可能都会有冲突,这里有可能需要手动merge两次,因为rebase时可能在提交commit4的时候提示冲突一次,在提交commit5的时候又冲突一次。

分析:
rebase:合并后分支图谱好看,一条线,但合并过程中出现冲突的话,比较麻烦(rebase过程中,一个commit出现冲突,下一个commit也极有可能出现冲突,一次rebase可能要解决多次冲突);
merge:合并后分支图谱不好看,一堆线交错,但合并有冲突的话,只要解一次就行了;

注:我一般的做法,如果合并分支的共同祖先分支相差一两个或两三个commit的话,我就用rebase,毕竟rebase合并后好看,分支图谱明确,如果和共同祖先分支相差很多个commit,说明rebase有可能出现多次冲突,合并会很麻烦,这时候我就会用merge

效果图(如何实操)

合理使用rebase,merge和只使用merge的对比图;
**rebase **
image.png
merge
image.png

操作流程

操作情况分析:
如果属于在一个分支上开发,A成员提交并上传了多次代码,B成员提交并上传了多次代码,C成员下拉代码;无论选择rebase还是merge,都是一样的性质,不需要纠结太多。(要告知上传代码节点-成员要同步更新)

如果属于在多个分支上开发,A成员在a分支上开发,B成员在b分支上开发,C成员在c分支上开发,主分支是master
情况1:
1、A成员在a分支上提交并上传了多次代码(开发完成后),并使用merge Selected into Current(将所选分支合并到当前分支),合并到主分支(master)-然后push到远程仓库(主分支)
2、A成员需要告知B、C成员我合并主分支上的代码了,这时候B、C成员需要更新本地主分支(master)代码,选择的是Merge the incoming changes into the current branch
并切换到自己分支,使用Rebase Current onto Selected把主分支加入自己的分支。
3、在更新代码完成后(可能会冲突,对比解决冲突即可),然后B成员在b分支上也提交并上传了多次代码(开发完成后),并使用merge Selected into Current(将所选分支合并到当前分支),合并到主分支(master)-然后push到远程仓库(主分支)
4、B成员需要告知A、C成员我合并主分支上的代码了
其余的成员分支重复2、3、4动作

情况2:
1、A成员在a分支上提交并上传了多次代码(开发完成后),并使用Rebase Current onto Selected(将所选分支合并到当前分支),合并到主分支(master)-然后push到远程仓库(主分支)
2、A成员需要告知B、C成员我合并主分支上的代码了,这时候B、C成员需要更新本地主分支(master)代码,选择的是Rebase the current branch on top of the incoming changes
并切换到自己分支,使用merge Selected into Current把主分支加入自己的分支。
3、在更新代码完成后(可能会冲突,对比解决冲突即可),然后B成员在b分支上也提交并上传了多次代码(开发完成后),并使用Rebase Current onto Selected(将所选分支合并到当前分支),合并到主分支(master)-然后push到远程仓库(主分支)
4、B成员需要告知A、C成员我合并主分支上的代码了
其余的成员分支重复2、3、4动作

操作步骤:
1、创建git项目,project1和project2,同时分别建立三个标识类(testBranch1、testBranch2、testBranch3)并提交master分支

2、分别给两个项目创建三个分支branch1、branch2、branch3分支
操作步骤:+ New Branch->右键点击新建的本地分支(如:branch1)->push:就上传远程仓库了。详细操作可以看我上面的演示。
image.png

3、在项目project1操作,我们分别切换到B1,B2,B3分支,并修改对应的类testBranch1、testBranch2、testBranch3,最后切换到master分支添加一个README.md文件,然后看一下时间轴(git log)

操作步骤-使用merge Selected into Current(branch2、branch3同样模式操作即可):
首先切换到branch1分支,修改branch1分支的代码,进行commit(这里注意,commit只是在本地进行了缓存,并没有提交到远程仓库;想要提交到远程仓库,进行push即可)
image.png

切换到master分支(主分支)把分支branch1更改的代码->合并到master分支上(又叫主分支)
image.png

合并结束后->master分支(代码)新增README.md文件->commit后
image.png

当出现冲突的时候如何解决?
image.png
image.png

4、在项目project2操作,我们分别切换到B1,B2,B3分支,并修改对应的类testBranch1、testBranch2、testBranch3,最后切换到master分支添加一个README.md文件,然后看一下时间轴(git log)

操作步骤-使用Rebase Current onto Selected(branch2、branch3同样模式操作即可):
image.png
合并结束后->查看git log就可以发现是一条直线
image.png

Git多次Commit合并为一次提交

我们希望把第一次到第五次修改合成一条记录
image.png

选择需要合并的提交,选择Squash Commits
image.png

**默认会将选中的几次提交 message 合并在一起,可以重新编辑提交的 message image.png

最后结果
image.png

点赞.jpg

各位看官》创作不易,点个赞!!!
诸君共勉:万事开头难,只愿肯放弃。

免责声明:本文章仅用于学习参考

猜你喜欢

转载自blog.csdn.net/SoulNone/article/details/130335086