zoukankan      html  css  js  c++  java
  • Git学习笔记(5)——分支管理

    本文主要记录了分支的原理、分支的创建,删除,合并、以及分支的使用策略。


    分支在实际中的作用

    假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。


    分支的原理描述

    在版本回退里,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。开始的时候,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向mastermaster才是指向提交的,所以,HEAD指向的就是当前分支。

    一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点.

    每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长:

    当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上.

    这样一个dev的分支就建成了,不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变。

    我们在dev上的工作完成了,就可以把dev合并到master上。最简单的方法,就是直接把master指向dev的当前提交,就完成了合并。合并完分支后,就可以删除无用的dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支。


    分支的创建与删除

    ubuntu@myUbuntu:~/joe/learngit$ ls
    abc.c  readme.txt
    ubuntu@myUbuntu:~/joe/learngit$ git status
    位于分支 master        //当前位于主分支
    您的分支与上游分支 'origin/master' 一致。
    无文件要提交,干净的工作区
    ubuntu@myUbuntu:~/joe/learngit$ 
    git checkout -b dev
        //创建一个分支并切换到当前分支
    切换到一个新分支 'dev'
    ubuntu@myUbuntu:~/joe/learngit$ 
    git branch
        //查看所有分支,(当前的分支前会有*号)
    * dev
      master
    ubuntu@myUbuntu:~/joe/learngit$ ls
    abc.c  readme.txt
    ubuntu@myUbuntu:~/joe/learngit$ vi readme.txt     //在dev分支下修改文件
    ubuntu@myUbuntu:~/joe/learngit$ 
    git status
        //查看状态,是在dev分支下
    位于分支 dev
    尚未暂存以备提交的变更:
      (使用 "git add <file>..." 更新要提交的内容)
      (使用 "git checkout -- <file>..." 丢弃工作区的改动)
    
        修改:     readme.txt
    
    修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
    ubuntu@myUbuntu:~/joe/learngit$ git add readme.txt 
    ubuntu@myUbuntu:~/joe/learngit$ 
    git commit -m "new dev branch"
    
    [dev 9409b92] new dev branch
     1 file changed, 2 insertions(+), 1 deletion(-)
    ubuntu@myUbuntu:~/joe/learngit$ 
    git checkout master
        //将dev分支下的工作提交以后,切换到主分支
    切换到分支 'master'
    您的分支与上游分支 'origin/master' 一致。
    ubuntu@myUbuntu:~/joe/learngit$ 
    cat readme.txt
             //主分支下查看文件发现文件内容并没有修改
    Git is a distributed version control system
    Git is free software distributed under the
    Are you ok?
    Yes,i am fine.
    What about you?
    ubuntu@myUbuntu:~/joe/learngit$ 
    git merge dev
            //dev分支和master分支合并
    更新 f10fe58..9409b92
    Fast
    -
    forward//Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。当然,也不是每次合并都能Fast-forward,就如下面的冲突
     readme.txt | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    ubuntu@myUbuntu:~/joe/learngit$ 
    cat readme.txt
             //合并以后,再次查看,文件内容已经修改
    Git is a distributed version control system
    Git is free software distributed under the
    Are you ok?
    Yes,i am fine.
    What about you
    Create a branch is so quick.
    ubuntu@myUbuntu:~/joe/learngit$ 
    git branch -d dev
        //删除分株
    已删除分支 dev(曾为 9409b92)。
    ubuntu@myUbuntu:~/joe/learngit$ git branch
    * master
    //git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:
    
    $ git branch dev    //创建分支
    $ git checkout dev    //切换分支
    Switched to branch 'dev'

    分支的冲突

    ubuntu@myUbuntu:~/joe/learngit$ git status
    位于分支 master
    您的分支领先 'origin/master'1 个提交。
      (使用 "git push" 来发布您的本地提交)
    无文件要提交,干净的工作区
    ubuntu@myUbuntu:~/joe/learngit$ 
    git checkout -b bran
        //新建bran分支,修改文件内容并提交
    切换到一个新分支 'bran'
    ubuntu@myUbuntu:~/joe/learngit$ vi abc.c 
    ubuntu@myUbuntu:~/joe/learngit$ cat abc.c 
    I am a new branch
    ubuntu@myUbuntu:~/joe/learngit$ git add abc.c 
    ubuntu@myUbuntu:~/joe/learngit$ 
    git commit -m "new bran"
    
    [bran 5aa28d8] new bran
     1 file changed, 1 insertion(+), 1 deletion(-)
    ubuntu@myUbuntu:~/joe/learngit$ 
    git checkout master
        //切换回主分支,修改同一个文件,并提交
    切换到分支 'master'
    您的分支领先 'origin/master'1 个提交。
      (使用 "git push" 来发布您的本地提交)
    ubuntu@myUbuntu:~/joe/learngit$ vi abc.c 
    ubuntu@myUbuntu:~/joe/learngit$ cat abc.c 
    I am not a branch
    ubuntu@myUbuntu:~/joe/learngit$ git add abc.c 
    ubuntu@myUbuntu:~/joe/learngit$ git 
    commit -m "not a branch"
    
    [master fe42f3e] not a branch
     1 file changed, 1 insertion(+), 1 deletion(-)
    ubuntu@myUbuntu:~/joe/learngit$ 
    git merge bran
        //此时合并分支的时候,出现了冲突(2个分支都对文件做了修改,那么合并的时候应该合并哪一个呢?此时需要手动解决以后,才可以合并。)
    自动合并 abc.c
    冲突(内容):合并冲突于 abc.c
    自动合并失败,修正冲突然后提交修正的结果。
    ubuntu@myUbuntu:~/joe/learngit$ git status
    位于分支 master
    您的分支领先 'origin/master'2 个提交。
      (使用 "git push" 来发布您的本地提交)
    您有尚未合并的路径。
      (解决冲突并运行 "git commit"未合并的路径:
      (使用 "git add <file>..." 标记解决方案)
    
        双方修改:   abc.c
    
    修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
    ubuntu@myUbuntu:~/joe/learngit$ 
    cat abc.c
         //查看文件内容
    <<<<<<< HEAD
    I am not a branch
    =======
    I am a new branch
    >>>>>>> bran
    //Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容
    ubuntu@myUbuntu:~/joe/learngit$ 
    vi abc.c
         //将其文件内容修改统一后,提交
    ubuntu@myUbuntu:~/joe/learngit$ cat abc.c 
    I am not a branch
    ubuntu@myUbuntu:~/joe/learngit$ git add abc.c 
    ubuntu@myUbuntu:~/joe/learngit$
    git commit -m "conflict ok"
    
    [master f73e798] conflict ok
    ubuntu@myUbuntu:~/joe/learngit$ 
    git log --graph --pretty=oneline --abbrev-commit
    //查看分支历史,形象的描写了冲突的位置
    *   f73e798 conflict ok
    |  
    | * 5aa28d8 new bran
    * | fe42f3e not a branch
    |/  
    * 9409b92 new dev branch
    * f10fe58 new abc
    * 0ad1dfe del ab.c
    * 7b6507e new ab.c
    * 020f927 del abc
    * 010726f del a line
    * c834e17 nothing
    * aa6b706 new abc.c
    * 82f4ed9 modify read
    * e32e92b del abc.c
    * ab22d92 test stage
    * d4e3943 understand how stage workd
    * 71038bf append GPL
    * 942f575 add distributed
    * b401faf joe's first txt
    ubuntu@myUbuntu:~/joe/learngit$ 
    git branch -
    d bran
    已删除分支 bran(曾为 5aa28d8)。

    分支管理策略

    合并分支时,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。

    如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

    ubuntu@myUbuntu:~/joe/learngit$ 
    git checkout -b dev
        //新建dev分支,修改文件并提交
    切换到一个新分支 'dev'
    ubuntu@myUbuntu:~/joe/learngit$ vi abc.c 
    ubuntu@myUbuntu:~/joe/learngit$ cat abc.c 
    I like you
    !
    
    ubuntu@myUbuntu:~/joe/learngit$ git add abc.c 
    ubuntu@myUbuntu:~/joe/learngit$ 
    git commit -m "dev branch"
    
    [dev cef4924] dev branch
     1 file changed, 1 insertion(+), 1 deletion(-)
    ubuntu@myUbuntu:~/joe/learngit$ git checkout master
    切换到分支 'master'
    您的分支领先 'origin/master'4 个提交。
      (使用 "git push" 来发布您的本地提交)
    //合并dev分支,--no-ff参数,表示禁用Fast forward,本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去
    ubuntu@myUbuntu:~/joe/learngit$ 
    git merge --no-ff -m "merge with no-ff"
     dev
    Merge made by the 'recursive' strategy.
     abc.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    ubuntu@myUbuntu:~/joe/learngit$ 
    git log --graph --pretty=oneline --abbrev-
    commit
    *   7877628 merge with no-ff
    |  
    | * cef4924 dev branch
    |/  
    *   f73e798 conflict ok
    |  
    | * 5aa28d8 new bran
    * | fe42f3e not a branch
    |/  
    * 9409b92 new dev branch
    * f10fe58 new abc

    使用fast forward的情况

    ubuntu@myUbuntu:~/joe/learngit$ 
    git checkout -
    b dev
    切换到一个新分支 'dev'
    ubuntu@myUbuntu:~/joe/learngit$ vi abc.c 
    ubuntu@myUbuntu:~/joe/learngit$ cat abc.c 
    I don
    't like you!
    ubuntu@myUbuntu:~/joe/learngit$ git add abc.c 
    ubuntu@myUbuntu:~/joe/learngit$ 
    git commit -m "dev"
    
    [dev b961f85] dev
     1 file changed, 1 insertion(+), 1 deletion(-)
    ubuntu@myUbuntu:~/joe/learngit$ git checkout master
    切换到分支 'master'
    您的分支领先 'origin/master'6 个提交。
      (使用 "git push" 来发布您的本地提交)
    ubuntu@myUbuntu:~/joe/learngit$ git merge dev
    更新 7877628..b961f85
    Fast-forward
     abc.c | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    ubuntu@myUbuntu:~/joe/learngit$ 
    git log --graph --pretty=oneline --abbrev-
    commit
    
    *
     b961f85 dev
    *   7877628 merge with no-ff
    |      //注意这2次分支的对比
    | * cef4924 dev branch
    |/  
    *   f73e798 conflict ok
    |  
    | * 5aa28d8 new bran
    * | fe42f3e not a branch
    |/  
    * 9409b92 new dev branch
    * f10fe58 new abc
    * 0ad1dfe del ab.c

    分支策略

    1. 首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
    2. 干活都在dev分支上,dev分支是不稳定的,新版本版本发布时,再把dev分支合并到master上,在master分支发布新版本;
    3. 每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

  • 相关阅读:
    LeetCode 40. 组合总和 II(Combination Sum II)
    LeetCode 129. 求根到叶子节点数字之和(Sum Root to Leaf Numbers)
    LeetCode 60. 第k个排列(Permutation Sequence)
    LeetCode 47. 全排列 II(Permutations II)
    LeetCode 46. 全排列(Permutations)
    LeetCode 93. 复原IP地址(Restore IP Addresses)
    LeetCode 98. 验证二叉搜索树(Validate Binary Search Tree)
    LeetCode 59. 螺旋矩阵 II(Spiral Matrix II)
    一重指针和二重指针
    指针的意义
  • 原文地址:https://www.cnblogs.com/zi-xing/p/4495485.html
Copyright © 2011-2022 走看看