Git 分支管理
分支创建与合并
master分支
创建Git仓库之后,会有一个默认的分支叫主分支,即master分支,master分支是一条线,Git用master指向最新的提交,再用HEAD指向master,就能确定当前分支,以及当前分支的提交点:

每次提交,master分支都会向前移动一步,随着不断提交,master分支的线也越来越长。
创建新分支
当我们创建新的分支,例如dev时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:

Git创建一个分支很快,因为只需要增加一个 dev 指针,再改变一下 HEAD的指向即可,工作区的文件都没有任何变化!
在新分支上进行开发
从现在开始,对工作区的修改和提交就是针对 dev 分支了,比如新提交一次后,dev 指针往前移动一步,而master 指针不变:

合并分支
假如我们在dev上的工作完成了,就可以把dev合并到master上。最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:

Git合并分支也很快,只需要修改指针,工作区内容也不变。
删除分支
合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:

git branch # 查看本地所有分支,当前所在的分支使用* 表示
git branch <name> # 创建分支
git checkout <name> # 切换分支
git checkout -b <name> # 创建并切换分支
git merge <name> # 合并某个分支到当前的分支
git branch -d <name> # 删除分支
分支合并冲突
所谓的分支合并冲突指的是,在两个分支上对同一个文件进行的修改在合并时发生冲突的情况,无法合并。
解决冲突的办法就是手动将冲突文件修改为我们最终希望的情况,之后再提交并合并。
例如:
-
新建分支
feature1:git checkout -b feature1在
feature1分支上readme.txt文件中修改为feature1 branch add line1,之后依次执行:git add readme.txt git commit -m "feature1 branch add" -
切换到
master分支:git checkout master此时,可以看到如下的信息:
Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits)Git还会自动提示我们当前
master分支比远程的master分支要超前1个提交。在
master分支上把readme.txt文件的修改为:master branch add line1,然后执行:git add readme.txt git commit -m "master branch add"现在,
master分支和feature1分支各自都分别有新的提交,变成了这样:

这种情况下,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突:
git merge feature1则会出现提示:
Auto-merging readme.txt CONFLICT (content): Merge conflict in readme.txt Automatic merge failed; fix conflicts and then commit the result.这意味着无法完成自动合并,此时使用
git status也可以看到发生冲突的文件,例如:

此时查看文件readme.txt,内容如下所示:

Git用<<<<<<<,=======,>>>>>>> 标记出不同分支的内容,此时就需要我们进行手动修改,将这个文件中的内容改为我们最终想要的样子,例如:confict fixed line1。
之后执行:
git add readme.txt
git commit -m "conflict fixed"
master分支和feature1分支变成了下图所示:
使用git log --graph可以查看分支合并的情况。
分支管理策略
主分支Master
代码库应该有一个、且仅有一个主分支。所有提供给用户使用的正式版本,都在这个主分支上发布。
Git主分支的名字,默认叫做 Master。它是自动建立的,版本库初始化以后,默认就是在主分支在进行开发。

开发分支Develop
主分支只用来分布重大版本,而日常开发应该在另一条分支上完成。我们把开发用的分支,叫做Develop。
如果想正式对外发布,就在Master分支上,对Develop分支进行合并。

团队合作的分支看起来就像这样:

每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
临时性分支
Master、Develop分支可以称为常设分支,除了常设分支之外,还有一些临时性分支:
- 功能
feature分支 - 预发布
release分支- 修补
bugfixbug分支
- 修补
这三种分支都属于临时性需要,使用完以后,应该删除,使得代码库的常设分支始终只有Master和Develop。
功能分支
功能分支是为了开发某种特定功能,从Develop分支上面分出来的。开发完成后,要再并入Develop。
功能分支的名字,可以采用feature-*的形式命名。

