git rebase
Git rebase 与 Git merge 的区别
如果经常多人协作开发的话,可能都很熟悉 git merge
, 我经常遇到这样的情况:
- 项目开发主分支是 develop 分支
- 我自己从 develop 分支上切出一个feature1 的分支进行开发
-
另一个同事切出一个 feature2 的分支进行开发!
当同事提前完成后将他的 feature 合并到 develop 分支(他的分支两个commit c6, c7)
而我后面完成后为了怕有冲突文件,一般都要先拉取下最新的 develop 合并到我们当前分支,没有冲突或者有冲突文件修改好冲突文件后再把我当前的分支 merge 到 develop 上去这样看流程是没啥问题哇,但是,看下图。
我的分支上只做了两次提交 c5 和 c8 但是我的分支上却多出一个 c9 是为啥呢? 都知道是 merge develop 后都会生成一个 merge 的 commit。
如果我有好几个同事之前都做了提交,我先 merge develop 第一次,发现我还有个问题,我又返回去改代码, 另外一个同事又提交了代码,这样我需要 merge 好几次,我这条分支就会多出很多merge的commit,就不能保持commit的清洁,查看 commit 记录非常不方便。如果想让你的分支在合并了 develop 的代码之后没有 commit 记录,就像没经历过合并,就该用 git rebase
。
现在我同样有两个分支 feature1 和 feature2, 都有各自的新的 commit,
我们先吧 feature2 merge 到 develop 上
$ git checkout develop
$ git merge feature1
现在我们切换到 feature1 上进行 rebase
$ git checkout feature1
$ git rebase develop
从上图我们可以看出,原本c4的提交指向c3提交的 develop 分支,rebase 之后c4就指向了c7了,而且这些提交都待了 一撇,其实这是 git 把 feature1 上的 commit 取消掉了, 然后临时保存成补丁,然后吧develop 分支更新到最新的,在把临时保存的补丁应用到 feature1 分支上。(
当 feature1 分支更新之后,它会指向这些新创建的提交(commit), 而那些老的提交会被丢弃在一边。
如果运行垃圾收集命令(pruning garbage collection), 这些被丢弃的提交就会删除.
总的来说就是把 feature1 变基到 develop 分支上,怎么理解这个变基呢,基就是根基、基础,我们把 feature1 的修改当做是在 develop 的基础上做的修改,改变这个基础的内容就叫变基。
冲突
在rebase的过程中,也许会出现冲突,在这种情况,Git会停止rebase并会让你去解决冲突;在解决完冲突后,用
git add
命令去更新这些内容的索引(index), 然后,你无需执行git commit
,只要执行:
$ git rebase --continue
这样git会继续应用余下的补丁。
在任何时候,你可以用--abort参数来终止rebase的行动,并且"mywork" 分支会回到rebase开始前的状态。
$ git rebase --abort
rebase 作为参数
另外,我们在使用git pull命令的时候,可以使用--rebase参数,即git pull --rebase,这里表示把你的本地当前分支里的每个提交(commit)取消掉,并且把它们临时 保存为补丁(patch)(这些补丁放到".git/rebase"目录中),然后把本地当前分支更新 为最新的"origin"分支,最后把保存的这些补丁应用到本地当前分支上。