Skip to content

Git 技巧 #5

Description

@Naetw

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 則跑到了暫存區。最後就可以以目前狀態進行提交,這樣就只有前三行會被提交上去。

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions