Git Pro讀書筆記-2-操做

1.取得項目的Git倉庫

1. 從當前目錄初始化:

git init

初始化後,在當前目錄下會出現一個名爲.git的目錄git

2. 將文件歸入版本控制:

git add *.c
$ git add README
$ git commit -m 'initial project version'

3. 從現有的倉庫克隆:

若是想對某個開源項目出一份力,能夠先把該項目的 Git 倉庫複製一份出來,這就須要用到 git clone命令。github

Git 收取的是項目歷史的全部數據(每個文件的每個版本),服務器上有的數據克隆以後本地也都有了。實際上,即使服務器的磁盤發生故障,用任何一個克隆出來的客戶端均可以重建服務器上的倉庫,回到當初克隆時的狀態(可能會丟失某些服務器端的掛鉤設置,但全部版本的數據仍舊還在,有關細節請參考第四章)。shell

克隆倉庫的命令格式爲:
git clone [url] git clone git://github.com/schacon/grit.git編程

若是但願在克隆的時候,本身定義要新建的項目目錄名稱,能夠在上面的命令最後指定:服務器

git clone [url] [document] git clone git://github.com/schacon/grit.git mygrit網絡

4. 提交更新到倉庫

工做目錄下面的全部文件都不外乎這兩種狀態:
- 已跟蹤:已跟蹤的文件是指原本就被歸入版本控制管理的文件,在上次快照中有它們的記錄,工做一段時間後,它們的狀態多是未更新,已修改或者已放入暫存區。
- 未跟蹤:而全部其餘文件都屬於未跟蹤文件。它們既沒有上次更新時的快照,也不在當前的暫存區域。fetch

工做目錄中的全部文件都屬於已跟蹤文件,且狀態爲未修改。url

圖片描述

5. 檢查當前文件狀態

git status

6. 跟蹤新文件

git add README

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

git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: README
#

git add 後能夠接要跟蹤的文件或目錄的路徑。若是是目錄的話,就說明要遞歸跟蹤全部該目錄下的文件。3d

7. 暫存已修改的文件

  1. 首先咱們先add一個文件:
    git add benchmarks.rb $ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: README # modified: benchmarks.rb
  2. 再修改它
  3. 而後執行git staus查看:

    gitOn 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)
    
    modified: benchmarks.rb

8. 查看已暫存和未暫存的更新

git diff 會使用文件補丁的格式顯示具體添加和刪除的行

此命令比較的是工做目錄中當前文件和暫存區域快照之間的差別,也就是修改以後尚未暫存起來的變化內容。

若要看已經暫存起來的文件和上次提交時的快照之間的差別,能夠用 git diff --cached 命令。( Git 1.6.1 及更高
版本還容許使用 git diff --staged,效果是相同的,但更好記些。)

請注意,單單 git diff 不過是顯示尚未暫存起來的改動,而不是此次工做和上次提交之間的差別。因此有時候你
一會兒暫存了全部更新過的文件後,運行 git diff 後卻什麼也沒有,就是這個緣由。

9. 提交更新

因此,每次準備提交前,先用 git status 看下,是否是都
已暫存起來了,而後再運行提交命令 git commit:

git commit

記住,提交時記錄的是放在暫存區域的快照,任何還未暫存的仍然保持已修改狀態,能夠在下次提交時歸入版本管
理。每一次運行提交操做,都是對你項目做一次快照,之後能夠回到這個狀態,或者進行比較。

10. 跳過使用暫存區域

只要在提交的時候,給 git commit 加上 -a 選項, Git 就會自動把全部已經跟蹤過的文件暫存起來一併提
交,從而跳過 git add 步驟:

git commit -a -m 'added new benchmarks'

11. 移除文件

要從 Git 中移除某個文件,就必需要從已跟蹤文件清單中移除(確切地說,是從暫存區域移除),而後提交。能夠用git rm 命令完成此項工做,並連帶從工做目錄中刪除指定的文件,這樣之後就不會出如今未跟蹤文件清單中了。
若是隻是簡單地從工做目錄中手工刪除文件,運行 git status 時就會在 「 Changed but not updated」 部分。

