分支管理

分支的用处:
就是你与你的同事一起完成一个项目时,你可以自己创建一个分支,这个分支你可以什么时候写代码或者提交都可以,处理完成后你可以将这个分支汇到大的分支上
个人理解,创建一个分支后,其实就是将工作区的内容复制一封到了另一个区域,比如之前存在主分支叫master,现在复制了一份内容后,存在另一个分支,叫dev,这个分支的内容和主分支一样,可以在dev分支上改动自己想做的内容,然后改动完成后,将其合并到主分支master上

一、创建与合并分支:
首先我们创建一个名字叫dev的分支,然后切换到dev分支(cd进入当前learngit文件夹内):


图片.png

git checkout命令加上-b参数表示创建并切换,相当于以下两条命令:
git branch dev
git checkout dev

然后,用git branch命令查看当前分支:


图片.png

git branch命令会列出所有分支,当前分支前面会标一个*号,目前的分支就是dev。

然后,我们就可以在dev分支上正常提交,比如对readme.txt做个修改,加上一行:
Creating a new branch is quick.
然后提交:


图片.png

现在,dev分支的工作完成,我们就可以切换回master分支:


图片.png

切换回master分支后,我们再去查看下readme.txt文件,刚才添加的内容不见了!
因为那个提交是在dev分支上,而master分支此刻的提交点并没有变

现在,我们把dev分支的工作成果合并到master分支上:


图片.png

git merge命令用于合并指定分支到当前分支。合并后,再查看readme.txt的内容,就可以看到,和dev分支的最新提交是完全一样的。

合并完成后,就可以放心地删除dev分支了:


图片.png

删除后,查看branch,就只剩下master分支了:


图片.png

因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。

小结
Git鼓励大量使用分支:

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

二、解决冲突
我认为的冲突就是:新创建分支后,对两个分支的同一个内容修改保存后,用git add 和 gitcommit提交后,当融合一个分支的时候,会出现冲突,因为两个分支的同一个内容都改了。
上一个实例:
准备新的feature1分支,继续我们的新分支开发:


图片.png

修改readme.txt最后一行,改为:
Creating a new branch is quick AND simple.
这样readme.txt的内容就变为了:


图片.png

然后在feature1分支上提交:


图片.png

然后切换到master分支:


图片.png

在master分支上把readme.txt文件的最后一行改为:
Creating a new branch is quick & simple.
这样master分支上的readme.txt文件就变成了:


图片.png

提交:


图片.png

现在,master分支和feature1分支各自都分别有新的提交,变成了这样:


图片.png

这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突,我们试试看:


图片.png

果然冲突了!Git告诉我们,readme.txt文件存在冲突,必须手动解决冲突后再提交。git status也可以告诉我们冲突的文件:
图片.png

我们可以打开readme.txt文件来看下现在是什么内容:


图片.png

Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容,我们修改如下后保存:


图片.png

再提交:


图片.png

用带参数的git log也可以看到分支的合并情况:


图片.png

最后,删除feature1分支:


图片.png

工作完成。

小结
当Git无法自动合并分支时,就必须首先解决冲突。解决冲突后,再提交,合并完成。
解决冲突就是把Git合并失败的文件手动编辑为我们希望的内容,再提交。
用git log --graph命令可以看到分支合并图。

三、分支管理策略
通常,合并分支时,如果可能,Git会用Fast forward模式,但这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,Git就会在merge时生成一个新的commit,这样,从分支历史上就可以看出分支信息。

下面我们实战一下--no-ff方式的git merge:
首先,仍然创建并切换dev分支:


图片.png

修改readme.txt文件,并提交一个新的commit:


图片.png

图片.png

以上是我们在dev分支上的操作;下面我们切换回master分支:
图片.png

准备合并dev分支,请注意--no-ff参数,表示禁用Fast forward:


图片.png

因为本次合并要创建一个新的commit,所以加上-m参数,把commit描述写进去。
合并后,我们用git log看看分支历史:
图片.png

可以看到,不使用Fast forward模式,merge后就像这样:
图片.png

分支策略
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。

小结
Git分支十分强大,在团队开发中应该充分应用。
合并分支时,加上--no-ff参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。

四、Bug分支
假如你现在正在dev分支上干活,但是接到通知在master分支上有一个bug需要处理。因为dev分支上的活还没有干完,无法提交,但是master分支上的bug需要马上处理。
这个就是这节所需要掌握的内容:隐藏现有工作区还未提交的内容,然后去其他分支处理bug:创建新的分支,在新的分支上解决内容,然后融合到master分支上。
举一个实例:
比如,我们在dev分支上修改readme.txt,添加保存了最后一句话:


图片.png

