Git基本操作


前面的話

  git有數以百計的命令,我們基本上不可能使用所有的命令。當我們在命令行工具中敲入git並回車時,git實際上已經把一些常用的命令列了出來,絕大多數時間里用到的也就是這幾個命令。本文將詳細介紹Git的基本操作

 

取得倉庫

  有兩種取得Git項目倉庫的方法。第一種是在現存的目錄下,通過導入所有文件來創建新的Git倉庫。第二種是從已有的Git倉庫克隆出一個新的鏡像倉庫來

【初始化新倉庫】

  要對現有的某個項目開始用Git管理,只需到此項目所在的目錄,執行:

$ git init

  初始化后,在當前目錄下會出現一個名為.git的目錄,所有Git需要的數據和資源都存放在這個目錄中。不過目前,僅僅是按照既有的結構框架初始化好了里邊所有的文件和目錄,但還沒有開始跟蹤管理項目中的任何一個文件

  如果當前目錄下有幾個文件想要納入版本控制,首先需要先用git add命令告訴Git開始對這些文件進行跟蹤

$ git add a.txt

  執行上面的命令,沒有任何顯示,這就對了。Unix的哲學是“沒有消息就是好消息”,說明添加成功

  要注意的是,所有的版本控制系統,其實只能跟蹤文本文件的改動,比如TXT文件,網頁,所有的程序代碼等等,Git也不例外。版本控制系統可以告訴你每次的改動,比如在第5行加了一個單詞“Linux”,在第8行刪了一個單詞“Windows”。而圖片、視頻這些二進制文件,雖然也能由版本控制系統管理,但沒法跟蹤文件的變化,只能把二進制文件每次改動串起來,也就是只知道圖片從100KB改成了120KB,但到底改了啥,版本控制系統不知道,也沒法知道

  不幸的是,Microsoft的Word格式是二進制格式,因此,版本控制系統是沒法跟蹤Word文件的改動的,前面我們舉的例子只是為了演示,如果要真正使用版本控制系統,就要以純文本方式編寫文件

  因為文本是有編碼的,比如中文有常用的GBK編碼,日文有Shift_JIS編碼,如果沒有歷史遺留問題,強烈建議使用標准的UTF-8編碼,所有語言使用同一種編碼,既沒有沖突,又被所有平台所支持

  使用Windows的同學要特別注意,千萬不要使用Windows自帶的記事本編輯任何文本文件。原因是Microsoft開發記事本的團隊使用了一個非常弱智的行為來保存UTF-8編碼的文件,他們自作聰明地在每個文件開頭添加了0xefbbbf(十六進制)的字符,你會遇到很多不可思議的問題,比如,網頁第一行可能會顯示一個“?”,明明正確的程序一編譯就報語法錯誤等等,都是由記事本的弱智行為帶來的

  然后使用命令git commit告訴Git,把文件提交到倉庫

$ git commit -m 'wrote a file'

  -m后面輸入的是本次提交的說明,可以輸入任意內容,當然最好是有意義的,這樣就能從歷史記錄里方便地找到改動記錄

  git commit命令執行成功后會提示,1個文件被改動,插入了2行內容

【克隆現有倉庫】

  如果想對某個開源項目出一份力,可以先把該項目的Git倉庫復制一份出來,這就需要用到git clone命令。如果熟悉其他的VCS比如Subversion,可能已經注意到這里使用的是clone而不是checkout。這是個非常重要的差別,Git收取的是項目歷史的所有數據(每一個文件的每一個版本),服務器上有的數據克隆之后本地也都有了。實際上,即便服務器的磁盤發生故障,用任何一個克隆出來的客戶端都可以重建服務器上的倉庫,回到當初克隆時的狀態

  克隆倉庫的命令格式為git clone [url]。比如,要克隆VUE的Git代碼倉庫 vue,可以用下面的命令:

$ git clone git://github.com/vuejs/vue.git

  這會在當前目錄下創建一個名為vue的目錄,其中包含一個.git的目錄,用於保存下載下來的所有版本記錄,然后從中取出最新版本的文件拷貝。如果進入這個新建的vue目錄,會看到項目中的所有文件已經在里邊了,准備好后續開發和使用。如果希望在克隆的時候,自己定義要新建的項目目錄名稱,可以在上面的命令末尾指定新的名字

