前言
分析git remote add <shortname> <url>命令的作用。
一、使用gitee
使用GitHub時,國內的用戶經常遇到的問題是訪問速度太慢,有時候還會出現無法連接的情況(原因你懂的)。
如果我們希望體驗Git飛一般的速度,可以使用國內的Git托管服務——Gitee(gitee.com)。
和GitHub相比,Gitee也提供免費的Git倉庫。此外,還集成了代碼質量檢測、項目演示等功能。對於團隊協作開發,Gitee還提供了項目管理、代碼托管、文檔管理的服務,5人以下小團隊免費。
Gitee的免費版本也提供私有庫功能,只是有5人的成員上限。
使用Gitee和使用GitHub類似,我們在Gitee上注冊賬號並登錄后,需要先上傳自己的SSH公鑰。選擇右上角用戶頭像 -> 菜單“修改資料”,然后選擇“SSH公鑰”,填寫一個便於識別的標題,然后把用戶主目錄下的.ssh/id_rsa.pub文件的內容粘貼進去:

點擊“確定”即可完成並看到剛才添加的Key:

如果我們已經有了一個本地的git倉庫(例如,一個名為learngit的本地庫),如何把它關聯到Gitee的遠程庫上呢?
首先,我們在Gitee上創建一個新的項目,選擇右上角用戶頭像 -> 菜單“控制面板”,然后點擊“創建項目”:

項目名稱最好與本地庫保持一致:
然后,我們在本地庫上使用命令git remote add把它和Gitee的遠程庫關聯:
git remote add origin git@gitee.com:liaoxuefeng/learngit.git
之后,就可以正常地用git push和git pull推送了!
如果在使用命令git remote add時報錯:
git remote add origin git@gitee.com:liaoxuefeng/learngit.git
fatal: remote origin already exists.
這說明本地庫已經關聯了一個名叫origin的遠程庫,此時,可以先用git remote -v查看遠程庫信息:
git remote -v origin git@github.com:michaelliao/learngit.git (fetch) origin git@github.com:michaelliao/learngit.git (push)
可以看到,本地庫已經關聯了origin的遠程庫,並且,該遠程庫指向GitHub。
我們可以刪除已有的GitHub遠程庫:
git remote rm origin
再關聯Gitee的遠程庫(注意路徑中需要填寫正確的用戶名):
git remote add origin git@gitee.com:liaoxuefeng/learngit.git
此時,我們再查看遠程庫信息:
git remote -v origin git@gitee.com:liaoxuefeng/learngit.git (fetch) origin git@gitee.com:liaoxuefeng/learngit.git (push)
現在可以看到,origin已經被關聯到Gitee的遠程庫了。通過git push命令就可以把本地庫推送到Gitee上。
有的小伙伴又要問了,一個本地庫能不能既關聯GitHub,又關聯Gitee呢?
答案是肯定的,因為git本身是分布式版本控制系統,可以同步到另外一個遠程庫,當然也可以同步到另外兩個遠程庫。
使用多個遠程庫時,我們要注意,git給遠程庫起的默認名稱是origin,如果有多個遠程庫,我們需要用不同的名稱來標識不同的遠程庫。
仍然以learngit本地庫為例,我們先刪除已關聯的名為origin的遠程庫:
git remote rm origin
然后,先關聯GitHub的遠程庫:
git remote add github git@github.com:michaelliao/learngit.git
注意,遠程庫的名稱叫github,不叫origin了。
接着,再關聯Gitee的遠程庫:
git remote add gitee git@gitee.com:liaoxuefeng/learngit.git
同樣注意,遠程庫的名稱叫gitee,不叫origin。
現在,我們用git remote -v查看遠程庫信息,可以看到兩個遠程庫:
git remote -v gitee git@gitee.com:liaoxuefeng/learngit.git (fetch) gitee git@gitee.com:liaoxuefeng/learngit.git (push) github git@github.com:michaelliao/learngit.git (fetch) github git@github.com:michaelliao/learngit.git (push)
如果要推送到GitHub,使用命令:
git push github master
如果要推送到Gitee,使用命令:
git push gitee master
這樣一來,我們的本地庫就可以同時與多個遠程庫互相同步:

Gitee也同樣提供了Pull request功能,可以讓其他小伙伴參與到開源項目中來。你可以通過Fork我的倉庫:https://gitee.com/liaoxuefeng/learngit,創建一個your-gitee-id.txt的文本文件, 寫點自己學習Git的心得,然后推送一個pull request給我,這個倉庫會在Gitee和GitHub做雙向同步。
二、git remote add <shortname> <url>命令具體解析
2.1命令+選項+參數-解析
1、命令git remote add <shortname> <url>:將遠程倉庫唯一的URL<url> 映射成為 在本地倉庫中對遠程倉庫起的別名<shortname>。(注意:git remote add <shortname> <url>只負責映射!它不會產生下載或上傳的流量!只有git clone,git fetch,git pull等才產生下載或上傳的流量!)
2、參數<shortname>:在本地倉庫中對遠程倉庫起的別名。而我們按照Git官方教程,一般會把參數<shortname>設置為origin。
為什么要強調在本地倉庫中?因為我們要知道git remote add <shortname> <url>是在我們自己的本地倉庫對遠程倉庫起的別名,這個別名只能在我們自己的本地倉庫使用,在真正的遠程倉庫那邊,遠程倉庫的名字是一個絕對唯一的URL(比如:git@github.com:michaelliao/learngit.git),而不是origin。甚至我們的開發團隊成員也可以自定義這個開發團隊成員他個人的本地倉庫中對遠程倉庫起的別名,比如官方教程2.5 Git 基礎 - 遠程倉庫的使用中的參考命令git remote add pb https://github.com/paulboone/ticgit,官方給參數<shortname>設置為pb而不是origin了。
3、參數<url>:遠程倉庫在互聯網上唯一的URL。比如廖雪峰的Git倉庫的SSH地址:git@github.com:michaelliao/learngit.git。
2.2命令實例解析-git remote add origin git@github.com:michaelliao/learngit.git
在Git官方教程2.5 Git 基礎 - 遠程倉庫的使用中,它對git remote add <shortname> <url>的解釋是:
運行 git remote add <shortname> <url> 添加一個新的遠程 Git 倉庫,同時指定一個你可以輕松引用的簡寫:
在廖雪峰Git教程添加遠程庫中,把一個已有的本地倉庫與遠程倉庫關聯,也用到了以下命令:
$ git remote add origin git@github.com:michaelliao/learngit.git
我們值得注意的是,上面的2份教程對該命令的解釋都是:git remote add <shortname> <url>命令用於添加一個新的遠程 Git 倉庫或者把一個已有的本地倉庫與遠程倉庫關聯。其實這些都不准確。
git remote add <shortname> <url>命令真實的用途是:將遠程倉庫唯一的URL<url> 映射成為 在本地倉庫中對遠程倉庫起的別名<shortname>。這是因為 遠程倉庫唯一的URL<url> 實在是太長了,比如git remote add origin git@github.com:michaelliao/learngit.git命令中的git@github.com:michaelliao/learngit.git,Git使用者每次使用涉及遠程倉庫的命令都要加這么長的名字作為參數實在太麻煩了,所以將遠程倉庫唯一的URL<url> 映射成為 <shortname>,這樣使用涉及遠程倉庫的命令只需要寫 本地倉庫中對遠程倉庫起的別名<shortname>就可以啦,比如廖雪峰Git教程添加遠程庫中的兩條命令連用:
上面第一個紅框中已經將origin映射為git@github.com:michaelliao/learngit.git。那么第二個紅框中想要push本地倉庫到遠程倉庫的命令中的遠程倉庫參數,甚至本倉庫中涉及遠程倉庫的所有命令的遠程倉庫參數,都可以使用origin這個超短字符代替,這樣是不是超級方便Git使用者操作遠程倉庫了?
所以這才是git remote add <shortname> <url>命令真實的用途是:將遠程倉庫唯一的URL<url> 映射成為 在本地倉庫中對遠程倉庫起的別名<shortname>,使用字符更短更間接的本地倉庫中對遠程倉庫起的別名<shortname>來幫助Git使用者簡易編寫涉及遠程倉庫的命令。
三、git push <遠程倉庫名> <本地分支名>:<遠程分支名>命令具體解析
3.1 命令+選項+參數-解析
git push <遠程倉庫名> <本地分支名>:<遠程分支名>:將本地分支推送到遠程倉庫的遠程分支。(注意:這里的遠程倉庫名依然是在本地倉庫中對遠程倉庫起的別名)
<遠程倉庫名>:在本地倉庫中對遠程倉庫起的別名,如上面設置的origin。
<本地分支名>:本地分支的名稱,比如我們在項目開發,一般主分支(也是默認分支)叫做master,一些新功能開發的分支叫做develop或feature。這些我們在我們自己電腦本地用git branch創建的分支就是本地分支。
<遠程分支名>:在遠程倉庫的普通分支,比如遠程倉庫上的master,自己在遠程倉庫創建的分支,以及自己推送到遠程倉庫上去的在遠程倉庫上的分支。
(注意:<遠程分支名>與 <遠程倉庫名>的情況不同:
(i)<遠程分支名>的取名由git push中的遠程分支名決定,一般Git使用者會省略<遠程分支名>這個參數,所以Git會默認把<本地分支名>設置為<遠程分支名>;
(ii)<本地分支名>無論在遠程倉庫還是本地倉庫就只有一個名字,不像<遠程分支名>有一個絕對URL地址名字和一個在本地倉庫中的別名。)
3.2 git push
如果當前分支曾經未被遠程跟蹤,那么GitBash會報錯:

錯誤提示中的upstream branch就是上游分支(別名:遠程分支),就是因為當前分支曾經未被遠程跟蹤,那么Git也不知道我們省略的 遠程倉庫名+本地分支名+遠程分支名 3個參數中必要填寫遠程倉庫名+本地分支名。

git push的意義:當Git使用者將當前分支遠程跟蹤到遠程倉庫的遠程分支后,可以直接用git push命令向遠程倉庫推送更新。這樣,Git使用者再也不用每次輸入此格式命令git push origin master來向遠程倉庫推送更新,因為這個命令太長了導致Git使用者體驗不佳。
3.3git push <遠程倉庫名> <本地分支名> 舉例:git push origin master
git 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 <遠程
倉庫名>。
3.4git push -u <遠程倉庫名> <本地分支名> 舉例:git push -u origin master
短選項-u用於指定git push命令中的<遠程倉庫名>的<遠程分支名>為<本地分支名>所跟蹤的上游分支。
相比於git push <遠程倉庫名> <本地分支名>,因為git push -u <遠程倉庫名> <本地分支名>使用了短選項-u,所以它使得當前分支遠程跟蹤了遠程分支。進而,往后再次Push當前分支時可以直接使用git push或者git push <遠程倉庫名>命令。
3.5git 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 <
遠程倉庫名> <本地分支名>是等價的。
3.6git push <遠程倉庫名> <本地分支名>:<遠程分支名> 舉例:git push origin serverfix:awesomebranch
一般善於偷懶的Git使用者會直接使用git push -u <遠程倉庫名> <本地分支名>命令來免去填寫<遠程分支名> 這個參數的麻煩。但是“免去填寫<遠程分支名> 這個參數的麻煩”只適用於本地分支名與被推送到的遠程分支名相同時的情況。
根據Git官方教程-3.5 Git 分支 - 遠程分支的描述:
在本地分支名是serverfix的情況下,如果並不想讓遠程倉庫上的分支也叫做 serverfix,可以運行 git push origin serverfix:awesomebranch 來將本地的 serverfix 分支推送到遠程倉庫上的 awesomebranch 分支。這樣就可推送本地分支到一個命名不相同的遠程分支。
參看鏈接:
廖雪峰的git教程:https://www.liaoxuefeng.com/wiki/896043488029600/1163625339727712
https://blog.csdn.net/wq6ylg08/article/details/89028412
