在git中最重要的两块内容就是两块:
1、上面提及到的git的状态流转、提交历史原理。
2、分支(分支原理、合并原理、解决冲突的原理、远程分支的原理。)
第一块重要的内容已经介绍的差不多了,接下来进行第二块重要的知识点。
分支的基础知识
1、分支的介绍
所谓的分支功能,就是可以同时拉出来多个代码副本,然后在不同的代码副本上,可以进行对应功能的开发。完成开发之后,可以将多个分支合并在一起,形成最终的代码。
在git中,每一个项目,不管你有多少个分支,不管你在哪个分支上开发最终都会形成一个完整的提交历史,树形结构。
每个分支,其实就只是一个指针而已,分支就指向了提交历史中的某个commit object。每个commit object就代表了这个项目的所有代码在那次提交的时候一个完整的快照版本,包含了之前没有变更的代码文件,也包括了这次提交的最新的修改/新增/删除的代码文件。所以每个commit object就代表了项目的一个版本。
Git的分支功能是一个很大的特色,非常的轻量级,分支的来回切换速度是很快的。在实际的开发过程中,分支绝对是最重要的功能。
2、分支的原理
分支是啥?
分支就是一个轻量级的指针,默认的分支是master。
每次提交master分支的指针默认就是指向最新的那个commit object的。每提交一次,master指针就会挪动,继续指向最新的commit object。
那么,Git 是如何知道你当前在哪个分支上工作的呢?
其实答案也很简单,git还维护了一个特殊的指针:HEAD。这个指针指向master分支指针。如果你创建了其他的分支,那么其他的分支也会指向某个commit object,而且此时如果工作在那个分支上,那么HEAD指针会指向那个分支。
3、分支命令
a、创建一个分支
git branch 分支名称
此命令可以创建一个新的分支,此时这个分支的指针会指向当前你所在的分支所指向的commit object上。

b、查看分支
git branch 可以查看本地分支

git branch -v 查看本地每个分支最后一次commit_hash

git branch -vv 可以展示本地分支与远程分支的对应关系

git branch -r 查看所有远程分支

git branch -a 查看所有分支(本地分支和远程分支)

git branch -av 查看所有分支(本地分支和远程分支),包含对应的最后一次commit-hash。

git branch -avv 展示所有分支(远程和本地)还可以展示本地分支与远程分支的对应关系

git log --oneline 可以查看各个分支指向哪个commit object。

c、切换分支
git checkout 分支名称
使用该命令可以切换到其他分支,此时HEAD指针会指向其他分支指针。

此时如果在testing分支上提交代码,那么会commit树会长出来一个新的commit object,而testing分支指正会指向最新的commit object,HEAD继续指向testing分支指针,而master指针还是指向之前的那个commit object。如下图:

git checkout master,会切换回master分支,此时HEAD指针会指向master指针,同时将master指针指向的那个commit object,对应的tree和其中的blob,也就是对应的文件快照恢复到工作区中来。此时使用git log --oneline
命令是不会显示未来提交的log的。
如下图:

再次在master分支上提交一个修改,此时从这个commit object会再长出来一个新的commit object,看起来就是跟testing分支当前指向的commit object形成了两个分叉。
git log --oneline --graph --all
查看commit树。这个命令很有用,可以打印出整颗commit树,同时告诉你各个分支当前指向哪个commit object。

