-2

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.

torek
  • 448,244
  • 59
  • 642
  • 775
cachius
  • 1,743
  • 1
  • 8
  • 21
  • 3
    Out of curiosity: is there any active performance issue that you're tracking or is this theoretical interest only? Because I can't imagine that this kind of difference makes *any* noticeable difference in a daily workflow. Which specific operations do you want to know the "performance" of? – Joachim Sauer Apr 04 '22 at 15:45
  • This is only of theoretical interest. – cachius Apr 04 '22 at 15:48
  • 1
    The semantic differences are elaborated in https://stackoverflow.com/q/17888695 – cachius Apr 04 '22 at 15:52

2 Answers2

1

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

torek
  • 448,244
  • 59
  • 642
  • 775
0

If you want ignore a folder use:

/folderName => ignore folderName || fileName from root directory

/folderName/ => ignore folderName from root directory

But if you folderName/ ignore all folders with the name folderName. I would guess that that tokes more time because he iterate recursive over all folders from root upwards.

but in my opinion it doesn't matter. gitignore is not important for the programme and has no influence on the performance of the programm.

Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79
  • I know it practically doesn't matter, but I'm interested in the subtle differences anyway: Maybe one alternative only runs a loop once while another runs it 10 times. By the way, `/folderName` would also exclude a file with that name, not just the dir. – cachius Apr 04 '22 at 15:47