$ git clone git://github.com/vuejs/vue.git myvue

  Git支持許多數據傳輸協議。之前的例子使用的是git://協議,不過也可以用http(s)://或者user@server:/path.git表示的SSH傳輸協議

 

倉庫更新記錄

  現在手上已經有了一個真實項目的Git倉庫,並從這個倉庫中取出了所有文件的工作拷貝。接下來,對這些文件作些修改,在完成了一個階段的目標之后,提交本次更新到倉庫

  工作目錄下面的所有文件都不外乎這兩種狀態:已跟蹤或未跟蹤。已跟蹤的文件是指本來就被納入版本控制管理的文件,在上次快照中有它們的記錄,工作一段時間后,它們的狀態可能是未更新,已修改或者已放入暫存區。而所有其他文件都屬於未跟蹤文件。它們既沒有上次更新時的快照,也不在當前的暫存區域。初次克隆某個倉庫時,工作目錄中的所有文件都屬於已跟蹤文件,且狀態為未修改

  在編輯過某些文件之后,Git將這些文件標為已修改。我們逐步把這些修改過的文件放到暫存區域,直到最后一次性提交所有這些暫存起來的文件,如此重復。所以使用Git時的文件狀態變化周期如下圖所示

【檢查當前文件狀態】

  要確定哪些文件當前處於什么狀態,可以用git status命令

$ git status

  如果在取得倉庫之后立即執行此命令,會看到類似這樣的輸出

  這說明現在的工作目錄相當干凈。換句話說,所有已跟蹤文件在上次提交后都未被更改過。此外,上面的信息還表明,當前目錄下沒有出現任何處於未跟蹤的新文件,否則Git會在這里列出來。最后,該命令還顯示了當前所在的分支是master,這是默認的分支名稱

  現在創建一個新文件README,保存退出后運行git status會看到該文件出現在未跟蹤文件列表中

  在狀態報告中可以看到新建的README文件出現在“Untracked files”下面。未跟蹤的文件意味着Git在之前的快照(提交)中沒有這些文件;Git不會自動將之納入跟蹤范圍,除非告訴它“我需要跟蹤該文件”,因而不用擔心把臨時文件什么的也歸入版本管理。不過現在的例子中,我們確實想要跟蹤管理README這個文件

【跟蹤新文件】

  使用命令git add開始跟蹤一個新文件。所以,要跟蹤README文件,運行

$ git add README.txt

  使用命令git add .會批量跟蹤所有工作目錄下未被跟蹤的文件

$ git add .

  此時再運行git status命令,會看到README文件已被跟蹤,並處於暫存狀態:

  只要在“Changes to be committed”這行下面的,就說明是已暫存狀態。如果此時提交,那么該文件此時此刻的版本將被留存在歷史記錄中

  之前我們使用git init后就運行了git add命令,開始跟蹤當前目錄下的文件。在git add后面可以指明要跟蹤的文件或目錄路徑。如果是目錄的話,就說明要遞歸跟蹤該目錄下的所有文件

  其實git add的潛台詞就是把目標文件快照放入暫存區域,也就是add file into staged area,同時未曾跟蹤過的文件標記為需要跟蹤

【暫存已修改文件】

  現在我們修改下之前已跟蹤過的文件README.txt,將其內容修改為hello 回車換行 world

  然后再次運行status命令,會看到這樣的狀態報告:

  文件README.txt出現在 “Changes not staged for commit” 這行下面,說明已跟蹤文件的內容發生了變化,但還沒有放到暫存區。要暫存這次更新,需要運行git add命令

  git add命令是個多功能命令,根據目標文件的狀態不同,此命令的效果也不同:可以用它開始跟蹤新文件,或者把已跟蹤的文件放到暫存區,還能用於合並時把有沖突的文件標記為已解決狀態等

  現在運行git add將README.txt放到暫存區,然后再看看git status的輸出:

  現在README.txt文件已暫存,下次提交時就會記錄到倉庫。假設此時,想要在README.txt里再加條注釋,重新編輯存盤后,准備好提交。不過且慢,再運行git status看看:

  實際上Git只不過暫存了運行git add命令時的版本,如果現在提交,那么提交的是添加注釋前的版本,而非當前工作目錄中的版本。所以,運行git add之后又做了修訂的文件,需要重新運行git add把最新版本重新暫存起來

