我找到了一种方法,git不会要求你藏匿,而是默默地删除你认为在.gitignore中安全的文件.即使您在初始提交后拥有相同的忽略文件,也是如此.
当您在提交中删除了所述文件但在.gitignore中列出然后您签出另一个存在的提交时,会发生此问题:
git init
mkdir ignored/
echo stuff > ignored/file
echo otherstuff > otherfile
git add -A
# Opps added my ignored folders files
# Forgeting to rm --cache
echo ignored/ > .gitignore ; git add .gitignore
git commit -m 'accidentally add ignored/file'
git status
touch dummyfile; git add dummyfile
# Remembered to rm --cache
git rm --cache -rf ignored/file #This file is now vulnerable to clobber
git commit -m 'add stuff'
echo somechange >> ignored/file
## Wait for it..
git checkout HEAD~
## somechange has been silently clobbered!!
# Please paste first paragraph, observe and then past the second.
# Note both commits have the correct ignore file and are not immune!
Run Code Online (Sandbox Code Playgroud)
(在将上面的代码粘贴到终端之前,cd到一个空文件夹)
反正有没有阻止这个无声的咒语?
这不是一个错误(或者至少,git开发人员不认为它是一个).
的内容.gitignore是不是 "文件应该被忽略"或"不应该触及路径名称"; 相反,它们是"不会自动添加的路径,并且被禁止显示为未跟踪"(这使得.gitignore名称不佳).
一旦您提交了文件,或者甚至将其添加到索引中,它就不再被忽略,无论它是否列在.gitignore.
对于某些文件,您可以使用git update-index --assume-unchanged或(更好)git update-index --skip-worktree,但一般情况下,如果您不小心提交了一个您不应该拥有的文件,并且您希望它被忽略,则必须"重写历史记录"以将其完全从存储库中删除得到好的行为.如果你没有推送任何内容并且几乎没有包含不需要的文件的提交,那就不是太难了,但是如果你已经推送或者有很多这样的提交会更难.
另请参阅Git - "假设未更改"和"跳过工作树"之间的差异.
[2016年12月添加的文字]
对于Git,跟踪文件有一个简短而简洁的定义:当且仅当索引中有条目时才跟踪文件.
"假设未更改"和"跳过工作树"事物是您可以在索引中手动设置或清除的标志.它们是单独的标志,可以单独设置,但不清楚设置它们意味着什么."假设未改变" 的意图仅仅是让Git更快,允许它假设文件没有改变,因此不需要更新git add,而"skip worktree"标志的意图是告诉Git"放手":不要只是假设它没有变化,尽量保持不变.这比看起来第一次脸红更难; 有关此内容的更多信息,请参阅上面的链接帖子.
为了设置这些标志,文件必须具有索引条目,因此必须对其进行跟踪.
如果未跟踪文件,则可能也可能不会忽略该文件.这些有很多来源:不仅仅是顶级.gitignore,它包含Git的pathspec变体的列表(每行一个),仅限于全局匹配和否定,还.gitignore包含存储库中每个子目录中的文件,文件$GIT_DIR/info/exclude是否存在,以及core.excludesFile如果该配置条目存在而命名的文件.要查找是否以及为何忽略文件,请使用git check-ignore自Git 1.8.2版本开始提供的文件.该-v选项告诉您哪个控制文件将文件标记为忽略.
不幸的是,正如在这个答案的问题中,"被忽略"有两个含义.匹配一个忽略路径使Git对未被跟踪的文件保持安静,这也使得Git可以随意破坏该文件.