rebase基础介绍
git代码合并有两种,git merge 和 git rebase 。两者目的相同,都是把不同分支的提交合并到一起,但是过程有差异。
git merge
作用:把源分支的提交合并到目标分支。过程中,目标分支改变,源分支不变。
优点:简单易上手/保留了提交历史和时间次序/分支结构不变
缺点:提交历史被大量的merge操作污染/git bisect调试困难
git rebase
作用:清除了历史,将一个分支完全转移到了目标分支
优点:复杂的历史变成优雅的提交线
缺点:分支上下文模糊了/dev分支以及feature分支需要经常更新release分支变动到本地
使用rebase时,正确的git flow是怎样的
- 每个feature分支都有单独的分支负责人,分支负责人需要在feature分支开发过程中每天rebase release分支,同时告诉feature分支的自开发分支,及时跟进更新。
- feature子分支开发人员需要在开发完自己的任务之后,将自己分支的点合并成一个点,然后合并到feature分支。
- feature分支负责人在确定所有子分支都已开发完毕并且都压点后合并到feature分支后,交付测试验收。
- 测试验收通过后将feature到release分支等待上线。
1.feature负责人拉出功能分支,并告知功能开发人员相关分支已拉出,可以创建自己的开发分支。
$ git checkout -b feature-xxx
$ git push --set-upstream origin feature-xxx
2.feature开发人员拉出属于自己的业务开发分支
张三
$ git checkout -b feature-xxx-zhangsan
$ git push --set-upstream origin feature-xxx-zhangsan
李四
$ git checkout -b feature-xxx-lisi
$ git push --set-upstream origin feature-xxx-lisi
3.feature开发人员开始做业务开发
张三
$ git add .
$ git commit -m '张三提交1'
$ git push
$ git add .
$ git commit -m '张三提交2'
$ git push
李四
$ git add .
$ git commit -m '李四提交1'
$ git push
$ git add .
$ git commit -m '李四提交2'
$ git push
4.fearure开发人员完成自己的开发任务之后将自己的提交记录合并成一个点
$ git rebase -i HEAD~2
-------------------------
pick 6e48844 张三提交1
pick 5f8e351 张三提交2
//进入编辑模式将第二行开始的pick全部修改成s,
然后esc :wq保存,进入commit msg界面做整理![请添加图片描述](https://img-blog.csdnimg.cn/1156922f478448b09b4c8e3fc57c9c41.gif)
# Rebase 356a5c0..5f8e351 onto 356a5c0 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
$ git status
On branch feature-xxx-zhangsan
Your branch and 'origin/feature-xxx-zhangsan' have diverged,
and have 1 and 2 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
idea git 中可以看到feature-xxx-zhangsan的本地分支已经将两次提交合并成一个点
have 1 and 2 different commits each, respectively.
此时需要将本地分支强推到远程分支
$ git push -f
5.合并到feature分支
先保证本地的feature分支是最新的
$ git checkout feature-xxx
$ git pull
$ git status
合并分支
$ git rebase feature-xxx-zhangsan feature-xxx
Successfully rebased and updated refs/heads/feature-xxx.
注意此时的本地分支已经切换到feature-xxx,也就是rebase命令的第二个参数
gir rebase branchA branchB其实会做两件事情
1.git checkout branchB
2.git rebase branchA
$ git branch
* feature-xxx
feature-xxx-lisi
feature-xxx-zhangsan
main
$ git status
On branch feature-xxx
Your branch is ahead of 'origin/feature-xxx' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
git status可以看到feature-xxx分支上已经有了feature-xxx-zhangsan分支合并的点
$ git push
6.合并到功能分支的时候出现冲突怎么办
李四同样走了这个流程但是在合并到feature分支的时候遇到了麻烦,有代码冲突了
$ git rebase feature-xxx-lisi feature-xxx
Successfully rebased and updated refs/heads/feature-xxx.
$ git status
On branch feature-xxx
Your branch and 'origin/feature-xxx' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
git status看到功能分支feature-xxx有落后,这时候需要拉取落后的代码到本地
注意这里不要直接使用git pull ,git pull 其实会做两个事情 git fetch + git merge , 会产生git提交记录的环线,这是我们要避免产生的事情。
请使用git pull --rebase
$ git pull --rebase
error: could not apply 49f99fb... lisi commit all
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 49f99fb... lisi commit all
Auto-merging src/main/java/com/example/leetcode/editor/test/Test.java
CONFLICT (content): Merge conflict in src/main/java/com/example/leetcode/editor/test/Test.java
可以看到出现了冲突(CONFLICT),这时候需要到idea中处理冲突
$ git status
On branch feature-xxx
Your branch is ahead of 'origin/feature-xxx' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
$ git push
rebase常见问题
1.作为一个feature负责人,发现落后release分支太多了怎么办
出现这种情况有两种原因:
- feature分支太久没有关注release分支的状态,导致落后release分支太多
- release分支被人无脑提交,没有压点
第二种情况是要极力避免的,这种不负责任的提交很可能导致各个feature分支后续的rebase提交需要解决多次冲突
第一种情况怎么解决:
- 先尝试直接rebase release,如果没有冲突或者只需要解决一两次冲突,那么就采用直接rebase的方式。
- 如果rebase release方式有冲突的点很多,那么可以采用将feature分支压点然后切换到release分支使用cherry-pick的方式做代码合并,然后重新创建feature分支,或者set-up-stream重新指向远程feature分支。
2.有人把开发主干分支压点然后强推了怎么办
注意:使用rebase的方式,如果分支是个公共分支,那么不允许rebase,这会打乱别人本地仓库的git提交线
commit msg规范
- feat:新功能(feature)
- fix:bug修复
- refactor:重构
- test:补充单元测试
- docs:补充文档
- style:样式/格式,不影响业务代码 or 逻辑
提交描述的时候,如果涉及多个内容,则使用1.2.3做标注
- 做了什么
- 做了什么
- 做了什么
一定要注意的事情
- 做任何操作的前后都一定要 git status查看工作区状态
- 自己的分支可以git push -f ,但是公共分支,一定不要这么做!
- 不要对公共分支做压点操作,永远不要!
- 使用git pull --rebase 一定是正确的。尽量不要使用git pull,一有冲突就会merge