builtin-add.c: optimize -A option and "git add ."
commit1e5f764c93edfd8f6575b6ede769b079a1fc5a21
authorJunio C Hamano <gitster@pobox.com>
Wed, 23 Jul 2008 05:30:40 +0000 (22 22:30 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sat, 26 Jul 2008 04:14:21 +0000 (25 21:14 -0700)
treeff51f0d6bad8585db5d2c7f85aa255646369b68a
parent041aee31be378b3b38e3a0913b29970a7f78873b
builtin-add.c: optimize -A option and "git add ."

The earlier "git add -A" change was done in a quite inefficient
way (i.e. it is as unefficient as "git add -u && git add ." modulo
one fork/exec and read/write index).

When the user asks "git add .", we do not have to examine all paths
we encounter and perform the excluded() and dir_add_name()
processing, both of which are slower code and use slower data structure
by git standards, especially when the index is already populated.

Instead, we implement "git add $pathspec..." as:

 - read the index;

 - read_directory() to process untracked, unignored files the current
   way, that is, recursively doing readdir(), filtering them by pathspec
   and excluded(), queueing them via dir_add_name() and finally do
   add_files(); and

 - iterate over the index, filtering them by pathspec, and update only
   the modified/type changed paths but not deleted ones.

And "git add -A" becomes exactly the same as above, modulo:

 - missing $pathspec means "." instead of being an error; and

 - "iterate over the index" part handles deleted ones as well,
   i.e. exactly what the current update_callback() in builtin-add.c does.

In either case, because fill_directory() does not use read_directory() to
read everything in, we need to add an extra logic to iterate over the
index to catch mistyped pathspec.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-add.c