Both examples in the question are actually very bad examples that can lead to data loss!
My advice: never append /*
to directories in .gitignore files, unless you have a good reason!
A good reason would be for example what Jefromi wrote: "if you intend to subsequently un-ignore something in the directory".
The reason why it otherwise shouldn't be done is that appending /*
to directories does on the one hand work in the manner that it properly ignores all contents of the directory, but on the other hand it has a dangerous side effect:
If you execute git stash -u
(to temporarily stash tracked and untracked files) or git clean -df
(to delete untracked but keep ignored files) in your repository, all directories that are ignored with an appended /*
will be irreversibly deleted!
Some background
I had to learn this the hard way. Somebody in my team was appending /*
to some directories in our .gitignore. Over the time I had occasions where certain directories would suddenly disappear. Directories with gigabytes of local data needed by our application. Nobody could explain it and I always hat to re-download all data. After a while I got a notion that it might have to do with git stash
. One day I wanted to clean my local repo (while keeping ignored files) and I was using git clean -df
and again my data was gone. This time I had enough and investigated the issue. I finally figured that the reason is the appended /*
.
I assume it can be explained somehow by the fact that directory/*
does ignore all contents of the directory but not the directory itself. Thus it's neither considered tracked nor ignored when things get deleted. Even though git status
and git status --ignored
give a slightly different picture on it.
How to reproduce
Here is how to reproduce the behaviour. I'm currently using Git 2.8.4.
A directory called localdata/
with a dummy file in it (important.dat
) will be created in a local git repository and the contents will be ignored by putting /localdata/*
into the .gitignore
file. When one of the two mentioned git commands is executed now, the directory will be (unexpectedly) lost.
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
If you do a git status --ignored
here, you'll get:
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/
Now either do
git stash -u
git stash pop
or
git clean -df
In both cases the allegedly ignored directory localdata
will be gone!
Not sure if this can be considered a bug, but I guess it's at least a feature that nobody needs.
I'll report that to the git development list and see what they think about it.