Git变基使用方式


变基 rebase 的特点:把分叉的提交历史“整理”成一条直线,看上去更直观。

Git变基使用方式


1. Rebase:产生意义

主要讲述其主要的用途和产生的作用

Git 中整合来自不同分支的修改主要有两种方法:merge 以及 rebase。对应 merge 操作来说,想必我们都已经使用过很多次了,而 rebase 又是用在哪里呢?已经其正确的使用方式,到底是什么呢?

我们使用 Git 进行产品开发的代码管理,势必是会存在多人在同一个分支上协同工作的问题,这样就很容易出现冲突。而遇到冲突的时候,一般情况都是已经有人在该分支上面提交代码了,我们不得不先将其他的提交 pull 到本地,然后在本地合并(如果有冲突的话),最后才能 push 成功。

$ git push origin master
To github.com:xxx/xxx.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to '[email protected]:xxx/xxx.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

但是我们会发现提交记录会变得有点嘎里嘎气的,强迫症的你可能需要一条干净的直线,因为太多无用的 commit 很让人不舒服。而且不利于每天下午的 code review 代码检视,同时也会污染分支提交记录。

如果使用 rebase 操作的话,可以把本地未 push 的分叉提交历史整理成直线。rebase 的目的是使得我们在查看历史提交的变化时更容易,因为分叉的提交需要三方对比。

$ git log --graph --pretty=oneline --abbrev-commit
*   e0ea545 (HEAD -> master) Merge branch 'master' of github.com:xxx/xxx
|\
| * f005ed4 (origin/master) add email info
* | 582d922 add author info
* | 8875536 add comment info
|/
* d1be385 init hello repo
......

2. Rebase:合并纪录

主要讲述如何将之前 commit 提交信息进行合并

这个时候,就该 rebase 上场了,其会使原本分叉的提交立马变成一条直线!这种神奇的操作,其实原理非常简单。注意观察,Git 把我们本地的提交“挪动”了位置,放到了 f005ed4 之后,这样,整个提交历史就成了一条直线。rebase 操作前后,最终的提交内容是一致的,但是,我们本地的 commit 修改内容已经变化了,它们的修改不再基于 d1be385,而是基于 f005ed4,但最后的提交 7e61ed4 内容是一致的。

$ git rebase
First, rewinding head to replay your work on top of it...
Applying: add comment
Using index info to reconstruct a base tree...
M    hello.py
Falling back to patching base and 3-way merge...
Auto-merging hello.py
Applying: add author
Using index info to reconstruct a base tree...
M    hello.py
Falling back to patching base and 3-way merge...
Auto-merging hello.py
# 再用 git log 看看发现变成直线了
$ git log --graph --pretty=oneline --abbrev-commit
* 7e61ed4 (HEAD -> master) add author info
* 3611cfe add comment info
* f005ed4 (origin/master) add email info
* d1be385 init hello repo
......

当然,我们也可以指定对最近的多少次的提交纪录进行合并。需要注意的是,不要合并已经提交到仓库的提交,不然会有问题。

编号 选项列表 对应含义解释
1 p, pick use commit
2 r, reword use commit, but edit the commit message
3 e, edit use commit, but stop for amending
4 s, squash use commit, but meld into previous commit
5 f, fixup like “squash”, but discard this commit’s log message
6 x, exec run command (the rest of the line) using shell
7 d, drop remove commit
# 合并最近的3次提交纪录
# 之后就会自动进入vi编辑模式
$ git rebase -i HEAD~3
s 7e61ed4 add author info
s 3611cfe add comment info
s f005ed4 add email info

# 最好编辑退出即可
# 如果你异常退出了vi窗口,不要紧张,执行下面操作即可
$ git rebase --edit-todo
$ git rebase --continue

3. Rebase:分支合并

讲述具体操作合并的操作步骤!

假设你们团队一直在 master 分支上面开发,但是因为新功能所以切了一个 dev 分支出来。这时,你的同事完成了自己开发的部分 hotfix 并将其合入了 master 分支,此时你的分支已经落后于 master 分支了。

恰巧,这时你需要同步 master 分支上面的改动,进行测试。我们就需要 merge 代码到自己的分支上。此时,我们会发现本地有一些 merge 信息。强迫症的你,可能认为这样会污染我们自己的原本干净的提交记录,想要保持一份干净的提交记录。此时,我们就是使用 rebase 了。

我们使用 git rebase 命令,先回退到同事 hotfix,后合并 master 分支:

  • 首先,git 会把 dev 分支里面的每个 commit 取消掉;
  • 其次,把上面的操作临时保存成 patch 文件,存在 .git/rebase 目录下;
  • 然后,把dev 分支更新到最新的 master 分支;
  • 最后,把上面保存的 patch 文件应用到 dev 分支上;

commit 记录上可以看出来,dev 分支是基于 hotfix 合并后的 master,自然而然的成为了最领先的分支,而且没有 mergecommit 记录,是不是感觉很舒服了。

# 我们自己在dev分支上面
$ git rebase master

4. Rebase:使用建议

不能忽视一个重要的事实:rebase 会改写历史记录

下面是一些在使用 rebase 当中需要注意的地方:

  • 最好是该分支只有你自己在使用,否则请谨慎操作。
  • 只使用 rebase 来清理本地的提交记录,千万不要尝试对已发布的提交进行操作。

虽然 rebase 相对于我们已知的整合操作来说有着比较显著的优点,但是这也是在很大程度上取决于个人的喜好。一些团队喜欢使用 rebase,而另一些可能倾向于使用 merge 合并。此外,rebase 相对于 merge 合并来说是比较复杂的,除非你和你的团队确定会用到 rebase 操作。


文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !
  目录