【忽略某些文件】

  一般我們總會有些文件無需納入Git的管理,也不希望它們總出現在未跟蹤文件列表。通常都是些自動生成的文件,比如日志文件,或者編譯過程中創建的臨時文件等。我們可以創建一個名為.gitignore的文件,列出要忽略的文件模式

  第一行告訴Git忽略所有以.o或.a結尾的文件。一般這類對象文件和存檔文件都是編譯過程中出現的,我們用不着跟蹤它們的版本

  第二行告訴Git忽略所有以波浪符(~)結尾的文件,許多文本編輯軟件都用這樣的文件名保存副本

  此外,可能還需要忽略log,tmp或者pid目錄,以及自動生成的文檔等等。要養成一開始就設置好.gitignore文件的習慣,以免將來誤提交這類無用的文件

  文件 .gitignore 的格式規范如下:

  1、所有空行或者以注釋符號 # 開頭的行都會被 Git 忽略

  2、可以使用標准的glob模式匹配

  3、匹配模式最后跟反斜杠(/)說明要忽略的是目錄

  4、要忽略指定模式以外的文件或目錄,可以在模式前加上嘆號(!)取反

  所謂的glob模式是指shell所使用的簡化了的正則表達式。星號(*)匹配零個或多個任意字符;[abc]匹配任何一個列在方括號中的字符(這個例子要么匹配一個a,要么匹配一個b,要么匹配一個c);問號(?)只匹配一個任意字符;如果在方括號中使用短划線分隔兩個字符,表示所有在這兩個字符范圍內的都可以匹配(比如[0-9]表示匹配所有0到9的數字)

# 此為注釋 – 將被 Git 忽略
# 忽略所有 .a 結尾的文件
*.a
# 但 lib.a 除外
!lib.a
# 僅僅忽略項目根目錄下的 TODO 文件,不包括 subdir/TODO
/TODO
# 忽略 build/ 目錄下的所有文件
build/
# 會忽略 doc/notes.txt 但不包括 doc/server/arch.txt
doc/*.txt
# ignore all .txt files in the doc/ directory
doc/**/*.txt

【查看已暫存和未暫存的更新】

  實際上git status的顯示比較簡單,僅僅是列出了修改過的文件,如果要查看具體修改了什么地方,可以用git diff命令

  現在,它已經能回答我們的兩個問題了:當前做的哪些更新還沒有暫存?有哪些更新已經暫存起來准備好了下次提交?git diff會使用文件補丁的格式顯示具體添加和刪除的行

  假如再次修改README文件后暫存,運行status命令將會看到:

  要查看尚未暫存的文件更新了哪些部分,不加參數直接輸入git diff:

  若要看已經暫存起來的文件和上次提交時的快照之間的差異,可以用git diff--cached命令  

  [注意]單單git diff不過是顯示還沒有暫存起來的改動,而不是這次工作和上次提交之間的差異。所以有時候一下子暫存了所有更新過的文件后,運行git diff后卻什么也沒有,就是這個原因

【提交更新】

  現在的暫存區域已經准備妥當可以提交了。在此之前,請一定要確認還有什么修改過的或新建的文件還沒有git add過,否則提交的時候不會記錄這些還沒暫存起來的變化。所以,每次准備提交前,先用git status看下,是不是都已暫存起來了,然后再運行提交命令git commit:

$ git commit

  這種方式會啟動文本編輯器以便輸入本次提交的說明,編輯器會顯示類似下面的文本信息

  可以看到,默認的提交消息包含最后一次運行git status的輸出,放在注釋行里,另外開頭還有一空行,供你輸入提交說明。完全可以去掉這些注釋行,不過留着也沒關系,多少能幫助回想起這次更新的內容有哪些。退出編輯器時,Git會丟掉注釋行,將說明內容和本次更新提交到倉庫

  另外也可以用-m參數后跟提交說明的方式,在一行命令中提交更新

  現在已經創建了第一個提交!可以看到,提交后它會提示,當前是在哪個分支(master)提交的,本次提交的完整SHA-1校驗和是什么(714666c),以及在本次提交中,有多少文件修訂過,多少行添改和刪改過

  [注意]提交時記錄的是放在暫存區域的快照,任何還未暫存的仍然保持已修改狀態,可以在下次提交時納入版本管理。每一次運行提交操作,都是對項目作一次快照,以后可以回到這個狀態,或者進行比較

