在學習完本文以後,你應該可以配置並初始化一個倉庫(repository)、開始或中止跟蹤(track)文件、暫存(stage)或提交(commit)更改。 本章也將向你演示如何配置 Git 來忽略指定的文件和文件模式、如何迅速而簡單地撤銷錯誤操做、如何瀏覽你的項目的歷史版本以及不一樣提交(commits)間的差別、如何向你的遠程倉庫推送(push)以及如何從你的遠程倉庫拉取(pull)文件。html
當安裝完 Git 應該作的第一件事就是設置你的用戶名稱與郵件地址。 這樣作很重要,由於每個 Git 的提交都會使用這些信息,而且它會寫入到你的每一次提交中,不可更改:git
「Junk Chen」是你本身設置的名字,junkchen@vip.qq.com是你的郵箱地址。github
再次強調,若是使用了 –global 選項,那麼該命令只須要運行一次,由於以後不管你在該系統上作任何事情,Git 都會使用那些信息。當你想針對特定項目使用不一樣的用戶名稱與郵件地址時,能夠在那個項目目錄下運行沒有 –global 選項的命令來配置。正則表達式
不少 GUI 工具都會在第一次運行時幫助你配置這些信息。shell
若是想要檢查你的配置,可使用 git config –list 命令來列出全部 Git 當時能找到的配置。安全
你能夠經過輸入 git config : 來檢查 Git 的某一項配置:ruby
若你使用Git時須要獲取幫助,有三種方法能夠找到Git命令的使用手冊:bash
如想要得到config命令的手冊,可執行:服務器
$ git help config
這些命令很棒,由於你隨時隨地可使用而無需聯網。網絡
安裝和初始配置都已經設置好了,下面就來看看具體的應用了。
兩種獲取Git項目倉庫的方法: 一是在現有項目或目錄下導入全部文件到Git中; 二是從一個服務器克隆一個現有的Git倉庫。
進入該項目目錄並輸入:
$ git init
該命令將建立一個名爲 .git 的子目錄,這個子目錄含有你初始化的 Git 倉庫中全部的必須文件,這些文件是 Git 倉庫的骨幹。
若是你想得到一份已經存在了的Git倉庫的拷貝,可使用git clone [url]。
$ git clone https://github.com/libgit2/libgit2
該命令執行後會在當前目錄下建立一個名爲 「libgit2」 的目錄,並在在這個目錄下初始化一個.git文件夾,從遠程倉庫拉取全部的數據放在改文件夾,而後從中讀取最新版本的文件的拷貝。 若是你進入到這個新建的 libgit2 文件夾,你會發現全部的項目文件已經在裏面了,準備就緒等待後續的開發和使用。 請將 https://github.com/libgit2/libgit2 替換爲你本身的Git倉庫地址。
$ git clone https://github.com/libgit2/libgit2 mylibgit
這將執行與上一個命令相同的操做,不過在本地建立的倉庫名字變爲 mylibgit。
Git 支持多種數據傳輸協議。 上面的例子使用的是https:// 協議,不過你也可使用 git:// 協議或者使用SSH 傳輸協議,好比 user@server:path/to/repo.git 。
如今咱們有了一個真實項目的 Git 倉庫,並從這個倉庫中取出了全部文件的工做拷貝。 當咱們對文件作了些修改,在完成一個階段的目標後,就提交本次更新到倉庫。
請記住,你工做目錄下的每個文件都不外乎這兩種狀態:已跟蹤或未跟蹤。 已跟蹤的文件是指那些被歸入了版本控制的文件,在上一次快照中有它們的記錄,在工做一段時間後,它們的狀態可能處於未修改,已修改或已放入暫存區。 工做目錄中除已跟蹤文件之外的全部其它文件都屬於未跟蹤文件,它們既不存在於上次快照的記錄中,也沒有放入暫存區。 初次克隆某個倉庫的時候,工做目錄中的全部文件都屬於已跟蹤文件,並處於未修改狀態。
編輯過某些文件以後,因爲自上次提交後你對它們作了修改,Git 將它們標記爲已修改文件。 咱們逐步將這些修改過的文件放入暫存區,而後提交全部暫存了的修改,如此反覆。
查看文件處於什麼狀態:
$ git status
若是咱們的工做目錄中建立了新的文件,可以使用git add開始跟蹤一個文件。如跟蹤 READEME.txt 文件:
$ git add READEME.txt
此時再運行 git status 命令,會看到 README 文件狀態已發生改變。
git add 命令使用文件或目錄的路徑做爲參數;若是參數是目錄的路徑,該命令將遞歸地跟蹤該目錄下的全部文件。
當一個已被跟蹤的文件每次被修改後,須要使用 git add 把最新版本添加到暫存區方可進行提交更新,不然不會提交本次更改到倉庫中。如 READEME.txt 文件被修改後添加暫存:
$ git add READEME.txt
git add 是個多功能命令:能夠用它開始跟蹤新文件,或者把已跟蹤的文件放到暫存區,還能用於合併時把有衝突的文件標記爲已解決狀態等。可理解爲 「添加內容到下一次提交中」。
若是 git status 命令的輸出對於你來講過於模糊,你想知道具體修改了什麼地方,能夠用 git diff 命令。
$ git diff
此命令比較的是工做目錄中當前文件和暫存區域快照之間的差別, 也就是修改以後尚未暫存起來的變化內容。
若要查看已暫存的將要添加到下次提交裏的內容,能夠用 git diff –cached 命令。(Git 1.6.1 及更高版本還容許使用 git diff –staged,效果是相同的,但更好記些。)
git diff 自己只顯示還沒有暫存的改動,而不是自上次提交以來所作的全部改動。 因此有時候你一會兒暫
存了全部更新過的文件後,運行 git diff 後卻什麼也沒有,就是這個緣由。
當使用 git add 添加到暫存區後,就能夠提交到倉庫了。在此以前,請必定要確認還有什麼修改過的或新建的文件尚未 git add 過,不然提交的時候不會記錄這些尚未暫存起來的變化。這些修改過的文件只保留在本地磁盤。因此,每次準備提交前,先用 git status 看下,是否是都已暫存起來了,而後在運行提交命令 git commit :
$ git commit -m "Input your commit message"
使用 -m 選項,添加提交信息。
到此,使用 Git 就完成了,初始化倉庫、添加文件、提交更新到倉庫的全過程。
儘管使用暫存區域的方式能夠精心準備要提交的細節,但有時候這麼作略顯得繁瑣。 Git 提供了一個跳過使用暫存區域的方式,只要在提交的時候,給 git commit 加上 -a 選項,Git就會自動把全部已經跟蹤過的文件暫存起來一併提交,從而跳過 git add 步驟。
$ git commit -a -m "Commit message"
要從 Git 中移除某個文件,就必需要從已跟蹤文件清單中移除(確切地說,是從暫存區域移除),而後提交。 能夠用 git rm 命令完成此項工做,並連帶從工做目錄中刪除指定的文件,這樣之後就不會出如今未跟蹤文件清單中了。
$ git rm <finame>
下一次提交時,該文件就再也不歸入版本管理了。 若是刪除以前修改過而且已經放到暫存區域的話,則必需要用強制刪除選項 -f(譯註:即 force 的首字母)。 這是一種安全特性,用於防止誤刪尚未添加到快照的數據,這樣的數據不能被 Git 恢復。
另一種狀況是,咱們想把文件從 Git 倉庫中刪除(亦即從暫存區域移除),但仍然但願保留在當前工做目錄中。 換句話說,你想讓文件保留在磁盤,可是並不想讓 Git 繼續跟蹤。 當你忘記添加 .gitignore 文件,不當心把一個很大的日誌文件或一堆 .a 這樣的編譯生成文件添加到暫存區時,這一作法尤爲有用。 爲達到這一目的,使用 –cached 選項:
$ git rm --cached README
git rm 命令後面能夠列出文件或者目錄的名字,也可使用 glob 模式。 比方說:
$ git rm log/\*.log
注意到星號 * 以前的反斜槓 \, 由於 Git 有它本身的文件模式擴展匹配方式,因此咱們不用 shell 來幫忙展開。此命令刪除 log/ 目錄下擴展名爲 .log 的全部文件。 相似的好比:
$ git rm \*~
該命令爲刪除以 ~ 結尾的全部文件。
不像其它的 VCS 系統,Git 並不顯式跟蹤文件移動操做。 若是在 Git 中重命名了某個文件,倉庫中存儲的元數據並不會體現出這是一次更名操做。 不過 Git 很是聰明,它會推斷出究竟發生了什麼。
既然如此,當你看到 Git 的 mv 命令時必定會困惑不已。 要在 Git 中對文件更名,能夠這麼作:
$ git mv file_from file_to
它會恰如預期般正常工做。 實際上,即使此時查看狀態信息,也會明白無誤地看到關於重命名操做的說明:
其實,運行 git mv 就至關於運行了下面三條命令:
如此分開操做,Git 也會意識到這是一次更名,因此無論何種方式結果都同樣。 二者惟一的區別是,mv 是一條命令而另外一種方式須要三條命令,直接用 git mv 輕便得多。不過有時候用其餘工具批處理更名的話,要記得在提交前刪除老的文件名,再添加新的文件名。
通常咱們總會有些文件無需歸入 Git 的管理,也不但願它們總出如今未跟蹤文件列表。 一般都是些自動生成的文
件,好比日誌文件,或者編譯過程當中建立的臨時文件等。 在這種狀況下,咱們能夠建立一個名爲 .gitignore
的文件,列出要忽略的文件模式。 來看一個實際的例子:
第一行告訴 Git 忽略全部以 .o 或 .a 結尾的文件。第二行告訴 Git 忽略全部以波浪符(~)結尾的文件,許多文本編輯軟件(好比 Emacs)都用這樣的文件名保存副本。此外,你可能還須要忽略 log,tmp 或者 pid 目錄,以及自動生成的文檔等等。 要養成一開始就設置好.gitignore 文件的習慣,以避免未來誤提交這類無用的文件。
文件 .gitignore 的格式規範以下:
所謂的 glob 模式是指 shell 所使用的簡化了的正則表達式。
在提交了若干更新後,想回顧下提交歷史,可以使用 git log 命令。
$ git log
在任何一個階段,你都有可能想要撤消某些操做。 這裏,咱們將會學習幾個撤消你所作修改的基本工具。 注意,有些撤消操做是不可逆的。 這是在使用 Git 的過程當中,會由於操做失誤而致使以前的工做丟失的少有的幾個地方之一。
有時候咱們提交完了才發現漏掉了幾個文件沒有添加,或者提交信息寫錯了。 此時,能夠運行帶有 –amend 選項的提交命令嘗試從新提交:
$ git commit --amend
這個命令會將暫存區中的文件提交。 若是自上次提交以來你還未作任何修改(例如,在上次提交後立刻執行了此命令),那麼快照會保持不變,而你所修改的只是提交信息。
文本編輯器啓動後,能夠看到以前的提交信息。 編輯後保存會覆蓋原來的提交信息。
例如,你提交後發現忘記了暫存某些須要的修改,能夠像下面這樣操做:
最終你只會有一個提交 - 第二次提交將代替第一次提交的結果。
如何操做暫存區域與工做目錄中已修改的文件, 這些命令在修改文件狀態的同時,也會提示如何撤消操做。 例如,你已經修改了兩個文件而且想要將它們做爲兩次獨立的修改提交,可是卻意外地輸入了 git add * 暫存了它們兩個。 如何只取消暫存兩個中的一個呢? git status 命令提示了你:
在 「Changes to be committed」 文字正下方,提示使用 git reset HEAD … 來取消暫存。 因此,咱們能夠這樣來取消暫存 CONTRIBUTING.md 文件:
若是你並不想保留對 CONTRIBUTING.md 文件的修改怎麼辦? 你該如何方便地撤消修改 - 將它還原成上次提交時的樣子(或者剛克隆完的樣子,或者剛把它放入工做目錄時的樣子)? 幸運的是,git status 也告訴了你應該如何作。 在最後一個例子中,未暫存區域是這樣:
它很是清楚地告訴了你如何撤消以前所作的修改。 讓咱們來按照提示執行:
能夠看到那些修改已經被撤消了。
記住,在 Git 中任何 已提交的 東西幾乎老是能夠恢復的。 甚至那些被刪除的分支中的提交或使用 –amend 選項覆蓋的提交也能夠恢復。 然而,任何你未提交的東西丟失後極可能再也找不到了。
爲了能在任意 Git 項目上協做,你須要知道如何管理本身的遠程倉庫。遠程倉庫是指託管在因特網或其餘網絡中你的項目的版本庫。 與他人協做涉及管理遠程倉庫以及根據須要推送或拉取數據。
若是想查看你已經配置的遠程倉庫服務器,能夠運行 git remote 命令。 它會列出你指定的每個遠程服務器的簡寫。 若是你已經克隆了本身的倉庫,那麼至少應該能看到 origin ,這是 Git 給你克隆的倉庫服務器的默認名字:
可指定選項 -v,回顯示須要讀寫遠程倉庫使用的 Git 保存的與其對應的URL。
若還想要查看某個遠程倉庫的更多信息,可使用 git remote show [remote-name] 命令,如查看 origin :
$ git remote show origin
運行 git remote add < shortname > < url > 添加一個新的遠程Git 倉庫,同時指定一個你能夠輕鬆引用的簡寫:
$ git remote add pb https://github.com/paulboone/ticgit
如今能夠在命令行中使用字符串 pb 來代替整個 URL。若是你想獲取 Paul 的倉庫中有但你沒有的信息,能夠運行 git fetch pb:
$ git fetch pb
如上面所示,從遠程倉庫中獲取數據,能夠執行:
$ git fetch <remote-name>
這個命令會訪問遠程倉庫,從中拉取全部你尚未的數據。執行完成後,你將會擁有遠程倉庫中全部分支的引用,可隨時合併或查看。
若你使用 git clone 命令克隆一個倉庫,命令會自動將其添加爲遠程倉庫並默認以 「origin」 爲簡寫。 因此,git fetch origin 會抓取克隆(或上一次抓取)後新推送的全部工做。 必須注意 git fetch 命令會將數據拉取到你的本地倉庫,它並不會自動合併或修改你當前的工做。 當準備好時你必須手動將其合併入你的工做。
若是你有一個分支設置爲跟蹤一個遠程分支,可使用 git pull 命令來自動的抓取而後合併遠程分支到當前分支。 默認狀況下,git clone 命令會自動設置本地 master 分支跟蹤克隆的遠程倉庫的master 分支(或無論是什麼名字的默認分支)。運行 git pull 一般會從最初克隆的服務器上抓取數據並自動嘗試合併到當前所在的分支。
使用 git push [remote-name] [branch-name] 命令能夠推送到遠程倉庫。 當你想要將 master 分支推送到 origin 服務器時(再次說明,克隆時一般會自動幫你設置好那兩個名字),那麼運行這個命令就能夠將你所作的備份到服務器:
$ git push origin master
只有當你有所克隆服務器的寫入權限,而且以前沒有人推送過期,這條命令才能生效。 當你和其餘人在同一時間克隆,他們先推送到上游而後你再推送到上游,你的推送就會毫無疑問地被拒絕。 你必須先將他們的工做拉取下來並將其合併進你的工做後才能推送。(可先 pull 再 push )
若是想要重命名引用的名字能夠運行 git remote rename 去修改一個遠程倉庫的簡寫名。 例如,想要將 pb 重命名爲 paul,能夠用 git remote rename 這樣作:
值得注意的是這一樣也會修改你的遠程分支名字。 那些過去引用 pb/master 的如今會引用 paul/master。
若是由於一些緣由想要移除一個遠程倉庫,你已經從服務器上搬走了或再也不想使用某一個特定的鏡像了,又或者某一個貢獻者再也不貢獻了 - 可使用 git remote rm :
git pull origin xf:xf
git push origin xf:xf
git push origin test