分支概念
每次提交,Git 保存的不是文件的变化或者差异,而是一系列不同时刻的快照 。Git都把不同时刻的快照串成一条时间线,这条时间线就是一个分支。
在之前的学习中,我们只有一条时间线,这个分支叫主分支,即master分支。
使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。
分支作用
假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
如果你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性将自己的分支合并到原来的分支上,既安全,又不影响别人工作。
git创建、切换和删除分支速度也非常快,因为分针也是一种指针,下面我们将会提到。
指针概念
在之前回退版本的时候,我们提到HEAD,它其实就是一个指针,指向当前版本。
当你回退版本的时候,Git仅仅是把HEAD从指向回退版本,所以版本回退的速度非常快。
其实分支也是一个指针,这个指针只是用来表明这个commit和master分支的之间的偏差。
简单流程
当我们还没有创建新分支时,默认只有一个分支,也就是主分支master,HEAD指针指向当前版本,也存在在master分支上,如下:
然后我们创建分支testing,于是就有一个指针testing指向当前版本 f30ab:
然后我们把HEAD指针切换分支,使他指向分支testing:
之后我们再次提交一个新的版本,可以发现新版本处于testing分支,而不处于master主分支:
这就表明testing分支上的版本不会影响master主分支上的版本。
当testing分支上的工作完成后,想要把testing分支合并到master主分支。
切换到主分支,使HEAD指针指向master主分支的版本,此时版本回退到f30ab:
直接把master指针指向testing:的当前提交,就完成了合并
操作
列出所有分支 git branch
当前分支前面会标一个*号。
$ git branch
* master
如果需要查看每一个分支的最后一次提交,可以运行 git branch -v 命令
查看哪些分支已经合并到当前分支,可以运行 git branch --merged
查看所有包含未合并工作的分支,可以运行 git branch --no-merged
(如果包含了还未合并的分支,尝试使用 git branch -d 命令删除它时会失败)
新建分支 git branch < branchname >
$ git branch testing
切换分支 git checkout < branchname > 或 git switch < branchname >
$ git checkout testing
$ git switch testing
Switched to branch testing
新建并切换分支 git checkout -b < branchname >或 git switch -c < branchname >
$ git checkout -b testing
$ git switch -c testing
分支合并 git merge < branchname >
HEAD指针指向的分支合并到< branchname >分支
举例:我HEAD指针指向master主分支,想要将master主分支合并到testing分支
$ git merge testing
Updating 2205433..4a88d6a
Fast-forward
test1.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
删除分支 git branch -d < branchname >
$ git branch -d testing
Deleted branch testing (was 5473bcd).
合并冲突
如果当前的分支情况如下图的,Git无法执行“快速合并”,只能试图把各自的修改合并起来,但这种合并就可能会有冲突。
我们执行git merge testing合并testing分支:
$ git merge testing
Auto-merging test1.txt
CONFLICT (content): Merge conflict in test1.txt
Automatic merge failed; fix conflicts and then commit the result.
命令 git status 也可以告诉我们冲突的文件。
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: test1.txt
no changes added to commit (use "git add" and/or "git commit -a")
此时我们查看一下test1.txt文件内容,Git用<<<<<<<,=======,>>>>>>>标记出不同分支的内容:
$ cat test1.txt
this is a file test.
test branch.
<<<<<<< HEAD
test master.
=======
test testing.
>>>>>>> testing
接下来就需要我们手动进行修改了,之后再次提交,此时的分支状态如下:
$ git commit -am " fixed test1"
用带参数的 git log 也可以看到分支的合并情况:
$ git log --graph --oneline
* 3e66e45 (HEAD -> master) test1.txt
|\
| * c6fca3e (testing) test testing
* | f4d62d7 test master
|/* 4a88d6a test branch
* 2205433 modify test1
* 5473bcd modified readme,and add test1
* cc2f16f add a readme file
分支策略
master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;
干活都在dev分支上,dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
项目成员都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。
所以,团队合作的分支看起来就像这样:
参考文献
- https://www.liaoxuefeng.com/wiki/896043488029600/900005860592480
- https://git-scm.com/book/zh/v2/Git-分支-分支的新建与合并