『現學現忘』Git基礎 — 19、在Git中進行忽略檔案操作

繁華似錦Fighting發表於2022-04-29

1、忽略檔案說明

有些時候,你必須把某些檔案放到Git工作目錄中,但又不能提交它們到本地版本庫,通常都是些自動生成的檔案、日誌檔案、系統快取檔案、編譯過程中建立的臨時檔案,或者儲存了資料庫密碼的配置檔案、人隱私檔案等等,每次執行git status命令時,都會顯示Untracked files ...(未被跟蹤),有強迫症的童鞋心裡肯定不爽。

正常來說,這些檔案都是不應該被提交到版本庫,倘若一不留神提交到版本庫,要麼洩露機密資訊,要麼造成經濟損失,要麼對團隊其他人工作造成不便。

好在Git考慮到了大家的感受,這個問題解決起來也很簡單,在Git工作區的根目錄下建立一個特殊的.gitignore檔案,然後把要忽略的檔名填進去,並且把.gitignore檔案提交到本地版本庫中。之後Git就會自動忽略這些檔案,再執行git status命令時就不對其進行檢測了。

即:"並不是所有的牛奶都叫特侖蘇",在版本控制系統中也有相似的表達,那就是"並不是所有的檔案都需要提交到本地版本庫"。

2、忽略檔案的原則

  1. 忽略作業系統自動生成的檔案,保持專案在不同作業系統中的純粹性和整潔度。
  2. 忽略編譯生成的中間檔案、可執行檔案等,比如Java編譯產生的.class檔案,
    即:忽略工具軟體自動生成的檔案,避免因個性化配置而產生的工作障礙。
  3. 忽略自己帶有敏感資訊的配置檔案,比如存放口令的配置檔案。

目標:只提交必要檔案,忽略無用檔案,儘可能考慮多種情況,不給他人制造麻煩。

3、.gitignore忽略規則

檔案 .gitignore 的格式規範如下:

  • 所有空行或者以 # 開頭的行都會被 Git 忽略。
  • 可以使用標準的glob模式匹配,它會遞迴地應用在整個工作區中。
  • 匹配模式可以以(/)開頭,防止遞迴。
  • 匹配模式最後跟/說明要忽略的是目錄。
  • 要忽略指定模式以外的檔案或目錄,可以在模式前加上歎號(!)取反。

所謂的glob模式是指shell所使用的簡化了的正規表示式。

  • 以#開頭的行用作註釋。
  • 星號(*)匹配零個或多個任意字元。
  • [abc]匹配任何一個列在方括號中的字元 (這個例子要麼匹配一個a,要麼匹配一個b,要麼匹配一個 c);
  • 問號(?)只匹配一個任意字元。
  • 如果在方括號中使用短劃線分隔兩個字元, 表示所有在這兩個字元範圍內的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的數字)。
  • 使用兩個星號(**)表示匹配任意中間目錄,比如 a/**/z 可以匹配 a/za/b/za/b/c/z 等。

我們再看一個 .gitignore 檔案的例子:

# 1.忽略public下的所有目錄及檔案
/public/*

# 2.不忽略/public/assets,就是特例的意思,assets檔案不忽略
!/public/assets

# 3.忽略具體的檔案
index.html

# 4.忽略所有的java檔案
*.java

# 5.忽略 a.java b.java
[ab].java

# 6.忽略 doc/ 目錄及其所有子目錄下的 .pdf 檔案
doc/**/*.pdf

# 7.忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt

# 8.忽略任何目錄下名為 build 的資料夾
build/

# 9.只忽略當前目錄下的 TODO 檔案,而不忽略 subdir/TODO檔案
/TODO

提示:要養成一開始就為你的新倉庫設定好.gitignore檔案的習慣,以免將來誤提交這類無用的檔案。

4、忽略檔案的三種方式

有鑑於此,我們應該尋求一種機制來規避這種事故的發生,在 git 版本控制系統中一般有三種不同的解決方案。

最常用也是最簡單的當屬 .gitignore 檔案。

(1)忽略單個倉庫中的檔案(遠端共用)

該方式是在工作中最常用的方式,配置方法是在倉庫的根目錄下新建 .gitignore 檔案,在檔案裡配置忽略規則,同時把 .gitignore 檔案加入版本管理。之後可以同步該配置到遠端倉庫,其他開發者可更新該檔案到本地倉庫,與其他克隆倉庫共享同一套忽略規則。

.gitignore檔案對其所在的目錄,及所在目錄的全部子目錄均有效。

1)檢視當前Git工作目錄中檔案狀態。

L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        hello.java
        local.txt
        test.java
        xyj-sha_hs.py
        xyj-sun_wk.py
        xyj-zhu_bj.py

nothing added to commit but untracked files present (use "git add" to track)

可以看到有6個未被追蹤的檔案。

2)在Git倉庫的根目錄下新建一個名為.gitignore的檔案。

因為是點開頭,沒有檔名,沒辦法直接在Windows系統中直接建立,要通過Git Bash客戶端,用Linux系統的方式新建.gitignore檔案。

# 建立.gitignore檔案。
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ touch .gitignore

# 檢視本地版本庫中是否成功建立.gitignore檔案。
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ ll -a
total 12
drwxr-xr-x 1 L 197121 0  4月 10 11:52 ./
drwxr-xr-x 1 L 197121 0  4月  2 21:54 ../
drwxr-xr-x 1 L 197121 0  4月 10 11:51 .git/
-rw-r--r-- 1 L 197121 0  4月 10 11:52 .gitignore
-rw-r--r-- 1 L 197121 0  4月  4 10:37 hello.java
-rw-r--r-- 1 L 197121 0  4月 10 11:46 local.txt
-rw-r--r-- 1 L 197121 0  4月  4 01:20 test.java
-rw-r--r-- 1 L 197121 0  4月  4 10:38 xyj-sha_hs.py
-rw-r--r-- 1 L 197121 0  4月  4 10:38 xyj-sun_wk.py
-rw-r--r-- 1 L 197121 0  4月  4 10:38 xyj-zhu_bj.py