如果正在开发的功能突然不需要了,那么需要将当前的Feature分支删除掉,此时因为新的功能分支并没有合并过,于是删除时应该强行删除:
git branch -D <name> # 强行丢弃一个没有被合并过的分支
预发布分支
预发布分支是指发布正式版本之前(即合并到Master分支之前),我们可能需要有一个预发布的版本进行测试。
预发布分支是从Develop分支上面分出来的,预发布结束以后,必须合并进Develop和Master分支。它的命名,可以采用release-*的形式。
修补bug分支
软件正式发布以后,难免会出现bug。这时就需要创建一个分支,进行bug修补。
修补bug分支是从Master分支上面分出来的。修补结束以后,再合并进Master和Develop分支。它的命名,可以采用fixbug-*的形式。

假设现在正在Develop分支上进行开发,开发工作没有完成,突然间接到修复bug的任务。
-
需要将
Develop分支的现场进行保存:git stash # 保存当前的工作现场,以便以后恢复现场后继续工作 -
确认是在哪个分支上修复bug,假设是在
Master上修复bug,那么首先要切换到Master分支上,再从Master创建临时分支:git checkout master # 切换到master分支 git checkout -b fixbug-404 # 从master分支上创建临时分支fixbug-404 -
修复bug,修复完成之后,到
Master分支上进行合并,合并完成后删除fixbug-404分支:git checkout master # 切换到master分支 git merge --no-ff -m "merged bug fix 404" fixbug-404 # 合并fixbug-404分支到master分支 git branch -d fixbug-404 # 删除fixbug-404分支 -
bug修复完成后,我们回
Develop分支继续干活:git checkout develop # 切换到develop分支此时,我们希望能够恢复到原来的保存到现场环境,在原来的基础上继续开展工作,恢复现场环境的方式有两种:
git stash apply # 恢复stash环境 git stash drop # 将stash内容删除另一种方式是:
git stash pop # 恢复stash环境的同时把stash内容删除假设我们保存了多个现场环境,那么我们首先,应该看一下有哪些
stash环境:git stash list # 查看保存了哪些stash环境然后,恢复到指定的
stash环境:git stash apply stash_id # 恢复到指定的stash环境 -
在
master分支上修复了bug后,我们要想一想,develop分支是早期从master分支分出来的,所以,这个bug其实在当前develop分支上也存在,那么此时如何复制fixbug-404提交的修改,Git专门提供了一个cherry-pick命令,让我们能复制一个特定的提交到当前分支:git checout develop # 切换到develop分支 git cherry-pick commit_id # 将指定提交的修改复制到当前的分支
多人协作
查看远程仓库信息
当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。
查看远程库的信息:
git remote # 查看远程库信息
git remote -v # 查看远程库的详细信息
例如:

上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。
推送分支
推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:
git push origin master # 将本地的master分支推送到远程库中的master分支
git push origin dev # 将本地的dev分支推送到远程库中的dev分支
但是,并不是一定要把本地分支往远程推送:
master分支是主分支,因此要时刻与远程同步;dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。
总之,就是在Git中,分支完全可以在本地自己藏着玩,是否推送,皆有你定。
抓取分支
多人协作时,大家都会往master和dev分支上推送各自的修改。
当在不同目录或者另一台电脑上执行git clone的时候,默认只能看到本地的master分支。
当另一个人要在dev分支上开发,就必须创建远程origin的dev分支到本地:
git checkout -b dev origin/dev # 根据远程的dev分支创建本地的dev分支
现在,他就可以在dev上继续修改,然后,时不时地把dev分支push到远程:
如果别人已经向origin/dev分支推送了他的提交,而碰巧你也对同样的文件作了修改,并试图推送:
git push origin dev # 将dev分支推送到远程仓库
有可能会造成推送失败,因为别人的最新提交和你试图推送的提交有冲突,解决办法是将远程最新的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.
原因是没有指定本地dev分支与远程origin/dev分支的链接,可以根据提示,设置dev和origin/dev的链接:
git branch --set-upstream-to=origin/dev dev # 设置本地dev与远程dev分支的链接
再次执行git pull,手动修改冲突,修改完成之后进行推送:git push origin dev。
所以当多人在同一个分支上协作时,很容易出现冲突。即使没有冲突,后push的童鞋不得不先pull,在本地合并,然后才能push成功。

浙公网安备 33010602011771号