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


分支在实际中的作用

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


分支的原理描述

在版本回退里,每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。开始的时候,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,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
file changed, insertions(+), 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 | ++-
file changed, insertions(+), 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' 共 个提交。
(使用 "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
file changed, insertion(+), deletion(-)
ubuntu@myUbuntu:~/joe/learngit$

git checkout master

    //切换回主分支,修改同一个文件,并提交
切换到分支 'master'
您的分支领先 'origin/master' 共 个提交。
(使用 "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
file changed, insertion(+), deletion(-)
ubuntu@myUbuntu:~/joe/learngit$

git merge bran

    //此时合并分支的时候,出现了冲突(2个分支都对文件做了修改,那么合并的时候应该合并哪一个呢?此时需要手动解决以后,才可以合并。)
自动合并 abc.c
冲突(内容):合并冲突于 abc.c
自动合并失败,修正冲突然后提交修正的结果。
ubuntu@myUbuntu:~/joe/learngit$ git status
位于分支 master
您的分支领先 'origin/master' 共 个提交。
(使用 "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
file changed, insertion(+), deletion(-)
ubuntu@myUbuntu:~/joe/learngit$ git checkout master
切换到分支 'master'
您的分支领先 'origin/master' 共 个提交。
(使用 "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 | +-
file changed, insertion(+), deletion(-)
ubuntu@myUbuntu:~/joe/learngit$

git log --graph --pretty=oneline --abbrev-

commit
* 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
file changed, insertion(+), deletion(-)
ubuntu@myUbuntu:~/joe/learngit$ git checkout master
切换到分支 'master'
您的分支领先 'origin/master' 共 个提交。
(使用 "git push" 来发布您的本地提交)
ubuntu@myUbuntu:~/joe/learngit$ git merge dev
更新 ..b961f85
Fast-forward
abc.c | +-
file changed, insertion(+), deletion(-)
ubuntu@myUbuntu:~/joe/learngit$

git log --graph --pretty=oneline --abbrev-

commit

*

 b961f85 dev
* 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分支上合并就可以了。

Git学习笔记(5)——分支管理的更多相关文章

  1. Git学习笔记五--分支管理

    为什么要引入分支? 分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了.如果等代码全部 ...

  2. git学习笔记08-分支管理策略-实际上我们应该怎么应用分支

    Git用Fast forward模式(快进模式),但这种模式下,删除分支后,会丢掉分支信息. 如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支 ...

  3. git 学习笔记 --Bug分支

    软件开发中,bug就像家常便饭一样.有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除. 当你接到一个修复一 ...

  4. git学习4:分支管理

    每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支.截止到目前,只有一条时间线,这个分支叫主分支,即master分支,HEAD指向master,master指向提交,所以,HEAD指向的就 ...

  5. 【Git】笔记4 分支管理1

    1.创建与合并分支 一开始的时候,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点: 每次提交,master分支都会向 ...

  6. git学习笔记09-bug分支-自己的分支改到一半了-要去改bug怎么办?

    当你接到一个修复一个代号101的bug的任务时,很自然地,你想创建一个分支issue-101来修复它,但是,等等,当前正在dev上进行的工作还没有提交: 并不是你不想提交,而是工作只进行到一半,还没法 ...

  7. 【Git】笔记5 分支管理2

    来源:廖雪峰 通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息. 如果要强制禁用Fast forward模式,Git就会在merge时生成一 ...

  8. git学习笔记12-标签管理-版本

    发布一个版本时,我们通常先在版本库中打一个标签(tag),这样,就唯一确定了打标签时刻的版本.将来无论什么时候,取某个标签的版本,就是把那个打标签的时刻的历史版本取出来.所以,标签也是版本库的一个快照 ...

  9. git 学习笔记--Feature分支

    软件开发中,总有无穷无尽的新的功能要不断添加进来. 添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合 ...

  10. GIT学习笔记(3):分支管理

    GIT学习笔记(3):分支管理 何谓分支 GIT是如何存储数据的 GIT不是存储文件差异或者变化量,而是一系列文件的快照.在Git提交时,会保存一个提交(commit)对象,该对象包含一个指向暂存内容 ...

随机推荐

  1. 读Windows核心编程-5-作业

    作业(Job) 有时候需要把一些进程集中管理,如终止一个进程以及它产生的子进程,但由于Windows并没有维护进程间父子关系,所以除非进程本身以某种方式记录这些信息,否则很难做到管理这种父子进程树.而 ...

  2. C# 如何给sql数据库的日期字段插入空值

    在C#中声明日期变量时用SqlDateTime类型,引用:using System.Data.SqlTypes; 例子:user.AbortDate = SqlDateTime.Null;

  3. ASP.NET页面之间传递值的几种方式

    目录 QueryString Session Cookie Application 一.QueryString QueryString是一种非常简单的传值方式,他可以将传送的值显示在浏览器的地址栏中. ...

  4. The Singleton pattern

    作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个类称为单例类. 单例模式的结构 单例模式的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一 ...

  5. javascript中onload事件如何绑定及执行顺序

    onload事件,顾名思义就是为了js程序能够在网页加载成功过后进行执行.对于放在head里面的js来说,非常必要. 如何给网页绑定onload,主要有三种方式: window.onload=func ...

  6. Eclipse创建Android模拟器创建选项解释

  7. 分析sql语句所有表名及其别名的正则表达式

    最近为了 写一个分布式的数据组件构想了很多的方案,最近一个简单易行的方案终于在脑袋里成型.昨晚想到凌晨1点多,发现方案虽简单,但所有的数据库工具就不能使用了 .除非自己写一下查询分析器来执行程序员自己 ...

  8. [UCSD白板题] Take as Much Gold as Possible

    Problem Introduction This problem is about implementing an algorithm for the knapsack without repeti ...

  9. H3C IRF mad检测

    这里 irf 两个交换机 S4 S5 S4 S4的MEmber id 为1 IRF member 1 renumber 1 S4的 irf 优先为10 irf member priority 10 链 ...

  10. php 正则

    1.中括号 [0-9]匹配0-9 [a-z]匹配a-z小写字母 [A-Z]匹配A-Z大写字母 [a-zA-Z]匹配所有大小写字母 可以使用ascii来制定更多 2.量词 p+匹配至少一个含p的字符串 ...