问题中的两个示例都非常糟糕,可能导致数据丢失!
我的建议是:除非你有充分的理由,否则不要在.gitignore文件中将/*
附加到目录中!
一个充分的理由可以是像Jefromi所写的那样:"如果您打算随后取消忽略目录中的某些内容"。
否则不应该这样做的原因是,将/*
附加到目录会在一方面正确地忽略目录中的所有内容,但另一方面会产生危险的副作用:
如果您在存储库中执行git stash -u
(暂时stash已跟踪和未跟踪文件)或git clean -df
(删除未跟踪但保留已忽略的文件),所有使用附加的/*
忽略的目录将被不可逆转地删除!
背景知识
我必须通过艰苦的方式学习这一点。我们团队中的某些人正在向我们的.gitignore文件中的某些目录附加/*
。随着时间的推移,我遇到了某些目录突然消失的情况。那是我们应用程序需要的本地数据的几千兆字节的目录。没有人能够解释这个问题,我总是不得不重新下载所有数据。过了一段时间,我有了一个想法,它可能与git stash
有关。有一天我想清理我的本地repo(同时保留ignored文件),我使用git clean -df
,我的数据再次丢失了。这次我受够了,调查了这个问题。最后我发现原因是附加的/*
。
我认为可以通过以下事实来解释:即directory/*
确实忽略目录中的所有内容,但不包括目录本身。因此,在删除东西时,它既不被视为已跟踪,也不被视为已忽略。尽管git status
和git status--ignored
在这个问题上有稍微不同的看法。
如何复制
以下是如何复制这种行为。我目前正在使用Git 2.8.4。
在本地git存储库中创建一个名为localdata/
的目录,并在其中放置一个虚拟文件(important.dat
),然后将其内容添加到.gitignore
文件中,使其被忽略(/localdata/*
)。当执行上述两个命令中的任意一个时,该目录将会意外地丢失。
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开发列表报告并看看他们对此的看法。
.gitignore
是否区分忽略文件和目录?例如,data
和data/
是不是有不同的含义? - Charlie Parkerdata
会忽略匹配的文件和目录,而data/
只会忽略匹配的目录。 - jox