# git 合并

Git commits历史是如何做到如此清爽的?

# Rebase场景一:如何合并多次提交记录

  1. 合并最近的n次提交记录

    git rebase -i HEAD~n
    
    1
  2. 进入vi编辑模式

    pick:保留该commit(缩写:p)

    reword:保留该commit,但我需要修改该commit的注释(缩写:r)

    edit:保留该commit, 但我要停下来修改该提交(不仅仅修改注释)(缩写:e)

    squash:将该commit和前一个commit合并(缩写:s)

    fixup:将该commit和前一个commit合并,但我不要保留该提交的注释信息(缩写:f)

    exec:执行shell命令(缩写:x)

    drop:我要丢弃该commit(缩写:d)

  3. 如果保存的时候,出错

    error: cannot 'squash' without a previous commit
    
    1

    注意不要合并先前提交的东西,也就是已经提交远程分支的纪录。

  4. 如果你异常退出了 vi 窗口

    git rebase --edit-todo
    
    1

    这时候会一直处在这个编辑的模式里,我们可以回去继续编辑,修改完保存一下

    git rebase --continue
    
    1
  5. 查看结果

    git log
    
    1

# Rebase场景二:分支合并

  1. 我们先从 master 分支切出一个 dev 分支,进行开发:

    git checkout -b feature
    
    1
  2. 这时候,你的同事完成了一次 hotfix,并合并入了 master 分支,此时 master 已经领先于你的 feature 分支了

  3. 恰巧,我们想要同步 master 分支的改动,首先想到了 merge

  4. 让我们来试试 git rebase而不是使用merge

    git rebase master
    
    1

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

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

  5. rebase 的过程中,也许会出现冲突 conflict。在这种情况,git 会停止 rebase 并会让你去解决冲突。在解决完冲突后,用 git add 命令去更新这些内容

    git rebase --continue
    
    1

    这样 git 会继续应用余下的 patch 补丁文件。

  6. 在任何时候,我们都可以用 --abort 参数来终止 rebase 的行动,并且分支会回到 rebase 开始前的状态。

    git rebase —abort
    
    1

# 注意事项

  1. 如果你想要一个干净的、线性的提交历史,没有不必要的合并提交,你应该使用 git rebase 而不是 git merge 来并入其他分支上的更改。

另一方面,如果你想要保存项目完整的历史,并且避免重写公共分支上的 commit, 你可以使用 git merge。两种选项都很好用,但至少你现在多了 git rebase 这个选择。

  1. 可以使用git commit --amend

# 参考

https://juejin.im/post/6869519303864123399

http://jartto.wang/2018/12/11/git-rebase/

https://git-scm.com/book/zh/v2/