• 12. Git rebase命令


    前言

    该文章只是记录了一些自己的见解,可能并不准确,只是为了学习时的一些记录,不喜勿喷,谢谢

    rebase命令可以用于分支的合并,可能有些朋友会觉得,分支合并不是可以使用merge命令吗,那么rebase命令和merge命令的区别是什么呢?

    rebase命令在效果上和 merge 命令效果类似,但是原理决然不同,下面我们分别来看看

    1. merge和rebase比较

    1.1 merge命令效果图

    使用merge命令后,效果图如下:

    可以看到,使用merge命令后,会生成一个节点,该节点有两个父id,分别对应两个分支的节点

    1.2 rebase命令效果图

    使用 rebase命令后效果图如下:

    最终的效果就是两个分支处于同一个历史线上,只是指向的历史节点不同而已,即消除了节点的分叉,代价就是将历史记录丢失

    2. rebase命令的使用

    2.1 使用场景

    推荐在还未推送到远程版本库时,想对分支进行合并,且消除节点的分叉,但是要注意会丢失以前的历史记录,因为会生成新的节点,如果我们追求完美,即对于历史不是很关注,可以使用该方式,因为该方式会导致历史线最终呈现一条直线。如果想完美保留历史线,则可以使用merge命令。

    2.2 模拟场景

    下面,我会在本地创建两个分支,在不同分支中修改同一个文件,且在不同分支各自提交,然后使用rebase命令合并,操作如下:

    [root@huangzb git5]# ll
    total 12
    -rw-r--r-- 1 root root 13 Apr 17 21:17 hello1.txt
    -rw-r--r-- 1 root root 13 Apr 17 21:17 hello2.txt
    -rw-r--r-- 1 root root  5 Apr 17 21:15 init.txt
    [root@huangzb git5]#
    [root@huangzb git5]# git branch
      dev
    * master
      test
    [root@huangzb git5]# git checkout dev
    Switched to branch 'dev'
    [root@huangzb git5]# echo 'hello dev1' > hello1.txt
    [root@huangzb git5]#
    [root@huangzb git5]# git add .
    [root@huangzb git5]# git commit -m 'update dev hello1'
    [dev 2b8d24d] update dev hello1
    1 file changed, 1 insertion(+)
    create mode 100644 hello1.txt
    [root@huangzb git5]#
    [root@huangzb git5]# echo 'hello dev2' > hello2.txt
    [root@huangzb git5]# git add .
    [root@huangzb git5]# git commit -m 'update dev2 hello2'
    [dev 0acb17c] update dev2 hello2
    1 file changed, 1 insertion(+)
    create mode 100644 hello2.txt
    [root@huangzb git5]#
    [root@huangzb git5]# git checkout test
    Switched to branch 'test'
    [root@huangzb git5]# echo 'hello test1' > hello1.txt
    [root@huangzb git5]# git add .
    [root@huangzb git5]# git commit -m 'update test1 hello1'
    [test c93f562] update test1 hello1
    1 file changed, 1 insertion(+)
    create mode 100644 hello1.txt
    [root@huangzb git5]# echo 'hello test2' > hello2.txt
    [root@huangzb git5]# git add .
    [root@huangzb git5]# git commit -m 'update test2 hello2'
    [test b24eeb3] update test2 hello2
    1 file changed, 1 insertion(+)
    create mode 100644 hello2.txt
    [root@huangzb git5]#
    

    通过上述的操作,形成如下图效果:

    2.3 使用步骤

    使用前,我们要想好,是哪个分支合并到哪个分支,例如,我们想将dev分支的代码合并到test分支,那么我们就需要先切换到test分支,使用rebase命令

    步骤如下:

    1. 切换到被合并的分支
    2. 使用 git rebase 将哪个分支合并 命令来进行合并操作。

    2.3.1 切换到被合并的分支

    对于我们的需求:将dev分支的代码合并到test分支中,则被合并的分支是test,那么操作如下:

    [root@huangzb git5]# git checkout test
    Switched to branch 'test'
    [root@huangzb git5]#
    

    2.3.2 使用命令git rebase操作

    使用命令 git rebase 待处理的分支 来进行合并,这里可能会遇到冲突,在本例中,我故意的修改同一个文件,必然会产生冲突,我们先来看看执行命令的效果

    [root@huangzb git5]# git rebase dev
    First, rewinding head to replay your work on top of it...
    Applying: update test1 hello1
    Using index info to reconstruct a base tree...
    Falling back to patching base and 3-way merge...
    Auto-merging hello1.txt
    CONFLICT (add/add): Merge conflict in hello1.txt
    error: Failed to merge in the changes.
    Patch failed at 0001 update test1 hello1
    The copy of the patch that failed is found in: .git/rebase-apply/patch
     
    Resolve all conflicts manually, mark them as resolved with
    "git add/rm <conflicted_files>", then run "git rebase --continue".
    You can instead skip this commit: run "git rebase --skip".
    To abort and get back to the state before "git rebase", run "git rebase --abort".
     
    [root@huangzb git5]#
    

    从上图中,可以看到使用该命令后,果然出现了冲突,给我们的提示翻一下,如下:

    首先,倒带头在上面重放你的作品。。。
     
    应用:更新test1 hello1
     
    使用索引信息重建基树。。。
     
    回到修补基地和3路合并。。。
     
    自动合并hello1.txt
     
    冲突(添加/添加):在hello1.txt中合并冲突
     
    错误:无法合并更改。
     
    修补程序在0001 update test1 hello1失败
     
    在以下位置找到失败的修补程序副本:.git/rebase apply/patch
     
     
     
    手动解决所有冲突,将其标记为已解决
     
    “git add/rm<conflicted_files>”,然后运行“git rebase--continue”。
     
    您可以跳过这个提交:运行“git rebase--skip”。
     
    要中止并返回到“git rebase”之前的状态,请运行“git rebase--abort”。
    

    从该段提示中,可以提取出以下重点:

    1. 从dev和test分支节点看,从最后的源头开始,dev分支有两次提交,这里会一个一个的尝试合并,每一次的合并属于自动合并,如果有冲突,会提示出冲突文件,如果解决了冲突,需要先使用 git add 命令告诉git以解决了冲突,然后使用命令 git rebase--continue 告诉git接着刚才的操作继续合并。
    2. 当然,也可以使用命令 git rebase--skip 忽略当前分支的修改,在本例中即直接使用dev分支的代码,以达到解决冲突的目的。
    3. 当然,如果我们在合并过程中,突然不想合并了,可以使用命令git rebase--abort 来取消合并,回到未合并之前的状态。

    下面,我们就来解决冲突,以及继续合并,看看效果。

    [root@huangzb git5]# cat hello1.txt
    <<<<<<< HEAD
    hello dev1
    =======
    hello test1
    >>>>>>> update test1 hello1
    [root@huangzb git5]# echo 'hello test1' > hello1.txt
    [root@huangzb git5]# git add .
    [root@huangzb git5]# git rebase --continue
    Applying: update test1 hello1
    Applying: update test2 hello2
    Using index info to reconstruct a base tree...
    Falling back to patching base and 3-way merge...
    Auto-merging hello2.txt
    CONFLICT (add/add): Merge conflict in hello2.txt
    error: Failed to merge in the changes.
    Patch failed at 0002 update test2 hello2
    The copy of the patch that failed is found in: .git/rebase-apply/patch
     
    Resolve all conflicts manually, mark them as resolved with
    "git add/rm <conflicted_files>", then run "git rebase --continue".
    You can instead skip this commit: run "git rebase --skip".
    To abort and get back to the state before "git rebase", run "git rebase --abort".
     
    [root@huangzb git5]# cat hello2.txt
    <<<<<<< HEAD
    hello dev2
    =======
    hello test2
    >>>>>>> update test2 hello2
    [root@huangzb git5]#
    [root@huangzb git5]# git rebase --skip
    

    再上图中,我分别的以两种方式来解决冲突,

    1. 手动解决
    2. 使用 --skip 放弃当前分支的修改。

    至此,合并完成,我们来看看最终的效果。

    [root@huangzb git5]# git log --graph
    * commit 9561e7957b3c3f051e1f530beca43cf25d82932a (HEAD -> test)
    | Author: lonely <lonely@lonely.com>
    | Date:   Fri Apr 17 21:21:05 2020 +0800
    |
    |     update test1 hello1
    |
    * commit 0acb17ce12df3d563b4d48f8a23b325fc0046fae (dev)
    | Author: lonely <lonely@lonely.com>
    | Date:   Fri Apr 17 21:19:56 2020 +0800
    |
    |     update dev2 hello2
    |
    * commit 2b8d24d7f9741ac8cc6cc3638ac2ab8e62cceb8f
    | Author: lonely <lonely@lonely.com>
    | Date:   Fri Apr 17 21:19:31 2020 +0800
    |
    |     update dev hello1
    |
    * commit ffa64b26e3b9737164d9a9a64bb2e387abb020b5
      Author: lonely <lonely@lonely.com>
      Date:   Fri Apr 17 21:16:19 2020 +0800
     
          init
    [root@huangzb git5]#
     
    

    从上图中,可以看出,最终的节点曲线就是一条直线,dev和test分支同属一条历史现。

  • 相关阅读:
    nginx rewrite 伪静态重写学习笔记
    正则表达式相关知识
    rpm的含义
    find命令的使用
    chmod的运用方式
    [GO]数组的比较和赋值
    [GO]二维数组的介绍
    [GO]变量内存和变量地址
    [GO]给导入包起别名
    阿里云负载均衡SLB 七层https协议 nginx 获取真实IP
  • 原文地址:https://www.cnblogs.com/duguxiaobiao/p/12722675.html
Copyright © 2020-2023  润新知