文章目錄
PHP技術交流群 170855791
擷取GIT倉庫
這裡有2種方法可以擷取git倉庫。將一個本地已經存在的項目或檔案夾匯入到Git中;或者clone一個遠程伺服器上已經存在的Git倉庫
初始化一個已經存在的檔案夾
要想將一個本地項目添加到git版本庫中,需要做的就是進入到這個檔案夾中,輸入下面的命令:
$git init
這個命令會在該項目的檔案夾中建立一個叫.git的子檔案夾,即本地git倉庫目錄,這是Git倉庫的基礎檔案,用來儲存中繼資料和對象資料。
當你開始想要使用版本控制器管理一個存在的項目時,你應當先跟蹤這個項目裡的檔案,之後提交這些檔案。可以使用一條或者多條git add命令來指定你想要放入暫存區中的檔案,如:
$git add *.c$git add README$git commit -m 'inital project version'
複製一個已經存在的git資料倉儲
複製一個遠端資料倉庫,需要使用git clone命令,該命令會將遠程倉庫裡的全部內容複製下來(但不包括.git/config以及gitignore檔案),包括不同版本的相同檔案。複製的完整命令為:$git clone [url],例如:
$git clone git://github.com/schacon/grit.git
使用上條命令後即可建立一個名為grit的目錄,其中包含了一個已經初始化好的.git檔案夾,以及所有的專案檔。如果你想把複製的檔案儲存為另一個檔案名稱,可以使用下面的命令:
$git clone git://github.com/schacon/grit.git mygrit
這條命令將會建立一個mygrit的檔案夾,並將複製下來的所有檔案放到該檔案夾下。
Tips:Git支援多種傳輸協議。上面的例子中使用的是git協議,你也可以使用http協議,SSH協議等等。
記錄Git倉庫的變更資訊
假設現在你已經擁有一個完整的git資料倉儲,當你每次需要修改一些專案檔並將這些修改快照提交到你的git資料倉儲中時,git都會擷取一個項目狀態資訊並將其記錄下來。
需要注意的是:在你的工作目錄中每個檔案都屬於下面2種狀態之一:被跟蹤和未被跟蹤。被追蹤檔案儲存在最後的快照中,未被跟蹤的檔案存在工作目錄中,但是它們沒有被載入到你的最後快照中,也沒有被載入到暫存區中,不參與版本控制。通過git add和git commit命令可以將它置入跟蹤庫中。被跟蹤的檔案有3種狀態:
unmodify:檔案已經存在庫中,未修改,即版本庫中的檔案快照內容與工作目錄中的檔案內容完全一致。這種類型的檔案有兩個去處,如果它被修改,而成為modified。如果使用”git rm”移出版本庫,則成為untracked檔案。
modified:檔案已修改,僅僅是修改,並沒有進行其它操作。這個檔案也有兩個去處,通過”git add”可進入暫存(staged)狀態,使用”git checkout”則丟棄修改,返因到unmodify狀態。這個checkout很好理解,就是取出庫中檔案,覆蓋當前檔案吧。
staged:暫存狀態。執得”git commit”則將修改同步到庫中,這時庫中的檔案與本地檔案又一致了,於是檔案是unmodify狀態。執行”git reset HEAD filenam”取消暫存,檔案狀態變為modified。
查看檔案狀態
查看檔案狀態的主要工具就是git的status命令,該命令會將工作目錄中的檔案與暫存區中的檔案進行對比後,將結果輸出到螢幕上。
$git status
該命令會列出當前項目中被追蹤檔案的變動資訊和狀態,同時也會列出未被跟蹤的檔案。在所列出的資訊中第一條資訊:On branch master說明你當前所使用的分支為:master。這是一個預設分支,有關分支的資訊在這裡就不做說明了。
該命令有一個常用參數--p,列出狀態資訊的簡寫形式。
$ git status -s
AM README
A hello.rb
跟蹤新檔案(添加到暫存區)
git中,在你使用提交命令commit之前,必須先要使用add命令,將該檔案添加到暫存區中,如果是新建立的檔案,也需要使用add命令將該檔案初始化並添加到暫存區中。如在工作目錄中建立立一個名為README的檔案,查看檔案狀態:
$ git status
顯示出如下資訊:
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# README
把它添加到暫存區中。
$git add README
此時在查看git版本庫的檔案狀態,就會看到如下資訊:
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached ..." to unstage)
#
# new file: README
#
如果此時提交,曆史快照中將會記錄檔案被add時的版本資訊。此外,如果add的是一個目錄名,那麼該目錄下的所有檔案都會被跟蹤添加到暫存區。使用 git add . 命令可以將當前工作目錄中的所有檔案遞迴的添加到暫存區中,同時也可以使用git add *,但是git add * 不會將子目錄下的檔案遞迴的添加到暫存區中。
記錄檔案修改資訊
假如此時你的項目中還有一個名為benchmarks.rb的檔案,並確定該檔案已經被跟蹤,此時對該檔案做一些修改,在查看檔案狀態,會列出類似下列的資訊
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: README
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: benchmarks.rb
#
benchmarks.rb資訊出現在Changed but not updated下面的地區中,檔案名稱前面顯示有modified的字樣,說明該檔案已經被修改過,但是還沒有被暫存。此時你運行git add命令將修改後的benchmarks.rb提交到暫存區後,再次執行git status命令:
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: README
# modified: benchmarks.rb
#
這2個檔案已經全部被提交到暫存區中,此時你在執行commit命令時,這2個檔案就會被全部提交到版本庫中。但是注意:如果在你使用commit命令之前又一次修改了benchmarks.rb檔案,此時在來看看檔案狀態:
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: README
# modified: benchmarks.rb
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: benchmarks.rb
#
簡寫資訊為:
$ git status -s
MM benchmarks.rb
A README
你會發現此時benchmarks.rb同時出現在2個狀態列中,這是為什麼呢?事實上當你使用add命令時,git會將檔案添加到暫存區中,commit命令是將暫存區中的內容儲存到git版本庫中,如果此時使用commit命令,實際上提交的將是上一次被add的檔案,而不是現在已經有過第二次修改的新檔案,所以在提交之前還要對該檔案再次使用add命令。
忽略指定檔案
有些時候你會希望git忽略掉某些你不想提交的檔案,或者不想在查看檔案狀態時顯示這些檔案,例如項目中產生的臨時檔案以及記錄檔等等,此時你就需要建立一個名為".gitignore"的檔案,將你想要讓git忽略的檔案記錄到該檔案中,如:
*.[oa] 這句話告訴git將忽略所有以.o或.a結尾的檔案
*~ 這句話告訴git將忽略所有以~為結尾的檔案
!lib.a # 但 lib.a 除外
/TODO # 僅僅忽略項目根目錄下的 TODO 檔案,不包括 subdir/TODO
build/ # 忽略 build/ 目錄下的所有檔案
doc/*.txt # 會忽略 doc/notes.txt 但不包括 doc/server/arch.txt
*.log 這句話告訴git將忽略所有以.log為結尾的檔案
查看被暫存檔案和未被暫存檔案的變更資訊
如果你覺得git status命令顯示的資訊太模糊,不能確切的顯示出你想要查看的具體的修改資訊,此時就可以使用 git diff命令。
預設情況下該命令會將工作目錄中的檔案與git倉庫中的檔案進行對比,這裡有幾個重要的選項:
--cached 將暫存區中的檔案與git倉庫中的檔案進行對比
HEAD 用來查看所有狀態的檔案的更改資訊
--stat 顯示精簡資訊
提交你的修改
當你修改好檔案後,通過git add命令將這些檔案的快照資訊存入暫存區,就可以使用commit命令將檔案提交到git倉庫中。這裡需要注意:任何你新增加的檔案或者修改過的檔案都不會被自動放到暫存區中,而commit命令只會提交暫存區中的檔案,因此不用忘記使用add命令將檔案添加到暫存區中。
$git commit
當執行完上面命令後,系統會為你開啟一個你設定好的檔案編譯器(通過$EDITER環境變數設定,如果沒有設定過則開啟系統的預設編譯器),將你需要添加的提交資訊從編譯器頂部開始添加,其中以‘#’開頭的行將會被忽略,不會被記錄進去,此外git還會將git status命令資訊自動輸入到該編譯器中供你參考,輸入好之後退出編譯器,即可完成提交(注意:如果你在編譯器中沒有輸入任何內容而直接退出,那麼本次提交將會失敗)。另外你也可以使用-m參數在命令中直接添加提交資訊,如:$git commit -m 'My Commit'。該命令還有一個重要的參數:-a。使用該參數後可以不用使用add命令將檔案添加到暫存區中,它會自動將所有改動過的被跟蹤的檔案全部提交,包括子檔案夾中的檔案也會被遞迴提交,但是對於建立的檔案你還是需要使用git add將該檔案進行跟蹤後才可以提交。完成提交後系統會輸出本次提交的一些簡單資訊。
移除檔案
如果你想將某個檔案從git倉庫中移除,可以使用git rm命令來實現,該命令將檔案從暫存區中刪除,當你下次commit後就會將該檔案從git資料倉儲中刪除掉,需要注意的是,使用該命令後,同時會將該檔案從你的工作目錄中刪除,可以為該命令添加一個--cached參數來防止刪除工作目錄中的檔案,但是該檔案會變為untracked狀態。如果你只是簡單的將檔案從工作目錄中刪除,當你執行git status命令查看檔案狀態時,你會發現該檔案在“change but not updateed”的地區下,此時你還是需要使用git rm命令將該檔案從暫存區中刪除並將其狀態更改為untranked。
同時git還支援使用萬用字元進行大量刪除檔案,例如:
$git rm log/\*.log 此處\為轉移字元,是必不可少的,該命令會刪除log檔案夾下的所有以.log結尾的檔案
$git rm \*~ 這條命令將會刪除所有以~結尾的檔案。
移動檔案
不像其它版本控制器那樣,git不支援檔案的重新命名,如果你嘗試為一個檔案重新命名,git不會儲存任何能夠通知你檔案有過重新命名操作的資訊。但是你可以使用mv命令來為檔案重新命名,如:
$git mv file_from file_to
事實上,使用次條命令重新命名一個檔案後,查看檔案狀態時,系統會顯示rename。
查看曆史提交記錄
git log命令用來查看commit提交記錄資訊,當你在有過提交記錄的git倉庫中使用該命令後,系統會列出會出現類似下面這樣的資訊:
commit 237c9d08a266cbcf9876843152e395ff1c47336b
Author: gbyukg <gbyukg@163.com>
Date: Thu Dec 1 14:55:21 2011 +0800
first
預設情況下,系統會按照提交時間由大到小的順序排列出來,其中這4行分別對應的是:
commit的檔案經過SHA-1 checksum 後所產生的40位編碼
本次提交的作者姓名以及郵箱
提交日期
提交時輸入的資訊
git log命令包含大量的複雜的選項,能夠讓你找出任何你想要的資訊,這裡介紹幾個主要的參數:
-p :它可以列出每次提交時檔案所做的修改的詳細資料,同時後面可以追加一個 -n(n為任意一個正整數)參數,該參數用來顯示最近n次的修改資訊,若n為0將不顯示任何資訊,如果n大於提交過的此時,則將所有提交資訊全部顯示出來。例:$git log -p -2 顯示最近2次提交的資訊。
--stat: 它可以將提交資訊簡化的顯示出來
--pretty: 按照指定格式顯示出日誌資訊,這裡有一些預設好的選項可供使用:oneling、short、full和fuller等等,如:git log -pretty=oneline。但是更有趣的選項是formate,它可以讓你按照自己指定的格式輸出日後資訊,例:$git log --pretty=format:"%h - %an , %ar : %s"。下面列出了format中的選項以及含義:
%H commit的雜湊值(SHA-1)
$h commit的雜湊值的縮寫(前七位)
%T 工作樹的雜湊值
$t 工作樹的簡寫雜湊值
$an 項目作者姓名
$ae 項目作者e-mail
$ad 做成日期
$ar 做成日期(小時制)
$cn 提交者姓名
$ce 提交者e-mail
$cd
$cr
$s 提交注釋
--shortstat 只是將--stat命令中的changed/deletions/insertions的資訊顯示出來
--name-only 顯示被更改過的檔案資訊列表
--name-status 顯示added/modifide/deleted的檔案資訊
--graph 以簡單的表徵圖形式顯示你的分支和合并記錄,如:$ git log --oneline --graph
擷取你想要的日誌資訊
git log命令中不僅包含了格式化輸出日誌的資訊,還提供了一些限制選項,這些選項可以減少日誌條數,事實上你可以直接使用-n選項,其中n是一個正整數,顯示最近的n條日誌記錄。
此外還有一些時間限制的選項,如--since和--until,這些選項將會非常有用。例如,下面的命令將會顯示過去2周內所發生的事情:
$ git log --since=2.weeks
這條命令提供了許多預設好的格式,你可以指明一個特定的日期("2011-11-04")或者一個類似於"2 years 3 day 5 minutes ago"的格式。
同時你也可以通過過濾將與你的查詢想匹配的資訊顯示出來。--author 選項允許你檢索出指定作者的資訊,--prep 選項允許你通過搜尋提交資訊中的關鍵字來顯示資訊。注意:如果你想同時使用--author和--prep選項,你必須在額外的添加一個--all-match選項,否則系統只會列出符合這2個條件中的一個條件的資訊
你也可以向git傳遞一個路徑,如果你指定了一個檔案夾或檔案,就可以限制系統只顯示這些檔案的一些變更資訊,通常該選項應當被放到最後的選項中,同時應當有2個-在檔案名稱前來將檔案名稱從選項中分離出來。
$ git log --pretty="%h:%s" --author=gitster --sincd="2010-10-01" --before="2011-11-01" --no-merges --t
git撤銷操作
更改最後一次提交:
當你使用commit命令後發現忘記了將其它修改過的檔案也一起提交到git資料倉儲中,或者提交的檔案需要再次修正一下才可以提交,或者在提交時輸入了錯誤的提交資訊,此時你就可是使用 $git commit --amend命令進行重新提交,這條命令會使用暫存區中的問進當作此次提交的內容,如果在上次提交過後暫存區中的內容沒有發生任何變化,那麼修改的只是提交資訊。使用該命令後,系統會再次開啟編譯器,此時編譯器中會顯示出你上次提交是所輸入的提交資訊,修改過提交資訊後儲存退出即可。
刪除暫存區中的檔案
當你使用add命令將檔案添加到暫存區後,發現某些檔案不需要提交,此時你希望將該檔案從暫存區中刪除,這是你可以使用 $git reset HEAD 該命令會將指定的file將暫存區中刪除,如果沒有指定file,則清空暫存區。
撤銷修改過的檔案
當你在工作目錄中修改完成一個檔案時,由於某些原因想要撤銷對這些檔案的修改,可以使用命令: $ git checkout filename 該命令會將檔案撤銷到上一次將對該檔案commit時的狀態。注意:該命令只能撤銷沒有被添加到暫存區中的檔案,如果想對某個已經使用add命令添加到暫存區中檔案進行撤銷,需要先使用git reseat HEAD 命令將該檔案從暫存區中刪除。
修複已提交檔案中的錯誤
如果你已經做了一個提交(commit),但是你馬上後悔了, 這裡有兩種截然不同的方法去處理這個問題:
1 建立一個新的提交(commit), 在新的提交裡撤消老的提交所作的修改. 這種作法在你已經把代碼發布的情況下十分正確.
2 你也可以去修改你的老提交(old commit). 但是如果你已經把代碼發布了,那麼千萬別這麼做; git不會處理項目的曆史會改變的情況,如果一個分支的曆史被改變了那以後就不能正常的合并.
建立新提交來修複錯誤
建立一個新的,撤消(revert)了前期修改的提交(commit)是很容易的; 只要把出錯的提交(commit)的名字(reference)做為參數傳給命令: git revert就可以了; 下面這條命令就示範了如何撤消最近的一個提交:
$ git revert HEAD
這樣就建立了一個撤消了上次提交(HEAD)的新提交, 你就有機會來修改新提交(new commit)裡的提交注釋資訊.
你也可撤消更早期的修改, 下面這條命令就是撤消“上上次”(next-to-last)的提交:
$ git revert HEAD^
在這種情況下,git嘗試去撤消老的提交,然後留下完整的老提交前的版本. 如果你最近的修改和要撤消的修改有重疊(overlap),那麼就會被要求手工解決衝突(conflicts), 就像解決合并(merge)時出現的衝突一樣.
譯者注: git revert 其實不會直接建立一個提交(commit), 把撤消後的檔案內容放到索引(index)裡,你需要再執行git commit命令,它們才會成為真正的提交(commit).
修改提交來修複錯誤
如果你剛剛做了某個提交(commit), 但是你又想馬上修改這個提交; git commit 現在支援一個叫--amend的參數,它能讓你修改剛才的這個提交(HEAD commit). 這項機制能讓你在代碼發布前,添加一些新的檔案或是修改你的提交注釋(commit message).
如果你在老提交(older commit)裡發現一個錯誤, 但是現在還沒有發布到代碼伺服器上. 你可以使用 git rebase命令的互動模式, "git rebase -i"會提示你在編輯中做相關的修改. 這樣其實就是讓你在rebase的過程來修改提交.