【跳過使用暫存區域】

  盡管使用暫存區域的方式可以精心准備要提交的細節,但有時候這么做略顯繁瑣。Git提供了一個跳過使用暫存區域的方式,只要在提交的時候,給git commit加上-a選項,Git就會自動把所有已經跟蹤過的文件暫存起來一並提交,從而跳過git add步驟

  跳過git add步驟,不等於完全不使用git add。因為git commit -a是將所有跟蹤過的文件暫存起來並提交,只是省略了暫存這一步。但一個未跟蹤狀態的文件需要使用git add命令來使其變成已跟蹤狀態

  關於git commit -a 與git commit -am的區別的詳細信息移步至此

【移除文件】

  要從Git中移除某個文件,就必須要從已跟蹤文件清單中移除(確切地說,是從暫存區域移除),然后提交。可以用git rm命令完成此項工作,並連帶從工作目錄中刪除指定的文件,這樣以后就不會出現在未跟蹤文件清單中了

  如果只是簡單地從工作目錄中手工刪除文件,運行git status時就會在“Changes not staged for commit”部分(也就是未暫存清單)看到

  運行git rm記錄此次移除文件的操作

   由上圖可知,直接從工作目錄中手工刪除文件a.txt,雖然文件被刪除,但其快照仍然處於未暫存區域,這時就需要使用git rm將a.txt從暫存區域移除

  最后提交的時候,該文件就不再納入版本管理了。如果刪除之前修改過並且已經放到暫存區域的話,則必須要用強制刪除選項-f(即force的首字母),以防誤刪除文件后丟失修改的內容

  另外一種情況是,我們想把文件從Git倉庫中刪除(亦即從暫存區域移除),但仍然希望保留在當前工作目錄中。換句話說,僅是從跟蹤清單中刪除。比如一些大型日志文件或者一堆.a編譯文件,不小心納入倉庫后,要移除跟蹤但不刪除文件,以便稍后在.gitignore文件中補上,用--cached選項即可:

$ git rm --cached a.txt

  以下代碼會遞歸刪除當前目錄及其子目錄中所有 ~ 結尾的文件

$ git rm \*~

  以下代碼會刪除所有被跟蹤,但在工作目錄被刪除的文件

$ git rm $(git ls-files --deleted)

【移動文件】

  不像其他的VCS系統,Git並不跟蹤文件移動操作。如果在Git中重命名了某個文件,倉庫中存儲的元數據並不會體現出這是一次改名操作。不過Git非常聰明,它會推斷出究竟發生了什么

  要在Git中對文件改名,可以這么做:

$ git mv file_from file_to

 

查看提交歷史

  在提交了若干更新之后,又或者克隆了某個項目,想回顧下提交歷史,可以使用git log命令查看

  接下來的例子會用我專門用於演示的 simplegit 項目,運行下面的命令獲取該項目源代碼:

git clone git://github.com/schacon/simplegit-progit.git

  然后在此項目中運行git log,應該會看到下面的輸出:

  默認不用任何參數的話,git log會按提交時間列出所有的更新,最近的更新排在最上面

  每次更新都有一個SHA-1校驗和、作者的名字和電子郵件地址、提交時間,最后縮進一個段落顯示提交說明

  git log有許多選項,下表列出了一些常用的選項及其釋義