这个时候因为还没有干完活,没有git add作提交,
这个时候我们git status,可以看到readme.txt属于未提交的状态;我们用git stash将这个工作区的内容隐藏起来:


图片.png

这个时候再来用git status来查看下:
图片.png

可以看到工作区是干净的,因为我用git stash隐藏了起来

现在来修复bug。我们知道了bug在分支master上,那么我们就在master分支上修复,就从master分支上创建临时分支:


图片.png

现在修复bug,需要把“Git is free software ...”改为“Git is a free software ...”,然后提交:


图片.png

修复完成后,切换到master分支,并完成合并:
图片.png

这样的话bug就处理好了,分支issue-101融合到master上了,
接着我们去dev分支上干完剩下的活。我们转到dev分支上,然后git status查看下情况:


图片.png

这个是和我们一开始隐藏后查看的情况一样,工作区还是干净的,我们用git stash list来查看下是什么情况:
图片.png

工作现场还在,Git把stash内容存在某个地方了,但是需要恢复一下,有两个办法:
一是用git stash apply恢复,但是恢复后,stash内容并不删除,你需要用git stash drop来删除;
另一种方式是用git stash pop,恢复的同时把stash内容也删了。

我们使用 git stash pop 来试下:


图片.png

我们再来用git stash list来查看下是否有隐藏的内容:


图片.png

可以看到已经没有隐藏的内容了。
我们再来打开readme.txt来看下内容:
图片.png

这个就是一开始干活自己编辑的内容,现在看到这个,就说明隐藏的内容已经回来了。

小结
修复bug时,我们会通过创建新的bug分支进行修复,然后合并,最后删除;
当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。

五、Feature分支
假如你创建一个Feature分支,在上面开发了一个功能,完了以后等到想合并Feature分支到dev分支上的时候,这个时候突然改变需求:需要删除Feature分支。
这个就是这节需要掌握的内容:强行删除一个没有被合并过的分支。

软件开发中,总有无穷无尽的新的功能要不断添加进来。
添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。
现在,你终于接到了一个新任务:开发代号为Vulcan的新功能。
于是准备开发:


图片.png

开发的文件是vulcan.txt:


图片.png

然后我们git add和git commit提交:
图片.png

切回dev分支,准备把feature-vulcan分支合并到dev分支上:
图片.png

但是,还没合并的时候,现在不需要合并了,且需要销毁feature-vulcan分支:
图片.png

但是我们看到,用我们之前学过的git branch -d 是销毁不掉的,提示是feature-vulcan这个分支还没有被完全合并,我觉得这样提醒是合理的,因为我们创建了这个feature-vulcan分支,如果就这样常规动作就销毁这个分支,我们很容易就在融合这个分支前就销魂这个分支而导致数据丢失,这个算是提醒,而且也说了,如果真的想删除,运行git branch -D,
现在我们强行删除:


图片.png

小结
开发一个新feature,最好新建一个分支;
如果要丢弃一个没有被合并过的分支,可以通过git branch -D <name>强行删除。

六、多人协作
这一章讲述的是关于在项目中工作的有关情景,包括推送本地仓库到远程仓库,还包括当你和你的同事都在相同的分支上完成项目,然后推送到远程的时候,遇到了冲突
这一节所必须掌握的内容是:1、推送本地仓库到远程仓库;2、抓取分支

当从远程仓库克隆时,实际上就是把本地的master分支和远程仓库的master分支对应起来,且,远程仓库的默认名称是origin。
要查看远程库的信息,用git remote:


图片.png

或者用git remote -v显示更详细的信息:


图片.png

上面显示了可以抓取(fetch)和推送(push)的origin的地址(这个地址是我在前面学习的课程中建立的)。如果没有推送权限,就看不到push的地址。

推送分支
推送分支,就是把该分支上所有的本地提交推送到远程库。推送时,要指定本地分支,这样Git就会把你指定的本地分支推送到远程库中对应的远程分支上:


图片.png

按我的理解,这条指令中,origin是远程仓库的名字,master是本地仓库的名字。所以在这条指令中,必须要有远程仓库和本地仓库,这样才可以对应起来,把本地仓库的内容推到远程仓库中去。
我的远程仓库在GitHub上,可以看到,更新已经推上去了:


图片.png

但是,并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?
master分支是主分支,因此要时刻与远程同步;
dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;

bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

抓取分支
多人协作的时候,大家都会往远程仓库中的master和dev分支上推送各自的修改,
现在,模拟一个你的小伙伴,可以在另一台电脑(注意要把SSH Key添加到GitHub)或者同一台电脑的另一个目录下克隆,
现在我就在同一台电脑上,找下别的目录(C:\Users\Administrator\gitskills),来克隆一下来自远程端的内容到这个别的目录中:


