I want to exclude the directory 'dir' from a git repo using .gitignore. No further exclude patterns shall refer to it with !/dir...
, it shall only be mentioned once in the .gitignore.
Which of these alternatives is the fastest for git to apply and decide not to look further into the dir?
/dir
/dir/
/dir/*
/dir/**
The pattern matching is implemented in git/dir.c. Relevant functions seem to be match_pathspec_item, do_match_pathspec, prep_exclude and treat_directory.
As you note indirectly, these aren't semantically equivalent since they act differently if /dir
is a file. However, if you somehow "know" that /dir
will in fact be a directory, /dir
and /dir/
would be the "efficient" ways to list these as they will omit opening-and-reading the directory.
Whether /dir/
is less efficient or just as efficient as /dir
depends on your OS and its readdir
implementation: when Git reads the directory /
(the top of the working tree), it gets the name components .
, ..
, README.txt
(assuming there is such a file), abc
(maybe a file, maybe a directory, we'll just assume there is something named abc
), dir
(a directory), and whatever else. It may also get a useful d_type
field: POSIX only requires a d_name
and d_ino
, but Linux and the BSDs have a d_type
field. The OS will fill in d_type
with one of:
DT_UNKNOWN
: we didn't tell you anythingDT_DIR
: this entity is for a directoryDT_REG
: this entity is for a regular fileGit will use this value, if it's available. If it is DT_DIR
, Git will know that dir
is a directory and won't need to call lstat
on the path when deciding whether the /dir/
entity matches. If it is DT_UNKNOWN
, Git won't know what kind of entity dir
represents and will need to call lstat
. However, for the /dir
anchored gitignore entry, Git doesn't care what kind of entity dir
represents, so it definitely won't need to call lstat
. But maybe it doesn't need to call lstat
anyway, so that this gains nothing.
(Should /dir
name a file and you want Git to store that file if it exists, or complain about it as untracked as appropriate, you should use /dir/
here and not worry about the cost of a single lstat
system call, even though it may be measured in hundreds of microseconds, or even low-digit milliseconds, rather than nanoseconds. But milliseconds do add up eventually, of course.)