git rm

最後提交的時候,該文件就再也不歸入版本管理了。若是刪除以前修改過而且已經放到暫存區域的話,則必需要用強制
刪除選項 -f(譯註:即 force 的首字母),以防誤刪除文件後丟失修改的內容。

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

git rm --cached readme.txt

後面能夠列出文件或者目錄的名字,也可使用 glob 模式。比方說:

git rm log/\*.log

按照 shell 擴展的話,僅僅刪除指定目錄下的文件而不會遞歸匹配。
此命令刪除所
有 log/ 目錄下擴展名爲 .log 的文件。相似的好比:

git rm \*~

會遞歸刪除當前目錄及其子目錄中全部 ~ 結尾的文件。

12.移動文件

不像其餘的 VCS 系統, Git 並不跟蹤文件移動操做。若是在 Git 中重命名了某個文件,倉庫中存儲的元數據並不會體現出這是一次更名操做。不過 Git 很是聰明,它會推斷出究竟發生了什麼,至於具體是如何作到的,咱們稍後再談。
既然如此,當你看到 Git 的 mv 命令時必定會困惑不已。要在 Git 中對文件更名,能夠這麼作:

git mv file_from file_to

其實,運行 git mv 就至關於運行了下面三條命令:

mv README.txt README
git rm README.txt
git add README

13. 查看提交歷史

git log

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

git log –p -2

此外,還有許多摘要選項能夠用,好比 --stat,僅顯示簡要的增改行數統計:

git log --stat

還有個經常使用的 --pretty 選項,能夠指定使用徹底不一樣於默認格式的方式展現提交歷史。好比用 oneline 將每一個提
交放在一行顯示,這在提交數很大時很是有用。另外還有 short, full 和 fuller 能夠用,展現的信息或多或少有
些不一樣,請本身動手實踐一下看看效果如何。

git log --pretty=oneline

但最有意思的是 format,能夠定製要顯示的記錄格式,這樣的輸出便於後期編程提取分析,像這樣:

git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 11 months ago : changed the verison number
085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code
a11bef0 - Scott Chacon, 11 months ago : first commit
選項 說明
**%H** 提交對象(commit)的完整哈希字串
**%h** 提交對象的簡短哈希字串
**%T** 樹對象(tree)的完整哈希字串
**%t** 樹對象的簡短哈希字串
**%P** 父對象(parent)的完整哈希字串
**%p** 父對象的簡短哈希字串
**%an** 做者(author)的名字
**%ae** 做者的電子郵件地址
**%ad** 做者修訂日期(能夠用 -date= 選項定製格式)
**%ar** 做者修訂日期,,,按多久之前的方式顯示
**%cn** 提交者(committer)*的名字
**%ce** 提交者的電子郵件地址
**%cd** 提交日期
**%cr** 提交日期,按多久之前的方式顯示
**%s** 提交說明

你必定奇怪做者(author) 和提交者(committer) 之間究竟有何差異,其實做者指的是實際做出修改的人,提交者指的
是最後將此工做成果提交到倉庫的人。因此,當你爲某個項目發去補丁,而後某個核心成員將你的補丁併入項目時,
你就是做者,而那個核心成員就是提交者。咱們會在第五章再詳細介紹二者之間的細緻差異。

14. 撤銷操做

修改最後一次提交

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

git commit --amend
取消已經暫存的文件
git reset HEAD benchmarks.rb
取消對文件的修改
git checkout -- benchmarks.rb

因此在用這條命令前,請務必肯定真的再也不須要保留剛纔的修改。若是隻是想回退版本,同時保留剛纔的修改以便未來繼續工做,能夠用下章介紹的 stashing 和分支來處理,應該會更好些。

15. 遠程倉庫的使用

遠程倉庫是指託管在網絡上的項目倉庫,可能會有好多個,其中有些你只能讀,另外有些能夠寫。同他人協做開發某個項目時,須要管理這些遠程倉庫,以便推送或拉取數據,分享各自的工做進展。

