zoukankan      html  css  js  c++  java
  • Git rebase 合并多次提交

    在一般研发管理流程中,我们一般都是这么使用Git版本的:

    • 0、先拿到一个需求(不细谈需求前面的采集、归纳整理、确认及评审等环节)
    • 1、从主分支checkout一个新分支
    • 2、在完成阶段性的目标后,提交代码
    • 3、完成整体需求后自测,并提测,提测内容包含当前分支代码
    • 4、通过测试后,代码合并到主分支
    • 5、新建tag,按照tag发布代码,系统上线

    整个流程没有什么问题,只是在git管理时,会在git的提交记录中看到每一次的提交,使得主分支的版本比较多,在特殊情况下,进行代码回溯及比较时,弄得头晕眼花。

    Git提供reabse命令,可以将多次commit合并成一个提交,这样提交记录看起来比较简洁些。

    没有rebase的示例

    开发改需求时,先checkout出了一个新分支feature_connectLimit_20201119,使用git log或者IDEA查看某需求的提交记录,如下图

    从上到下对应的revision number如下表

    9e1a88efb9cad48a46a1103a6920d752afca3513
    9a32e0bc33c8d31bb6d9f2150af247aa784df14d
    9fa7517460aac5c8d3e617be0e8c92d3e0570926
    d1fcf3db8a49207a065624295121b903d06bec64
    d0096d69986a70ea7911dd521fcfafcd7dad13e0
    2fe0e3f1ac36d6299bb2618394d0d73ab79e17c7
    37a19607401bbe929884ae36d34f0df450754692
    

    合并到主分支(main)时,如果不进行处理,就会在主分支看到6条commit,如下图

    以上还是比较乐观的情况,主分支只需要fast-forward到最新commit即可。如果发生冲突,再进行merge后,版本图表就不是一条简简单单的直线了。

    rebase示例

    git 提供了reabase命令,可以将(连续的、关联性的)多次commit合并成一个新的commit,再重新合并到主分支。

    我们将2fe0e3f1~9e1a88ef这6个commit合并成一个新的commit。
    具体看以下命令:

    git checkout feature_connectLimit_20201119
    git rebase -i 37a19607
    

    其中,-i 的参数是不需要合并的 commit 的 hash 值。
    进入到vi的编辑模式,

    pick 2fe0e3f1a --story=1038913 --user=xxx 国内外 - 限制过去60分钟内呼叫短信次数 https://www.tapd.cn/xxx/s/xxx
    pick d0096d699 呼叫记录:插入时检查重复
    pick d1fcf3db8 呼叫记录:根据redis插入时检查重复
    pick 9fa751746 --story=1038913 --user=xxx 国内外 - 限制过去60分钟内呼叫短信次数 https://www.tapd.cn/xxx/s/xxx
    pick 9a32e0bc3 代码还原
    pick 9e1a88efb 调整缓存key
    
    # Rebase 37a196074..9e1a88efb onto 9fa751746 (6 commands)
    #
    # 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 <commit> = like "squash", but discard this commit's log message
    # x, exec <command> = run command (the rest of the line) using shell
    

    可以看到其中分为两个部分,上方未注释的部分是填写要执行的指令,而下方注释的部分则是指令的提示说明。指令部分中由前方的命令名称、commit hash 和 commit message 组成。

    根据命令注释,我们很容易知道 pick 和 squash 这两个命令的大概意义。

    pick 的意思是要会执行这个 commit
    squash 的意思是这个 commit 会被合并到前一个commit
    

    我们将 d0096d699~9e1a88efb 这5个 commit 前方的命令改成 squash 或 s,然后输入:wq以保存并退出,如下

    pick 2fe0e3f1a --story=1038913 --user=xxx 国内外 - 限制过去60分钟内呼叫短信次数 https://www.tapd.cn/xxx/s/xxx
    s d0096d699 呼叫记录:插入时检查重复   
    s d1fcf3db8 呼叫记录:根据redis插入时检查重复   
    s 9fa751746 --story=1038913 --user=xxx 国内外 - 限制过去60分钟内呼叫短信次数 https://www.tapd.cn/xxx/s/xxx
    s 9a32e0bc3 代码还原   
    s 9e1a88efb 调整缓存key
    

    这时我们会看到新的commit message 的编辑界面,大概列举了要合并的commit的log信息。

    # This is a combination of 6 commits.
    # This is the 1st commit message:
    
    --story=1038913 --user=xxx 国内外 - 限制过去60分钟内呼叫短信次数 https://www.tapd.cn/xxx/s/xxx
    
    # This is the commit message #2:
    
    呼叫记录:插入时检查重复
    
    # This is the commit message #3:
    
    呼叫记录:根据redis插入时检查重复
    
    # This is the commit message #4:
    
    --story=1038913 --user=xxx 国内外 - 限制过去60分钟内呼叫短信次数 https://www.tapd.cn/xxx/s/xxx
    
    # This is the commit message #5:
    
    代码还原
    
    # This is the commit message #6:
    
    调整缓存key
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    #
    # Date:      Fri Nov 20 19:08:02 2020 +0800
    #
    # interactive rebase in progress; onto 37a196074
    # Last commands done (6 commands done):
    #    squash 9a32e0bc3 代码还原
    #    squash 9e1a88efb 调整缓存key
    # No commands remaining.
    # You are currently rebasing branch 'feature_connectLimit_20201119' on '37a196074'.
    #
    # Changes to be committed:
    ...file lists
    

    输入新的提交信息,this is a rebase test for many times commit;,并:wq保存退出。再次查看 commit 历史信息,你会发现这些commit已经合并了。

    这是合并的commit的提交信息:

    合并到主分支后,也只有一条commit,这些清爽多了。

  • 相关阅读:
    AngularJS之ng-repeat指令
    AngularJS之ng-controller指令
    HttpClient通过Post上传文件
    response.setHeader()的用法
    response 设置响应头的常用几种方法
    理解HTTP session原理及应用
    mysqldump 利用rr隔离实现一致性备份
    Struts标签、Ognl表达式、el表达式、jstl标签库这四者之间的关系和各自作用
    AngularJS之ng-model指令
    AngularJS之ng-app指令
  • 原文地址:https://www.cnblogs.com/Candies/p/14031207.html
Copyright © 2011-2022 走看看