赞
踩
标题上的两个命令:merge和rebase都是用来合并分支的。
这里不解释rebase命令,以及两个命令的原理,详细解释参考这里。
下面的内容主要说的是两者在实际操作中的区别。
分支就是便于多人在同一项目中的协作开发。比方说:每个人开发不同的功能,在各自的分支开发过程中互不影响,完成后都提交到develop分支。极大的提高了开发的效率。
每个人创建一个分支进行开发,当开发完成,需要合并到develop分支的时候,就需要用到合并的命令。
合并的时候,有可能会产生冲突。
冲突的产生是因为在合并的时候,不同分支修改了相同的位置。所以在合并的时候git不知道哪个到底是你想保留的,所以就提出疑问(冲突提醒)让你自己手动选择想要保留的内容,从而解决冲突。
fetch命令:
- git fetch <远程主机名> #这个命令将某个远程主机的更新全部取回本地
-
- git fetch <远程主机名> <分支名> #如果只想取回特定分支的更新,可以指定分支名
- git fetch origin master #最常见的命令如取回origin 主机的master 分支
取回更新后,会返回一个FETCH_HEAD ,指的是某个branch在服务器上的最新状态,我们可以在本地通过它查看刚取回的更新信息:
git log -p FETCH_HEAD
可以看到返回的信息包括更新的文件名,更新的作者和时间,以及更新的代码(19行红色[删除]和绿色[新增]部分)。
我们可以通过这些信息来判断是否产生冲突,以确定是否将更新merge到当前分支。
merge命令:
- git merge <branch> #将branch分支合并到当前分支
- git merge origin/master #将远程分支合并到当前分支
-
- 这两个命令可以加上--no-ff 表示 不要Fast-Foward合并,这样可以生成merge提交,然后需要再加上-m参数,表示对提交的说明
pull命令:
- 格式:git pull <远程主机名> <远程分支名>:<本地分支名>
- git pull origin master:master 将远程库origin的master分支的更新下载并与master分支合并
- git pull origin master 将远程库origin的master分支的更新下载并与当前分支合并(相当于 git fetch origin master + git merge origin/master)
- git pull origin 将远程库origin与当前分支存在追踪关系的分支的更新下载并合并到当前分支
- git pull 如果当前分支只有一个追踪关系,就将对于远程分支的更新下载并合并到当前分支中
git rebase branchName
采用merge和rebase后,git log的区别,merge命令不会保留分支的commit,rebase会保留所有的commit:
rebase 会把你当前分支的 commit 放到公共分支的最后面,所以叫变基。就好像你从公共分支又重新拉出来这个分支一样。
举例:如果你从 master 拉了个feature分支出来,然后你提交了几个 commit,这个时候刚好有人把他开发的东西合并到 master 了,这个时候 master 就比你拉分支的时候多了几个 commit,如果这个时候你 rebase master 的话,就会把你当前的几个 commit,放到那个人 commit 的后面。
merge 会把公共分支和你当前的commit 合并在一起,形成一个新的 commit 提交
处理冲突的方式:
git add .
和git commit -m 'fix conflict'
。这个时候会产生一个commit。git add .
和git rebase --continue
,不会产生额外的commit。这样的好处是,‘干净’,分支上不会有无意义的解决分支的commit;坏处,如果合并的分支中存在多个commit
,需要重复处理多次冲突。git pull
和git pull --rebase
区别:git pull
做了两个操作分别是‘获取’和合并。所以加了rebase就是以rebase的方式进行合并分支得到一条干净的分支流。
git pull = git fetch origin branchName+ git merge branchName
git pull --rebase = git fetch origin branchName+ git rebase branchName
git rebase --continue; 让 rebase 过程继续执行。
git rebase --abort; 发生代码冲突后,放弃合并,回到操作前的样子。
2.2 git merge
和 git merge --no-ff
的区别1、我自己尝试merge
命令后,发现:merge 时并没有产生一个commit。不是说merge时会产生一个merge commit吗?
注意:只有在冲突的时候,解决完冲突才会自动产生一个commit。
如果想在没有冲突的情况下也自动生成一个commit,记录此次合并就可以用:git merge --no-ff
命令,下面用一张图来表示两者的区别:
2、如果不加 --no-ff 则被合并的分支之前的commit都会被抹去,只会保留一个解决冲突后的 merge commit。
我的理解:主要是看哪个命令用的熟练,能够有效的管理自己的代码;还有就是团队用的是哪种方式。
我对于rebase比较熟悉,所以我一般都用rebase
,但是现在的公司用的是merge --no-ff
命令合并分支。所以,我在工作上就用merge,个人项目就用rebase。
也可以两者结合:
获取远程项目中最新代码时:git pull --rebase
,这个时隐性的合并远程分支的代码不会产生而外的commit(但是如果存在冲突的commit太多就像上面说的,需要处理很多遍冲突)。
合并到分支的时候:git merge --no-ff
,自动一个merge commit,便于管理(这看管理人员怎么认为了)
注意:
抛出问题:
为什么不要再公共分支使用rebase?
因为往后放的这些 commit 都是新的,这样其他从这个公共分支拉出去的人,都需要再 rebase,相当于你 rebase 东西进来,就都是新的 commit 了
merge和rebase实际上只是用的场景不一样
更通俗的解释一波.
比如rebase,你自己开发分支一直在做,然后某一天,你想把主线的修改合到你的分支上,做一次集成,这种情况就用rebase比较好.把你的提交都放在主线修改的头上
如果用merge,脑袋上顶着一笔merge的8,你如果想回退你分支上的某个提交就很麻烦,还有一个重要的问题,rebase的话,本来我的分支是从3拉出来的,rebase完了之后,就不知道我当时是从哪儿拉出来的我的开发分支
同样的,如果你在主分支上用rebase, rebase其他分支的修改,是不是要是别人想看主分支上有什么历史,他看到的就不是完整的历史课,这个历史已经被你篡改了
git rebase -i dev 可以将dev分支合并到当前分支
这里的”-i“是指交互模式。就是说你可以干预rebase这个事务的过程,包括设置commit message,暂停commit等等。
git rebase --continue 让 rebase 过程继续执行
git rebase --abort 放弃一次合并
合并多次commit操作:
1 git rebase -i dev
2 修改最后几次commit记录中的pick 为squash
3 保存退出,弹出修改文件,修改commit记录再次保存退出(删除多余的change-id 只保留一个)
4 git add .
5 git rebase --continue
6 git push origin 开发分支
1.合并当前分支的多个commit记录
$ git log --pretty=format:'%h: %s'
2eeb74a: modify c
5d340c4: modify b
e51aaca: modify b
16aee3f: modify b
58c8fed: modify a
f6f3452: Initial commit
其实,中间的对 b 的 3 次提交完全可以合并成一次 commit,这个时候 rebase 就很有用了。
2.找到想要合并的commit然后使用rebase -i
这里的合并的 commit 是待合并的多个 commit 之前的那个 commit,这里也就是最下面那个 modify a 的commit。
$ git rebase -i 58c8fed
注意:git rebase -i startPonit endPoint
前开后闭区间,这里的 startPonit 是指需要合并的 commit 的前一个 commit (即当前示例中的 58c8fed ),因为三个 commit 肯定要基于上一个 commit 合并成了新的 commit。
谨慎使用 endPoint,该参数省略即默认表示从起始 commit 一直到最后一个,但是一旦你填写了,则表示endPoint 后面的commit全部不要了。
3.进入Interact交互界面
终端会进入选择交互界面,让你进行变基选择操作。
最上面三行,就是刚刚选中的三个 commit,按时间顺序依次往下排序。
前面的三个 Pick 其实就是下面 Commands 展示的 7 种命令中的第一个 p,也就是 use commit。
4.使用s命令合并到上一个commit
按 i 进入操作,将第 2 和 第 3 个 commit 的 pick 改成 s,按 Esc 退出操作,输入 :wq 保存并退出。
5.修改commit记录
接下来会弹出第二个页面,分别展示 3 个commit的提交信息。
这里三个信息都是一样的,我们选用第一个的提交信息,将其余的全部注释掉,重复上述步骤,保存退出即可。
# 执行结果
$ git rebase -i 58c8fed
[detached HEAD 792e41c] modify b
Date: Tue Mar 14 12:28:51 2023 +0800
1 file changed, 1 insertion(+)
Successfully rebased and updated refs/heads/master.
6.查看最新合并情况
$ git log --pretty=format:'%h: %s'
e6c4bbd: modify c
792e41c: modify b
58c8fed: modify a
f6f3452: Initial commit
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。