$git status -s
A dirA/dirA-1/dirA-1-1/file1.txt
A dirA/dirA-1/dirA-1-2/file3.txt
A dirA/dirA-1/file4.txt
A dirB/dirB-1/dirB-1-1/file6.txt
A file7.txt
?? dirA/dirA-1/dirA-1-2/file2.html
?? dirB/dirB-1/dirB-1-1/file5.html
$ (ulimit -s 128 && git add -p drivers)
Can't exec "git": Argument list too long at .../git-add--interactive line 177.
Died at .../git-add--interactive line 177.
That's on the linux.git repository, which has about 20K files in the "drivers" directory (none of them modified in this case). The "ulimit -s" trick is necessary to show the problem on Linux even for such a gigantic set of paths.
Other operating systems have much smaller limits (e.g., a real-world case was seen with only 5K files on OS X).
Even when it does work, it's really slow. The pathspec
code is not optimized for huge numbers of paths. Here's
the same case without the ulimit:
$ time git add -p drivers
No changes.
real 0m16.559s
user 0m53.140s
sys 0m0.220s
We can improve this by skipping "ls-files" completely, and just feeding the original pathspecs to the diff commands.
Historically the pathspec language supported by "diff-index" was weaker, but that is no longer the case.