git变基

作者: 学习编程王同学 | 来源:发表于2018-01-16 15:58 被阅读66次

    我们已经使用过git的合并(merge)功能,与之功能类似的是rebase(变基)。

    开始前请记住:不要对在你的仓库外有副本的分支进行变基。

    变基的实质是丢弃一些现有的提交,并且新建一些内容一样但实际上不同的提交。所以如果你的分支上的内容已经被共享,进行变基之后就会有一部分现有提交被丢弃,这会给其他用户带来麻烦与困惑。

    合并是将两个分支的最新快照以及共同祖先进行三方合并,并且生成一个新的快照。比如下图是将C7、C6和C4进行三方合并。

    合并是三方合并

    还有另外一种方法,就是变基。变基将提取C5和C6中的补丁和修改,并且将其在C7上重新作用一次,然后生成一个新的提交。

    变基会生成内容一样但实际不同的提交

    如上图所示,在testing分支进行变基操作到master后,git会进行如下操作:

    • 找到testing分支和master分支的共同祖先,即C4。
    • 收集共同祖先C4到目前提交C6的所有修改和补丁,放到临时文件中。
    • 将目前的分支testing指向目标基底master
    • testing上依次应用临时文件中所有的修改和补丁。本例中为将C5和C6的修改和补丁依次应用。
    • 生成一个新的提交,即C8。

    三方合并和变基生成的新提交C8内容是一致的,不同的是提交历史:三方合并能够清楚地看到合并的历史,而变基只有一条串联的历史。

    如果你要向他人维护的项目贡献代码,就可以将自己的修改都变基到master上,推送之后,维护者只需要进行快进操作。

    现在让我们实践一下。

    我们创建一条分支testing,并且在该分支上进行两次提交。

    然后回到master分支,进行一次提交。

    再次切换到testing分支。

    提交历史大致如下:

    * c36bdf6 (master) i see you there
    | * c5a1cc4 (HEAD -> testing) i see you here
    | * 86a451c water water everywhere
    |/  
    * af05578 (origin/master) We all love git.
    

    如果现在从testing变基到master,那么86a451cc5a1cc4中所做的修改会依次重演到master。如果遇到冲突,那么会依次需要人工解决冲突。为了避免多次修改冲突,我们将86a451cc5a1cc4合并为一次提交:

    $ git reset --soft af05578
    $ git commit -m "i see water here"
    [testing cf6dc96] i see water here
     1 file changed, 4 insertions(+)
    $ git log --oneline --decorate --graph --all
    * cf6dc96 (HEAD -> testing) i see water here
    | * c36bdf6 (master) i see you there
    |/  
    * af05578 (origin/master) We all love git.
    

    现在执行变基到master的操作:

    $ git rebase master
    First, rewinding head to replay your work on top of it...
    Applying: i see water here
    Using index info to reconstruct a base tree...
    M   README.md
    Falling back to patching base and 3-way merge...
    Auto-merging README.md
    CONFLICT (content): Merge conflict in README.md
    error: Failed to merge in the changes.
    Patch failed at 0001 i see water here
    The copy of the patch that failed is found in: .git/rebase-apply/patch
    
    When you have resolved this problem, run "git rebase --continue".
    If you prefer to skip this patch, run "git rebase --skip" instead.
    To check out the original branch and stop rebasing, run "git rebase --abort".
    

    在执行变基操作时,git提示我们README.md有冲突,解决冲突后使用git rebase --continue继续执行变基操作。现在请解决冲突,将文件添加到暂存区后表示该文件冲突解决完成。解决后继续执行变基操作:

    $ git rebase --continue 
    Applying: i see water here
    

    git告诉我们更改已经被应用到master分支。提交历史如下:

    * c148ffd (HEAD -> testing) i see water here
    * c36bdf6 (master) i see you there
    * af05578 (origin/master) We all love git.
    

    可以看到,git帮我们生成了一个新的提交,并且testing指向该提交。提价历史变成了一条串联的线。

    最后,将master快进到testing即可:

    $ git checkout master 
    Switched to branch 'master'
    Your branch is ahead of 'origin/master' by 1 commit.
      (use "git push" to publish your local commits)
    $ git merge testing 
    Updating c36bdf6..c148ffd
    Fast-forward
     README.md | 4 ++++
     1 file changed, 4 insertions(+)
    

    相关文章

      网友评论

          本文标题:git变基

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