git分支管理

Git分支功能

Git的主要分为主分支master,开发分支develop(dev),辅助分支dev-*,release-*,hotfix-*

  • 主分支(master)
    作用:开发者可以从主分支上发布新版本,也可以获得线上代码
  • 开发分支(develop)
    作用:开发者将自己的分支首先合并到开发分枝上,也可以从开发分枝上获得最新开发的代码
  • 辅助分支(dev-*,release-*,hotfix-*)
    作用:
Feature branches:“管理功能开发”的分支,命名以`dev-`开头,用于开发版本新功能,完成后合并至develop分支
Release branches:“帮助构建可发布代码”的分支,命名以`release-`开头,从develop上面拉取,用于与发布新版本和修复预发布版本bug,完成后分别合并至master和develop分支
Hotfix branches:“便捷修复发布版本Bug分支”,命名以`hotfix-`开头,从master分支上拉取,用于快速修复线上Bug,完成后分别合并至master和develop分支

分支产生的原因:
1.需要开发这对一个项目进行并行开发
2.修复旧版本中的bug


4.jpg

就像上面的AB,就创建了各自的分支,别人看不到,还可以在原来的分支上面继续工作,等到最后可以合并在一起,即安全,又高效。


5.jpg

创建合并分支

  • 每次提交,Git都会把它们串成一条时间线,这个时间线就是一个分支,每个都会有一个master分支,叫做主分支,默认HEAD开始指向主分支,Git用master指向最新的提交

    6.jpg

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

    7.jpg

  • Git创建一个分支很快,新增一个dev指针,在改变HEAD指向即可,工作区的文件没有变化
    但是从切换分支开始,对工作区的修改和提交就针对dev分支了,每次新的提交,dev就向前移动一次,master指针不移动

    8.jpg

  • dev分支的工作完成之后想要和master分支合并,只需要把master指针,指向当前dev的提交即可,这样就完成了合并

    9.jpg

  • 合并分之后,也可以删除dev分支。删除dev分支,就是删除dev指针

    10.jpg

命令
创建分支:git branch <name>
切换分支:git checkout <name>
查看分支:git branch
创建+切换分支:git checkout -b <name>
合并某分支到当前分支:git merge <name>
删除分支:git checkout -d <name>

eg:
1.创建dev分支,并切换到dev分支

》 git branch dev 创建分支
> git checkout dev 切换到dev分支
或者
> git checkout -b dev 创建并合并分支

2.git branch列出所有分支,Git版本库中总是存在着唯一一个活动分支,用星号(*)标记的就是当前活跃的分支

> git branch
 * dev
   master

3.在dev分支下修改文件file1并提交修改,切换回master分支,你会发现file1文件并没有做任何修改

> git branch 查看目前位于哪个分支(此时为master分支)
  dev
* master
> cat file1 查看master分支下file1文件内容
hello world!
> git checkout dev 切换到dev分支
Switched to branch 'dev'
> echo "I love china" >> file1 修改文件file1(这是追加了一句)
> git add file1
> git commit -m "I love china" 提交修改
[dev b8a482b] I love china
 1 file changed, 1 insertion(+)
> git checkout master 再次切换到master分支
Switched to branch 'master'
> cat file1 查看file1内容,你会发现内容没有改变
hello world!

4.dev分支工作结果可以合并到master分支上了

  • 切换分支错误
    切换分支可能会失败,这是因为我们当前分支工作区、暂存区存在一些修改,并且没有确认提交
> git checkout master
error: Your local changes to the following files would be overwritten by checkout:
        file1
Please, commit your changes or stash them before you can switch branches.
Aborting

解决方法:

1.提交修改后切换
> git commit --all
> git checkout master
2.放弃这部分修改并切换
> git checkout --force master
--force强制切换
  • git merge <branchname>合并分支
>  git merge dev
Updating 9c4b701..614031d
Fast-forward
 hello.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 hello.txt

上面信息中有一个Fast-forward,意思是此次合并是“快进模式”。就是把master指针指向dev分值的当前提交,所以合并非常快,Git默认是这种提交模式
5.git branch -d <branchname>删除分支

git branch -d dev
Deleted branch dev (was ed7a0b9).
> git branch 只剩下master分支
* master

分支冲突:

编辑冲突:
我们可能会多个人在不同分支上对同一个文件的同一处做不同修改,这时Git不知道采用哪一个,就会出错误
树木冲突:
一个分支修改了内容, 另个一分支删除了文件, 在试图合并时就会出现树冲突。假设子分支(如 dev)是要合并到主分支 master 的, 处理的方法有:
(1)放弃 dev 的修改:强制删除 dev 分支, 然后提交即可。
(2)放弃 master 的修改----分下面两种情况:

    master 修改了内容, dev 删除了文件:
            在 master 分支中删除该文件, 然后提交;
    master 删除了文件, dev 修改了内容:                                         在 master 分支中添加被修改的文件, 然后提交。

eg:编辑冲突
创建新的分支branch2,修改文件file1,

> git checkout -b branch2
> echo "my name is ymd" >> file1

在分支branch2上提交修改

