Git Hooks
Git 可以在某些事件發生時,觸發自訂腳本。Hooks 分成兩組,客戶端跟伺服器端,hooks 預設是保存在 .git/hooks 底下,這邊只紀錄客戶端的 pre-commit。
pre-commit
會在輸入 git commit 時被觸發,常用於檢查東西是否遺漏、測試是否有跑過、檢查 trailing spaces、Linter 工具等等,若腳本回傳值非零時,Git 會放棄此次提交。可以使用 git commit --no-verify 來強制忽略。
git diff Options
--cached (--staged)
預設是將上一次 commit(也就是 HEAD)跟當前暫存區的去做比較,可以在 --cached 後面加上 來跟特定 commit 做比較。
--diff-filter
顧名思義可以將 diff 出來的結果做過濾,這裡可以根據檔案的類別來做過濾:
- (A) Added
- (C) Copied
- (D) Deleted
- (M) Modified
- (R) Renamed
--name-only
只列出檔案名稱。
透過上面三個選項,在撰寫 pre-commit 腳本來檢查 coding style 時十分方便,可以幫助我們拿到這次想要 commit 的所有檔案名稱列表,前提是已經都進入暫存區(staging area)。此外,也可以利用 grep 再做更進一步的副檔名過濾。
git checkout-index
將 index 中列出的檔案複製到工作目錄底下,預設不會覆寫掉存在的檔案。檔案內容會是暫存區的狀態。也就是可以在 pre-commit 中利用這個指令來輸出檔案內容並用 linter 檢查 coding style。
加上 --temp 這個選項,可以把檔案內容寫進暫存檔案。
只提交未追蹤檔案的一部分
首先利用 git add -N 來加入未追蹤的檔案,-N 代表的是告訴 Git 只紀錄說這個檔案之後會被加進來,因此這個檔案的會被加進 index 中但是不會有任何內容。
接著利用 git add -i 進入互動模式,介面大致如下:
» git add -i
staged unstaged path
1: +0/-0 +5/-0 hhhh
2: +2/-1 nothing hi
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now>
最上面的是目前 index 與 HEAD 差異的狀態,接著可以輸入 5 來進入 patch 模式,這時候可以選擇要 patch 哪個檔案,選擇後會進入像是平常用 git add ${file} -p 那樣,會詢問是否要暫存這個區塊(stage this hunk),這時因為 index 上沒有紀錄任何內容,因此跟工作目錄的差異就是整個檔案內容,沒辦法用 s 來切割區塊,這時需要用 e 來手動編輯區塊:
1 # Manual hunk edit mode -- see bottom for a quick guide
2 @@ -0,0 +1,5 @@
3 +Line1
4 +Line2
5 +Line3
6 +Line4
7 +Line5
8 # ---
9 # To remove '-' lines, make them ' ' lines (context).
10 # To remove '+' lines, delete them.
11 # Lines starting with # will be removed.
12 #
13 # If the patch applies cleanly, the edited hunk will immediately be
14 # marked for staging. If it does not apply cleanly, you will be given
15 # an opportunity to edit again. If all lines of the hunk are removed,
16 # then the edit is aborted and the hunk is left unchanged.
要手動編輯區塊最重要的是注意資訊的符合,也就是第二行的 -0,0 +1,5,因為這個檔案全部都是新增內容,因此 - 的區塊沒東西,+ 的話顯示 1,5 前面代表從檔案的第幾行新增的,後面的數字代表這次總共新增的多少行,因次若只想新增前三行,就依照最下方的指示將 Line4 以及 Line5 刪除,並將數字 5 改成 3,接著存檔離開。接著在互動模式中輸入 1 來顯示目前狀態:
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now> 1
staged unstaged path
1: +3/-0 +2/-0 hhhh
2: +2/-1 nothing hi
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
What now>
可以發現 1 那邊的 hhhh 這個檔案從原本的 +5 剩下 +2,而 3 則跑到了暫存區。最後就可以以目前狀態進行提交,這樣就只有前三行會被提交上去。
Git Hooks
Git 可以在某些事件發生時,觸發自訂腳本。Hooks 分成兩組,客戶端跟伺服器端,hooks 預設是保存在
.git/hooks底下,這邊只紀錄客戶端的pre-commit。pre-commit會在輸入
git commit時被觸發,常用於檢查東西是否遺漏、測試是否有跑過、檢查 trailing spaces、Linter 工具等等,若腳本回傳值非零時,Git 會放棄此次提交。可以使用git commit --no-verify來強制忽略。git diffOptions--cached(--staged)預設是將上一次 commit(也就是 HEAD)跟當前暫存區的去做比較,可以在
--cached後面加上 來跟特定 commit 做比較。--diff-filter顧名思義可以將 diff 出來的結果做過濾,這裡可以根據檔案的類別來做過濾:
--name-only只列出檔案名稱。
透過上面三個選項,在撰寫
pre-commit腳本來檢查 coding style 時十分方便,可以幫助我們拿到這次想要 commit 的所有檔案名稱列表,前提是已經都進入暫存區(staging area)。此外,也可以利用grep再做更進一步的副檔名過濾。git checkout-index將 index 中列出的檔案複製到工作目錄底下,預設不會覆寫掉存在的檔案。檔案內容會是暫存區的狀態。也就是可以在
pre-commit中利用這個指令來輸出檔案內容並用 linter 檢查 coding style。加上
--temp這個選項,可以把檔案內容寫進暫存檔案。只提交未追蹤檔案的一部分
首先利用
git add -N來加入未追蹤的檔案,-N代表的是告訴 Git 只紀錄說這個檔案之後會被加進來,因此這個檔案的會被加進 index 中但是不會有任何內容。接著利用
git add -i進入互動模式,介面大致如下:最上面的是目前 index 與 HEAD 差異的狀態,接著可以輸入
5來進入 patch 模式,這時候可以選擇要 patch 哪個檔案,選擇後會進入像是平常用git add ${file} -p那樣,會詢問是否要暫存這個區塊(stage this hunk),這時因為 index 上沒有紀錄任何內容,因此跟工作目錄的差異就是整個檔案內容,沒辦法用s來切割區塊,這時需要用e來手動編輯區塊:要手動編輯區塊最重要的是注意資訊的符合,也就是第二行的
-0,0 +1,5,因為這個檔案全部都是新增內容,因此-的區塊沒東西,+的話顯示1,5前面代表從檔案的第幾行新增的,後面的數字代表這次總共新增的多少行,因次若只想新增前三行,就依照最下方的指示將Line4以及Line5刪除,並將數字 5 改成 3,接著存檔離開。接著在互動模式中輸入 1 來顯示目前狀態:可以發現 1 那邊的
hhhh這個檔案從原本的 +5 剩下 +2,而 3 則跑到了暫存區。最後就可以以目前狀態進行提交,這樣就只有前三行會被提交上去。