【GIT操作】如何合并多个commit

场景

在单个分支中有着多次commit,并push到了远程分支上。假设分支的commit如下图,一共有5次commit。

1
2
3
4
5

计划将第二次commit至第五次commit合并成一个commit。合并效果,如下图。

1
5'

操作步骤

通过git bash工具交互式操作。

  1. 查询commit的commitID

    git log --oneline
    

    --oneline参数,代表将每个commit压缩成一行,只显示commitIDcommit message的第一行。

    d5ace53 第5次commit
    25d5ae5 第4次commit
    73c98f9 第3次commit
    a50f132 第2次commit
    d5d1335 第1次commit
    
  2. 变基到第一次commit,开启交互式操作。

    git rebase -i d5d1335
    

    -i参数,代表展开交互界面

    pick a50f132 第2次commit
    pick 73c98f9 第3次commit
    pick 25d5ae5 第4次commit
    pick d5ace53 第5次commit
    
    # Rebase d5d1335..d5ace53 onto d5d1335 (4 command)
    #
    # Commands:
    # p, pick <commit> = use commit
    # r, reword <commit> = use commit, but edit the commit message
    # e, edit <commit> = use commit, but stop for amending
    # s, squash <commit> = use commit, but meld into previous commit
    # f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
    #                    commit's log message, unless -C is used, in which case
    #                    keep only this commit's message; -c is same as -C but
    #                    opens the editor
    # x, exec <command> = run command (the rest of the line) using shell
    # b, break = stop here (continue rebase later with 'git rebase --continue')
    # d, drop <commit> = remove commit
    # l, label <label> = label current HEAD with a name
    # t, reset <label> = reset HEAD to a label
    # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
    #         create a merge commit using the original merge commit's
    #         message (or the oneline, if no original merge commit was
    #         specified); use -c <commit> to reword the commit message
    
    

    insert键,进入编辑模式,将3,4,5commit的pick修改成ssquash

    pick a50f132 第2次commit
    s 73c98f9 第3次commit
    s 25d5ae5 第4次commit
    s d5ace53 第5次commit
    
    # Rebase d5d1335..d5ace53 onto d5d1335 (4 command)
    #
    # Commands:
    # p, pick <commit> = use commit
    # r, reword <commit> = use commit, but edit the commit message
    # e, edit <commit> = use commit, but stop for amending
    # s, squash <commit> = use commit, but meld into previous commit
    # f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
    #                    commit's log message, unless -C is used, in which case
    #                    keep only this commit's message; -c is same as -C but
    #                    opens the editor
    # x, exec <command> = run command (the rest of the line) using shell
    # b, break = stop here (continue rebase later with 'git rebase --continue')
    # d, drop <commit> = remove commit
    # l, label <label> = label current HEAD with a name
    # t, reset <label> = reset HEAD to a label
    # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
    #         create a merge commit using the original merge commit's
    #         message (or the oneline, if no original merge commit was
    #         specified); use -c <commit> to reword the commit message
    
    

    保存,展开修改message的界面,类似rebase的界面。

    # This is a combination of 4 commits.
    # This is the 1st commit message:
    
    第2次commit
    
    # This is the commit message #2:
    
    第3次commit
    
    # This is the commit message #3:
    
    第4次commit
    
    # This is the commit message #4:
    
    第5次commit
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    #
    # Date:      Fri Dec 29 17:22:02 2023 +0800
    #
    # interactive rebase in progress; onto d5d1335
    # Last commands done (4 commands done):
    #   pick a50f132 第2次commit
    #   s 73c98f9 第3次commit
    #   s 25d5ae5 第4次commit
    #   s d5ace53 第5次commit
    # No commands remaining.
    # You are currently rebasing branch 'Dev_Br20231207-mergecommit' on 'd5d1335'.
    #
    # Changes to be committed:
    
    

    修改后保存。

    # This is a combination of 4 commits.
    # This is the 1st commit message:
    
    合并commit2至commit5
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    #
    # Date:      Fri Dec 29 17:22:02 2023 +0800
    #
    # interactive rebase in progress; onto d5d1335
    # Last commands done (2 commands done):
    #   pick a50f132 第2次commit
    #   s 73c98f9 第3次commit
    #   s 25d5ae5 第4次commit
    #   s d5ace53 第5次commit
    # No commands remaining.
    # You are currently rebasing branch 'Dev_Br20231207-mergecommit' on 'd5d1335'.
    #
    # Changes to be committed:
    
    

    保存后会回到命令行界面。

    $ git rebase -i d5d1335
    [detached HEAD fce4ac1] 1.测试1 1.测试2
     Date: Fri Dec 29 17:22:02 2023 +0800
     1 file changed, 1 insertion(+), 1 deletion(-)
    Successfully rebased and updated refs/heads/Dev_Br20231207-mergecommit.
    
  3. 强制推送到远程分支。

    git push -f
    

    可能需要输出账号密码。

注意点

  1. 这种方式只能支持单个分支中的普通提交点。
  2. 不支持多分支合并无法操作。
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