1. 程式人生 > 實用技巧 >git 學習筆記 - git add/commit/log 等基本操作介紹

git 學習筆記 - git add/commit/log 等基本操作介紹

  這裡是將原來的兩篇博文做了拆分.感覺之前一篇文章中涵蓋的東西太多,看起來容易讓人失去信心,主題也不是很明確.經過拆分後,這篇文章主要記錄 git 進行本地操作時的基本命令,包括 git add/commit/log等,也就是介紹涉及本地修改/提交等操作的命令.關於git 中倉庫和檔案狀態的基本概念可以參見拆分出來的另一篇博文git 學習記錄—— git 中的倉庫、檔案狀態等概念介紹.  

  git 本地操作命令

    git status

    git add

    git commit

    git rm

    git log

    git diff

  git 設定

  git 本地操作命令

  git status —— 檢視檔案狀態

  通過 git status 檢視當前目錄下各個檔案的狀態。git status 還會給出各種狀態下檔案可以使用的操作指令。

    git status          //檢視當前資料夾下各個檔案的狀態
    git status -s       //檢視各檔案狀態,使用字母簡單表示檔案狀態

  一個 git 倉庫下檔案的狀態主要有 (對應git 學習記錄—— git 中的倉庫、檔案狀態等概念介紹):

  Untracked files : 對應並未被 git 追蹤記錄的檔案,當通過 git init 初始化一個目錄時,是初始化了一個空的 git 目錄,所有該目錄下的檔案均處於未被 git 追蹤記錄的狀態。新建檔案的狀態也屬於此類;

  changes not staged for commit : 僅限於已經被 git 追蹤記錄( tracked )的檔案。若這些檔案發生了修改,但還沒有被通過 git add 加入需要進行提交的狀態( staged ),則處於此狀態;

  changes to be committed : 僅限於已經被 git 追蹤記錄( tracked )的檔案。當這些檔案發生了修改,且已經通過 git add 加入需要進行提交的狀態,則處於此狀態。通過 git commit 提交的修改即為處於該狀態的檔案的修改;

  筆者進行實踐時新建 test 目錄,其中僅包含一個 hello.cpp 檔案,在通過 git init 初始化後,即生成一個空的 git repository,git status 的結果如下圖,可以看到此時的 hello.cpp 處於 Untracked 狀態。

  

  git add —— 新增檔案至待修改狀態

  通過 git add 新增檔案至待提交的狀態( changes to be committed )。git add 主要有兩個功能: a.將未被 git 追蹤記錄( untracked )的檔案"加入" git 倉庫的記錄中; b.將處於 changes not staged for commit 狀態下的檔案的修改新增至需要進行提交的狀態( staged )。這兩個功能均會將檔案變為 changes to be committed 狀態。

    git add file-list        //將 file-list 指定的檔案新增至 changes to be committed 狀態
    git add .                //將當前目錄下所有的檔案新增至 changes to be committed 狀態

  使用者可通過 git add 命令將當前目錄下處於 untracked 狀態下的檔案"新增"至 git 倉庫中。在筆者的實踐中,即通過 git add hello.cpp 將 hello.cpp 加入 changes to be committed 狀態,也可使用 git add . 命令將當前目錄下所有檔案變為 changes to be committed 狀態。

  git commit —— 提交修改至倉庫

  通過指令 git commit 提交所有處於 staged 狀態的檔案。注意使用上述命令只會提交使用 git add 命令標記為 staged 狀態的檔案

  通過指令 git commit 提交時 Git 會通過預設編輯器顯示一個編輯介面,使用者需編輯提交資訊(commit message),用於標識該次提交。其中 # 開始的行表示註釋,使用者編輯結束退出後,Git會使用該提交資訊建立新的提交(即生成新的快照)。預設的顯示內容包括最近一次 git status 命令顯示的結果(註釋),使用提交時加入引數 -v 則會將 git diff 指令的結果也包含在顯示內容中,使用者可以通過取消註釋或編輯新內容來修改提交資訊( Ubuntu 系統下執行結果 )。

  使用者也可以使用 git commit -m "commit message" 命令來直接指定提交資訊,可用於提交流程更簡潔的情況。

    git commit -m "test"        //使用提交資訊 "test" 提交所有 staged 的修改
    git commit --allow-empty    //允許無內容的提交
    git commit -am "test"       //直接將所有被修改的檔案提交,相當於先 git add 再 commit

  注意:git commit 儲存的資料僅儲存在本地倉庫中,若需要同步至遠端倉庫,需要使用 git 支援的遠端倉庫操作。同時,第一次使用 git commit 進行提交時需要設定好使用者的使用者名稱和郵箱,可以檢視後文的git 設定部分。

  

  git rm —— 刪除對檔案的追蹤

  在 git 中,刪除一個檔案包括取消檔案的 tracked 狀態,之後再進行提交,可通過命令 git rm 完成上述操作。更具體描述可以參考這裡

  git rm a.c 會將檔案a.c 刪除,並將刪除這個"修改"標記為 staged 狀態。當使用 git commit 命令之後,a.c 檔案就會從工作目錄中消失,並不再為 tracked 狀態。這樣可以保證不會在之後的操作中將該檔案視為 untracked 檔案再次進行處理。

  注意:常規的刪除操作如 rm,會使得刪除的檔案處於 Changes not staged for commit 狀態,而 git rm 的刪除操作使得被刪除檔案處於 Changed to be commited 狀態。對於後者,使用者提交之後,被刪除的檔案之後不再被 git 記錄,而前者由於並不會被提交,會一直保持該狀態。

  對於已經修改並被加入staged狀態的檔案來說,通過 git rm 刪除該檔案需要使用 -f 引數,以避免刪除 git 尚未記錄的檔案和其他誤操作。

  使用引數 git rm --cached xxx 可以使得檔案不再被 git 記錄,但繼續存在於工作目錄下,作用與 .gitignore 檔案類似。

  

  git log —— 檢視提交歷史

  對於本地建立的或自其他倉庫克隆的具有多次提交記錄的專案,可以通過 git log 命令檢視歷史的提交記錄。

  預設情況, git log 會根據提交順序的逆序排列(即最近的提交最先顯示), git log 會顯示提交順序及其對應的SHA-1雜湊值,以及作者、郵箱、提交日期和提交資訊等內容。

  

  git log 有一些常用的引數可以用於更精確的顯示需要的內容。

    -p           //在 log 條目中加入每次提交的修改資訊
    -n           //僅顯示最近的n個提交條目
    --stat       //顯示每次提交被修改的檔案的資訊
    --pretty=options    //options可以為online、short等,也可以自行指定輸出的格式資訊,可以參考這裡
    --graph             //輸出字元樹的形式顯示提交記錄

  git diff——檢視修改情況

  通過指令 git status 可以得知當前各個檔案所處的狀態(是否發生改變等),通過指令 git diff可以得知某一檔案發生的怎樣的改變。

  git diff                   //檢視那些再次修改但尚未被staged的檔案修改情況,如 git add a.c 命令之後,再次對 a.c 所做的(而又未被staged)的修改
  git diff --stage       //檢視當前staged狀態下的檔案較之原始(未修改狀態下,也就是上一次提交時)的檔案的修改情況
  git diff commit1 commit2   //比較兩次提交之間的差別

  git diff 會將當前工作目錄下的檔案與處於staged狀態的檔案進行比較,並將差異結果顯示出來。可以視為顯示自上一次 git add 後進行的修改情況。

  git diff --stage會將當前處於staged狀態的檔案與上一次提交的結果進行比較,並將結果顯示出來。可以視為顯示自上一次 git commit 後進行的修改情況。

  注意:指令 git diff 只會顯示還未被staged的修改,即之前已經通過 git add 命令加入staged狀態的修改是不被顯示的。使用引數 --staged或--cached顯示當前已經處於staged狀態的修改,即與上一次提交進行比較的結果。

  撤銷與修改操作

  (1)針對提交過程:若發現存在部分檔案未正確提交(未加入 staged 狀態)或提交資訊有疏漏,可以先將需要補充提交的檔案加入 staged 狀態,再使用 git commit --amend 命令,則本次提交會取代上一次的提交,在此過程中,也可以修改提交資訊;

  (2)針對 staged 狀態的檔案:使用命令 git reset HEAD filename 可以將 filename 檔案從 staged 狀態中恢復至一般修改狀態;

  (3)針對已經修改的檔案:若想要將已經修改的檔案恢復至未修改的狀態,可以使用 git checkout --filename,則會將對應檔案從之前的提交記錄中恢復,而簡單的丟棄對其的修改;

  事實上,通過 git status 命令獲得當前工作目錄中檔案的狀態資訊時,針對每種檔案狀態會有相應的 git 操作提示。使用者可以直接使用 git status 命令檢視特定的檔案型別如何進行操作。

  其他

  (1)跳過 staged area 狀態:在命令 git commit 中加入 -a 引數,git 會直接將所有 tracked 檔案提交,而不再需要使用 git add 將其轉換為 staged 狀態。

  (2)可建立一個 .gitignore 檔案,來設定不需要 Git 進行顯示和提交的檔案(處理時直接忽略),最簡單的 .gitignore 檔案的寫入就是每個檔案/資料夾佔一行,所有被包含在其中的內容都被 git 所忽略。具體的寫法可參考這裡

 git 設定

  git 通過其攜帶的工具 git config 來對修改配置變數從而對應用進行個性化設定,個性化設定的變數可能會被儲存在三個不同的位置,各自有著不同的作用域( Ubuntu 環境下目錄結構 )。

    (1) /etc/gitconfig,全域性的 git 變數設定。其中的設定會應用到系統所有使用者和 git 倉庫。通過 git config 的 --system 引數進行設定。

    (2) ~/.gitconfig或~/.config/git/config,使用者個人的 git 變數設定,該設定應用於該使用者的所有操作。通過 --global 引數進行設定。

    (3) git目錄中的 config 檔案(下文的.config目錄中),記錄對該 git 目錄的一些配置變數。

  每一層設定的配置變數的值會覆蓋上一層的設定值,故而 git 目錄中的 config 檔案中特定設定的效果會掩蓋 /etc/gitconfig 中的對應的設定效果。

  設定個人資訊

  設定個人有關的資訊,包括使用者名稱和 email,在進行提交之前,必須進行使用者名稱和郵箱名的設定。這是與單個使用者相關的設定,故而使用引數 --global。 

    git config --global user.name "xxx"
    git config --global user.email email_address

  設定預設編輯器   

    git config --global core.editor vim        //在 Ubuntu 環境下設定編輯器為 vim

  檢視設定

  可以通過以下命令對 git 的配置引數進行檢視

    git config --list           //檢視當前已經設定的所有變數值,會從以上三個檔案中讀取,故而特定變數可能出現多次,其最後出現的值為 git 實際使用的值             
    git config key_name         //檢視Git當前使用的特定變數的值,如 git config user.name

  git 幫助

  使用者可以通過命令列方式獲得幫助,包括如下命令,可以通過幫助資訊和網路資源理解 git 相關命令的功能。 

    git help <action>      //如通過 git help config 來過得對config操作的相關幫助    
    man git-行為名          //如通過 man git-config 來獲得幫助
    git command -h         //獲得簡略的幫助提示,如 git config -h

參考和學習資源:

    Git Handbook

    github-git-cheat-sheet, Github

    Pro Git,2nd edition

    Pro Git,中文版第二版