分支
每次的版本提交到分支(branch),Git都会把它们串成一条时间线,而这条时间线就是一个分支,在版本库建立初期,只有一条时间线,在Git里,这条分支叫做主分支,即master分支。
使用分支意味着你可以从开发主线上分离开来,然后在不影响主线的同时继续工作。
创建了一个属于你自己的分支,别人看不到,还继续在原来的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到开发完毕后,再一次性合并到原来的分支上,这样,既安全,又不影响别人工作。
创建分支及合并
HEAD
(指针)严格来说不是指向版本提交点,而是指向master
(指针),而master
(指针)才是指向版本提交点。
如一开始,master
分支只是一条线,master
指向最新的版本提交点,而HEAD
则是指向master
,使用二者的作用就是:HEAD
确定当前分支,master
确定当前分支的提交点。
当创建一个分支,如创建名叫dev
的分支时,Git会创建一个dev
指针并指向当前master
指向的版本提交点,再把HEAD
指针指向dev
。
由于此时HEAD
指针指向dev
,所以从现在开始,对工作区的修改和提交都是针对dev
分支,而不是matser
分支。
当想要把dev
分支与master
分支合并时,Git就是直接把master
指针指向dev
当前指向的版本提交点,再把HEAD
指向master
,就完成合并了。
以上就是Git创建分支与合并分支的基本原理,而具体操作流程如下:
- 创建新分支
dev
,并HEAD
切换到dev
分支。可执行git branch <branch_name>
命令创建新分支,再执行git checkout <branch_name>
命令切换到dev
分支。以上操作可以执行git checkout -b <branch_name>
命令一步完成。
eg:
E:\Git>git branch dev
E:\Git>git checkout dev
Switched to branch 'dev'
git checkout -b <branch_name>
命令中的-b
表示创建并切换。
E:\Git>git checkout -b dev
Switched to a new branch `dev`
然后使用git branch
命令可以查看所有的分支,当前分支前面还标记*
号。
E:\Git>git branch
* dev
master
- 当
dev
分支工作完成,要把dev
与master
合并。要先把HEAD
切换到master
,再执行git merge branch_name
命令把dev
的分支合并到master
分支上:
解决冲突:假如建立分支后,还对主分支进行操作,那么合并的时候就有可能发生冲突,冲突的事项会在试图合并之后的文本上显示,此时需要手动清除冲突,然后将文件添加提交到主分支上后,方可删除分支。
此时执行git log --graph --pretty=oneline --addrev-commit
命令可以查看分支合并的情况
eg:
E:\Git>git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'
E:\Git>git merge dev
Updating 09c37cd..a695d1b
Fast-forward
Hello,Seiei.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
注意:上面的Fast-forward信息表示这次合并是“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。但在这模式下删除分支后就会丢掉分支信息,如果想要强制禁用快进模式,就可以添加
--no--f
参数,即git merge --no-f -m <info> <branch_name>
(因为本次合并要创建一个新的commit(所以速度慢),所以加上-m参数,把commit描述写进去。),此时执行git log --graph --abbrev-commit
命令就可以完整的看到主分支与创建分支合并的过程。(不然使用快速模式,只能看到一条主分支时间线)
- 合并完后,就可以执行
git branch -d <branch_name>
或git branch -D <branch_name>**删除
dev`分支**了。
eg:
E:\Git>git branch -d dev
Deleted branch dev (was a695d1b)
E:\Git>git branch
* master
分支的管理
分支策略
在实际的开发中,我们应该按照一下三个基本原则进行分支管理:
master
主分支应该要是非常稳定,即master
主分支仅用来发布新版本,平时的工作都不在主分支上;- 平时的工作都在创建的
dev
分支上,也就是说dev
分支是不稳定的,到某个时候,比如1.0版本发布时,再把dev分支合并到master上,在master分支发布1.0版本; - 而各自的工作人员则是在
dev
上又有各自的分支,时不时的再往dev
上合并。
所以团队合作分支应该像是下面这样:
Bug分支
修复bug时,可以通过创建新的bug分支进行修复,然后合并,最后删除bug分支,当手头工作没有完成时,先把工作现场git stash一下,然后去修复bug,修复后,再git stash pop,回到工作现场。
执行git stash
命令,把当前的工作现场“存储”起来(包括工作区、暂存区、分支的内容),等以后恢复现场后在工作。
eg:
E:\Git>git status
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: Hello,Seiei.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
E:\Git>git stash
Saved working directory and index state WIP on master: 543fe42 merge three
此时在执行git status
命令,显示工作区是干净的。
接下来就可以创建bug分支来修复bug,修复完之后就可以执行git stash list
命令来查看之前保存的工作现场。
eg:
E:\Git>git stash list
stash@{0}: WIP on master: 543fe42 merge three
查看完之后,可以执行两个方法恢复:
1. 执行git stash apply
命令恢复,但此时stash
内容并不删除,需要执行git stash drop
来删除;
2. 执行git stash pop
命令恢复,恢复同时stash
内容也同时删除。
eg:
E:\Git>git stash apply
E:\Git>git stash drop
或
E:\Git>gig stash pop
注: Git可以多次stash,恢复的时候,先用git stash list查看,然后恢复指定的stash,用命令
git stash apply stash@{num}
向远程库推送本地分支
推送分支的命令在之前的文章《Git的远程仓库》就有说道,执行git push origin <branch_name>
命令。
eg:
E:\Git>git push origin master
E:\Git>git push origin dev
并不是一定要把所有本地分支往远程推送:
master
分支是主分支,因此要时刻与远程同步;dev
分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;- bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;
- feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。
同时,如果在远程库推送发生冲突,可以执行
git pull
把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送。
抓取分支
从远程库clone时,默认情况下,只能看到本地的master分支。想要抓取别的分支就可以执行git checkout -b <branch_name> origin/<branch_name>
命令。
eg:
E:\Git>git checkout -b dev origin/dev
总结:
查看分支:
git branch
创建分支:
git branch <branch_name>
切换分支:
git checkout <branch_name>
创建并切换分支:
git checkout -b <branch_name>
快速模式合并某分支到当前分支:
git merge <branch_name>
普通模式合并某分支到当前分支:
git merge --no-f -m <info> <branch_name>
普通模式合并后的历史有分支,能看出来曾经做过合并,而fast forward合并就看不出来曾经做过合并。图形路径显示合并路径情况:
git log --graph --pretty=oneline --abbrev-commit
删除分支:
git branch -d <branch_name>
强制删除分支:
git branch -D <branch_name>
保存当前工作环境(包括工作区和暂存区):
git stash
查看保存工作列表:
git stash list
恢复工作环境:
git stash apply
删除stash内容:
git stash drop
恢复工作环境并删除stash内容:
git stash pop
查看远程库信息:
git remote
或git remote -v
远程库中抓取非master分支:
git checkout -b <branch_name> origin/<branch_name>