问题中的两个例子实际上都是非常糟糕的例子,可能导致数据丢失!
我的建议:切勿将 /* 附加到 .gitignore 文件中的目录,除非你有充分的理由!
例如 Jefromi 写的一个很好的理由是:“如果您打算随后取消忽略目录中的某些内容”。
不应该这样做的原因是,一方面将/* 附加到目录确实会以正确忽略目录的所有内容的方式工作,但另一方面它也有危险的一面效果:
如果您在存储库中执行git stash -u(临时存储已跟踪和未跟踪的文件)或git clean -df(删除未跟踪但保留忽略的文件),所有被忽略并附加/* 的目录将是不可撤销地删除!
一些背景
我必须以艰苦的方式学习这一点。我团队中的某个人将/* 附加到我们的.gitignore 中的某些目录中。随着时间的推移,我遇到过某些目录会突然消失的情况。包含我们应用程序所需的千兆字节本地数据的目录。没有人能解释它,我总是讨厌重新下载所有数据。过了一会儿,我想到它可能与git stash 有关。有一天,我想清理我的本地存储库(同时保留被忽略的文件),我正在使用git clean -df,但我的数据又消失了。这次我受够了并调查了这个问题。我终于想通了,原因是附加的/*。
我认为这可以通过directory/* 确实忽略目录的所有内容而不是目录本身这一事实来解释。因此,当内容被删除时,它既不会被视为跟踪也不会被忽略。尽管git status 和git status --ignored 给出的图片略有不同。
如何重现
这里是如何重现该行为。我目前使用的是 Git 2.8.4。
将在本地 git 存储库中创建一个名为 localdata/ 的目录,其中包含一个虚拟文件 (important.dat),并将 /localdata/* 放入 .gitignore 文件中将忽略其内容。当现在执行上面提到的两个 git 命令之一时,该目录将(意外地)丢失。
mkdir test
cd test
git init
echo "/localdata/*" >.gitignore
git add .gitignore
git commit -m "Add .gitignore."
mkdir localdata
echo "Important data" >localdata/important.dat
touch untracked-file
如果您在此处输入git status --ignored,您将获得:
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
untracked-file
Ignored files:
(use "git add -f <file>..." to include in what will be committed)
localdata/
现在要么做
git stash -u
git stash pop
或
git clean -df
在这两种情况下,据称被忽略的目录localdata 都会消失!
不确定这是否可以被认为是一个错误,但我想这至少是一个没人需要的功能。
我会把这个报告给 git 开发列表,看看他们是怎么想的。