Git遠程操作詳解(基礎)

Git是目前最流行的版本管理系統,學會Git幾乎成了開發者的必備技能。

Git有很多優勢,其中之一就是遠程操作非常簡便。本文詳細介紹5個Git命令,它們的概念和用法,理解了這些內容,你就會完全掌握Git遠程操作。

  • git clone
  • git remote
  • git fetch
  • git pull
  • git push

本文針對初級用戶,從最簡單的講起,但是需要讀者對Git的基本用法有所瞭解。同時,本文覆蓋了上面5個命令的幾乎所有的常用用法,所以對於熟練用戶也有參考價值。

git

一、git clone

遠程操作的第一步,通常是從遠程主機克隆一個版本庫,這時就要用到git clone命令。


$ git clone <版本庫的網址>

比如,克隆jQuery的版本庫。


$ git clone https://github.com/jquery/jquery.git

該命令會在本地主機生成一個目錄,與遠程主機的版本庫同名。如果要指定不同的目錄名,可以將目錄名作爲git clone命令的第二個參數。


$ git clone <版本庫的網址> <本地目錄名>

git clone支持多種協議,除了HTTP(s)以外,還支持SSH、Git、本地文件協議等,下面是一些例子。


$ git clone http[s]://example.com/path/to/repo.git/
$ git clone ssh://example.com/path/to/repo.git/
$ git clone git://example.com/path/to/repo.git/
$ git clone /opt/git/project.git 
$ git clone file:///opt/git/project.git
$ git clone ftp[s]://example.com/path/to/repo.git/
$ git clone rsync://example.com/path/to/repo.git/

SSH協議還有另一種寫法。


$ git clone [user@]example.com:path/to/repo.git/

通常來說,Git協議下載速度最快,SSH協議用於需要用戶認證的場合。各種協議優劣的詳細討論請參考官方文檔

二、git remote

爲了便於管理,Git要求每個遠程主機都必須指定一個主機名。git remote命令就用於管理主機名。

不帶選項的時候,git remote命令列出所有遠程主機。


$ git remote
origin

使用-v選項,可以參看遠程主機的網址。


$ git remote -v
origin  .com:jquery/jquery.git (fetch)
origin  .com:jquery/jquery.git (push)

上面命令表示,當前只有一臺遠程主機,叫做origin,以及它的網址。

克隆版本庫的時候,所使用的遠程主機自動被Git命名爲origin。如果想用其他的主機名,需要用git clone命令的-o選項指定。


$ git clone -o jQuery https://github.com/jquery/jquery.git
$ git remote
jQuery

上面命令表示,克隆的時候,指定遠程主機叫做jQuery。

git remote show命令加上主機名,可以查看該主機的詳細信息。


$ git remote show <主機名>

git remote add命令用於添加遠程主機。


$ git remote add <主機名> <網址>

git remote rm命令用於刪除遠程主機。


$ git remote rm <主機名>

git remote rename命令用於遠程主機的改名。


$ git remote rename <原主機名> <新主機名>

三、git fetch

一旦遠程主機的版本庫有了更新(Git術語叫做commit),需要將這些更新取回本地,這時就要用到git fetch命令。


$ git fetch <遠程主機名>

上面命令將某個遠程主機的更新,全部取回本地。

git fetch命令通常用來查看其他人的進程,因爲它取回的代碼對你本地的開發代碼沒有影響。

默認情況下,git fetch取回所有分支(branch)的更新。如果只想取回特定分支的更新,可以指定分支名。


$ git fetch <遠程主機名> <分支名>

比如,取回origin主機的master分支。


$ git fetch origin master

所取回的更新,在本地主機上要用"遠程主機名/分支名"的形式讀取。比如origin主機的master,就要用origin/master讀取。

git branch命令的-r選項,可以用來查看遠程分支,-a選項查看所有分支。


$ git branch -r
origin/master

$ git branch -a
* master
  remotes/origin/master

上面命令表示,本地主機的當前分支是master,遠程分支是origin/master

取回遠程主機的更新以後,可以在它的基礎上,使用git checkout命令創建一個新的分支。


$ git checkout -b newBrach origin/master

上面命令表示,在origin/master的基礎上,創建一個新分支。

此外,也可以使用git merge命令或者git rebase命令,在本地分支上合併遠程分支。


$ git merge origin/master
# 或者
$ git rebase origin/master

上面命令表示在當前分支上,合併origin/master

四、git pull

git pull命令的作用是,取回遠程主機某個分支的更新,再與本地的指定分支合併。它的完整格式稍稍有點複雜。