選項         說明
-p            按補丁格式顯示每個更新之間的差異
--word-diff       按 word diff 格式顯示差異
--stat          顯示每次更新的文件修改統計信息
--shortstat       只顯示 --stat 中最后的行數修改添加移除統計
--name-only       僅在提交信息后顯示已修改的文件清單
--name-status     顯示新增、修改、刪除的文件清單
--abbrev-commit   僅顯示 SHA-1 的前幾個字符,而非所有的 40 個字符
--relative-date   使用較短的相對時間顯示(比如,“2 weeks ago”)
--graph        顯示 ASCII 圖形表示的分支合並歷史
--pretty        使用其他格式顯示歷史提交信息可用的選項包括oneline,short,full,fuller 和format(后跟指定格式)
--oneline        `--pretty=oneline --abbrev-commit` 的簡化用法

  接下來介紹些最常用的選項

  我們常用-p選項展開顯示每次提交的內容差異,用-2則僅顯示最近的兩次更新

  該選項除了顯示基本信息之外,還在附帶了每次commit的變化。當進行代碼審查,或者快速瀏覽某個搭檔提交的commit的變化的時候,這個參數就非常有用了

  某些時候,單詞層面的對比,比行層面的對比,更加容易觀察。Git提供了--word-diff選項。我們可以將其添加到git log -p命令的后面,從而獲取單詞層面上的對比。在程序代碼中進行單詞層面的對比常常是沒什么用的。不過需要在書籍、論文這種很大的文本文件上進行對比的時候,這個功能就顯出用武之地了

  如上圖所示,這里並沒有平常看到的添加行或者刪除行的信息。這里的對比顯示在行間。新增加的單詞被{+ +}括起來,被刪除的單詞被[- -]括起來。在進行單詞層面的對比的時候,可能希望上下文(context)行數從默認的3行,減為1行,那么可以使用-U1選項。上面的例子中,我們就使用了這個選項

  另外,git log還提供了許多摘要選項可以用,比如--stat,僅顯示簡要的增改行數統計:

  每個提交都列出了修改過的文件,以及其中添加和移除的行數,並在最后列出所有增減行數小計。 還有個常用的--pretty選項,可以指定使用完全不同於默認格式的方式展示提交歷史。比如用oneline將每個提交放在一行顯示,這在提交數很大時非常有用。另外還有short,full和fuller可以用,展示的信息或多或少有些不同

  最有意思的是format,可以定制要顯示的記錄格式,這樣的輸出便於后期編程提取分析

  下表中列出了常用的格式占位符寫法及其代表的意義

選項        說明
%H         提交對象(commit)的完整哈希字串
%h         提交對象的簡短哈希字串
%T         樹對象(tree)的完整哈希字串
%t         樹對象的簡短哈希字串
%P         父對象(parent)的完整哈希字串
%p         父對象的簡短哈希字串
%an        作者(author)的名字
%ae        作者的電子郵件地址
%ad        作者修訂日期(可以用 -date= 選項定制格式)
%ar        作者修訂日期,按多久以前的方式顯示
%cn        提交者(committer)的名字
%ce        提交者的電子郵件地址
%cd        提交日期
%cr        提交日期,按多久以前的方式顯示
%s         提交說明  

  作者(author)和提交者(committer)之間究竟有何差別,其實作者指的是實際作出修改的人,提交者指的是最后將此工作成果提交到倉庫的人。所以,當你為某個項目發布補丁,然后某個核心成員將你的補丁並入項目時,你就是作者,而那個核心成員就是提交者

【限制輸出長度】

  除了定制輸出格式的選項之外,git log還有許多非常實用的限制輸出長度的選項,也就是只輸出部分提交信息。比如使用-2,它只顯示最近的兩條提交,實際上,這是-<n>選項的寫法,其中的n可以是任何自然數,表示僅顯示最近的若干條提交。不過實踐中我們是不太用這個選項的,Git在輸出所有提交時會自動調用分頁程序(less),要看更早的更新只需翻到下頁即可

  另外還有按照時間作限制的選項,比如--since和--until。下面的命令列出所有最近兩周內的提交

$ git log --since=2.weeks

  可以給出各種時間格式,比如說具體的某一天(“2008-01-15”),或者是多久以前(“2 years 1 day 3 minutes ago”)

  還可以給出若干搜索條件,列出符合的提交。用--author選項顯示指定作者的提交,用--grep選項搜索提交說明中的關鍵字。(請注意,如果要得到同時滿足這兩個選項搜索條件的提交,就必須用--all-match選項。否則,滿足任意一個條件的提交都會被匹配出來)

  另一個真正實用的git log選項是路徑(path),如果只關心某些文件或者目錄的歷史提交,可以在git log 選項的最后指定它們的路徑。因為是放在最后位置上的選項,所以用兩個短划線(--)隔開之前的選項和后面限定的路徑名

  下表還列出了其他常用的類似選項

選項              說明
-(n)             僅顯示最近的 n 條提交
--since, --after      僅顯示指定時間之后的提交
--until, --before     僅顯示指定時間之前的提交
--author          僅顯示指定作者相關的提交
--committer        僅顯示指定提交者相關的提交

【使用圖形化工具查閱提交歷史】

  有時候圖形化工具更容易展示歷史提交的變化,隨Git一同發布的gitk就是這樣一種工具。它是用Tcl/Tk寫成的,基本上相當於git log命令的可視化版本,凡是git log可以用的選項也都能用在gitk上。在項目工作目錄中輸入gitk命令后,就會啟動下圖所示的界面

  上半個窗口顯示的是歷次提交的分支祖先圖譜,下半個窗口顯示當前點選的提交對應的具體差異

 

