• Git进阶之代码回滚、合并代码、从A分支选择N次提交,合并到B分支【revert、merge、rebase、cherry-pick】



    在很长一段时间里,我对Git的操作只限于:提交代码,拉取代码,合并代码。

    虽然上面这些操作在日常工作中也足够了,但不会点高级知识不利于装X,今天我们来学习几个高级点的操作。


    一、前提


    在正式操作之前,我们先来共知几个命令和概念。


    SHA标识


    每一次提交Git都会生成一个唯一SHA标识(简单来说就是为这次提交生成一个唯一字符串),代码合并、回滚、检出都和这个标识相关。

    注:SHA标识是指Git中的SHA-1哈希标识符,它是一个40个字符的字符串,用于唯一标识Git中的每个提交、对象和分支。SHA-1是一个加密哈希函数,它接受输入(例如文件内容或提交信息)并生成一个唯一的40字符长的哈希值。


    git log


    Git 的每次提交都会携带很多信息,提交者、提交时间、唯一SHA标识等,想要查看这些信息,可以使用 git log 命令。


    git log

    完整的查看 log信息,展示效果如下:

    在这里插入图片描述


    git log --oneline

    精简提交信息,以一行的方式展示
    在这里插入图片描述

    git log --graph --oneline

    以时间线的方式查看精简的日志信息

    在这里插入图片描述


    二、回滚代码


    代码回滚,提交了错误的代码、代码错合并到非目标分支

    1. commit 回滚
    2. merge 回滚

    回滚


    使用 git log --graph --oneline 查看日志线,并找到我们要撤回提交的hash

    在这里插入图片描述

    1、找到我们要回滚commit的 hash
    git log --graph --oneline
    
    2、执行回滚命令   回滚之后可能是有冲突的,是需要手动解决冲突
    git revert 1b17801
    git push
    
    
    3、回滚 mergn
    git revert f259bf5
    git push
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    冲突


    如果回滚的时候有冲突,会这样提示

    在这里插入图片描述


    方式一

    可以选择放弃这次的回滚 git revert --abort


    方式二

    -- 1、手动解决冲突
    
    -- 2、提交修改
    git add .
    
    -- 3、继续revert, 会弹出一个文件,可以修改commit的描述,也可以直接关闭
    git revert --continue
    
    -- 4、push代码
    git push
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    三、合并代码


    合并代码就是把branchA的代码移植到branchB,有两个命令可以来完成此操作:merge、rebase。

    假如branchA是我们的开发分支,branchB是正式分支,在branchA上面我们提交了三次。现在我们来看看使用 merge 和 rebase 合并会有什么不同。


    Merge

    merge会把branchA所有的提交打包成一个最终状态,去和branchB的最终状态来一次合并。如果有冲突,我们只需要解决一次冲突就好了。

    # branchA 当前log
    A---B---C (branchA)
    
    # branchB 当前log
    D---E---F---G (branchB)
    
    
    # 在branchB 上执行 git merge branchA  
    
          A---B---C (branchA)
         /         \
    D---E---F---G---H (branchB, merge commit)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    其实就是把 branchA 当前的状态当作一次提交合并到branchB上去,所以会形成一次新的提交 H。对branchA没什么改变,对branchB 多了一次提交。(Merge remote-tracking branch ‘origin/branchA’ into branchB)


    Rebase

    rebase 会把branchA 上的每一次提交,都依次合并到 branchB 上去。 如果在branchA上的三次提交都和branchB有冲突,那你就要解决三次冲突。(因为它是依次提交的)

    # branchA 当前log
    A---B---C (branchA)
    
    # branchB 当前log
    D---E---F---G (branchB)
    
    
    # 在branchB 上执行 git rebase branchA  
    
                 A--B--C (branchA, rebased)
                /
    D---E---F---G (branchB)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    从结果来看相对于 merge, rebase有两个特殊点(代码没有冲突的情况下)

    1. 它不会生成新的 SHA标识。
    2. 目标分支成了一条直线,且更长了。(具体看branchA提交的次数)

    结论

    合并代码的时候使用 merge,可以更好的看到提交的变更,并保留每个分支的独立性和历史记录,只需要解决一次冲突,所以在正常情况下,更推荐使用 merge 来合并代码。

    当然如果你是把别的分支 rebase到自己的分支,那没什么关系,最起码不会影响到别人。


    Rebase 合并 commit


    rebase 除了上面的合并代码,它还有一个很大的用处就是合并commit,开发的过程中我们可能提交了很多乱七八糟的commit,但是为了更美观,我们可以把多个commit合并成一个新的commit。

    合并commit有两个方式

    1. 以头为标准,往下合并N个commit git rebase -i HEAD~N
    2. 以某个节点向上做commit合并 git rebase xxx xxx 就是commit的hash值

    假设我们有三次提交,现在我们要把 two 和 three 合并成一个新的提交 two and three

    在这里插入图片描述


    git rebase -i 49412a4

    执行命令后,会弹出一个文本窗口,让我们来确定要对这次rebase的操作,可以对每个commit进行很多。

    在这里插入图片描述

    pick 687575f three commit 改为 squash 687575f three commit 然后保存退出。

    保存后,又会弹出一个窗口,告知我们修改 commit的提交信息

    修改前

    # This is a combination of 2 commits.
    # This is the 1st commit message:
    
    two commit
    
    # This is the commit message #2:
    
    three commit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    修改后

    # This is a combination of 2 commits.
    # This is the 1st commit message:
    
    two three commit
    
    # This is the commit message #2:
    
    three commit
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    保存后就成功

    在这里插入图片描述


    再次查看日志

    在这里插入图片描述


    rebase修改commit的操作有很多,上面我们用了一个squash,下面是全部的命令,可以根据需要选择

    命令解释简写
    pick使用提交,即应用该提交的更改。p
    reword使用提交,但可以编辑提交消息。r
    edit使用提交,但停下来以进行修改。 e
    squash使用提交,将其融入到前一个提交中。s
    exec使用shell运行命令(行中的其余部分)。x
    break在此处停止(稍后使用 git rebase --continue 继续进行rebase)。 b
    drop删除提交。d
    label为当前HEAD标记一个名称。l
    reset将HEAD重置为一个标签。t
    merge将标签合并到HEAD上,并且可以选择编辑合并提交的消息。m
    fixup类似于"squash",但仅保留前一个提交的日志消息,除非使用了-C,这种情况下仅保留当前提交的消息;-c-C 相同,但会打开编辑器。f

    四、从A分支选择N次提交,合并到B分支


    如标题所示,目的是从A分支拣取某几次提交到B分支,可使用命令 git cherry-pick

    假设在A分支上提交了三次,三次的hash分别是 A1、A2、A3, 现在我们要把 A2、A3 提交合并到B分支上,需要执行的命令如下:

    -- 1、切换到B分支
    git checkout B
    
    -- 2、把A2、A3 提交合并过来
    git cherry-pick A2 A3
    
    -- 3、提交代码
    git push
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    正常流程就是上面这样,但合并代码总面临着冲突,如果冲突了就会显示下面的异常

    在这里插入图片描述


    冲突了的解决办法有两个


    方式一

    取消这次的操作 git cherry-pick --abort


    方式二

    解决冲突

    -- 1、先手动解决冲突
    
    -- 2、添加修改
    git add .
    
    -- 3、在解决冲突后继续执行git cherry-pick命令 、 会弹出一个文件,可以修改commit的描述,也可以直接关闭
    git cherry-pick --continue
    
    -- 4、push代码
    git push
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

  • 相关阅读:
    【C语言趣味教程】(7) 存储类:auto 关键字 | register 关键字 | 存储期 | 自动存储期 | 动态存储期 | 线程存储期 | 动态分配存储期 | 静态变量
    Linux系统编程——总结初识Linux(常用命令、特点、常见操作系统)
    导致MySQL索引失效的场景(随时补充)
    linux 设备树of函数学习笔记
    Flutter开发程序员兼职副业平台推荐
    TypeError: RedLock is not a constructor.
    【WebRTC---源码篇】(二:二)视频源VideoSourceBase
    微擎模块 啦啦外卖跑腿小程序最新版14.3 带最新跑腿前端+教学视频 完整包
    面向计算思维培养的PBL教学模式设计以模式识别课程为例
    大数据ClickHouse进阶(三):TTL深入了解
  • 原文地址:https://blog.csdn.net/Tomwildboar/article/details/130904877