前言
最近代码的版本控制工具由SVN换成了Git,只用管理个人项目常用的灵魂三步git add、git commit、git push看来是行不通了,之前虽然也一直在用 git,但是用法很有限,主要集中在前面提到的三步,所以为了更好的工作,我决定还是好好总结一下。
分支在Git的操作里有着很重要的地位,代表了不同的开发线路,创建一个分支,也就多了一个索引文件,相比于SVN分支拷贝全部文件来说来方便的多,所以Git使得按功能分支的开发模式变得非常简单,在开发过程中常常需要对分支进行操作。
远程仓库
本来就几个分支,操作上也没有太麻烦,但是加入了远程仓库以后,事情变得复杂起来。有了远程仓库一般意味着代码开发需要多人合作了,这时候常常会产生冲突,分支合并时也变得不那么容易了。
远程仓库其实也很好理解,就是放在远处用来保存代码资源的一个仓库,其实和本地的代码库没有什么区别,这个远程仓库主要是为了把大家修改的代码都合并到一起,给大家提供一个统一的目标点。
远程仓库究竟有多远,常见的代码托管平台:github、gitlab、码云都可以提供远程仓库,如果你在月球上放置一台可以联网的代码仓库服务器,那么距离就是38.4万千米,但是远程仓库也可以很近,你也可以把本机电脑的D盘里的代码仓库作为E盘的代码仓库的远程仓库,或许远程仓库可能只和你隔了一个文件夹。
由于网络的原因,github 和 gitlab 访问常常很慢,所以为了做练习测试推送,我在码云创建了一个仓库 gitstart,它的地址大概是这个样子:git@gitee.com:myname/gitstart.git,创建的方法一搜一大把,上面提到的几个托管平台,在哪创建都可以,一定要记住地址,因为后面还要用到。
建立联系
本地创建文件夹并进入
1 | albert@homepc MINGW64 /d |
这里的文件夹名字可以和远程仓库不同,但是为了看起来方便对应,还是取相同的名字好一点。
初始化仓库
1 | albert@homepc MINGW64 /d/gitstart |
临时插播好奇心(不在流程中)
目前这个状态有点意思,初始化完之后,(master) 这个字符串表示当前是在 master分支,查一下日志看看:
1 | albert@homepc MINGW64 /d/gitstart (master) |
提示也是正确的,说 master分支没有任何提交,但是我们查询一下分支看看:
1 | albert@homepc MINGW64 /d/gitstart (master) |
居然是空的,没有分支,查询 .git\HEAD 文件发现里面有一行 ref: refs/heads/master,说明当前分支时 master,但是为什么查询分支没有结果呢?
打开 .git\refs\heads 目录,发现这个文件夹下根本没有 master文件,其实想想也对,Git 中的分支其实对应着 commit id,现在什么都没有提交,master 也就找不到 commit id,所以就是有 master 文件,里面也不知道写什么。
查询远程仓库
1 | albert@homepc MINGW64 /d/gitstart (master) |
依旧什么内容都没有,说明还没有和远程仓库建立联系。
与远程仓库建立对应关系
1 | albert@homepc MINGW64 /d/gitstart (master) |
这一步需要注意,origin看起来就是一个远程仓库的别名,代表着 git@gitee.com:myname/gitstart.git 这个代码仓库,刚刚提到过,这个远程仓库也可以是本地的,所以你添加git remote add origin d:/test 也是可以的,就表明 gitstart 的远程仓库是本地的 test 仓库。
第一个分支
刚刚说过,现在本地库的状态有些特殊,实际上刚刚在码云上创建的 git@gitee.com:myname/gitstart.git 库也很特殊,他们都没有真正的分支,这时只要我们成功提交一次,创建一个commit id,就相当于初始化了master分支。
添加README文件
1 | albert@homepc MINGW64 /d/gitstart (master) |
查询当前分支
1 | albert@homepc MINGW64 /d/gitstart (master) |
这次可以是出现了,分支为 master,前面的 * 表示为当前分支。
将分支推送到远程仓库
1 | albert@homepc MINGW64 /d/gitstart (master) |
至此,本地仓库和远程仓库就建立了联系,下面可以开始学习 Git 分支命令了。
分支操作
新建分支
新建分支可以使用 git branch branch_name 命令,以下就是一个创建名为 release 分支的命令:
1 | albert@homepc MINGW64 /d/gitstart (master) |
也可以使用 git checkout -b branch_name 来创建一个新分支,创建完会自动切换到新分支:
1 | albert@homepc MINGW64 /d/gitstart (master) |
切换分支
这是一个很奇怪的命令,命令格式为 git checkout branch_name,总感觉 checkout 子命令包揽了不属于自己的工作,如果在git branch的基础上加一个参数会更合理的一点,但这和切换分支的实际含义可能还有关系,切换分支其实就是修改HEAD文件中的 commit id,而没有真正的发生切换。
1 | albert@homepc MINGW64 /d/gitstart (dev) |
查看本地分支
像刚才我们创建的 release 分支和 dev 分支都是在本地创建的,这样的分支通过 git branch 命令就可以查看
1 | albert@homepc MINGW64 /d/gitstart (dev) |
这样就列举了本地的所有分支,在当前分支名字 dev 前面哈还有一个 * 作为标记
查看远程分支
只要在上面的命令基础上加上 -r 参数就行了
1 | albert@homepc MINGW64 /d/gitstart (dev) |
查询到的分支只有 origin/master 一个,这个分支是一开始我们进行第一次提交产生 master 分支之后,通过 git push -u origin master 推送到远程仓库的,所以现在只有一个。
查看所有分支
所有分支包括本地分支和远程分支,将 -r 参数换成 -a 参数就可以了
1 | albert@homepc MINGW64 /d/gitstart (dev) |
将本地分支推送到远程仓库
其实之前已经操作过了,可以试着复习一下,git push -u origin branch_name,其实这是一个简写,-u 可以写成 --set-upstream 表示设置上游分支,其实就是和远程仓库的分支建立联系。
branch_name 也是 local_branch_name:remote_branch_name的一种简写,冒号前表示本地分支,冒号后面表示远程分支,如果只写一个就表示两个分支名相同,远程仓库中如果没有这个分支就会新建一个。
也就是说 git push -u origin dev 和 git push--set-upstream origin dev:dev 是一样的,下面来试一下,然后查看一下分支:
1 | albert@homepc MINGW64 /d/gitstart (dev) |
冒号前后的米名字是不是一定相同呢?完全没有必要,我们可以让本地的 release 分支对应远程的 master 分支,只不过这样怪怪的,但是操作上完全可以的。
1 | albert@homepc MINGW64 /d/gitstart (dev) |
查看本地分支与远程分支对应关系
这个也是刚刚知道的,可以使用 git branch -vv 命令,注意是两个 v:
1 | albert@homepc MINGW64 /d/gitstart (release) |
执行这个命令之后可以看出,本地的 master 和 release 分支都对应着远程的 master 分支
删除本地分支
我们先复习一下新建分支,然后把它推送到远程仓库,再使用 git branch -d branch_name 命令进行删除
1 | albert@homepc MINGW64 /d/gitstart (release) |
开始删除分支,删除之前记得切换到别的分支,否则删除不成功
1 | albert@homepc MINGW64 /d/gitstart (feature_test) |
删除远程分支
通过上面的操作我们发现只删除了本地的分支,远程的分支还在,要想删除远程分支,需要使用 git push origin --delete branch_name 命令
1 | albert@homepc MINGW64 /d/gitstart (dev) |
这次再查看时发现远程分支也被删掉了。
获取远程主分支到本地
其实 Git 的克隆命令默认就是把远程仓库的主分支下载到本地,我们可以使用 git clone 远程地址 本地文件夹 命令来克隆一个仓库,如果本地文件夹省略,则默认新建一个与仓库名相同的文件夹:
1 | albert@homepc MINGW64 /d |
获取远程其他分支到本地
从上面命令执行后的结果来看,当前本地仓库中只有 master 分支,其他的分支都是在远程仓库上,这时可以用 git checkout branch_name 命令来下载远程分支:
1 | albert@homepc MINGW64 /d/gitstartcopy (master) |
看到这里可能会疑惑了,git checkout branch_name 不是切换分支的命令吗?实际上当 branch_name 分支在本地不存在而远程仓库存在时,这个命令与 git checkout -b <branch> --track <remote>/<branch> 含义相同,会在本地新建一个分支,并与远程分支建立联系。
常用集合
- 新建分支:
git checkout -b branch_name - 切换分支:
git checkout branch_name - 查看分支:
git branch -a - 删除分支:
git branch -d branch_name - 推送分支到远程:
git push origin branch_name - 删除远程的分支:
git push origin --delete branch_name - 拉取远程分支到本地:
git checkout branch_name - 查询分支的对应关系:
git branch -vv
总结
- 以上这些命令都是在本地测试过的,可能考虑的不太全面,不过没关系,以后的分支操作还会补充到这里。
- 这些命令在有些特殊的情况下使用可能会遇到问题,如果大家发现了问题请及时指出,我会尽快修改的。