$ git pull <遠程主機名> <遠程分支名>:<本地分支名>

比如,取回origin主機的next分支,與本地的master分支合併,需要寫成下面這樣。


$ git pull origin next:master

如果遠程分支是與當前分支合併,則冒號後面的部分可以省略。


$ git pull origin next

上面命令表示,取回origin/next分支,再與當前分支合併。實質上,這等同於先做git fetch,再做git merge


$ git fetch origin
$ git merge origin/next

在某些場合,Git會自動在本地分支與遠程分支之間,建立一種追蹤關係(tracking)。比如,在git clone的時候,所有本地分支默認與遠程主機的同名分支,建立追蹤關係,也就是說,本地的master分支自動"追蹤"origin/master分支。

Git也允許手動建立追蹤關係。


git branch --set-upstream master origin/next

上面命令指定master分支追蹤origin/next分支。

如果當前分支與遠程分支存在追蹤關係,git pull就可以省略遠程分支名。


$ git pull origin

上面命令表示,本地的當前分支自動與對應的origin主機"追蹤分支"(remote-tracking branch)進行合併。

如果當前分支只有一個追蹤分支,連遠程主機名都可以省略。


$ git pull

上面命令表示,當前分支自動與唯一一個追蹤分支進行合併。

如果合併需要採用rebase模式,可以使用--rebase選項。


$ git pull --rebase <遠程主機名> <遠程分支名>:<本地分支名>

如果遠程主機刪除了某個分支,默認情況下,git pull 不會在拉取遠程分支的時候,刪除對應的本地分支。這是爲了防止,由於其他人操作了遠程主機,導致git pull不知不覺刪除了本地分支。

但是,你可以改變這個行爲,加上參數 -p 就會在本地刪除遠程已經刪除的分支。


$ git pull -p
# 等同於下面的命令
$ git fetch --prune origin 
$ git fetch -p

五、git push

git push命令用於將本地分支的更新,推送到遠程主機。它的格式與git pull命令相仿。


$ git push <遠程主機名> <本地分支名>:<遠程分支名>

注意,分支推送順序的寫法是<來源地>:<目的地>,所以git pull是<遠程分支>:<本地分支>,而git push是<本地分支>:<遠程分支>。

如果省略遠程分支名,則表示將本地分支推送與之存在"追蹤關係"的遠程分支(通常兩者同名),如果該遠程分支不存在,則會被新建。


$ git push origin master

上面命令表示,將本地的master分支推送到origin主機的master分支。如果後者不存在,則會被新建。

如果省略本地分支名,則表示刪除指定的遠程分支,因爲這等同於推送一個空的本地分支到遠程分支。


$ git push origin :master
# 等同於
$ git push origin --delete master

上面命令表示刪除origin主機的master分支。

如果當前分支與遠程分支之間存在追蹤關係,則本地分支和遠程分支都可以省略。


$ git push origin

上面命令表示,將當前分支推送到origin主機的對應分支。

如果當前分支只有一個追蹤分支,那麼主機名都可以省略。


$ git push

如果當前分支與多個主機存在追蹤關係,則可以使用-u選項指定一個默認主機,這樣後面就可以不加任何參數使用git push


$ git push -u origin master

上面命令將本地的master分支推送到origin主機,同時指定origin爲默認主機,後面就可以不加任何參數使用git push了。

不帶任何參數的git push,默認只推送當前分支,這叫做simple方式。此外,還有一種matching方式,會推送所有有對應的遠程分支的本地分支。Git 2.0版本之前,默認採用matching方法,現在改爲默認採用simple方式。如果要修改這個設置,可以採用git config命令。


$ git config --global push.default matching
# 或者
$ git config --global push.default simple

還有一種情況,就是不管是否存在對應的遠程分支,將本地的所有分支都推送到遠程主機,這時需要使用--all選項。


$ git push --all origin

上面命令表示,將所有本地分支都推送到origin主機。

如果遠程主機的版本比本地版本更新,推送時Git會報錯,要求先在本地做git pull合併差異,然後再推送到遠程主機。這時,如果你一定要推送,可以使用--force選項。


$ git push --force origin 

上面命令使用--force選項,結果導致遠程主機上更新的版本被覆蓋。除非你很確定要這樣做,否則應該儘量避免使用--force選項。

最後,git push不會推送標籤(tag),除非使用--tags選項。


$ git push origin --tags

六、查看用戶名和郵箱地址:


$ git config user.name


$ git config user.email
七、修改用戶名和郵箱地址:


$ git config --global user.name "username"


$ git config --global user.email "email"



(完)

轉自:

