目录
分支介绍
创建分支
切换分支
和并分支
删除分支
合并冲突
分支管理策略
分支策略
bug分支
其他问题
强行删除临时分支
结语
分支介绍
在版本回退里发现:每次提交,git都会把它们穿成一条时间线,而这条时间线就可以理解为一个分支。截止到现在,在git里,这个分支叫主分支,即master分支。
再来理解一下HEAD,严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的是当前分支
每次提交,master分支都会向前移动一步,master分支的线也会也来越长
[az@VM-8-7-centos gitcode]$ cat .git/HEAD
ref: refs/heads/master
[az@VM-8-7-centos gitcode]$ cat .git/refs/heads/master
341b701b4a690982616de789502d40c0e37eb160
创建分支
git支持我们查看或支持其他分支,在这里我们来创建一个自己的分支dev,
git branch 查看当前本地所有分支
git branch dev 新建分支dev
[az@VM-8-7-centos gitcode]$ git branch
* master
[az@VM-8-7-centos gitcode]$ git branch dev
[az@VM-8-7-centos gitcode]$ git branch
dev
* master
分支前面有*表示当前所在的分支
[az@VM-8-7-centos gitcode]$ cat .git/refs/heads/*
341b701b4a690982616de789502d40c0e37eb160
341b701b4a690982616de789502d40c0e37eb160
[az@VM-8-7-centos gitcode]$ cat .git/refs/heads/dev
341b701b4a690982616de789502d40c0e37eb160
发现目前dev和master指向同一个修改,也可以验证HEAD目前是指向master的
切换分支
git checkout [分支名] 命令可以切换dev
[az@VM-8-7-centos gitcode]$ git checkout dev
D README
Switched to branch 'dev'
[az@VM-8-7-centos gitcode]$ cat .git/HEAD
ref: refs/heads/dev
切换分支后,查看HEAD指针发现HEAD指向dev分支
这时候,在dev分支下,向Readme文件添加代码:
然后切换回master分支
发现没有新添加的代码,这时候我们查看两个分支的指向:
[az@VM-8-7-centos gitcode]$ cat .git/refs/heads/dev
6893cfc3ed6d216e6f1b1b9922f4b3bd6ce81117
[az@VM-8-7-centos gitcode]$ cat .git/refs/heads/master
341b701b4a690982616de789502d40c0e37eb160
发现两个分支指向的提交是不同的
这里就能明白了,因为我们是在dev分支上提交的,而master分支此刻的提交点并没有变,此时的状态如图:
切换到master当然看不到提交了
和并分支
为了在master主分支上能看到新的提交,就需要把dev分支合并到master分支
合并命令:git merge dev 把dev分支合并到当前分支上
[az@VM-8-7-centos gitcode]$ git branch
dev
* master
[az@VM-8-7-centos gitcode]$ git merge dev
Updating 341b701..6893cfc
Fast-forward
Readme | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[az@VM-8-7-centos gitcode]$ cat Readme
hello world
for new branch
这样就能看到新提交的代码了
(Fast-forward 代表“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。还有其他方式的合并)
删除分支
合并完成后,dev分支对我们来说就没有用了,保持良好的习惯,删除掉没用的分支
注意:不能删除当前所在的分支,必须先切换到其他分支上
删除命令:git branch -d dev 删除dev分支
[az@VM-8-7-centos gitcode]$ git branch
dev
* master
[az@VM-8-7-centos gitcode]$ git branch -d dev
Deleted branch dev (was 6893cfc).
[az@VM-8-7-centos gitcode]$ git branch
* master
合并冲突
但是在dev分支提交后,master分支也有提交,这时再合并,就有可能造成合并冲突
创建新分支dev1演示。 新命令:git checkout -b dev1可以完成创建和切换两步动作
[az@VM-8-7-centos gitcode]$ git checkout -b dev1
D README
Switched to a new branch 'dev1'
[az@VM-8-7-centos gitcode]$ git branch
* dev1
master
添加新代码并提交:
master也添加新代码并提交
合并分支
[az@VM-8-7-centos gitcode]$ git merge dev1
Auto-merging Readme
CONFLICT (content): Merge conflict in Readme
Automatic merge failed; fix conflicts and then commit the result.
这时候发现两个分支的东西都出现了
这时候我们必须手动调整冲突代码。并需要再次提交修正后的结果(必须要再次提交)
此时的状态就变成了:
合并后不要忘记删除dev1分支git branch -d dev1
分支管理策略
通常合并分支时,git会采用Fast forward模式。这种模式下,删除分支后,查看分支历史时,会丢掉分支信息,看不出来到底是merge合并进来的还是正常提交的
但是在合并冲突时,就不是Fast forward模式了,这样的好处是,从分支历史上就可以看出分支信息了(即使后来删除dev1分支,也能看到master其实是由其他分支合并得到的)
当然我们也可以强制禁用Fast forward模式,也就会在merge时生成一个新的commit,方面查看信息。下面我们尝试禁用Fast forward模式:
创建并切换新分支dev2
[az@VM-8-7-centos gitcode]$ git checkout -b dev2
Switched to a new branch 'dev2'
修改并提交新代码
以--no-ff方式合并分支,因为会创建新的commit 所以要-m把描述写进去
[az@VM-8-7-centos gitcode]$ git merge --no-ff -m "merge with no-ff" dev2
Merge made by the 'recursive' strategy.
Readme | 1 +
1 file changed, 1 insertion(+)
查看分支历史:(--graph以分支图的方式展示)
所以在合并分⽀时,加上 --no-ff 参数就可以⽤普通模式合并,合并后的历史有分⽀,能看出来曾 经做过合并,⽽ fast forward 合并就看不出来曾经做过合并。
分支策略
在实际开发中,我们应该按照几个基本原则进行分支管理:
首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能直接在上面写代码;
工作应该都在dev分支上,也就是说dev分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本;
bug分支
加入我们现在正在dev分支上进行开发,突然发现master分支上有bug需要解决,可是现在git的代码开发了一半,还无法提交怎么办?
git 提供了git stash 命令,可以将当前的工作区信息进行储藏,被储藏的内容可以在将来某个时间恢复出来
:git stash
Saved working directory and index state WIP on dev2: 41b082f modify ReadMe
:gitcode$ git status
On branch dev2
nothing to commit, working tree clean
用git status查看工作区,就是干净的,因此可以放心地创建分支来修复bug
修复后
刚才的工作东西用git stash list命令看看
工作现场还在,Git 把 stash 内容存在某个地方了,但是需要恢复⼀下,如何恢复现场呢?我们可以使用git stash pop 命令,恢复的同时会把 stash 也删了,示例如下:
另外,恢复现场也可以采⽤ git stash apply 恢复,但是恢复后,stash内容并不删除,你需要 ⽤ git stash drop 来删除; 你可以多次stash,恢复的时候,先⽤ git stash list 查看,然后恢复指定的stash,⽤命令 git stash apply stash@{0}
其他问题
我们有时候在其他分支上写代码时,master分支被修复了一个bug,这时候我们再合并可能就会有冲突
这个时候,我们应该先在dev上合并下master(就是更新master),然后再让master去合并dev
这样做的目的是有冲突可以在本地分支解决并测试,而不影响master
强行删除临时分支
有时候,如果分支的代码写到一半突然作废了
使用git branch -d是不能删除这个分支的,因为还没有提交
所以有了新方法:
git branch -D dev 这样可以强行删除分支dev
结语
分支在实际中有什么用呢?假设你准备开发⼀个新功能,但是需要两周才能完成,第⼀周你写了50% 的代码,如果立刻提交,由于代码还没写完,不完整的代码库会导致别人不能干活了。如果等代码全 部写完再一次提交,又存在丢失每天进度的巨大风险。 现在有了分支,就不用怕了。你创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上 正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再⼀次性合并到原来的分支上,这样,既安全,又不影响别人工作。并且 Git 无论创建、切换和删除分支,Git在1秒钟之内就能完成!无论你的版本库是1个文件还是1万个文件。