3)將需要忽略的檔案寫入.gitignore檔案中。

提示:每個檔案或者正則匹配佔一行。

# 配置.gitignore檔案內容
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ echo "xyj-*.py" > .gitignore

# 檢視.gitignore檔案內容
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ cat .gitignore
xyj-*.py

4)將.gitignore檔案提交到本地版本庫。

# 1.檢視當前Git工作目錄中檔案狀態
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore	# 檔名都為紅色
        hello.java
        local.txt
        test.java

nothing added to commit but untracked files present (use "git add" to track)

# 我們可以看到,xyj開頭的檔案已經被忽略掉了,但只是在本地起作用。

# 2.追蹤.gitignore檔案
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git add .gitignore

L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   .gitignore	# 檔名為綠色

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        hello.java	# 檔名都為紅色
        local.txt
        test.java

# 3.提交.gitignore檔案到本地版本庫
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git commit -m 'create ignore file'
[master d3ceba8] create ignore file
 1 file changed, 1 insertion(+)
 create mode 100644 .gitignore

L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        hello.java	# 檔名都為紅色
        local.txt
        test.java

這樣就完成可忽略檔案的整個過程了。

(2)忽略單個倉庫中的檔案(本地使用)

用這種方式配置忽略檔案,不會同步該設定至遠端倉庫,只在本機起作用。

配置方法是直接編輯Git倉庫根目錄下的.git/info/exclude檔案,把要忽略的規則直接寫入,這個方法只在本機當前倉庫起效,不會對其他的克隆倉庫起效。

1)檢視當前Git工作目錄中檔案狀態。

L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        hello.java	# 檔名都為紅色
        local.txt
        test.java

nothing added to commit but untracked files present (use "git add" to track)

可以看到有3個未被追蹤的檔案。

2)編輯Git倉庫根目錄下的.git/info/exclude檔案,配置忽略。

# 1.我們先來檢視一下.git/info/exclude檔案的預設內容
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ cat .git/info/exclude
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~

# 2.配置忽略檔案,把local.txt檔案進行忽略
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ echo "local.txt" >> .git/info/exclude

L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ cat .git/info/exclude
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
local.txt

3)再次檢視當前Git工作目錄中檔案狀態。

L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        hello.java
        test.java

nothing added to commit but untracked files present (use "git add" to track)

我們可以看到local.txt檔案被忽略了。

(3)全域性忽略

忽略規則由本機所有倉庫共用(也就是對本機的所有Git倉庫都起作用),配置方法如下:

Linux中,這時把全域性要忽略的檔案列表.gitignore放當前使用者根目錄下( ~/.gitconfig ):

git config --global core.excludesfile '~/.gitignore'

Windows中,這時把全域性要忽略的檔案列表.gitignore放當前使用者根目錄下:

git config --global core.excludesfile "%USERPROFILE%\.gitignore(可自定義)"

我們以Windows系統為例:

1)檢視當前Git工作目錄中檔案狀態。

L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        hello.java
        test.java

2)建立.gitignore忽略檔案。

我們可以複製使用者根目錄下的.gitconfig檔案,並改名為.gitignore檔案。

注意:

  • .gitconfig檔案可以改成其他名稱,如.gitignore_global,這樣好區分工作目錄中的.gitignore忽略檔案。
  • .gitconfig檔案也可以使用.txt格式的文字檔案代替,例如gitignore_global.txt

如下:

# 複製檔案,生成gitignore_global.txt檔案
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ cp /c/Users/L/.gitconfig /c/Users/L/gitignore_global.txt

# 檢視gitignore_global.txt檔案是否生成
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ ll /c/Users/L/.git*
-rw-r--r-- 1 L 197121 90  4月  5 20:52 /c/Users/L/.gitconfig
-rw-r--r-- 1 L 197121 90  4月  5 20:59 /c/Users/L/gitignore_global.txt

# 清空gitignore_global.txt檔案中的內容
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ echo "" > /c/Users/L/gitignore_global.txt

3)將忽略檔案配置到Git全域性配置檔案.gitconfig檔案中。

通過如下命令進行配置。

git config --global core.excludesfile /c/Users/L/gitignore_global.txt

執行命令後,檢視.gitconfig檔案內容,如下:

[user]
	name = sun_wk
	email = sun_wk@126.com
# 下面兩行是生成的
[core]
	excludesfile = C:/Users/L/gitignore_global.txt

提示:如果之前配置global級別的配置簽名,.gitconfig檔案就已經被建立。

至此之後,所有Git倉庫都會自動應用這個gitignore_global.txt檔案中,所配置忽略的檔案。

當然本例子是存放於 當前使用者的根目錄下,你可以改成其他路徑,但是不推薦。

4)把需要忽略的檔案加入到gitignore_global.txt檔案中。

gitignore_global.txt檔案中的內容清空,之後新增要忽略的檔案。

gitignore_global.txt檔案內容如下:

# 忽略所有.java檔案,也可以單個檔案寫
*.java

5)檢視learngit倉庫工作目錄檔案狀態。

L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git status
On branch master
nothing to commit, working tree clean

可以看到hello.javatest.java兩個未被追蹤的檔案被忽略掉了。

提示:其實可以直接將gitignore_global.txt檔案中的內容直接寫到.gitconfig檔案中,效果也一樣的。只不過這樣會比較混亂一點,還是推薦上面詳細敘述的方法來設定Git全域性忽略檔案。

參考:

相關文章