add global --literal-pathspecs option
Git takes pathspec arguments in many places to limit the
scope of an operation. These pathspecs are treated not as
literal paths, but as glob patterns that can be fed to
fnmatch. When a user is giving a specific pattern, this is a
nice feature.
However, when programatically providing pathspecs, it can be
a nuisance. For example, to find the latest revision which
modified "$foo", one can use "git rev-list -- $foo". But if
"$foo" contains glob characters (e.g., "f*"), it will
erroneously match more entries than desired. The caller
needs to quote the characters in $foo, and even then, the
results may not be exactly the same as with a literal
pathspec. For instance, the depth checks in
match_pathspec_depth do not kick in if we match via fnmatch.
This patch introduces a global command-line option (i.e.,
one for "git" itself, not for specific commands) to turn
this behavior off. It also has a matching environment
variable, which can make it easier if you are a script or
porcelain interface that is going to issue many such
commands.
This option cannot turn off globbing for particular
pathspecs. That could eventually be done with a ":(noglob)"
magic pathspec prefix. However, that level of granularity is
more cumbersome to use for many cases, and doing ":(noglob)"
right would mean converting the whole codebase to use
"struct pathspec", as the usual "const char **pathspec"
cannot represent extra per-item flags.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-12-19 23:37:30 +01:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='test globbing (and noglob) of pathspec limiting'
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
test_expect_success 'create commits with glob characters' '
|
|
|
|
test_commit unrelated bar &&
|
|
|
|
test_commit vanilla foo &&
|
2013-01-06 15:07:43 +01:00
|
|
|
# insert file "f*" in the commit, but in a way that avoids
|
|
|
|
# the name "f*" in the worktree, because it is not allowed
|
|
|
|
# on Windows (the tests below do not depend on the presence
|
|
|
|
# of the file in the worktree)
|
|
|
|
git update-index --add --cacheinfo 100644 "$(git rev-parse HEAD:foo)" "f*" &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m star &&
|
add global --literal-pathspecs option
Git takes pathspec arguments in many places to limit the
scope of an operation. These pathspecs are treated not as
literal paths, but as glob patterns that can be fed to
fnmatch. When a user is giving a specific pattern, this is a
nice feature.
However, when programatically providing pathspecs, it can be
a nuisance. For example, to find the latest revision which
modified "$foo", one can use "git rev-list -- $foo". But if
"$foo" contains glob characters (e.g., "f*"), it will
erroneously match more entries than desired. The caller
needs to quote the characters in $foo, and even then, the
results may not be exactly the same as with a literal
pathspec. For instance, the depth checks in
match_pathspec_depth do not kick in if we match via fnmatch.
This patch introduces a global command-line option (i.e.,
one for "git" itself, not for specific commands) to turn
this behavior off. It also has a matching environment
variable, which can make it easier if you are a script or
porcelain interface that is going to issue many such
commands.
This option cannot turn off globbing for particular
pathspecs. That could eventually be done with a ":(noglob)"
magic pathspec prefix. However, that level of granularity is
more cumbersome to use for many cases, and doing ":(noglob)"
right would mean converting the whole codebase to use
"struct pathspec", as the usual "const char **pathspec"
cannot represent extra per-item flags.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-12-19 23:37:30 +01:00
|
|
|
test_commit bracket "f[o][o]"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'vanilla pathspec matches literally' '
|
|
|
|
echo vanilla >expect &&
|
|
|
|
git log --format=%s -- foo >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'star pathspec globs' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
bracket
|
|
|
|
star
|
|
|
|
vanilla
|
|
|
|
EOF
|
|
|
|
git log --format=%s -- "f*" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'bracket pathspec globs and matches literal brackets' '
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
bracket
|
|
|
|
vanilla
|
|
|
|
EOF
|
|
|
|
git log --format=%s -- "f[o][o]" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'no-glob option matches literally (vanilla)' '
|
|
|
|
echo vanilla >expect &&
|
|
|
|
git --literal-pathspecs log --format=%s -- foo >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'no-glob option matches literally (star)' '
|
|
|
|
echo star >expect &&
|
|
|
|
git --literal-pathspecs log --format=%s -- "f*" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'no-glob option matches literally (bracket)' '
|
|
|
|
echo bracket >expect &&
|
|
|
|
git --literal-pathspecs log --format=%s -- "f[o][o]" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'no-glob environment variable works' '
|
|
|
|
echo star >expect &&
|
|
|
|
GIT_LITERAL_PATHSPECS=1 git log --format=%s -- "f*" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_done
|