zoukankan      html  css  js  c++  java
  • Git多分支管理

    Git多分支管理

    问题背景

    实际工作过程中如果既定版本号为1.0的发布版本中包含两个最新的产品特性,而这两个特性分别由两个小组并行开发,那么两个小组的特性分支开发完毕之后应该如何合并入1.0的发布版本,不同merge参数带来不尽相同的效果让人容易混淆,这里就专门对比一下常用参数的异同。

    举个例子

    这里我们假定有下面的情况:发布版本号为1.0对应的分支名称是release1.0,其下两个特性分支名称分别为feature1.0-1、feature1.0-2。初始状态下release1.0、feature1.0-1、feature1.0-2均从master创建而来。feature1.0-1由team1开发,feature1.0-2由team2并行开发,其中team1、team2各有有三次提交,详情如下。

    commit 5f234c579c204e7a57de79380fd0412e234f37d8 (HEAD -> feature1.0-1, origin/feature1.0-1)
    Author: team1 <team1@gmail.com>
    Date:   Fri Jun 4 23:39:24 2021 +0800
    
        team1 update file3
    
    commit 157fe9c1104064c68f8b8b6dee92c60d0a9bc1bf
    Author: team1 <team1@gmail.com>
    Date:   Fri Jun 4 23:37:54 2021 +0800
    
        team1 update file1
    
    commit ae8352071aad40348ad287a4f1e7f27e6b37ad66 (origin/release1.0, origin/master, origin/feature1.0-2, origin/HEAD)
    Author: elfcafe <remote@kov.com>
    Date:   Fri Jun 4 22:24:34 2021 +0800
    
        init commit
    

    team2三次提交:

    hackun$ git log
    commit 0250a1956079ff91454e5251028a292dd941365b (HEAD -> feature1.0-2)
    Author: team2 <team2@gmail.com>
    Date:   Fri Jun 4 23:39:52 2021 +0800
    
        team2 add file4
    
    commit 9d3f9edbef2eb8e6f5d392827a64f1c444754a2a
    Author: team2 <team2@gmail.com>
    Date:   Fri Jun 4 23:38:53 2021 +0800
    
        team2 upddte file2
    
    commit ae8352071aad40348ad287a4f1e7f27e6b37ad66 (origin/release1.0, origin/master, origin/feature1.0-2, origin/feature1.0-1, origin/HEAD)
    Author: elfcafe <remote@kov.com>
    Date:   Fri Jun 4 22:24:34 2021 +0800
    
        init commit
    

    这里我们采用ff和no-ff两种不同的merge参数进行合并来对比下merge不同的行为

    ff模式

    hackun$ git branch
    * release1.0
    hackun$ git log
    commit ae8352071aad40348ad287a4f1e7f27e6b37ad66 (HEAD -> release1.0, origin/release1.0, origin/master, origin/HEAD)
    Author: elfcafe <remote@kov.com>
    Date:   Fri Jun 4 22:24:34 2021 +0800
    
        init commit
    hackun$ git merge origin/feature1.0-1
    Updating ae83520..5f234c5
    Fast-forward
     file1 | 1 +
     file3 | 1 +
     2 files changed, 2 insertions(+)
    

    ff即fast-forward,作为git merge时候默认选项,merge执行提示中会显示Fast-forward字样,查看执行过后的结果:

    hackun$ git log --graph --decorate --pretty=oneline --abbrev-commit
    * 5f234c5 (HEAD -> release1.0, origin/feature1.0-1) team1 update file3
    * 157fe9c team1 update file1
    * ae83520 (origin/release1.0, origin/master, origin/HEAD) init commit
    

    此次合并只是把feature1.0-1中的两次修改映射到了release1.0上,并没有产生单独的merge记录

    下面继续合并feature1.0-2中的变更:

    hackun$ git merge origin/feature1.0-2
    ......编辑提交信息
    Merge made by the 'recursive' strategy.
     file2 | 1 +
     file4 | 0
     2 files changed, 1 insertion(+)
     create mode 100644 file4
    

    由于产生了独立的merge提交,所以提交后的分支记录如下:

    hackun$ git log --graph --pretty=format:'%Cred%h%Creset %ad %s %C(yellow)%d%Creset %C(bold blue)<%an>%Creset' --date=short --date-order
    *   99f5fab 2021-06-04 Merge remote-tracking branch 'origin/feature1.0-2' into release1.0  (HEAD -> release1.0) <elfcafe>
    |  
    | * 0250a19 2021-06-04 team2 add file4  (origin/feature1.0-2) <team2>
    * | 5f234c5 2021-06-04 team1 update file3  (origin/feature1.0-1) <team1>
    | * 9d3f9ed 2021-06-04 team2 upddte file2  <team2>
    * | 157fe9c 2021-06-04 team1 update file1  <team1>
    |/  
    * ae83520 2021-06-04 init commit  (origin/release1.0, origin/master, origin/HEAD) <elfcafe>
    

    no-ff模式

    合并步骤大体都一致,不同的是我们在合并feature1.0-1、feature1.0-2时都使用了--no-ff参数

    MacBookProEvo:release1.0_bak hackun$ git merge --no-ff origin/feature1.0-1
    Merge made by the 'recursive' strategy.
     file1 | 1 +
     file3 | 1 +
     2 files changed, 2 insertions(+)
     
    MacBookProEvo:release1.0_bak hackun$ git merge --no-ff origin/feature1.0-2
    Merge made by the 'recursive' strategy.
     file2 | 1 +
     file4 | 0
     2 files changed, 1 insertion(+)
     create mode 100644 file4
    

    两次merge的参数都指定了----no-ff,最后的效果如下:

    MacBookProEvo:release1.0_bak hackun$ git log --graph --pretty=format:'%Cred%h%Creset %ad %s %C(yellow)%d%Creset %C(bold blue)<%an>%Creset' --date=short --date-order
    *   ed0543b 2021-06-05 Merge remote-tracking branch 'origin/feature1.0-2' into release1.0  (HEAD -> release1.0) <elfcafe>
    |  
    *    287a3c8 2021-06-04 Merge remote-tracking branch 'origin/feature1.0-1' into release1.0  <elfcafe>
    |   
    | | * 0250a19 2021-06-04 team2 add file4  (origin/feature1.0-2) <team2>
    | * | 5f234c5 2021-06-04 team1 update file3  (origin/feature1.0-1) <team1>
    | | * 9d3f9ed 2021-06-04 team2 upddte file2  <team2>
    | |/  
    |/|   
    | * 157fe9c 2021-06-04 team1 update file1  <team1>
    |/  
    * ae83520 2021-06-04 init commit  (origin/release1.0, origin/master, origin/HEAD) <elfcafe>
    
    

    这里287a3c8作为feature1.0-1并入release1.0的节点,ed0543b代表feature1.0-2并入release1.0的节点,结构上非常清晰。

    回退分支

    回退分支主要针对release1.0而言,如果release1.0的两次合并请求都采用了之前提到的(--no-ff方式)

    尚未push

    先看下都尚未push到remote的情况

    这时候如果需要只保留feature1.0-1的分支特性(剔除team2开发feature1.0-2),那么直接rest到HEADˆ,便轻松回退掉了feature1.0-2相关代码。

    MacBookProEvo:release1.0_bak_orig hackun$ git reset HEAD^ --hard 
    HEAD is now at 287a3c8 Merge remote-tracking branch 'origin/feature1.0-1' into release1.0
    
    hackun$ git log --graph --pretty=format:'%Cred%h%Creset %ad %s %C(yellow)%d%Creset %C(bold blue)<%an>%Creset' --date=short --date-order --all
    *   287a3c8 2021-06-04 Merge remote-tracking branch 'origin/feature1.0-1' into release1.0  (HEAD -> release1.0) <elfcafe>
    |  
    | | * 0250a19 2021-06-04 team2 add file4  (origin/feature1.0-2) <team2>
    | * | 5f234c5 2021-06-04 team1 update file3  (origin/feature1.0-1) <team1>
    | | * 9d3f9ed 2021-06-04 team2 upddte file2  <team2>
    | |/  
    |/|   
    | * 157fe9c 2021-06-04 team1 update file1  <team1>
    |/  
    * ae83520 2021-06-04 init commit  (origin/release1.0, origin/master, origin/HEAD) <elfcafe>
    

    如果release1.0需要只保留feature1.0-2(剔除feature1.0-1),那么是不是直接reset到HEADˆˆ就好了呢?我们来试试看:

    hackun$ git reset HEAD^^ --hard
    
    bogon:release1.0_noff hackun$ git lg
    * 0250a19 2021-06-04 team2 add file4  (origin/feature1.0-2) <team2>
    | * 5f234c5 2021-06-04 team1 update file3  (origin/feature1.0-1) <team1>
    * | 9d3f9ed 2021-06-04 team2 upddte file2  <team2>
    | * 157fe9c 2021-06-04 team1 update file1  <team1>
    |/  
    * ae83520 2021-06-04 init commit  (HEAD -> release1.0, origin/release1.0, origin/master, origin/HEAD) <elfcafe>
    

    可以看到release直接回退到了ae83520初始commit,team1和team2的提交都被无情退回了,显然结果并不完全符合我们的预期。这时候我们需要重新合并一次team2的feature1.0-2分支。

    hackun$ git merge -no-ff origin/feature1.0-2
    error: did you mean `--no-ff` (with two dashes ?)
    MacBookProEvo:release1.0_noff hackun$ git merge --no-ff origin/feature1.0-2
    Merge made by the 'recursive' strategy.
     file2 | 1 +
     file4 | 0
     2 files changed, 1 insertion(+)
     create mode 100644 file4
     
    hackun$ git lg
    *   1bc9be6 2021-06-08 Merge remote-tracking branch 'origin/feature1.0-2' into release1.0  (HEAD -> release1.0) <elfcafe>
    |  
    | * 0250a19 2021-06-04 team2 add file4  (origin/feature1.0-2) <team2>
    | | * 5f234c5 2021-06-04 team1 update file3  (origin/feature1.0-1) <team1>
    | * | 9d3f9ed 2021-06-04 team2 upddte file2  <team2>
    |/ /  
    | * 157fe9c 2021-06-04 team1 update file1  <team1>
    |/  
    * ae83520 2021-06-04 init commit  (origin/release1.0, origin/master, origin/HEAD) <elfcafe>
    

    己经push

    如果release1.0的两次合并请求(--no-ff方式)已经push到了remote。

    这时候如果需要只保留feature1.0-1的分支特性(剔除team2开发feature1.0-2)就需要revert对应的merge-c00569

    MacBookProEvo:release1.0_noff hackun$ git show
    commit c00569074fab8629823b3382411f9d2ddc231bc7 (HEAD -> release1.0, origin/release1.0)
    Merge: 287a3c8 0250a19
    Author: elfcafe <remote@kov.com>
    Date:   Mon Jun 7 16:42:44 2021 +0800
    
        Merge remote-tracking branch 'origin/feature1.0-2' into release1.0
    
    ......
    
    MacBookProEvo:release1.0_noff hackun$ git revert HEAD -m 1
    [release1.0 f9ef0bb] Revert "Merge remote-tracking branch 'origin/feature1.0-2' into release1.0"
     2 files changed, 1 deletion(-)
     delete mode 100644 file4
    MacBookProEvo:release1.0_noff hackun$ git lg
    * f9ef0bb 2021-06-08 Revert "Merge remote-tracking branch 'origin/feature1.0-2' into release1.0"  (HEAD -> release1.0) <elfcafe>
    *   c005690 2021-06-07 Merge remote-tracking branch 'origin/feature1.0-2' into release1.0  (origin/release1.0) <elfcafe>
    |  
    *    287a3c8 2021-06-04 Merge remote-tracking branch 'origin/feature1.0-1' into release1.0  <elfcafe>
    |   
    | | * 0250a19 2021-06-04 team2 add file4  (origin/feature1.0-2) <team2>
    | * | 5f234c5 2021-06-04 team1 update file3  (origin/feature1.0-1) <team1>
    | | * 9d3f9ed 2021-06-04 team2 upddte file2  <team2>
    | |/  
    |/|   
    | * 157fe9c 2021-06-04 team1 update file1  <team1>
    |/  
    * ae83520 2021-06-04 init commit  (origin/master, origin/HEAD) <elfcafe>
    
    

    对比当前版本与预期版本差异,no difference

    hackun$ git diff HEAD 287a3c
    
    

    如果需要只保留feature1.0-2的分支特性(剔除team1开发feature1.0-1)就需要revert对应的merge

    hackun$ git revert 287a3c8 -m 1
    [release1.0 4c0e9ae] Revert "Merge remote-tracking branch 'origin/feature1.0-1' into release1.0"
     2 files changed, 2 deletions(-)
    MacBookProEvo:release1.0_noff hackun$ git lg
    * 4c0e9ae 2021-06-17 Revert "Merge remote-tracking branch 'origin/feature1.0-1' into release1.0"  (HEAD -> release1.0) <elfcafe>
    *   c005690 2021-06-07 Merge remote-tracking branch 'origin/feature1.0-2' into release1.0  <elfcafe>
    |  
    *    287a3c8 2021-06-04 Merge remote-tracking branch 'origin/feature1.0-1' into release1.0  <elfcafe>
    |   
    | | * 0250a19 2021-06-04 team2 add file4  (origin/feature1.0-2) <team2>
    | * | 5f234c5 2021-06-04 team1 update file3  (origin/feature1.0-1) <team1>
    | | * 9d3f9ed 2021-06-04 team2 upddte file2  <team2>
    | |/  
    |/|   
    | * 157fe9c 2021-06-04 team1 update file1  <team1>
    |/  
    * ae83520 2021-06-04 init commit  (origin/release1.0, origin/master, origin/HEAD) <elfcafe>
    

    比较当前版本与预期版本差异 nodifference

    hackun$ git diff 4c0e9ae 0250a19
    
    
  • 相关阅读:
    2020春Python程序设计_练习1
    热词分析——性能战术
    《淘宝网》质量属性
    架构师应该如何工作?
    寒假学习(十四)
    寒假学习(十三)
    灭霸冲刺(3)
    灭霸冲刺(2)
    灭霸冲刺(1)
    灭霸计划会议
  • 原文地址:https://www.cnblogs.com/elfcafe/p/14896914.html
Copyright © 2011-2022 走看看