分支在实际中有什么用呢?假设你准备开发一个新功能,但是需要两周才能完成,第一周你写了50%的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全部写完再一次提交,又存在丢失每天进度的巨大风险。
现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
其他版本控制系统如SVN等都有分支管理,但是用过之后你会发现,这些版本控制系统创建和切换分支比蜗牛还慢,简直让人无法忍受,结果分支功能成了摆设,大家都不去用。
但Git的分支是与众不同的,无论创建、切换和删除分支,Git在1秒钟之内就能完成!无论你的版本库是1个文件还是1万个文件。
每次提交,Git都把它们串成一条时间线,这条时间线就是一个分支。
菜鸟讲的操作,截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即master分支。HEAD严格来说不是指向提交,而是指向master,master才是指向提交的 ,所以,HEAD指向的就是当前分支。
一开始的时候,master分支是一条线,Git用 master 指向最新的提交,再用 HEAD 指向 master ,就能确定当前分支,以及当前分支的提交点:
每次提交,master分支都会向前移动一步,这样,随着你不断提交,master分支的线也越来越长。
当我们创建新的分支,例如: dev 时,Git新建了一个指针叫dev,指向master相同的提交,再把HEAD指向dev,就表示当前分支在dev上:
Git创建一个分支很快,因为除了增加一个dev指针,改改HEAD的指向,工作区的文件都没有任何变化!
不过,从现在开始,对工作区的修改和提交就是针对dev分支了,比如新提交一次后,dev指针往前移动一步,而master指针不变:
假如我们在dev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最简单的方法,就是直接把master指向dev的当前提交,就完成了合并:
Git合并分支也很快!就改改指针,工作区内容也不变!
合并完分支后,甚至可以删除dev分支。删除dev分支就是把dev指针给删掉,删掉后,我们就剩下了一条master分支:
介绍完了git的原理,接下来自然少不了实际操作!
首先,大家看一下自己的分支:
git branch
如果是跟着菜鸟学习的读者,这里应该只会出现:
* master
git branch 命令会列出所有分支,当前分支前面会标一个 * 号。
接下来,我们创建dev分支,并切换到dev分支:
git checkout -b dev
或
git switch -c dev
或
git branch dev
git checkout dev
或
git branch dev
git switch dev
这面上面两种是创建并转到分支;而下面的两种则是先创建,然后转到分支。
再次 git branch
$ git branch
* dev
master
这里菜鸟直接复习上一次讲的删除,使用 git rm gittwo,然后再git status ,结果如下:
$ git status
On branch dev
Changes to be committed:
(use "git restore --staged ..." to unstage)
deleted: gittwo
然后尝试使用 git restore --staged ,无反应,使用 git status,结果如下:
$ git status
On branch dev
Changes not staged for commit:
(use "git add/rm ..." to update what will be committed)
(use "git restore ..." to discard changes in working directory)
deleted: gittwo
no changes added to commit (use "git add" and/or "git commit -a")
然后尝试使用 git checkout – gittwo ,结果:
正好验证了当时的菜鸟的说法!如果不清楚请看 撤销修改 / 删除文件
这里只是复习,其实不想复习的只需要进行第一步操作 git rm gittwo 就行了!(如果感兴趣也是可以用两种方式删除,当作复习)
然后提交
$ git commit -m "remove gittwo"
[dev 96cb575] remove gittwo
1 file changed, 1 deletion(-)
delete mode 100644 gittwo
此时一切都是再dev分支上修改的,怎么判断呢?当然是跳回到master看看,gittwo还在不在!
执行 git switch master,
gittwo又回来了,打印 git branch,
$ git branch
dev
* master
这个时候,我们需要提交了,把dev分支的工作成果合并到master分支上,提交之前还是老习惯,git status 结果如下:
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
这就表示,master是最新的,你有分支没有提交上来!现在,我们把dev分支的工作成果合并到master分支上:
$ git merge dev
Updating 80b9641..96cb575
Fast-forward
gittwo | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 gittwo
注意:上面的Fast-forward信息,Git告诉我们,这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。
当然,也不是每次合并都能Fast-forward,我们后面会讲其他方式的合并。
再来 git status,结果如下:
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
Git还会自动提示我们当前master分支比远程的master分支要超前1个提交。这里只是提示你可以和GitHub仓库同步了!
合并后,就会发现,gittwo又没了,这次两个版本里面都没有了,不对,这里说两个版本是错误的,因为这里只是把master指针指向了dev。其实dev和master就是一个指针,既然现在master已经和dev指向同一个地方,那么自然可以删除掉dev这个指针!
使用 git branch -d dev(分支名)
$ git branch -d dev
Deleted branch dev (was 96cb575).
再次 git branch 和 git status,结果如下:
asus@XXX MINGW64 /e/Git_warehouse (master)
$ git branch
* master
asus@XXX MINGW64 /e/Git_warehouse (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
(use "git push" to publish your local commits)
nothing to commit, working tree clean
如果你在合并分支之前,发现不想要分支了,你可以使用 git branch -D dev(分支名),如下(这是菜鸟写后面补的,所以名称不一样,是feature1):
asus@XXX MINGW64 /e/Git_warehouse (master)
$ git branch
feature1
* master
asus@XXX MINGW64 /e/Git_warehouse (master)
$ git branch -d feature1
error: The branch 'feature1' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feature1'.
asus@XXX MINGW64 /e/Git_warehouse (master)
$ git branch -D feature1
Deleted branch feature1 (was e103410).
asus@XXX MINGW64 /e/Git_warehouse (master)
$ git branch
* master