图片.png

去相关的目录下,可以看到learngit文件夹已经到了gitskills中(之前gitskills中只有README.md文件)。
中间出现了一个小插曲:
在上面我们用git remote -v来查看远程仓库的具体信息,我们看到的是github.com后面是/,但是,我使用了这个/,git竟然找不到远程仓库:


图片.png

可以看到,上面两个截图的远程地址,差别只是在一个是冒号,另一个是/。/这个无法使用,所以我们今后只能用github.com后面是冒号。
当你的小伙伴从远程库clone时(也就是我在同一个电脑的另一个目录下模拟的),默认情况下,你的小伙伴只能看到本地的master分支。不信可以用git branch命令看看:
图片.png

这段按我的理解是,master分支是本地目录默认的,所以也就只能看到master分支。

现在,你的小伙伴要在dev分支上开发,就必须创建远程origin分支到本地,于是他用这个命令创建本地dev分支:


图片.png

这之中出现了一个小问题,廖老师的网站是这样写的:


图片.png

所以一开始我也是这样写的,但是怎么创建都创建不了:
图片.png

后来我想,其实我也想到我在GitHub上没有origin/dev分支,我想我有learngit仓库,我也就又试了下这个:


图片.png

也是出现了相同的结果。后来我就想,我在远端只有一个origin,我就只写了这个,没有在后面带上斜杠以及任何东西,就创建成功了,我想廖老师所说的那样的情况,是因为廖老师origin上有dev分支。

然后,小伙伴就可以在dev上继续修改(在此添加了新的内容env.txt),保存,然后,把dev分支push到远程:


图片.png

这样我的小伙伴已经推送完了他的修改。现在就该我了,我就在我之前所在的目录(learngit)中,做一个同样的修改(增加env.txt):


图片.png

修改完成后,我也做同样的提交并且推送:
图片.png

我试了好几次,都是推送成功,不知道怎么才能做出因冲突而推送失败的操作。
那就继续按着老师所说的内容继续下去:
推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送:

 git pull
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.
   git pull <remote> <branch>
If you wish to set tracking information for this branch you can do so with:
   git branch --set-upstream-to=origin/<branch> dev

git pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接:

 git branch --set-upstream-to=origin/dev dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.

再pull:

 git pull
Auto-merging env.txt
CONFLICT (add/add): Merge conflict in env.txt
Automatic merge failed; fix conflicts and then commit the result.

这回git pull成功,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突完全一样。解决后,提交,再push:

 git commit -m "fix env conflict"
[dev 57c53ab] fix env conflict

 git push origin dev
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 621 bytes | 621.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To github.com:michaelliao/learngit.git
   7a5e5dd..57c53ab  dev -> dev

因此,多人协作的工作模式通常是这样
首先,可以试图用git push origin <branch-name>推送自己的修改;
如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;
如果合并有冲突,则解决冲突,并在本地提交;
没有冲突或者解决掉冲突后,再用git push origin <branch-name>推送就能成功!
如果git pull提示no tracking information,则说明本地分支和远程分支的链接关系没有创建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>。
这就是多人协作的工作模式,一旦熟悉了,就非常简单。

小结
查看远程库信息,使用git remote -v;
本地新建的分支如果不推送到远程,对其他人就是不可见的;
从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;
在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;
建立本地分支和远程分支的关联,使用git branch --set-upstream branch-name origin/branch-name;
从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。

以上是我看廖雪峰老师的网站,然后做的学习摘抄,无意侵犯老师作品,如有侵犯,我会删除。

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

推荐阅读更多精彩内容

  • 远程仓库 到目前为止,我们已经掌握了如何在Git仓库里对一个文件进行时光穿梭,你再也不用担心文件备份或者丢失的问题...
    归云丶阅读 1,958评论 0 5
  • 本系列教程来自廖雪峰的官方网站,现在搬运过来,目的帮助自己和小白学习收藏!附赠:常用git命令清单 目录 前言 创...
    Blizzard_liu阅读 1,133评论 0 4
  • 分支管理 分支就是科幻电影里面的平行宇宙,当你正在电脑前努力学习Git的时候,另一个你正在另一个平行宇宙里努力学习...
    bo_song阅读 708评论 0 1
  • 学习笔记,非原创。谢谢 Git鼓励大量使用分支: 创建与合并分支 :查看分支:git branch创建分支:git...
    Rising_life阅读 799评论 0 1
  • git分支使用的坏习惯 最近使用git提交代码发现大家的方式都不一样,自己在使用中也遇到了一些问题,导致代码危险。...
    好奇的小刺猬阅读 1,703评论 0 1