Is there a difference between /dir
and /dir/
in the .gitignore file within a Git repository?
How are the following different?
/dir
/dir/
/dir/*
Is there a difference between /dir
and /dir/
in the .gitignore file within a Git repository?
How are the following different?
/dir
/dir/
/dir/*
The Patterns Have Different Meanings
According to the Pattern Format section of gitignore(5):
What this means is that "dir" can be a file, directory, or symbolic link, but "dir/" with a trailing slash will only match a directory. In most cases, the difference won't matter, but when it does, understanding the distinction can remove ambiguity from your .gitignore files.
Git 2.23 (Q3 2019) attempts to revamp the description about slashes in gitignore patterns (used to indicate things like "anchored to this level only" and "only matches directories")
The documentation now includes:
This is a old question, but high ranked on Google and the top voted answer is wrong. Here goes the correct answer.
Yes, these rules are different.
/dir
will match a file, directory, link, anything nameddir
/dir/
will match only a directory nameddir
/dir/*
will match all files, directories and anything else inside a directory nameddir
(but not thedir
directory itself)./dir
,/dir/
and/dir/*
are NOT equivalent. The difference is very clear when using overriding rules, like the famous!.gitkeep
to get around the limitation of tracking empty directories. Suppose the existence of the filedir/.gitkeep
/dir
and/dir/
, Git won't even look inside the directory so the.gitkeep
won't be seen./dir/*
, the file will be detected by Git and the directory will be kept if this.gitkeep
is committed, because the rule doesn't apply to the directory itself, only to its contents.OBS: All the rules mentioned above are anchored at the current directory (the place where the
.gitignore
is), because of the/
prefix. Without the prefix, the rules would apply not only for that specific directory, but also for the sub-directories or everywhere in the repository, if the.gitignore
is located at the root level.