撤銷操作

  任何時候,都有可能需要撤消剛才所做的某些操作。接下來,介紹一些基本的撤消操作相關的命令。請注意,有些撤銷操作是不可逆的,所以請務必謹慎小心,一旦失誤,就有可能丟失部分工作成果

【修改最后一次提交】

  有時候我們提交完了才發現漏掉了幾個文件沒有加,或者提交信息寫錯了。想要撤消剛才的提交操作,可以使用--amend選項重新提交:

$ git commit --amend

  此命令將使用當前的暫存區域快照提交。如果剛才提交完沒有作任何改動,直接運行此命令的話,相當於有機會重新編輯提交說明,但將要提交的文件快照和之前的一樣

  啟動文本編輯器后,會看到上次提交時的說明,編輯它確認沒問題后保存退出,就會使用新的提交說明覆蓋剛才失誤的提交

  如果剛才提交時忘了暫存某些修改,可以先補上暫存操作,然后再運行 --amend 提交:

$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

  上面的三條命令最終只是產生一個提交,第二個提交命令修正了第一個的提交內容

【取消已經暫存的文件】

  下面將演示如何取消暫存區域中的文件,以及如何取消工作目錄中已修改的文件。查看文件狀態的時候就提示了該如何撤消,所以不需要死記硬背

  來看下面的例子,有兩個修改過的文件,我們想要分開提交,但不小心用git add.全加到了暫存區域。該如何撤消暫存其中的一個文件呢?其實,git status的命令輸出已經告訴了我們該怎么做:

  在“Changes to be committed”下面,括號中有提示,可以使用git reset HEAD <file>...的方式取消暫存

【取消對文件的修改】

  如果覺得剛才對a.txt的修改完全沒有必要,該如何取消修改,回到之前的狀態(也就是修改之前的版本)呢?git status同樣提示了具體的撤消方法,接着上面的例子,現在未暫存區域看起來像這樣:

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   a.txt

  在第二個括號中,我們看到了拋棄文件修改的命令

  可以看到,該文件已經恢復到修改前的版本

  這條命令有些危險,所有對文件的修改都沒有了,因為我們剛剛把之前版本的文件復制過來重寫了此文件。所以在用這條命令前,請務必確定真的不再需要保留剛才的修改。如果只是想回退版本,同時保留剛才的修改以便將來繼續工作,以后會介紹

【總結】

  當文件被提交后(git commit),就無法撤銷了,只能使用--amend命令來修改提交說明,或增加要提交的文件

  當文件被提交前,如果想恢復文件內容,如果文件處於暫存區(stage),則需要先使用git reset HEAD <file>的方式取消暫存,然后再使用git checkout -- <file>的方式來恢復文件內容

 

使用遠程倉庫

  要參與任何一個Git項目的協作,必須要了解該如何管理遠程倉庫。遠程倉庫是指托管在網絡上的項目倉庫,可能會有好多個,其中有些你只能讀,另外有些可以寫。同他人協作開發某個項目時,需要管理這些遠程倉庫,以便推送或拉取數據,分享各自的工作進展。管理遠程倉庫的工作,包括添加遠程庫,移除廢棄的遠程庫,管理各式遠程庫分支,定義是否跟蹤這些分支等等

【查看當前的遠程庫】

  要查看當前配置有哪些遠程倉庫,可以用git remote命令,它會列出每個遠程庫的簡短名字。在克隆完某個項目后,至少可以看到一個名為origin的遠程庫,Git默認使用這個名字來標識你所克隆的原始倉庫:

 

  也可以加上 -v 選項(v為--verbose的簡寫,中文意思是冗長的),顯示對應的克隆地址:

  如果有多個遠程倉庫,此命令將全部列出

$ cd grit
$ git remote -v
bakkdoor  git://github.com/bakkdoor/grit.git
cho45     git://github.com/cho45/grit.git
defunkt   git://github.com/defunkt/grit.git
koke      git://github.com/koke/grit.git
origin    git@github.com:mojombo/grit.git

  這樣一來,就可以非常輕松地從這些用戶的倉庫中,拉取他們的提交到本地。請注意,上面列出的地址只有origin用的是SSH URL鏈接,所以也只有這個倉庫我能推送數據上去

