意义
变基是另外一种比较常用的合并分支的方法:
git rebase <分支名>
通过该指令将提交到某一分支上的所有修改都移至另一分支上,使得提交历史更加整洁,尽管实际的开发工作是并行的,但它们看上去就像是串行的一样,提交历史是一条直线。
变基操作
首先,我们创建 iss52 和 iss53 分支:
git branch iss52
git branch iss53
然后,在 iss52 分支进行修改并提交一次:
$ git checkout iss52
$ git add .
$ git commit -m'修改iss52'
接下来,切换到 main 分支,merge 合并 iss52 分支:
$ git checkout main
$ git merge iss52
最后,在 iss53 分支进行两次修改并分别提交:
$ git checkout iss53
$ git add .
$ git commit -m'修改iss53'
如果 iss53 上的工作已经完成,需要将其内容合并入 main 分支,这次我们选择使用变基完成合并。
变基的原理其实是找到 iss53 和 main 分支的最近共同祖先 C1,然后对比 iss53 分支相对于 C1 的历次提交( C3 和 C4 ),最后将 C3 和 C4 的修改按序应用到 main 分支所指的快照 C2 上。
执行步骤
在执行变基之前,需要保证 main 分支指向最新提交:
$ git checkout main
$ git pull
Already up to date.
然后,切换至 iss53 分支进行变基:
$ git checkout iss53
$ git rebase main
Successfully rebased and updated refs/heads/iss53.
与 git merge
相比,变基使得提交历史是一条直线,非常整洁,除此区别之外,两者最终效果是一样的。
Sourcetree 提示:超前3个版本,落后2个版本,说明本地仓库与远程仓库存在冲突,这种情况通过普通的 git push 无法解决,
因此,可以通过 git push
添加 -f
、 --force
或者 --force-with-lease
选项,来强制推送本地提交历史覆盖服务器上的提交历史。
git push -f
是 git push --force
的简写方式,这个指令会强制覆盖远程仓库的提交历史,可能会导致数据丢失或冲突。git push --force-with-lease
是一个更安全的方式来进行强制推送,如果远程分支的提交历史与本地分支不一致,那么推送将被拒绝,从而避免覆盖其他人的提交。
$ git push -f
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 12 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 602 bytes | 602.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/AttitudeToLife/git-practise.git
+ 9b3d537...02a310a iss53 -> iss53 (forced update)
由于 iss53 是我们自己创建的开发分支,一般来说通过 git push -f
强制推送是可以的,切记不要在共享分支上使用该指令。
截止到目前,iss53 分支已经包含了 iss52 的分支内容,最后,切换回 main 分支,进行一次 merge 合并:
$ git checkout main
$ git merge iss53
$ git push
现在,我们已经把 iss53 分支内容成功合并入 main 分支。
解决冲突
在切换至 iss53 分支进行变基操作时,如果 iss52 和 iss53 的分支,对同一文件做了不同的修改,就会产生冲突:
$ git checkout iss53
$ git rebase main
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
error: could not apply d556a63... 修改iss53
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
此时,Git 会暂停下来,需要去手动解决冲突。
打开包含冲突的文件,冲突部分会被标记为 <<<<<<<,=======,>>>>>>>:
如果感觉不够直观,推荐使用 VSCode 另一种合并工具(点击“在合并编辑器中解析”)。
按照变基的基本原理,iss53 分支上 C3 和 C4 的修改会按序应用到 main 分支所指的快照 C2 上,所以,首先是解决 C2 与 C3 的冲突:
一般情况下, C2 与 C3 的修改都需要保留。
解决冲突之后,点击“完成合并”,执行 git rebase --continue
指令:
$ git rebase --continue
启动文本编辑器,这里无需修改,按键盘 Esc
,再按 Shift + ;
,输入 wq
保存退出即可。
Sourcetree 上显示,newC3 已经移动到 C2 的上面:
由于 C4 是需要移动到 newC3 的上面,因此,接下来是解决 newC3 与 C4 的冲突:
点击“完成合并”,继续执行 git rebase --continue
指令,启动文本编辑器,依旧无需修改,保存退出即可。
$ git rebase --continue
[detached HEAD 0d93019] 第二次修改iss53
1 file changed, 1 insertion(+)
Successfully rebased and updated refs/heads/iss53.
至此,冲突解决完毕。
在整个解决冲突的过程中,随时可以使用 git rebase --abort
指令来放弃变基操作。
变基原则
变基可以让提交记录更为整洁,为了避免覆盖其他人的提交,切记要在自己创建的本地分支执行变基,不要在已经被推送至共用分支的提交上执行变基。
共同学习,写下你的评论
评论加载中...
作者其他优质文章