查看當前的遠程倉庫

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

git clone git://github.com/schacon/ticgit.git

也能夠加上 -v 選項(譯註:此爲 --verbose 的簡寫,取首字母),顯示對應的克隆地址:

git remote -v
origin git://github.com/schacon/ticgit.git
添加遠程倉庫
git remote add [shortname]
git remote add pb git://github.com/paulboone/ticgit.git

如今能夠用字串 pb 指代對應的倉庫地址了。好比說,要抓取全部 Paul 有的,但本地倉庫沒有的信息,能夠運行 git fetch pb:

git fetch pb
remote: Counting objects: 58, done.
remote: Compressing objects: 100% (41/41), done.
remote: Total 44 (delta 24), reused 1 (delta 0)
Unpacking objects: 100% (44/44), done.
From git://github.com/paulboone/ticgit
* [new branch] master -> pb/master
* [new branch] ticgit -> pb/ticgit
從遠程倉庫抓取數據
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]
git remote show origin
* remote origin
URL: git://github.com/schacon/ticgit.git
Remote branch merged with 'git pull' while on branch master
master
Tracked remote branches
master
ticgit
遠程倉庫的刪除和重命名

在新版 Git 中能夠用 git remote rename 命令修改某個遠程倉庫的簡短名稱,好比想把 pb 改爲 paul,能夠這麼
運行:

$ git remote rename pb paul
$ git remote
origin
paul

注意,對遠程倉庫的重命名,也會使對應的分支名稱發生變化,原來的 pb/master 分支如今成了 paul/master。
碰到遠端倉庫服務器遷移,或者原來的克隆鏡像再也不使用,又或者某個參與者再也不貢獻代碼,那麼須要移除對應的遠端倉庫,能夠運行 git remote rm 命令:

$ git remote rm paul
$ git remote
origin

16. 打標籤

列出現有標籤:
git tag

咱們能夠用特定的搜索模式列出符合條件的標籤:

git tag -l 'v1.4.2.*'
新建標籤:
  • 輕量級的( lightweight):就是個指向特定提交對象的引用
  • 含附註的( annotated):存儲在倉庫中的一個獨立對象,它有自身的校驗和信息,包含着標籤的名字,電子郵件地址和日期,以及標籤說明,

通常咱們都建議使用含附註型的標籤,以便保留相關信息;

含附註的標籤:

建立一個含附註類型的標籤很是簡單,用 -a (譯註:取 annotated 的首字母)指定標籤名字便可:

git tag -a v1.4 -m 'my version 1.4'

而 -m 選項則指定了對應的標籤說明, Git 會將此說明一同保存在標籤對象中。若是在此選項後沒有給出具體的說明內容, Git 會啓動文本編輯軟件供你輸入。

可使用 git show 命令查看相應標籤的版本信息,並連同顯示打標籤時的提交對象。

git show v1.4
簽署標籤:

只須要把以前的 -a 改成 -s

git tag -s v1.5 -m 'my signed 1.5 tag'
輕量級標籤

輕量級標籤實際上就是一個保存着對應提交對象的校驗和信息的文件。

git tag v1.4-lw
驗證標籤
git tag -v v1.4.2.1
後期加註標籤
git log --pretty=oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
4682c3261057305bdd616e23b64b0857d832627b added a todo file
166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme

咱們忘了在提交 「 updated rakefile」 後爲此項目打上版本號 v1.2,不要緊,如今也能作。只要在打標籤的時候跟上對應提交對象的校驗和(或前幾位字符)便可:

git tag -a v1.2 9fceb02
分享標籤

默認狀況下, git push 並不會把標籤傳送到遠端服務器上,只有經過顯式命令才能分享標籤到遠端倉庫。其命令格
式如同推送分支,運行 git push origin [tagname] 便可:

git push orign v1.5

若是要一次推送全部(本地新增的)標籤上去,可使用 --tags 選項:

git push origin --tags
相關文章
相關標籤/搜索