English ▾ 主題 ▾ 最新版本 ▾ gitignore 最後更新於 2.54.0

名稱

gitignore - 指定刻意不追蹤且需忽略的檔案

概要

$XDG_CONFIG_HOME/git/ignore, $GIT_DIR/info/exclude, .gitignore

描述

gitignore 檔案指定了 Git 應該忽略的刻意不追蹤檔案。已經由 Git 追蹤的檔案不會受到影響;詳情請參閱下方的「注意事項」。

gitignore 檔案中的每一行都指定了一個模式。在決定是否忽略某個路徑時,Git 通常會檢查來自多個來源的 gitignore 模式,其優先順序由高至低如下(在同一優先級內,最後一個匹配的模式決定最終結果):

  • 從命令列讀取的模式(適用於支援此功能的指令)。

  • 從與該路徑位於同一目錄,或任何上層目錄(直到工作樹的頂層)的 .gitignore 檔案中讀取的模式。較高層級檔案中的模式會被較低層級檔案中的模式覆蓋。這些模式是相對於 .gitignore 檔案所在位置進行匹配的。專案通常會將這類 .gitignore 檔案納入儲存庫中,包含專案建置過程中所產生的檔案模式。

  • $GIT_DIR/info/exclude 讀取的模式。

  • 從組態變數 core.excludesFile 所指定的檔案中讀取的模式。

將模式放置在哪個檔案中,取決於該模式的使用目的。

  • 應該受版本控制並透過 clone 分發到其他儲存庫的模式(即所有開發者都想忽略的檔案),應該放入 .gitignore 檔案中。

  • 特定於某個儲存庫,但不需要與其他相關儲存庫共享的模式(例如,位於儲存庫內但僅限於單一使用者工作流程的輔助檔案),應該放入 $GIT_DIR/info/exclude 檔案中。

  • 使用者希望 Git 在所有情況下都忽略的模式(例如使用者所選編輯器產生的備份或暫存檔案),通常放入使用者 ~/.gitconfig 中由 core.excludesFile 指定的檔案內。其預設值為 $XDG_CONFIG_HOME/git/ignore。如果未設定 $XDG_CONFIG_HOME 或該變數為空,則改用 $HOME/.config/git/ignore。

Git 的底層工具(例如 git ls-filesgit read-tree)會讀取由命令列選項指定的,或由命令列選項所指定檔案中的 gitignore 模式。高階 Git 工具(例如 git statusgit add)則使用上述來源的模式。

