Git合并最近的commit

合并commit的做法一般用在pull request的时候,把开发同一功能时的所有琐碎的commit合并到一个(假装自己的代码是高质量代码(手动滑稽))。主要使用的命令是git rebase 或者git reset,这两个命令的区别可以看这里,一般推荐用git rebase,因为commit的历史能保存下来。

1. git rebase

首先用git log查看commit历史确定需要操作的commit,比如:

commit 0bca654809387dc226cfc4ff872f65601809f485
Author: CasiaFan <fanzongshaoxing@gmail.com>
Date:   Wed Aug 16 13:13:12 2017 +0800

    fix typo

commit b5bf9998e40dc165d7e3055bae47172de11225d4
Author: CasiaFan <fanzongshaoxing@gmail.com>
Date:   Wed Aug 16 10:02:30 2017 +0800

    add random vertical flip during image preprocessing

commit 70a4958184106b9ce848da34be34bdf0dbf36450
Author: CasiaFan <fanzongshaoxing@gmail.com>
Date:   Wed Aug 16 09:58:55 2017 +0800

    step by step running

commit d68608c2dbd41a1b89363f4b743bc5464b6749be
Author: CasiaFan <fanzongshaoxing@gmail.com>
Date:   Mon Aug 14 15:52:47 2017 +0800

    modify description

如果需要操作最近4个commit:

git rebase -i HEAD~4   # 操作对象为从倒数第4个commit开始到当前的commit
# git rebase -i d68608c2dbd41a1b89363f4b743bc5464b6749be  # 倒数第4个commit 的id

然后会跳出编辑页面像这样:

pick d68608c modify description
pick 70a4958 step by step running
pick b5bf999 add random vertical flip during image preprocessing
pick 0bca654 fix typo

# Rebase 529bf46..0bca654 onto 529bf46 (4 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# 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.
#
# Note that empty commits are commented out

把需要保留的commit之前保留pick,需要合并的前面改成squash,编辑保存退出以后输入新的commit message,最后保存退出。

# This is a combination of 6 commits.
add random vertical flip for image preprocessing  # 合并后的commit
# The first commit's message is:
test
# This is the 2nd commit message:

object detection api usage step

# This is the 3rd commit message:

modify description

# This is the 4th commit message:

step by step running

# This is the 5th commit message:

add random vertical flip during image preprocessing

# This is the 6th commit message:

fix typo

这个时候再git log的日志如下:

commit 7f774d88eb6884c97c8b3c05a9268afa581d5b57
Author: Unknown <fanzongshaoxing@gmail.com>
Date:   Mon Aug 14 15:45:29 2017 +0800

    add random vertical flip for image preprocessing
    test
    
    object detection api usage step
    
    modify description
    
    step by step running
    
    add random vertical flip during image preprocessing
    
    fix typo

如果修改了一半不想合并了就用git rebase --abort删除。

git reset

git reset --soft "HEAD~4"
git commit --amend

或者

git reset --hard HEAD~4  # 将branch状态切到到4个commit之前
git merge --squash HEAD@{1}  # 将当前commit(此时为倒数第四个)之后的commit都合并
git commit # commit squashed changes

参考

https://stackoverflow.com/questions/5189560/squash-my-last-x-commits-together-using-git
https://stackoverflow.com/questions/2563632/how-can-i-merge-two-commits-into-one
http://zerodie.github.io/blog/2012/01/19/git-rebase-i/

点赞