6.分支管理
首先我们创建一个分支dev,然后切换到dev:
git checkout -b dev 相当于git branch dev + git checkout dev 。创建分支并且切换到分支上去。
git branch可以查看当前所有分支,当前分支前面标识一个*号。
然后我们修改READ.md文件如下:
然后添加并提交:
现在我们的dev分支工作完成了,现在我们切换到master分支,然后把dev分支合并到master分支上:
然后我们再删除掉dev分支,再用git branch查看分支,只剩下master分支:
1)解决冲突
我们准备一个新分支例如“newobject”,继续我们的分支开发:
修改READ.md然后在newobject分支上提交:
然后切换回master分支,然后一样把READ.md修改:
然后提交:
这种情况下,git无法执行“快速合并”,只能试图把各自修改的合并起来,但这种合并可能发生冲突:
git status也可以告诉我们冲突:
查看READ.md也能发现信息:
Git用
<<<<<<<
,
=======
,
>>>>>>>
标记出不同分支的内容,我们修改如下后保存:
然后提交:
然后用带参数的git log查看分支的合并情况:
最后删除分支:
2)分支管理策略
通常,合并分支时,如果可能,git会用Fast forward模式,这种模式下,删除分支后,会丢掉分支信息。
如果要强制禁用Fast forward模式,git会在merge时生成一个新的commit,这样从历史上就可以看出分支信息。
下面我们就使用–no-ff方式git merge。
像1)中一样,切换新的分支,修改READ.md,然后提交,再切换回master:
然后切换回master,然后用 –no-ff参数,表示禁用Fast-forward来合并分支:
因为本次合并要创建一个新的commit,所以加上
-m
参数,把commit描述写进去。
然后用带参数的git log查看:
分支策略
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,
master
分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
那在哪干活呢?干活都在
dev
分支上,也就是说,
dev
分支是不稳定的,到某个时候,比如1.0版本发布时,再把
dev
分支合并到
master
上,在
master
分支发布1.0版本;
你和你的小伙伴们每个人都在
dev
分支上干活,每个人都有自己的分支,时不时地往
dev
分支上合并就可以了。
所以,团队合作的分支看起来就像这样:
小结
Git分支十分强大,在团队开发中应该充分应用。
合并分支时,加上
--no-ff
参数就可以用普通模式合并,合并后的历史有分支,能看出来曾经做过合并,而
fast forward
合并就看不出来曾经做过合并。
3)Bug分支
软件开发中,bug就像家常便饭一样,有了bug就修复。git中分支功能是如此强大,所以每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
当接到一个修复bug的任务的时候,很自然的创建一个分支issue-1来修复它,但是现在你正在dev上工作还没提交,而且工作干到一半,还不能提交。git有一个stash功能,将当前的工作现场“存藏”起来,等你恢复现场后继续工作:
用git status就可以看到工作区是干净的。
然后确定在哪个分支上修改bug,假定在master分支上修复,就从master创建临时分支:
修改完bug就切换到master分支,并完成合并,最后删除issue-1分支:
然后切换到最初的dev工作分支,开始继续之前的工作,用git status看是干净的:
用git stash list查看“存藏”的工作现场:
现在恢复的办法有两种 : 1.用git stash apply恢复,但是恢复后,stash并不删除,你需要用git stash drop来删除;
2.使用git stash pop,恢复的同时删除stash:
再用git stash list 查看,就没任何内容了,你可以多次stash,恢复的时候,先用
git stash list
查看,然后恢复指定的stash,用命令:
4)feature分支
当你增加一个新需求的时候,你肯定不希望把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发完成后,合并删掉feature分支。
新建feature1分支,然后修改内容并提交:
切换回dev分支,准备合并,但是此时上级说不需要这次开发的内容,虽然白干了,但是还要删除未提交的内容,但是你发现销毁失败:
git提示说没有合并,如果删除,就要强行删除用大写的-D参数:
5)多人协作
当你从远程仓库克隆时,实际上Git自动把本地的
master
分支和远程的
master
分支对应起来了,并且,远程仓库的默认名称是
origin
。
要查看远程仓库的信息,就用git remote,或者用git remote -v显示更加详细的内容:
上面显示了可以抓取和推送的origin的地址。
推送分支
推送分支,就是把该分支上的所有本地提交的推送到远程库。推送时,要指定本地分支,这样git就会把该分支推送到远程库对应的远程分支上:
如果要推送其他分支,比如dev,就改成:
但是,并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?
-
master
分支是主分支,因此要时刻与远程同步; -
dev
分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步; -
bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
-
feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。
抓取分支
多人协作的时候,大家往往都会往master和dev上推送各自的修改。
现在,模拟多人协作,模拟你的另一个伙伴,可以在另一台电脑或者在同一台电脑上另一个目录克隆:
从远程仓库克隆下来的, 你的伙伴默认只能看到本地的master分支:
你的伙伴要在dev上开发,就必须创建远程origin的dev分支到本地:
现在他在dev上修改,并时不时的把dev分支push到远程上去:
你小伙伴已经向origin dev分支上提交了,你也要对同样的文件修改,并试图推送:
推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用
git pull
把最新的提交从
origin/dev
抓下来,然后,在本地合并,解决冲突,再推送:
git pull也失败了,原因是没有指定本地
dev
分支与远程
origin/dev
分支的链接,根据提示,设置
dev
和
origin/dev
的链接:
然后你再pull:
然后修改冲突,提交,push:
因此,多人协作的工作模式通常是这样:
-
首先,可以试图用
git push origin <branch-name>
推送自己的修改;
-
如果推送失败,则因为远程分支比你的本地更新,需要先用
git pull
试图合并;
-
如果合并有冲突,则解决冲突,并在本地提交;
-
没有冲突或者解决掉冲突后,再用
git push origin <branch-name>
推送就能成功!
如果
git pull
提示
no tracking information
,则说明本地分支和远程分支的链接关系没有创建,用命令
git branch --set-upstream-to=origin/<branch-name> <branch-name>
。