> git add file1
> git commit -m "branch2 commit"

切换到master分支,之后修改文件file1并提交

> git checkout master 
> echo "my name is xiaoyin" >> file1
> git add file1
> git commit -m "master file1"

这时,master分支和branch2分支都有一次提交
合并分支

> git merge branch2
Auto-merging file1
CONFLICT (content): Merge conflict in file1
Automatic merge failed; fix conflicts and then commit the result.

现在,Git不能执行“快速合并”,只能试着把各自的修改合并起来,但是这种合并往往会产生冲突

  • 解决编辑冲突:
    为了方便查看冲突我们可以将git配置成三路模式
> git config merge.conflictstyle diff3

1.启动合并工具

> git mergetool 

或者手动合并

a:编辑受影响的文件
b:采用--ours或者--theirs选项,选择只选用自己或者别人那个版本的文件
> git checkout --theirs <name>

2.提交修改

> git add .
> git commit -m "<message>"

当然我们也可以取消合并

> git reset --merge
  • --no-ff合并时禁用Fast forward模式
    通常git在合并分支采用的是Fast forward模式,就是合并之后删除分支,会丢掉分支信息,如果强制禁止了Fast forward模式,Git就会在合并时生成一个新的commit,使得我们能在分支历史上看出分支信息。
# git merge --no-ff -m "no-ff" dev

在实际应用中,master分支应该是非常那个稳定的,只用来发布新版本,平时不能在上面工作,需要另选一个分支,比如dev,就是大家合并版本到dev分支上,只有新版本发布时,再把最新版本从dev合并到master分支上
开发一个新功能最好创建一个新分支

  • 编辑冲突
# git merge brnach2
fatal: brnach2 - not something we can merge
  • git checkout -D <branchname> 强制删除一个从未合并过的分支

变基Rebase

  • 避免钻石链
    11.jpg

如上图所示,一个项目会多个开发者多次提交,这样就存在许多杂乱的分支,Git用rebase命令帮我们理顺这些历史记录,篡改历史记录

12.jpg

所有rebase操作对象都是commit,但是未push到公共仓库,变基后在没有gc时,还可以通过原来的散列值访问原来的分支

# git rebase master 
  • 移值分支
    移值不属于原分支的版本
    前期:
    13.jpg

移植后:git rebase master --onto relase1


14.jpg
# git checkout dev切换到待移动分支
# git log master..dev

或者直接在原分支上查看

# git checkout master
# git log HEAD..dev显示在dev上而不在当前分支的提交
# git rebase master --onto relase1
rebase命令的第一个参数所指定的是原分支(这里是master分支),然后,Git会确认dev上面所有不属于原分支的提交(这里是E和F),最后通过--onto选项将这些提交拷贝到指定位置上(这里是release1分支)

一次完整的移植合并分支:
1.原本的分支:

15.jpg

2.现在我需要将client分支上做的改变而非server上面的改变(A8和A9),直接在master分支中重演一遍

# git rebase --onto master server client
取出client分支,找出client分支和server分支共同祖先之后的变化,然后把他们在master上面重放一遍(server和client这两个分支修改的应该是不同的文件)
16.jpg

3.快进master分支:

# git checkout master
# git merge client
17.jpg

4.现在把server分支的变化也包含进来。我们可以直接把server分支变基到master分支
git rebase <主分支> <特性分支>
先取出特性分支,比如server,再到主分支master上重演

# git rebase master server

所以,server分支的进度应用到master基础上,如下图所示:


18.jpg

5.快进主干分支:

# git checkout master
# git merge server

6.删掉client和server分支

# git branch -d clien
# git branch -d server

7.最后的提交历史


19.jpg
  • rebase冲突解决
    rebase命令和merge命令一样会在相关修改不匹配的时候发生冲突
    1.手动解决或者通过合并工具解决,将他们从新添加至暂存区
    然后执行rebase命令,加上--continue选项,从该点继续之前的进程
# git add file1
# git add file2
# git rebase --continue

2.选项--abort选项取消这次rebase命令
3.选项--skip选项跳过引起这次冲突的提交

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 四、 分支开发工作流 现在你已经学会新建和合并分支,那么你可以或者应该用它来做些什么呢? 在本节,我们会介绍一些常...
    常大鹏阅读 2,078评论 3 24
  • Git 分支 Git命令大全 对于任何一个文件,在Git内都只有三种状态:已提交(committed),已修改(m...
    carrey001阅读 805评论 0 4
  • 纯手工打造每一篇开源资讯与技术干货,数十万程序员和Linuxer已经关注 1 Git 分支 - 分支简介 有人把 ...
    尘世不扰阅读 693评论 0 3
  • 1. 创建与合并分支 在Git里每次提交会被串成一条时间线,这条时间线就是一个分支.而HEAD是指向当前分支,当前...
    程序员七哥阅读 537评论 0 5
  • 纤云弄巧,飞星传恨,银汉迢迢暗度。金风玉露一相逢,便胜却人间无数。 柔情似水,佳期如梦,忍顾鹊桥归路。两情若是久长...
    竹韵相印阅读 387评论 0 2