隨之而來的問題是:為什么我增加了 .gitignore 里的規(guī)則卻沒有效果?
這是因為我們誤解了 .gitignore 文件的用途,該文件只能作用于 Untracked Files,也就是那些從來沒有被 Git 記錄過的文件(自添加以后,從未 add 及 commit 過的文件)。
1. git rm --cached logs/xx.log // if file is traced
2. 然后更新 .gitignore 忽略掉目標文件,
3. 最后 git commit -m "We really don't want Git to track this anymore!"
之所以你的規(guī)則不生效,是因為那些 .log 文件曾經(jīng)被 Git 記錄過,因此 .gitignore 對它們完全無效。這也正是開頭那段簡短答案所做的事情:
1. 從 Git 的數(shù)據(jù)庫中刪除對于該文件的追蹤;
2. 把對應(yīng)的規(guī)則寫入 .gitignore,讓忽略真正生效;
3. 提交+推送。
最后有一點需要注意的,git rm --cached 刪除的是追蹤狀態(tài),而不是物理文件;如果你真的是徹底不想要了,你也可以直接rm+忽略+提交。
About Another Command
git update-index --assume-unchanged logs/*.log的真正用法是這樣的:
你正在修改一個巨大的文件,你先對其 git update-index --assume-unchanged,這樣 Git 暫時不會理睬你對文件做的修改;
當(dāng)你的工作告一段落決定可以提交的時候,重置改標識:git update-index --no-assume-unchanged,于是 Git 只需要做一次更新,這是完全可以接受的了;
提交+推送。
另外,根據(jù)文檔的進一步描述:
This option can be also used as a coarse file-level mechanism to ignore uncommitted changes in tracked files (akin to what .gitignore does for untracked files).
這段描述告訴我們兩個事實:
雖然可以用其來達成樓主想要的結(jié)果,但這是不講究的做法(coarse);
同樣的事情更應(yīng)該用 .gitignore 文件來實現(xiàn)(針對未追蹤的文件)。
git update-index --assume-unchanged logs/*.log雖然能達到(暫時的)目的,但并非最正確的做法,這樣做是誤解了 git update-index 的含義,而且這樣做帶來的最直接(不良)后果是這樣的:
所有的團隊成員都必須對目標文件執(zhí)行:
git update-index --assume-unchanged <PATH>。
這是因為即使你讓 Git 假裝看不見目標文件的改變,
但文件本身還是在 Git 的歷史記錄里的,
所以團隊的每個人在 fetch 的時候都會拉到目標文件的變更。
(但實際上目標文件是根本不想被 Git 記錄的,
而不是假裝看不見它發(fā)生了改變)
一旦有人改變目標文件之后沒有
git update-index --assume-unchanged <PATH> 就直接 push 了,
那么接下來所有拉取了最新代碼的成員必須重新執(zhí)行 update-index,
否則 Git 又會開始記錄目標文件的變化。
這一點實際上很常見的,比如說某成員換了機器或者硬盤,重新 clone 了一份代碼庫,
由于目標文件還在 Git 的歷史記錄里,
所以他/她很可能會忘記 update-index。