文章目录
前言
最近代码的版本控制工具由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
,创建的方法一搜一大把,上面提到的几个托管平台,在哪创建都可以,一定要记住地址,因为后面还要用到。
建立联系
本地创建文件夹并进入
albert@homepc MINGW64 /d
$ mkdir gitstart
albert@homepc MINGW64 /d
$ cd gitstart/
albert@homepc MINGW64 /d/gitstart
$
这里的文件夹名字可以和远程仓库不同,但是为了看起来方便对应,还是取相同的名字好一点。
初始化仓库
albert@homepc MINGW64 /d/gitstart
$ git init
Initialized empty Git repository in D:/gitstart/.git/
albert@homepc MINGW64 /d/gitstart (master)
$
临时插播好奇心(不在流程中)
目前这个状态有点意思,初始化完之后,(master)
这个字符串表示当前是在 master
分支,查一下日志看看:
albert@homepc MINGW64 /d/gitstart (master)
$ git log
fatal: your current branch 'master' does not have any commits yet
albert@homepc MINGW64 /d/gitstart (master)
$
提示也是正确的,说 master
分支没有任何提交,但是我们查询一下分支看看:
albert@homepc MINGW64 /d/gitstart (master)
$ git branch -a
albert@homepc MINGW64 /d/gitstart (master)
$
居然是空的,没有分支,查询 .git\HEAD
文件发现里面有一行 ref: refs/heads/master
,说明当前分支时 master
,但是为什么查询分支没有结果呢?
打开 .git\refs\heads
目录,发现这个文件夹下根本没有 master
文件,其实想想也对,Git
中的分支其实对应着 commit id
,现在什么都没有提交,master 也就找不到 commit id
,所以就是有 master
文件,里面也不知道写什么。
查询远程仓库
albert@homepc MINGW64 /d/gitstart (master)
$ git remote -v
albert@homepc MINGW64 /d/gitstart (master)
$
依旧什么内容都没有,说明还没有和远程仓库建立联系。
与远程仓库建立对应关系
albert@homepc MINGW64 /d/gitstart (master)
$ git remote add origin git@gitee.com:myname/gitstart.git
albert@homepc MINGW64 /d/gitstart (master)
$ git remote -v
origin git@gitee.com:myname/gitstart.git (fetch)
origin git@gitee.com:myname/gitstart.git (push)
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文件
albert@homepc MINGW64 /d/gitstart (master)
$ echo "learn git branch command">README.md
albert@homepc MINGW64 /d/gitstart (master)
$ git add README.md
warning: LF will be replaced by CRLF in README.md.
The file will have its original line endings in your working directory
albert@homepc MINGW64 /d/gitstart (master)
$ git commit -m"add readme file"
[master (root-commit) 3226b63] add readme file
1 file changed, 1 insertion(+)
create mode 100644 README.md
查询当前分支
albert@homepc MINGW64 /d/gitstart (master)
$ git branch -a
* master
这次可以是出现了,分支为 master
,前面的 *
表示为当前分支。
将分支推送到远程仓库
albert@homepc MINGW64 /d/gitstart (master)
$ git push -u origin master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 248 bytes | 248.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-3.8]
To gitee.com:myname/gitstart.git
* [new branch] master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
至此,本地仓库和远程仓库就建立了联系,下面可以开始学习 Git
分支命令了。
分支操作
新建分支
新建分支可以使用 git branch branch_name
命令,以下就是一个创建名为 release
分支的命令:
albert@homepc MINGW64 /d/gitstart (master)
$ git branch release
也可以使用 git checkout -b branch_name
来创建一个新分支,创建完会自动切换到新分支:
albert@homepc MINGW64 /d/gitstart (master)
$ git checkout -b dev
Switched to a new branch 'dev'
albert@homepc MINGW64 /d/gitstart (dev)
$
切换分支
这是一个很奇怪的命令,命令格式为 git checkout branch_name
,总感觉 checkout
子命令包揽了不属于自己的工作,如果在git branch
的基础上加一个参数会更合理的一点,但这和切换分支的实际含义可能还有关系,切换分支其实就是修改HEAD文件中的 commit id
,而没有真正的发生切换。
albert@homepc MINGW64 /d/gitstart (dev)
$ git checkout release
Switched to branch 'release'
albert@homepc MINGW64 /d/gitstart (release)
$ git checkout dev
Switched to branch 'dev'
albert@homepc MINGW64 /d/gitstart (dev)
$
查看本地分支
像刚才我们创建的 release
分支和 dev
分支都是在本地创建的,这样的分支通过 git branch
命令就可以查看
albert@homepc MINGW64 /d/gitstart (dev)
$ git branch
* dev
master
release
这样就列举了本地的所有分支,在当前分支名字 dev
前面哈还有一个 *
作为标记
查看远程分支
只要在上面的命令基础上加上 -r
参数就行了
albert@homepc MINGW64 /d/gitstart (dev)
$ git branch -r
origin/master
查询到的分支只有 origin/master
一个,这个分支是一开始我们进行第一次提交产生 master
分支之后,通过 git push -u origin master
推送到远程仓库的,所以现在只有一个。
查看所有分支
所有分支包括本地分支和远程分支,将 -r
参数换成 -a
参数就可以了
albert@homepc MINGW64 /d/gitstart (dev)
$ git branch -a
* dev
master
release
remotes/origin/master
将本地分支推送到远程仓库
其实之前已经操作过了,可以试着复习一下,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
是一样的,下面来试一下,然后查看一下分支:
albert@homepc MINGW64 /d/gitstart (dev)
$ git push -u origin dev
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-3.8]
remote: Create a pull request for 'dev' on Gitee by visiting:
remote: https://gitee.com/myname/gitstart/pull/new/myname:dev...myname:master
To gitee.com:myname/gitstart.git
* [new branch] dev -> dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
albert@homepc MINGW64 /d/gitstart (dev)
$ git branch -a
* dev
master
release
remotes/origin/dev
remotes/origin/master
冒号前后的米名字是不是一定相同呢?完全没有必要,我们可以让本地的 release
分支对应远程的 master
分支,只不过这样怪怪的,但是操作上完全可以的。
albert@homepc MINGW64 /d/gitstart (dev)
$ git checkout release
Switched to branch 'release'
albert@homepc MINGW64 /d/gitstart (release)
$ git push -u origin release:master
Everything up-to-date
Branch 'release' set up to track remote branch 'master' from 'origin'.
查看本地分支与远程分支对应关系
这个也是刚刚知道的,可以使用 git branch -vv
命令,注意是两个 v
:
albert@homepc MINGW64 /d/gitstart (release)
$ git branch -vv
dev 3226b63 [origin/dev] add readme file
master 3226b63 [origin/master] add readme file
* release 3226b63 [origin/master] add readme file
执行这个命令之后可以看出,本地的 master
和 release
分支都对应着远程的 master
分支
删除本地分支
我们先复习一下新建分支,然后把它推送到远程仓库,再使用 git branch -d branch_name
命令进行删除
albert@homepc MINGW64 /d/gitstart (release)
$ git checkout -b feature_test
Switched to a new branch 'feature_test'
albert@homepc MINGW64 /d/gitstart (feature_test)
$ git push origin feature_test
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-3.8]
remote: Create a pull request for 'feature_test' on Gitee by visiting:
remote: https://gitee.com/myname/gitstart/pull/new/myname:feature_test...myname:master
To gitee.com:myname/gitstart.git
* [new branch] feature_test -> feature_test
albert@homepc MINGW64 /d/gitstart (feature_test)
$ git branch -a
dev
* feature_test
master
release
remotes/origin/dev
remotes/origin/feature_test
remotes/origin/master
开始删除分支,删除之前记得切换到别的分支,否则删除不成功
albert@homepc MINGW64 /d/gitstart (feature_test)
$ git checkout dev
Switched to branch 'dev'
Your branch is up to date with 'origin/dev'.
albert@homepc MINGW64 /d/gitstart (dev)
$ git branch -d feature_test
Deleted branch feature_test (was 3226b63).
albert@homepc MINGW64 /d/gitstart (dev)
$ git branch -a
* dev
master
release
remotes/origin/dev
remotes/origin/feature_test
remotes/origin/master
删除远程分支
通过上面的操作我们发现只删除了本地的分支,远程的分支还在,要想删除远程分支,需要使用 git push origin --delete branch_name
命令
albert@homepc MINGW64 /d/gitstart (dev)
$ git push origin --delete feature_test
remote: Powered by GITEE.COM [GNK-3.8]
To gitee.com:myname/gitstart.git
- [deleted] feature_test
albert@homepc MINGW64 /d/gitstart (dev)
$ git branch -a
* dev
master
release
remotes/origin/dev
remotes/origin/master
这次再查看时发现远程分支也被删掉了。
获取远程主分支到本地
其实 Git
的克隆命令默认就是把远程仓库的主分支下载到本地,我们可以使用 git clone 远程地址 本地文件夹
命令来克隆一个仓库,如果本地文件夹省略,则默认新建一个与仓库名相同的文件夹:
albert@homepc MINGW64 /d
$ git clone https://gitee.com/myname/gitstart.git gitstartcopy
Cloning into 'gitstartcopy'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
albert@homepc MINGW64 /d
$ cd gitstartcopy/
albert@homepc MINGW64 /d/gitstartcopy (master)
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/dev
remotes/origin/master
获取远程其他分支到本地
从上面命令执行后的结果来看,当前本地仓库中只有 master
分支,其他的分支都是在远程仓库上,这时可以用 git checkout branch_name
命令来下载远程分支:
albert@homepc MINGW64 /d/gitstartcopy (master)
$ git checkout dev
Switched to a new branch 'dev'
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
albert@homepc MINGW64 /d/gitstartcopy (dev)
$ git branch -a
* dev
master
remotes/origin/HEAD -> origin/master
remotes/origin/dev
remotes/origin/master
albert@homepc MINGW64 /d/gitstartcopy (dev)
$ git branch -vv
* dev 3226b63 [origin/dev] add readme file
master 3226b63 [origin/master] add readme file
看到这里可能会疑惑了,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
总结
- 以上这些命令都是在本地测试过的,可能考虑的不太全面,不过没关系,以后的分支操作还会补充到这里。
- 这些命令在有些特殊的情况下使用可能会遇到问题,如果大家发现了问题请及时指出,我会尽快修改的。