pathspec: don't error out on all-exclusionary pathspec patterns

Instead of erroring out and telling the user that they should add a positive pattern that covers everything else, just _do_ that. For commands where we honor the current cwd by default (ie grep, ls-files etc), we make that default positive pathspec be the current working directory. And for commands that default to the whole project (ie diff, log, etc), the default positive pathspec is the whole project. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Linus Torvalds committed Feb 7, 2017 at 21:08 UTC 859b7f1d0e742493d2a9396794cd9040213ad846
3 files changed +17 -8
Documentation/glossary-content.txt
+3 -1
@@ -387,7 +387,9 @@ Glob magic is incompatible with literal magic.
387 exclude;;
388 After a path matches any non-exclude pathspec, it will be run
389 through all exclude pathspec (magic signature: `!` or its
390 - synonym `^`). If it matches, the path is ignored.
390 + synonym `^`). If it matches, the path is ignored. When there
391 + is no non-exclude pathspec, the exclusion is applied to the
392 + result set as if invoked without any pathspec.
393 --
394
395 [[def_parent]]parent::
pathspec.c
+10 -5
@@ -522,7 +522,7 @@ void parse_pathspec(struct pathspec *pathspec,
522 }
523
524 pathspec->nr = n;
525 - ALLOC_ARRAY(pathspec->items, n);
525 + ALLOC_ARRAY(pathspec->items, n + 1);
526 item = pathspec->items;
527 prefixlen = prefix ? strlen(prefix) : 0;
528
@@ -546,10 +546,15 @@ void parse_pathspec(struct pathspec *pathspec,
546 pathspec->magic |= item[i].magic;
547 }
548
549 - if (nr_exclude == n)
550 - die(_("There is nothing to exclude from by :(exclude) patterns.\n"
551 - "Perhaps you forgot to add either ':/' or '.' ?"));
552 -
549 + /*
550 + * If everything is an exclude pattern, add one positive pattern
551 + * that matches everyting. We allocated an extra one for this.
552 + */
553 + if (nr_exclude == n) {
554 + int plen = (!(flags & PATHSPEC_PREFER_CWD)) ? 0 : prefixlen;
555 + init_pathspec_item(item + n, 0, prefix, plen, "");
556 + pathspec->nr++;
557 + }
558
559 if (pathspec->magic & PATHSPEC_MAXDEPTH) {
560 if (flags & PATHSPEC_KEEP_ORDER)
t/t6132-pathspec-exclude.sh
+4 -2
@@ -25,8 +25,10 @@ EOF
25 test_cmp expect actual
26 '
27
28 -test_expect_success 'exclude only should error out' '
29 - test_must_fail git log --oneline --format=%s -- ":(exclude)sub"
28 +test_expect_success 'exclude only no longer errors out' '
29 + git log --oneline --format=%s -- . ":(exclude)sub" >expect &&
30 + git log --oneline --format=%s -- ":(exclude)sub" >actual &&
31 + test_cmp expect actual
32 '
33
34 test_expect_success 't_e_i() exclude sub' '