【添加遠程倉庫】

  添加一個新的遠程倉庫,可以指定一個名字,以便將來引用,運行git remote add [shortname] [url]

  現在可以用字符串pb指代對應的倉庫地址了。比如說,要抓取所有Paul有的,但本地倉庫沒有的信息,可以運行git fetch pb:

  現在,Paul 的主干分支(master)已經完全可以在本地訪問了,對應的名字是 pb/master,你可以將它合並到自己的某個分支,或者切換到這個分支,看看有些什么有趣的更新

【從遠程倉庫抓取數據】

  正如之前所看到的,可以用下面的命令從遠程倉庫抓取數據到本地:

$ git fetch [remote-name]

  此命令會到遠程倉庫中拉取所有你本地倉庫中還沒有的數據。運行完成后,你就可以在本地訪問該遠程倉庫中的所有分支,將其中某個分支合並到本地,或者只是取出某個分支,一探究竟

  如果克隆了一個倉庫,此命令會自動將遠程倉庫歸於origin名下。所以,git fetch origin會抓取從你上次克隆以來別人上傳到此遠程倉庫中的所有更新(或是上次fetch以來別人提交的更新)。有一點很重要,fetch命令只是將遠端的數據拉到本地倉庫,並不自動合並到當前工作分支,只有當你確實准備好了,才能手工合並

  如果設置了某個分支用於跟蹤某個遠端倉庫的分支,可以使用git pull命令自動抓取數據下來,然后將遠端分支自動合並到本地倉庫中當前分支。在日常工作中我們經常這么用,既快且好。實際上,默認情況下git clone命令本質上就是自動創建了本地的master分支用於跟蹤遠程倉庫中的master分支(假設遠程倉庫確實有master分支)。所以一般我們運行git pull,目的都是要從原始克隆的遠端倉庫中抓取數據后,合並到工作目錄中的當前分支

【推送數據到遠程倉庫】

  項目進行到一個階段,要同別人分享目前的成果,可以將本地倉庫中的數據推送到遠程倉庫。實現這個任務的命令很簡單:git push [remote-name] [branch-name]。如果要把本地的master分支推送到origin服務器上(再次說明下,克隆操作會自動使用默認的master和origin名字),可以運行下面的命令

$ git push origin master

  只有在所克隆的服務器上有寫權限,或者同一時刻沒有其他人在推數據,這條命令才會如期完成任務。如果在你推數據前,已經有其他人推送了若干更新,那你的推送操作就會被駁回。你必須先把他們的更新抓取到本地,合並到自己的項目中,然后才可以再次推送

【查看遠程倉庫信息】

  我們可以通過命令git remote show [remote-name]查看某個遠程倉庫的詳細信息,比如要看所克隆的origin倉庫,可以運行:

  除了對應的克隆地址外,它還給出了許多額外的信息。它友善地告訴你如果是在master分支,就可以用git pull命令抓取數據合並到本地。另外還列出了所有處於跟蹤狀態中的遠端分支

  上面的例子非常簡單,而隨着使用Git的深入,git remote show給出的信息可能會像這樣:

$ git remote show origin
* remote origin
  URL: git@github.com:defunkt/github.git
  Remote branch merged with 'git pull' while on branch issues
    issues
  Remote branch merged with 'git pull' while on branch master
    master
  New remote branches (next fetch will store in remotes/origin)
    caching
  Stale tracking branches (use 'git remote prune')
    libwalker
    walker2
  Tracked remote branches
    acl
    apiv2
    dashboard2
    issues
    master
    postgres
  Local branch pushed with 'git push'
    master:master

  它告訴我們,運行git push時缺省推送的分支是什么(最后兩行)。它還顯示了有哪些遠端分支還沒有同步到本地(第六行的caching分支),哪些已同步到本地的遠端分支在遠端服務器上已被刪除(Stale tracking branches下面的兩個分支),以及運行git pull時將自動合並哪些分支(前四行中列出的issues和master分支)

【遠程倉庫的刪除和重命名】

  在新版Git中可以用git remote rename命令修改某個遠程倉庫在本地的簡稱,比如想把pb改成paul,可以這么運行:

$ git remote rename pb paul

  [注意]對遠程倉庫的重命名,也會使對應的分支名稱發生變化,原來的pb/master分支現在成了paul/master

  碰到遠端倉庫服務器遷移,或者原來的克隆鏡像不再使用,又或者某個參與者不再貢獻代碼,那么需要移除對應的遠端倉庫,可以運行git remote rm命令:

$ git remote rm paul


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM