Search code examples
gitgitignore

What is fastest way to .gitignore a directory: With or without trailing slash and **?


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.


Solution

  • 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:

    Git 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.)