Git官方中关于git远程仓库的使用教程(必看):
2.5 Git 基础 - 远程仓库的使用:https://git-scm.com/book/zh/v2/Git-基础-远程仓库的使用
3.5 Git 分支 - 远程分支:https://git-scm.com/book/zh/v2/Git-分支-远程分支
看完上面的教程后,我们再一步一步抠细节。
最近在看廖雪峰Git+Git官方的教程,git远程仓库有很多命令,但是教程里面讲解的都是特别模糊的,现在就做一个疏导。
git branch -vv -a
命令具体解析在开始下面的命令解析之前,我们一定要学会git branch -vv -a
这个命令,这个是查询本地仓库+远程仓库+跟踪关系最全的命令了,它可以查询:
(i)本地仓库使用git remote add
命令映射过的所有远程仓库的所有分支;
(ii)使用4大跟踪远程分支命令
关联了所有远程仓库的所有远程跟踪分支的所有本地分支;(4大跟踪远程分支命令
在下面章节讲解)
图片解析:上图是博主我使用git branch -vv -a
命令查询的结果。
dev
分支,一个白色的master
分支,6个有remotes/
字符串开头且红色的远程分支。[origin/dev]
和[origin/master]
,它们代表本地仓库的dev
和master
分支分别远程跟踪了远程仓库origin的dev
和master
远程分支。remotes/origin/HEAD ->origin/master
远程分支比较特殊,origin/HEAD就像一个指针,表示默认分支,下图中它指向origin/master,代表着origin/master是默认分支。git remote add
命令映射的2个远程仓库remotes/liao
和remotes/origin
。remotes/liao
是廖雪峰老师的Git教程的远程仓库,remotes/origin
是博主我自己用来测试的远程仓库。git remote add
命令具体解析命令git remote add
:将远程仓库唯一的URL
映射成为 在本地仓库中对远程仓库起的别名
。(注意:git remote add
只负责映射!它不会产生下载或上传的流量!只有git clone
,git fetch
,git pull
等才产生下载或上传的流量!)
参数
:在本地仓库中对远程仓库起的别名
。而我们按照Git官方教程,一般会把参数
设置为origin
。
为什么要强调在本地仓库中
?因为我们要知道git remote add
是在我们自己的本地仓库对远程仓库起的别名,这个别名只能在我们自己的本地仓库使用,在真正的远程仓库那边,远程仓库的名字是一个绝对唯一的URL(比如:[email protected]:michaelliao/learngit.git
),而不是origin
。甚至我们的开发团队成员也可以自定义这个开发团队成员他个人的本地仓库中对远程仓库起的别名,比如官方教程2.5 Git 基础 - 远程仓库的使用中的参考命令git remote add pb https://github.com/paulboone/ticgit
,官方给参数
设置为pb
而不是origin
了。
参数
:远程仓库在互联网上唯一的URL。比如廖雪峰的Git仓库的SSH地址:[email protected]:michaelliao/learngit.git
。
git remote add origin [email protected]:michaelliao/learngit.git
在Git官方教程2.5 Git 基础 - 远程仓库的使用中,它对git remote add
的解释是:
运行
git remote add
添加一个新的远程 Git 仓库,同时指定一个你可以轻松引用的简写:
//Git官方教程2.5 Git 基础 - 远程仓库的示例
$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin https://github.com/schacon/ticgit (fetch)
origin https://github.com/schacon/ticgit (push)
pb https://github.com/paulboone/ticgit (fetch)
pb https://github.com/paulboone/ticgit (push)
在廖雪峰Git教程添加远程库中,把一个已有的本地仓库与远程仓库关联,也用到了以下命令:
$ git remote add origin [email protected]:michaelliao/learngit.git
我们值得注意的是,上面的2份教程对该命令的解释都是:git remote add
命令用于添加一个新的远程 Git 仓库或者把一个已有的本地仓库与远程仓库关联。其实这些都不准确。
git remote add
命令真实的用途是:将远程仓库唯一的URL
映射成为 在本地仓库中对远程仓库起的别名
。这是因为 远程仓库唯一的URL
实在是太长了,比如git remote add origin [email protected]:michaelliao/learngit.git
命令中的[email protected]:michaelliao/learngit.git
,Git使用者每次使用涉及远程仓库的命令都要加这么长的名字作为参数实在太麻烦了,所以将远程仓库唯一的URL
映射成为
,这样使用涉及远程仓库的命令只需要写 本地仓库中对远程仓库起的别名
就可以啦,比如廖雪峰Git教程添加远程库中的两条命令连用:
上面第一个红框中已经将origin
映射为[email protected]:michaelliao/learngit.git
。那么第二个红框中想要push本地仓库到远程仓库的命令中的远程仓库参数,甚至本仓库中涉及远程仓库的所有命令的远程仓库参数,都可以使用origin
这个超短字符代替,这样是不是超级方便Git使用者操作远程仓库了?
所以这才是git remote add
命令真实的用途是:将远程仓库唯一的URL
映射成为 在本地仓库中对远程仓库起的别名
,使用字符更短更间接的本地仓库中对远程仓库起的别名
来帮助Git使用者简易编写涉及远程仓库的命令。
git push <远程仓库名> <本地分支名>:<远程分支名>
命令具体解析git push <远程仓库名> <本地分支名>:<远程分支名>
:将本地分支推送到远程仓库的远程分支。(注意:这里的远程仓库名
依然是在本地仓库中对远程仓库起的别名
)<远程仓库名>
:在本地仓库中对远程仓库起的别名,如上面命令解析2(1)中设置的origin
。<本地分支名>
:本地分支的名称,比如我们在项目开发,一般主分支(也是默认分支)叫做master,一些新功能开发的分支叫做develop或feature。这些我们在我们自己电脑本地用git branch
创建的分支就是本地分支。<远程分支名>
:在远程仓库的普通分支,比如远程仓库上的master,自己在远程仓库创建的分支,以及自己推送到远程仓库上去的在远程仓库上的分支。<远程分支名>
与 <远程仓库名>
的情况不同:<远程分支名>
的取名由git push
中的远程分支名
决定,一般Git使用者会省略<远程分支名>
这个参数,所以Git会默认把<本地分支名>
设置为<远程分支名>
;<本地分支名>
无论在远程仓库还是本地仓库就只有一个名字,不像<远程分支名>
有一个绝对URL地址名字和一个在本地仓库中的别名。)git push <远程仓库名> <本地分支名>:<远程分支名>
命令的多种常用写法git push
在使用git push
命令之前,因为省略了 远程仓库名+本地分支名+远程分支名
3个参数中必要填写的远程仓库名+本地分支名
这2个参数,所以当前分支曾经必须被4大跟踪远程分支命令
远程跟踪到远程仓库的远程分支。(虽然你可能会说Git可以用当前分支的名字自动填补本地分支名+远程分支名
,这样会导致命令的作用太狭隘,所以Git不允许;另外Git再智能也不知道远程仓库名
这个参数呀,Git又不会读心术来知道Git使用者想用哪个远程仓库,所以必须至少补上远程仓库名+本地分支名
这2个参数)
upstream branch
就是上游分支(别名:远程分支),就是因为当前分支曾经未被远程跟踪,那么Git也不知道我们省略的 远程仓库名+本地分支名+远程分支名
3个参数中必要填写远程仓库名+本地分支名
这2个参数到底是什么呀!所以报错了。本地分支名
设置为当前分支,把参数远程仓库名+远程分支名
设置为远程追踪的远程仓库+远程分支。这样这3个被省略的参数就被填补上了,所以不会报错。git push
指令加了-u
参数后,往后再push代码只需要git push
或git push origin master
就可以了。git push
的意义:当Git使用者将当前分支远程跟踪到远程仓库的远程分支后,可以直接用git push
命令向远程仓库推送更新。这样,Git使用者再也不用每次输入此格式命令git push origin master
来向远程仓库推送更新,因为这个命令太长了导致Git使用者体验不佳。
git push <远程仓库名>
举例:git push origin在使用git push <远程仓库名>
命令之前,因为省略了 本地分支名+远程分支名
2个参数中必要填写本地分支名
这1个参数,所以当前分支曾经必须被4大跟踪远程分支命令
远程跟踪到远程仓库的远程分支。(虽然你可能又会说Git可以用当前分支的名字自动填补本地分支名+远程分支名
,但是Git认为这本地分支名+远程分支名
两个参数如果直接默认当前分支的名字会让git push <远程仓库名>
命令变得狭隘化,Git认为git push <远程仓库名>
应该是可以在某一分支中随意指定要Push的任意分支,而不应该直接默认当前分支的名字自动填充缺省参数
来给Git使用者偷懒,所以Git坚决规定:如果当前分支未被远程跟踪,那么本地分支名
必填,远程分支名
选填)
upstream branch
就是上游分支(别名:远程分支),就是因为当前分支曾经未被远程跟踪,那么Git也不知道我们省略的 本地分支名+远程分支名
2个参数中必要填写的本地分支名
这1个参数到底是什么呀!所以报错了。本地分支名
设置为当前分支,把参数远程分支名
设置为远程追踪的远程分支。这样这3个被省略的参数就被填补上了,所以不会报错。git push <远程仓库名>
的意义:相比于git push
用于方便Git使用者Push当前分支,git push <远程仓库名>
主要是方便在当前分支中不用切换到要想Push的任意分支,直接输入git push <要想Push的任意分支的远程仓库名>
就可以实现在一个分支中Push另一个分支到远程仓库
。
git push <远程仓库名> <本地分支名>
举例:git push origin mastergit push <远程仓库名> <本地分支名>
是第一次Push分支时必须使用的命令(因为第一次Push分支必须指定<远程仓库名> <本地分支名>
),它省略了远程分支名
,但是根据Git官方教程介绍,如果Git使用者没有填写<远程分支名>
,Git会用已经填写的<本地分支名>
来填补缺省的<远程分支名>
。
Git官方教程-3.5 Git 分支 - 远程分支是这么描述的:
如果希望和别人一起在名为
serverfix
的分支上工作,你可以像推送第一个分支那样推送它。 运行git push (远程仓库名) (远程分支名)
:
$ git push origin serverfix
这里有些工作被简化了。 Git 自动将
serverfix
分支名字展开为refs/heads/serverfix:refs/heads/serverfix
,那意味着,“推送本地的 serverfix 分支来更新远程仓库上的 serverfix 分支。” 我们将会详细学习 Git 内部原理 的refs/heads/
部分,但是现在可以先把它放在儿。 你也可以运行git push origin serverfix:serverfix
,它会做同样的事 - 相当于“推送本地的 serverfix 分支,将其作为远程仓库的 serverfix 分支”。
注意:git push <远程仓库名> <本地分支名>
并未使用短选项-u
或长选项--set-upstream
,所以它并未使得当前分支远程跟踪了远程分支,所以往后再次Push当前分支时依然要使用git push <远程仓库名> <本地分支名>
命令,不可以缩短为git push
或者git push <远程仓库名>
。
git push -u <远程仓库名> <本地分支名>
举例:git push -u origin master短选项-u
用于指定git push
命令中的<远程仓库名>
的<远程分支名>
为<本地分支名>
所跟踪的上游分支。
相比于git push <远程仓库名> <本地分支名>
,因为git push -u <远程仓库名> <本地分支名>
使用了短选项-u
,所以它使得当前分支远程跟踪了远程分支。进而,往后再次Push当前分支时可以直接使用git push
或者git push <远程仓库名>
命令。
git push --set-upstream <远程仓库名> <本地分支名>
举例:git push --set-upstream origin master相比于git push -u <远程仓库名> <本地分支名>
,git push --set-upstream <远程仓库名> <本地分支名>
把短选项-u
换成了长选项--set-upstream
。因为--set-upstream
长选项等价的短选项是-u
,所以git push --set-upstream <远程仓库名> <本地分支名>
与git push -u <远程仓库名> <本地分支名>
是等价的。
git push <远程仓库名> <本地分支名>:<远程分支名>
举例:git push origin serverfix:awesomebranch一般善于偷懒的Git使用者会直接使用git push -u <远程仓库名> <本地分支名>
命令来免去填写<远程分支名>
这个参数的麻烦。但是“免去填写<远程分支名>
这个参数的麻烦”只适用于本地分支名
与被推送到的远程分支名
相同时的情况。
根据Git官方教程-3.5 Git 分支 - 远程分支的描述:
在本地分支名是
serverfix
的情况下,如果并不想让远程仓库上的分支也叫做serverfix
,可以运行git push origin serverfix:awesomebranch
来将本地的serverfix
分支推送到远程仓库上的awesomebranch
分支。这样就可推送本地分支到一个命名不相同的远程分支。
git clone []
命令具体解析git clone []
:复制远程仓库
中HEAD指针指向的分支(默认是master分支,其他分支一律不复制)中的每一次提交记录和所有提交版本的文件,粘贴到本地文件夹当前GitBash所在路径/[]
,如果Git使用者未填写
,那么默认为远程仓库
的项目名,并自动默认远程仓库名称为origin和自动设置本地 master 分支远程跟踪远程仓库的 HEAD指针指向的分支(默认是master分支)。
中HEAD指针"就是唯一特殊的红色的remotes/origin/HEAD ->origin/master
远程分支,origin/HEAD就像一个指针,表示默认分支,下图中它指向origin/master,代表着origin/master是默认分支)
:远程仓库在互联网上唯一的URL。比如廖雪峰的Git仓库的SSH地址:[email protected]:michaelliao/learngit.git
。[]
:粘贴下来的所有项目文件应该存放的路径(既可是绝对路径也可是相对路径),该路径的最后一个字符串代表的是项目根目录(也是:本地仓库名)。若Git使用者未填写
,那么默认为远程仓库
的项目名。[]
写入绝对路径,hello
为项目根目录(也是:本地仓库名)。git clone [email protected]:jedlee6/RemoteRepositoryTest.git
上图的git clone [email protected]:jedlee6/RemoteRepositoryTest.git really
命令就是克隆远程仓库[email protected]:jedlee6/RemoteRepositoryTest.git
到本地仓库really
文件夹中。
同时使用git branch -vv -a
来查询查询本地仓库+远程仓库+跟踪关系,我们发现:
git clone []
只复制远程仓库
中HEAD指针指向的分支,其他分支一律不复制。remotes/origin/HEAD ->origin/master
远程分支不包括在内),但是克隆到本地仓库的只有远程仓库
中HEAD指针指向的master分支,这也证实了我们对命令git clone []
的一段定义:“复制远程仓库
中HEAD指针指向的分支(默认是master分支)中的每一次提交记录和所有提交版本的文件。”git clone
命令会自动默认远程仓库名称为origin,设置本地 master 分支远程跟踪克隆的远程仓库中HEAD指针指向的master分支。origin/master
看到本地 master 分支远程跟踪远程分支master。分支
与远程分支
与跟踪分支
与远程跟踪分支
的区别有一点特别重要:分支不是某一条提交记录串起来的线,分支是一个指针!
[1]git的跟踪分支和远程跟踪分支学习笔记
[2]Git-远程分支,远程跟踪分支,跟踪分支的区别
跟踪远程分支命令
[3]git跟踪远程分支,查看本地分支追踪和远程分支的关系(简书这篇文章里面git branch -u a b
命令的a b
写反了)
[4]Git本地分支与远程分支的追踪关系
[5]git 设置分支跟踪关系
[6]git 本地分支追踪远程分支
一个本地分支只能远程跟踪一个远程分支,如果设置新的远程跟踪的远程分支,新的会代替旧的。
git remote add可以映射多个远程仓库。
在本地创建分支用跟踪远端非master分支,用
git checkout -b newbranch origin/special
该命令会以远端special分支的内容创建本地的newbranch分支,从而可以在远端special分支的基础上开发.
如果想要将本地分支与远程分支设置为不同名字,你可以轻松地将上面的newbranch设置为不同的名字:
git checkout -b sf origin/serverfix
现在,本地分支 sf 会自动从 origin/serverfix 拉取
上面的命令也可以简化为
git checkout --track origin/special
该命令会在本地创建一个special分支用于跟踪远端的special分支并切换到本地special分支
设置已有的本地分支跟踪一个刚刚拉取下来的远程分支,或者想要修改正在跟踪的上游分支,你可以在任意时间使用 -u 或 --set-upstream-to 选项运行 git branch 来显式地设置。
git branch -u origin/serverfix
在跟踪分支里输入git push,Git 会自行推断应该向哪个服务器的哪个分支推送数据。反过来,在跟踪分支里运行git pull 会获取所有远程索引,并把它们的数据都合并到本地分支中来,同时Git 还能自动地识别去哪个服务器上抓取、合并到哪个分支。
--set-upstream
选项与--set-upstream-to
选项的区别--set-upstream
选项用于指定git push
命令中的<远程仓库名>
的<远程分支名>
为<本地分支名>
所跟踪的上游分支。举例:git push --set-upstream origin master
。并且--set-upstream
长选项等价的短选项是-u
,所以上面的举例可以写成git push -u origin master
,这两个命令是等价的。--set-upstream-to
选项用于git branch
,举例:git branch --set-upstream-to origin/dev dev
。并且--set-upstream-to
长选项等价的短选项是-u
,所以上面的举例可以写成git branch -u origin/dev dev
,这两个命令是等价的。本文参考文献:
[1]git的跟踪分支和远程跟踪分支学习笔记
[2]Git-远程分支,远程跟踪分支,跟踪分支的区别
[3]git跟踪远程分支,查看本地分支追踪和远程分支的关系(简书这篇文章里面git branch -u a b
命令的a b
写反了)
[4]Git本地分支与远程分支的追踪关系
[5]git 设置分支跟踪关系
[6]git 本地分支追踪远程分支
[7]git push -u origin master和git push <远程主机名> <本地分支名>:<远程分支名>作用
[8]Git官方教程对git push -u选项解释
[9]3.5 Git 分支 - 远程分支
[10]3.1 Git 分支 - 分支简介