注意:
如果当前分支有修改的内容仍然存在工作区或者是暂存区,是不允许切换分支的!
c、远程分支
git push -u origin (分支名)
此命令将本地分支推送到远程仓库里,形成一个同名的远程分支。
第一次执行命令加了参数-u后,以后即可直接用
git push
代替git push origin master
也可以运行git push origin testing:otherTesting
来实现相同的效果,它的意思是“上传我本地的 testing分支到远程仓库otherTesting分支中去”如果使用
git checkout -b
切换的远程分支,也可以不加-u 直接使用git push
命令,因为本地仓库与远程仓库已经关联起来了。
git pull origin (分支名)
从版本库(既可以是远程的也可以是本地的)将代码更新到本地。
git pull会把你已经关联过(track)的所有的分支的代码都拉取一遍。
git pull origin (分支名) 是指定拉取某个分支,可以没有被关联过。
例如:'git pull origin master'就是将origin这个版本库的代码更新到本地的master分支,该功能类似于SVN的update。
d、远程拉取分支
git fetch origin
此命令会抓取下来远程仓库新增了哪些分支。仅仅将远程版本库的commit树拉取下来,同时拉取下来所有最新的远程分支。
git checkout -b 本地分支
如果本地分支存在则只切换到本地分支,若不存在则创建并切换到该分支。只涉及到本地分支,不会涉及到远程分支。
git checkout -b 本地分支 origin/远程分支
origin/远程分支,就代表了远程仓库里的那个分支,然后这个命令一执行,就是在本地创建一个远程分支对应的本地分支,互相关联起来。
如果本地没有此分支但是远程仓库上面有此分支需要用此命令来直接切换到远程分支无需本地再创建。

e、删除分支
git push origin --delete 分支名称
删除远程分支,不会删除本地分支
git branch -d 分支名称
删除本地分支,不会删除远程分支
git branch -D 分支名称
强制删除本地分支。如果分支没有合并到当前分支是不让你删除的,可以用 -D 进行强制删除。
f、追踪远程分支remote-tracking
远程版本库的分支,在本地都有追踪分支,remote-tracking 分支。
比如说本地的master分支,对应的远程分支就是origin/master。比如本地的feature/iss53分支,对应的远程分支就是origin/feature/iss53。
如果我们是使用clone命令克隆的远程版本库,那么默认就会将本地的master分支创建为追踪origin/master远程分支的。
git branch -u origin/serverfix
可以让当前本地分支track某个指定的远程分支。
git branch -vv
可以查看每个本地分支track的远程分支。

g、成为追踪分支的几种情况:
让本地仓库和远程仓库关联起来或者被追踪的命令们,即分支的本地分支track远程分支:
git clone 默认是master分支进行关联。
git checkout -b 本地分支 origin/远程分支
git push -u origin (分支名)
git branch -u origin/serverfix
只要是被追踪了,就可以直接使用 git pull
git push
这两个命令。
已经关联track的分支注意事项:
1、git pull
git push
这里不加任何其他命令参数就可以直接运行哦。
2、git pull命令是把所有track的分支全部拉下来!
3、git push命令是把当前所在分支的数据推送上去!
4、git branch -u origin/serverfix 如果本地存在serverfix依然可以进行关联,但是会有变动的文件会被git改为modified或者其他状态如果远程不存在则会创建一个
5、git branch --set-upstream-to origin/serverfix serverfix 如果远程不存在则会关联失败
6、git push -u和git branch --set-upstream-to指令之间的区别:
我要把本地分支serverfix与远程仓库origin里的分支serverfix建立关联。(如果使用下列途径1的话,首先,你要切换到serverfix分支上(git checkout serverfix)两个途径:
git push -u origin serverfix
git branch --set-upstream-to=origin/serverfix serverfix这两种方式都可以达到目的。但是1方法更通用,因为你的远程库有可能并没有serverfix分支,这种情况下你用2方法就不可行,连目标分支都不存在,怎么进行关联呢?
所以总结一下:
git push -u origin serverfix相当于 git push origin serverfix + git branch --set-upstream-to=origin/serverfix
h、合并本地分支
git merge 本地分支名
把该本地分支合并到当前本地分支
merge分为两种:
1、fast-forward,快进式merge。
2、3-way merge,三路合并
具体原理下一章实战中讲解。
i、查看分支合并未合并
git branch --merged
可以查看哪些分支被merge到当前的分支了。
git branch --no-merged
可以查看哪些分支还没有被merge到当前分支。




