美文网首页
Git 直线式分支结构

Git 直线式分支结构

作者: SapientiaWind | 来源:发表于2018-12-28 17:43 被阅读7次

    日常开发中提交代码

    首先说一下我们原来的工作流程, 我们有一个默认master分支, 一个dev分支, 日常开发中, 我们还会创建一个关于本次功能对应的本地分支(如 invoice分支), 本次修改全部放在invoice分支上, 然后当开发完成测试通过后, 通过merge合并分支到dev, 最后提交版本验证通过后再提交到master分支上.

    1545989656680.png

    我相信大多数公司的开发流程都是这样的. 这样并没有什么问题, 但是久而久之, 你就会发现分支结构复杂,乱. 还有在dev/master上, 针对同一个invoice功能, leader并不想知道我们开发这个功能进行了多少次bug修改, 新功能提交, 也就是说在dev/master上只存在一个invoicecommit就可以了. 那这里就涉及到另一种提交代码的技巧.

    rebase命令

    其实,还有一种方法:你可以提取在 invoice 中引入的补丁和修改,然后在 dev 的基础上应用一次。 在 Git 中,这种操作就叫做 变基。 你可以使用 rebase 命令将提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一样。

    它的原理是首先找到这两个分支(即当前分支 invoice、变基操作的目标基底分支 dev)的最近共同祖先 A1(SHA-1值),然后对比当前分支相对于该祖先的历次提交,提取相应的修改并存为临时文件,然后将当前分支指向目标基底A3(SHA-1值), 最后以此将之前另存为临时文件的修改依序应用.

    理解完工作原理就直接来看具体在提交的时候如何操作吧.

    Git rebase 使用方法

    1. 合并多次commit

    • 注: 保证仅仅对自己私有的提交单进行rebase操作,对于已经合并进远程仓库的历史提交单,不要使用rebase操作合并commit单。

    例如 我有三次commit:

    commit 7df9296a1b80c8eaa2dc3a21122ae3d03ee0b210
    Author: bianzhifeng <bianzhifeng@czb365.com>
    Date:   Fri Dec 28 14:43:11 2018 +0800
    
        dev4
    
    commit b3880ad738d8e4aaadd321505cebb515e08b33b0
    Author: bianzhifeng <bianzhifeng@czb365.com>
    
        dev3
    
    commit bc52c40ef867ebc26e9824ed8363ac3c9a2a3a81
    Author: bianzhifeng <bianzhifeng@czb365.com>
    Date:   Fri Dec 28 13:55:39 2018 +0800
    
        dev2   
    
    commit cb4a5ac9bde58fe36d77dcbe8106c1a72f594aa5 (origin/master, master)
    Author: bianzhifeng <bianzhifeng@czb365.com>
    Date:   Fri Dec 28 14:25:40 2018 +0800
    
        dev1
    

    现在我想把 dev4 dev3 dev2 合并成一个, 那么输入git rebase -i cb4a..., 也就是提交的SHA-1值, 但是要注意是要合并的前一条的SHA-1值, 所以我这里填写的SHA-1值为dev1SHA-1值.

    之后便会出现下方的vi界面:

    pick 7df9296 dev4
    pick b3880ad dev3
    pick bc52c40 dev2
    
    # Rebase cb4a5ac..bc52c40 onto cb4a5ac (3 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
    # 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.
    #
    # These lines can be re-ordered; they are executed from top to bottom.
    #
    # If you remove a line here THAT COMMIT WILL BE LOST.
    "~/Desktop/gitrebasetest/.git/rebase-merge/git-rebase-todo" 29L, 1117C
    

    这里最重要的就是squashpick, 默认三个提交都是pick. pick代表提交记录, squash代表合并到前一个记录, 所以如果想把dev3 dev2合并到dev4的记录中, 那我们把dev3 dev2前对应的pick/p修改为squash/s, 然后按ESC :wq退出.

    • 注: 这里s代表向上合并, 如果只是想把dev2合并到dev4, 那么调整把dev2/dev3位置互换, 而且只修改dev2对应的修改为s, dev3不修改使用p即可

    然后便会进入另一个vi界面:

    # This is a combination of 3 commits.
    # This is the 1st commit message:
    
    dev4
    
    # This is the commit message #2:
    
    dev3
    
    # This is the commit message #3:
    
    dev2
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    #
    # Date:      Fri Dec 28 14:43:11 2018 +0800
    #
    # interactive rebase in progress; onto b3880ad
    # Last commands done (3 commands done):
    "~/Desktop/gitrebasetest/.git/COMMIT_EDITMSG" 36L, 703C
    

    在这里, 可以修改本次提交的提示信息, 然后保存退出就可完成合并.

    2. 变基:

    例如把invoice变基到dev, 那么切换到dev分支, 执行git rebase invoice, 就完成了变基.
    如果遇到冲突, 那么解决冲突后 git add . ,然后 git rebase --continue就可以了.

    做完如上两部, 再次打开你的dev分支, 你会看到一个直线的并且针对一个版本只有一个commit的分支.

    相关文章

      网友评论

          本文标题:Git 直线式分支结构

          本文链接:https://www.haomeiwen.com/subject/dydelqtx.html