git 使用 rebase 代替 merge

合并还是变基

合并分支时,应使用rebase合并分支而不是使用merge

merge

在分支很多的时候,merge会使提交变得异常混乱,查找某个提交会非常不好找,即使使用图形工具,也无法快速的查找,如果想退到某次提交更是难上加难。merge即使删除了合并过来的分支,其合并轨迹也依然被保留,所以还是很乱。

git merge

rebase

在分支很多的时候,不会产生很多的分支线,实践中应该就只有master,release等分支线,功能分支线在合并到master 上后都被删除,这样提交基本都在一条线上,十分清楚整洁。

git rebase

使用rebase合并分支

场景分析:

功能feature1feature2都在开发,feature1先上线,合并到了master,此时,feature2不应使用mergemaster进行合并操作,而是使用rebase进行合并

  • master上的提交有:[m1, m2, m3]

  • feature1上的提交有: [f1_01, f1_02, f1_03]

  • feature2上的提交有: [f2_01, f2_02, f2_03]

feature1先被合并到master:

  • master上的提交有:[m1, m2, m3, f1_01, f1_02, f1_03]

feature2合并master

  • feature2上的提交有:[m1, m2, m3, f1_01, f1_02, f1_03,f2_01_new, f2_02_new, f2_03_new]

合并步骤

feature2要把master上的提交合并过来,使用rebase 而不是merge,这样就会不产生合并提交,在向master提交时就变成了快速向前

git co feature2
git rebase master

# 如果发生冲突,解决冲突后把冲突文件加入 index 区
git add -u
# 运行continue 以使rebase完成
git rebase --continue
  • 步骤1:git rebase master:以master分支做为feature2的基础

  • 步骤2:计算出feature2master上的差异提交,相当于git log master...feture2,即[f2_01, f2_02, f2_03]

  • 步骤3:把[f2_01, f2_02, f2_03]master上的最新提交f1_03上进行重放生成新的提交

    [f2_01_new, f2_02_new, f2_03_new]

    重放生成过程:

    1. f2_01以f1_03为基础,生成新的f2_01_new
    2. f2_02以f2_01_new为基础,生成新的f2_02_new
    3. f2_03以f2_02_new为基础,生成新的f2_03_new
  • 步骤4:把当前分支设置为feature2

    feature2rebase后的提交有[m1, m2, m3, f1_01, f1_02, f1_03,f2_01_new, f2_02_new, f2_03_new]

    之前的旧的[f2_01, f2_02, f2_03]feature2上就看不到了,但依然在git中,如果没有其它分支指向它们,则会被git 回收机制删除

小结

  1. merge会让提交变得越来越混乱
  2. rebase可以使主线一直保持清晰,rebase操作可以看是剪支操作,把分支剪下来,接到主线上。这样就可以把多条分支线变为一条,使所有提交变得清晰。
  3. 不要对已经push了的分支进行rebase,这会让已经存在的提交丢失,如果有人已经拉取了这个分支,也会给别人提交带来混乱