使用Git都快2年了,能够说熟练使用git,遇到不会的也可以自己查询git帮助手册。平时可以根据shell的管道命令,组合一些命令比如git show commitID | grep “diff”来看看某次提交修改了哪些文件,还经常帮助同事解决git上面的问题。但是自己心里明白,还是有很多地方不是很懂。这几天抽空温故了下proGit,基于平日的思考,感觉有了不少的进步,准备总结下。这里事先说明:本篇总结适合一定Git基础的人看,自己总结的可能有些地方理解错误,请理解请指出。
我们在使用git init命令初始化一个仓库的时候,发现都会默认新建立了一个master分支。也就是说一个仓库一般都会存在一个master分支,只要你不去删除它。在使用git clone命令克隆一个仓库时候,也会发现默认新建立了一个master分支,并且这个分支跟踪的远程分支是master。clone出来的仓库,其中的master分支跟踪的远程分支实际上可以存在也可以不存在,不过这都对于本地master分支没有关系,一次push操作就可以让其存在或者不存在了。:-D
clone出来的本地仓库会把远程仓库看为origin仓库,这样很多地方就会出现origin字眼。使用git branch -r命令查看远程分支,会发现所有的远程分支都会有origin字段。ProGit是这样说说明的,clone仓库的时候,都会在本地建立指向远程仓库分支的远程分支,并且增加origin字段,git branch -r命令查看的其实就是这些分支,当然就都有origin了。使用git checkout -b branchName branchName命令新建一条跟踪远程分支的分支,就是从本地远程分支的基础上建立一个分支,所以要在中心库的分支名字前面加上origin。
有了前面的本地建立的远程分支知识,在顺道总结下git fetch和git pull命令。git fetch命令其实就是更新本地远程分支,这些远程分支只有在git branch -r命令下才能看到,都是悄悄的更新,一般看不到。git fetch命令也仅仅是更新本地远程分支,不做其它操作,所以没有任何其他影响或者副作用。git pull命令就不同了,他会更新本分支跟踪的本地远程分支,并且将本地远程分支merge到本分支上。在每个仓库下,查看.git/config文件会看到类似下面的类容:
[branch "master"] remote = origin merge = refs/heads/master
这些就是本分支跟踪的远程分支,也是git pull命令时候会merge的分支。使用git fetch会更新所有的本地远程分支,git pull一般是更新一条本地远程分支。
准确的分支名称是什么,在执行repo init命令或者git clone命令的时候是能看清楚的,其参数-b后面接的内容就是一条分支的准确名称。其他的诸如git checkout -b 或者 git branch,都是本地化操作,其后面的分支名称都是本地自己规定的,不是中心库里面的分支名称。使用repo init命令下载下来的git仓库没有新建默认本地分支,仅仅是有了所有的本地远程分支,可以使用repo start命令迅速建立一条默认分支。repo start的命令也仅有2中用法:1.后面加--all,即为当前代码的所有仓库新建默认分支 2.不加--all,为当前仓库新建默认分支。这里的默认分支就是repo init -b后面接的内容,在repo配置文件manifest.xml里面也可以看到。
git push命令都会涉及到远程仓库,一般使用clone命令或者repo inti命令产生的本地仓库,都会将默认的远程仓库设置为origin,这也就是git push后面常常接一个origin命令的原因。
git里面的分支可以说是一个个指针,其指向不同的节点,节点的前进或者后退就对应中分支的提交或者回退。所谓的当前分支,即有在这些指针之外还有一个特殊的指针,head指针。这个指针不指向节点,而是指向分支名称指针。