Re: "git add -i" with path gives "Argument list too long"
[cc'd Junio: there is a question of path limiters versus pathspecs near the bottom].
On Mon, Jan 04, 2010 at 07:43:10PM +0100, Wincent Colaiuta wrote:
Show 11 quoted lines
> Just ran "git add -i <path>" with "<path>" pointing to a subdirectory
> which happens to have a bunch of files in it (about 7k) and it barfed
> thusly:
>
> Can't exec "git": Argument list too long at /usr/local/libexec/git-
> core/git-add--interactive line 158.
> Died at /usr/local/libexec/git-core/git-add--interactive line 158.
>
> I see that what it's trying to do under the hood is:
>
> git diff-index --cached --numstat --summary HEAD -- <7,000+ paths...>
Yep, and there is a similar diff-files call after that.
Show 5 quoted lines
> Sure, we could divide the paths into smaller groups, run multiple
> invocations of "git diff-index", and concatenate the results. But it
> would be nicer if there was some other way that we could get at the
> same information without having to pass 7,000 paths explicitly on the
> command line; is there any which I am overlooking?
No, I don't think there is way to do it with the current code short of breaking up the output.
Show 6 quoted lines
> The enormous file list is the result of passing <path> into "git ls-
> files -- <path>". Would it be worth:
>
> - either, modifying "git diff-index" to accept a list of paths over
> stdin so that we could at least pipe the output from "git ls-files"
> into "git diff-index"
We could do that. It would also need a patch for diff-files. And unfortunately it makes their interface somewhat inconsistent then with diff-tree, which already has a --stdin but uses it for a list of tree-ishes.
> - or, preferably, teach "git diff index" to recurse into directories
> rather than expect a list of paths-of-blobs (possibly with a command
> line switch to activate the behaviour if it were deemed a dangerous
> default)
Doesn't it already do this? If I say "git diff index subdir" it will limit the diff only to things inside subdir/.
In fact, it is tempting to do this:
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index bfd1003..a8b3e30 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -275,15 +275,6 @@ sub list_modified {
my ($only) = @_;
my (%data, @return);
my ($add, $del, $adddel, $file);
- my @tracked = ();
-
- if (@ARGV) {
- @tracked = map {
- chomp $_;
- unquote_path($_);
- } run_cmd_pipe(qw(git ls-files --), @ARGV);
- return if (!@tracked);
- }
my $reference;
if (defined $patch_mode_revision and $patch_mode_revision ne 'HEAD') {
@@ -295,7 +286,7 @@ sub list_modified {
}
for (run_cmd_pipe(qw(git diff-index --cached
--numstat --summary), $reference,
- '--', @tracked)) {
+ '--', @ARGV)) {
if (($add, $del, $file) =
/^([-\d]+) ([-\d]+) (.*)/) {
my ($change, $bin);
@@ -320,7 +311,7 @@ sub list_modified {
}
}
- for (run_cmd_pipe(qw(git diff-files --numstat --summary --), @tracked)) {
+ for (run_cmd_pipe(qw(git diff-files --numstat --summary --), @ARGV)) {
if (($add, $del, $file) =
/^([-\d]+) ([-\d]+) (.*)/) {
$file = unquote_path($file);
but note that the pathspecs given to ls-files and the path limiters
given to diff are not quite the same. So "git add -i '*.c'" will
currently find "subdir/foo.c", but would not with the above patch. Is
that what you meant when you said "recurse into directories"?
I seem to recall Junio noting in the past the inconsistencies in git
about what is a path and what is a pathspec. Is this one of those
inconsistencies, and would it be a positive thing to fix it?
-Peff