模式格式 (PATTERN FORMAT)

  • 空白行不匹配任何檔案,因此可用作閱讀時的分隔符號。

  • 以 # 開頭的行視為註解。若模式本身以井字號開頭,請在第一個井字號前加上反斜線 ("\")。

  • 尾部的空白會被忽略,除非它們被反斜線 ("\") 轉義。

  • 可選的前綴 "!" 用於否定模式;任何先前模式排除的匹配檔案將再次被納入。如果某個檔案的父目錄已被排除,則無法將該檔案重新納入。基於效能考量,Git 不會列出被排除的目錄,因此無論在哪裡定義,包含在其中的檔案模式都不會產生作用。若模式以字面上的 "!" 開頭,請在第一個 "!" 前加上反斜線 ("\"),例如 "\!important!.txt"。

  • 斜線 "/" 用作目錄分隔符號。分隔符號可能出現在 .gitignore 搜尋模式的開頭、中間或結尾。

  • 如果模式的開頭或中間(或兩者皆有)存在分隔符號,則該模式是相對於 .gitignore 檔案本身所在目錄層級的。否則,該模式亦可匹配 .gitignore 層級以下的任何層級。

  • 從工作樹外部的排除來源(如 $GIT_DIR/info/exclude 和 core.excludesFile)讀取的模式,其處理方式如同指定在工作樹根目錄一樣,亦即這類模式中的開頭斜線 "/" 會將匹配錨定在儲存庫的根目錄。

  • 如果模式結尾有分隔符號,則該模式僅會匹配目錄;否則,該模式可同時匹配檔案和目錄。

  • 例如,模式 doc/frotz/ 匹配 doc/frotz 目錄,但不匹配 a/doc/frotz 目錄;然而 frotz/ 匹配 frotz 以及作為目錄的 a/frotz(所有路徑皆相對於 .gitignore 檔案)。

  • 星號 "*" 匹配除斜線外的任何內容。字元 "?" 匹配除 "/" 外的任何單一字元。範圍表示法(例如 [a-zA-Z])可用於匹配範圍內的一個字元。詳細說明請參閱 fnmatch(3) 及 FNM_PATHNAME 旗標。

  • 反斜線 ("\") 可用於跳脫任何字元。例如,"\*" 匹配字面上的星號(而 "\a" 匹配 "a",儘管在那裡不需要跳脫)。與 fnmatch(3) 一樣,位於模式末尾的反斜線為無效模式,且永遠不會匹配。

與完整路徑名稱比對的模式中,兩個連續的星號 ("**") 可能具有特殊含義

  • 開頭的 "**" 後接斜線表示匹配所有目錄。例如,"**/foo" 匹配任何地方的檔案或目錄 "foo",與模式 "foo" 相同。"**/foo/bar" 匹配位於目錄 "foo" 下方任何地方的檔案或目錄 "bar"。

  • 尾部的 "/**" 匹配內部的所有內容。例如,"abc/**" 匹配目錄 "abc" 內的所有檔案,相對於 .gitignore 檔案的位置,且深度無限。

  • 斜槓後跟兩個連續星號再跟斜槓可比對零個或多個目錄。例如,"a/**/b" 可比對 "a/b"、"a/x/b"、"a/x/y/b" 等等。

  • 其他連續的星號被視為普通星號,並根據上述規則進行匹配。

組態設定 (CONFIGURATION)

可選的組態變數 core.excludesFile 指向一個包含要排除之檔名模式的檔案路徑,與 $GIT_DIR/info/exclude 類似。排除檔案中的模式會與 $GIT_DIR/info/exclude 中的模式併用。

注意事項

gitignore 檔案的目的是確保某些未由 Git 追蹤的檔案保持不被追蹤的狀態。

若要停止追蹤目前已受追蹤的檔案,請使用 git rm --cached 將檔案從索引中移除。接著可將該檔名加入 .gitignore 檔案,以防止該檔案在後續提交中被重新加入。

當存取工作樹中的 .gitignore 檔案時,Git 不會跟隨符號連結。這能確保無論是從索引或樹狀物件存取檔案,還是從檔案系統存取,行為都保持一致。

範例

  • 模式 hello.* 匹配任何以 hello. 開頭的檔案或目錄。如果想將其限制在該目錄內而不包含子目錄,可在模式前加上斜線,即 /hello.*;此時該模式匹配 hello.txthello.c,但不匹配 a/hello.java

  • 模式 foo/ 將匹配目錄 foo 及其下的路徑,但不會匹配常規檔案或符號連結 foo(這與 Git 中路徑規格 pathspec 的運作方式一致)。

  • 模式 doc/frotz/doc/frotz 在任何 .gitignore 檔案中皆有相同的效果。換句話說,如果模式中已經有中間的斜線,開頭的斜線就沒有影響。

  • 模式 foo/* 匹配 foo/test.json(常規檔案)、foo/bar(目錄),但不匹配 foo/bar/hello.c(常規檔案),因為模式中的星號不匹配包含斜線的 bar/hello.c

    $ git status
    [...]
    # Untracked files:
    [...]
    #       Documentation/foo.html
    #       Documentation/gitignore.html
    #       file.o
    #       lib.a
    #       src/internal.o
    [...]
    $ cat .git/info/exclude
    # ignore objects and archives, anywhere in the tree.
    *.[oa]
    $ cat Documentation/.gitignore
    # ignore generated html files,
    *.html
    # except foo.html which is maintained by hand
    !foo.html
    $ git status
    [...]
    # Untracked files:
    [...]
    #       Documentation/foo.html
    [...]

另一個例子

    $ cat .gitignore
    vmlinux*
    $ ls arch/foo/kernel/vm*
    arch/foo/kernel/vmlinux.lds.S
    $ echo '!/vmlinux*' >arch/foo/kernel/.gitignore

第二個 .gitignore 阻止了 Git 忽略 arch/foo/kernel/vmlinux.lds.S

排除除特定目錄 foo/bar 之外的所有內容的範例(注意 /* - 若沒有斜線,萬用字元也會排除 foo/bar 內的所有內容)

    $ cat .gitignore
    # exclude everything except directory foo/bar
    /*
    !/foo
    /foo/*
    !/foo/bar

GIT

git[1] 套件的一部分