作者:阮一峯

原文地址:http://www.ruanyifeng.com/blog/2014/06/git_remote.html

版本回退版本學習:

版本回退學習


1 簡介

最近在使用Git時遇到了遠程分支需要版本回滾的情況,於是做了一下研究,寫下這篇博客。

2 問題

如果提交了一個錯誤的版本,怎麼回退版本?

如果提交了一個錯誤的版本到遠程分支,怎麼回退遠程分支版本?

如果提交了一個錯誤的版本到公共遠程分支,又該怎麼回退版本?

3 本地分支版本回退的方法

如果你在本地做了錯誤提交,那麼回退版本的方法很簡單 
先用下面命令找到要回退的版本的commit id:

git reflog 
  • 1
  • 1

接着回退版本:

git reset --hard Obfafd
  • 1
  • 1

0bfafd就是你要回退的版本的commit id的前面幾位

4 自己的遠程分支版本回退的方法

如果你的錯誤提交已經推送到自己的遠程分支了,那麼就需要回滾遠程分支了。 
首先要回退本地分支:

git reflog
git reset --hard Obfafd
  • 1
  • 2
  • 1
  • 2

緊接着強制推送到遠程分支:

git push -f
  • 1
  • 1

注意:本地分支回滾後,版本將落後遠程分支,必須使用強制推送覆蓋遠程分支,否則無法推送到遠程分支

5 公共遠程分支版本回退的問題

看到這裏,相信你已經能夠回滾遠程分支的版本了,那麼你也許會問了,回滾公共遠程分支和回滾自己的遠程分支有區別嗎? 
答案是,當然有區別啦。

一個顯而易見的問題:如果你回退公共遠程分支,把別人的提交給丟掉了怎麼辦?

下面來分析:

假如你的遠程master分支情況是這樣的:

A1–A2–B1

其中A、B分別代表兩個人,A1、A2、B1代表各自的提交。並且所有人的本地分支都已經更新到最新版本,和遠程分支一致。

這個時候你發現A2這次提交有錯誤,你用reset回滾遠程分支master到A1,那麼理想狀態是你的隊友一拉代碼git pull,他們的master分支也回滾了,然而現實卻是,你的隊友會看到下面的提示:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)
nothing to commit, working directory clean
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

也就是說,你的隊友的分支並沒有主動回退,而是比遠程分支超前了兩次提交,因爲遠程分支回退了嘛。

(1) 這個時候,你大吼一聲:兄弟們,老子回退版本了。如果你的隊友都是神之隊友,比如: Tony(騰訊CTO),那麼Tony會冷靜的使用下面的命令來找出你回退版本後覆蓋掉的他的提交,也就是B1那次提交:

git reflog
  • 1
  • 1

然後冷靜的把自己的分支回退到那次提交,並且拉個分支:

git checkout tony_branch        //先回到自己的分支  
git reflog                      //接着看看當前的commit id,例如:0bbbbb    
git reset --hard B1             //回到被覆蓋的那次提交B1
git checkout -b tony_backup     //拉個分支,用於保存之前因爲回退版本被覆蓋掉的提交B1
git checkout tony_branch        //拉完分支,迅速回到自己分支
git reset --hard 0bbbbbb        //馬上回到自己分支的最前端
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

通過上面一通敲,Tony暫時舒了一口氣,還好,B1那次提交找回來了,這時tony_backup分支最新的一次提交就是B1,接着Tony要把自己的本地master分支和遠程master分支保持一致:

git reset --hard origin/master
  • 1
  • 1

執行了上面這條命令後,Tony的master分支才真正的回滾了,也就是說你的回滾操作才能對Tony生效,這個時候Tony的本地maser是這樣的:

A1

接着Tony要再次合併那個被丟掉的B1提交:

git checkout master             //切換到master
git merge tony_backup           //再合併一次帶有B1的分支到master
  • 1
  • 2
  • 1
  • 2

好了,Tony終於長舒一口氣,這個時候他的master分支是下面這樣的:

A1 – B1

終於把丟掉的B1給找回來了,接着他push一下,你一拉也能同步。

同理對於所有隊友也要這樣做,但是如果該隊友沒有提交被你丟掉,那麼他拉完代碼git pull之後,只需要強制用遠程master覆蓋掉本地master就可以了

git reset --hard origin/master
  • 1
  • 1

(2) 然而很不幸的是,現實中,我們經常遇到的都是豬一樣的隊友,他們一看到下面提示:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)
nothing to commit, working directory clean
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

就習慣性的git push一下,或者他們直接用的SourceTree這樣的圖形界面工具,一看到界面上顯示的是推送的提示就直接點了推送按鈕,臥&槽,你辛辛苦苦回滾的版本就這樣輕鬆的被你豬一樣的隊友給還原了,所以,只要有一個隊友push之後,遠程master又變成了:

A1 – A2 – B1

這就是分佈式,每個人都有副本。這個時候你連揍他的心都有了,怎麼辦呢?你不能指望每個人隊友都是git高手,下面我們用另外一種方法來回退版本。

注意:博主是在虛擬機中實驗的,用於模擬兩個人的操作,如果你在一個機器上,用同一個賬號在不同的目錄下克隆兩份代碼來實驗的話,回退遠程分支後,另外一個人是不會看到落後遠程分支兩次提交的,所以請務必使用虛擬機來模擬A、B兩個人的操作

6 公共遠程分支版本回退的方法

使用git reset回退公共遠程分支的版本後,需要其他所有人手動用遠程master分支覆蓋本地master分支,顯然,這不是優雅的回退方法,下面我們使用另個一個命令來回退版本:

git revert HEAD                     //撤銷最近一次提交
git revert HEAD~1                   //撤銷上上次的提交,注意:數字從0開始
git revert 0ffaacc                  //撤銷0ffaacc這次提交
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

git revert 命令意思是撤銷某次提交。它會產生一個新的提交,雖然代碼回退了,但是版本依然是向前的,所以,當你用revert回退之後,所有人pull之後,他們的代碼也自動的回退了。 
但是,要注意以下幾點:

  1. revert 是撤銷一次提交,所以後面的commit id是你需要回滾到的版本的前一次提交
  2. 使用revert HEAD是撤銷最近的一次提交,如果你最近一次提交是用revert命令產生的,那麼你再執行一次,就相當於撤銷了上次的撤銷操作,換句話說,你連續執行兩次revert HEAD命令,就跟沒執行是一樣的
  3. 使用revert HEAD~1 表示撤銷最近2次提交,這個數字是從0開始的,如果你之前撤銷過產生了commi id,那麼也會計算在內的。
  4. 如果使用 revert 撤銷的不是最近一次提交,那麼一定會有代碼衝突,需要你合併代碼,合併代碼只需要把當前的代碼全部去掉,保留之前版本的代碼就可以了.

git revert 命令的好處就是不會丟掉別人的提交,即使你撤銷後覆蓋了別人的提交,他更新代碼後,可以在本地用 reset 向前回滾,找到自己的代碼,然後拉一下分支,再回來合併上去就可以找回被你覆蓋的提交了。

7 revert 合併代碼,解決衝突

使用revert命令,如果不是撤銷的最近一次提交,那麼一定會有衝突,如下所示:

<<<<<<< HEAD
全部清空
第一次提交
=======
全部清空
>>>>>>> parent of c24cde7... 全部清空
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

解決衝突很簡單,因爲我們只想回到某次提交,因此需要把當前最新的代碼去掉即可,也就是HEAD標記的代碼:

<<<<<<< HEAD
全部清空
第一次提交
=======
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

把上面部分代碼去掉就可以了,然後再提交一次代碼就可以解決衝突了。

8 繼續擴展,簡單粗暴的回滾方法

看到這裏也許你已經覺得學會了遠程倉庫版本回滾方法了,但是實踐中總是會遇到很多不按套路來的問題,考慮下面一種情況:

如果你們開發中,忽然發現前面很遠的地方有一次錯誤的合併代碼,把本來下一次才能發的功能的代碼合併到了這一次來了,這個時候全體成員都覺得直接回滾比較快,因爲他們都有備份,覆蓋了無所謂,這個時候用reset的話對隊友的要求比較高,用revert的話呢要大面積的解決衝突,也很麻煩呀,怎麼辦呢?

這個時候,可以使用簡單粗暴的辦法,直接從那個錯誤的提交的前一次拉取一份代碼放到其他目錄,然後將master代碼全部刪除,把那份新代碼方進去,然後提交,果然簡單粗暴啊,雖然這種方法不入流,但是,實踐中發現很好使啊,所以,實踐是檢驗真理的唯一標準。遇到問題還是要靈活應對。 
如果你遇到問題,歡迎給我留言,我CSDN博客———“梧桐那時雨”。

9 總結

遠程分支回滾的三種方法:

  1. 自己的分支回滾直接用reset
  2. 公共分支回滾用revert
  3. 錯的太遠了直接將代碼全部刪掉,用正確代碼替代

原文地址:http://blog.csdn.net/aguangg_6655_la/article/details/56288995
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章