Merge branch 'bc/parse-options-exit-0-on-help'

Option parsing with 'git rev-parse --parseopt' and in most 'git'
subcommands has been updated to exit with 0 (instead of 129) when the
help option ('-h' or '--help') is requested directly by the user,
aligning with standard Unix convention.

* bc/parse-options-exit-0-on-help:
  parse-options: exit 0 on -h
  rev-parse: have --parseopt callers exit 0 on --help
  parse-options: add a separate case for help output on error
  t1517: skip svn tests if svn is not installed
main
Junio C Hamano 2026-07-19 10:42:16 -07:00
commit 620657c941
40 changed files with 113 additions and 74 deletions

View File

@ -1038,6 +1038,8 @@ int cmd_blame(int argc,
case PARSE_OPT_UNKNOWN:
break;
case PARSE_OPT_HELP:
exit(0);
case PARSE_OPT_HELP_ERROR:
case PARSE_OPT_ERROR:
case PARSE_OPT_SUBCOMMAND:
exit(129);

View File

@ -433,6 +433,8 @@ int cmd_shortlog(int argc,
case PARSE_OPT_UNKNOWN:
break;
case PARSE_OPT_HELP:
exit(0);
case PARSE_OPT_HELP_ERROR:
case PARSE_OPT_ERROR:
case PARSE_OPT_SUBCOMMAND:
exit(129);

View File

@ -1133,6 +1133,8 @@ int cmd_update_index(int argc,
break;
switch (parseopt_state) {
case PARSE_OPT_HELP:
exit(0);
case PARSE_OPT_HELP_ERROR:
case PARSE_OPT_ERROR:
exit(129);
case PARSE_OPT_COMPLETE:

View File

@ -99,7 +99,7 @@ test_create_subtree_add () {
}

test_expect_success 'shows short help text for -h' '
test_expect_code 129 git subtree -h >out 2>err &&
git subtree -h >out 2>err &&
test_must_be_empty err &&
grep -e "^ *or: git subtree pull" out &&
grep -F -e "--[no-]annotate" out

View File

@ -583,7 +583,7 @@ static enum parse_opt_result parse_long_opt(
ambiguous.option->long_name,
(abbrev.flags & OPT_UNSET) ? "no-" : "",
abbrev.option->long_name);
return PARSE_OPT_HELP;
return PARSE_OPT_HELP_ERROR;
}
if (abbrev.option) {
if (*arg_end)
@ -1037,6 +1037,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
usage_with_options(usagestr, options);
case PARSE_OPT_COMPLETE:
case PARSE_OPT_HELP:
case PARSE_OPT_HELP_ERROR:
case PARSE_OPT_ERROR:
case PARSE_OPT_DONE:
case PARSE_OPT_NON_OPTION:
@ -1072,6 +1073,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
case PARSE_OPT_NON_OPTION:
case PARSE_OPT_SUBCOMMAND:
case PARSE_OPT_HELP:
case PARSE_OPT_HELP_ERROR:
case PARSE_OPT_COMPLETE:
BUG("parse_short_opt() cannot return these");
case PARSE_OPT_DONE:
@ -1099,6 +1101,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
case PARSE_OPT_SUBCOMMAND:
case PARSE_OPT_COMPLETE:
case PARSE_OPT_HELP:
case PARSE_OPT_HELP_ERROR:
BUG("parse_short_opt() cannot return these");
case PARSE_OPT_DONE:
break;
@ -1133,6 +1136,8 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
goto unknown;
case PARSE_OPT_HELP:
goto show_usage;
case PARSE_OPT_HELP_ERROR:
goto show_usage_stderr;
case PARSE_OPT_NON_OPTION:
case PARSE_OPT_SUBCOMMAND:
case PARSE_OPT_COMPLETE:
@ -1166,6 +1171,9 @@ unknown:
show_usage:
return usage_with_options_internal(ctx, usagestr, options,
USAGE_NORMAL, USAGE_TO_STDOUT);
show_usage_stderr:
return usage_with_options_internal(ctx, usagestr, options,
USAGE_NORMAL, USAGE_TO_STDERR);
}

int parse_options_end(struct parse_opt_ctx_t *ctx)
@ -1197,6 +1205,8 @@ int parse_options(int argc, const char **argv,
parse_options_start_1(&ctx, argc, argv, prefix, options, flags);
switch (parse_options_step(&ctx, options, usagestr)) {
case PARSE_OPT_HELP:
exit(0);
case PARSE_OPT_HELP_ERROR:
case PARSE_OPT_ERROR:
exit(129);
case PARSE_OPT_COMPLETE:
@ -1363,7 +1373,7 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
parse_options_check_harder(opts);

if (!usagestr)
return PARSE_OPT_HELP;
return err ? PARSE_OPT_HELP_ERROR : PARSE_OPT_HELP;

if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
fprintf(outfile, "cat <<\\EOF\n");
@ -1474,9 +1484,9 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t
fputc('\n', outfile);

if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
fputs("EOF\n", outfile);
fputs("EOF\nexit 0\n", outfile);

return PARSE_OPT_HELP;
return err ? PARSE_OPT_HELP_ERROR : PARSE_OPT_HELP;
}

void NORETURN usage_with_options(const char * const *usagestr,
@ -1495,11 +1505,11 @@ void show_usage_with_options_if_asked(int ac, const char **av,
if (!strcmp(av[1], "-h")) {
usage_with_options_internal(NULL, usagestr, opts,
USAGE_NORMAL, USAGE_TO_STDOUT);
exit(129);
exit(0);
} else if (!strcmp(av[1], "--help-all")) {
usage_with_options_internal(NULL, usagestr, opts,
USAGE_FULL, USAGE_TO_STDOUT);
exit(129);
exit(0);
}
}
}

View File

@ -57,7 +57,8 @@ enum parse_opt_option_flags {
};

enum parse_opt_result {
PARSE_OPT_COMPLETE = -3,
PARSE_OPT_COMPLETE = -4,
PARSE_OPT_HELP_ERROR = -3,
PARSE_OPT_HELP = -2,
PARSE_OPT_ERROR = -1, /* must be the same as error() */
PARSE_OPT_DONE = 0, /* fixed so that "return 0" works */

View File

@ -522,7 +522,7 @@ test_expect_success 'Verify descending sort' '
'

test_expect_success 'Give help even with invalid sort atoms' '
test_expect_code 129 ${git_for_each_ref} --sort=bogus -h >actual 2>&1 &&
${git_for_each_ref} --sort=bogus -h >actual 2>&1 &&
grep "^usage: ${git_for_each_ref}" actual
'


View File

@ -260,7 +260,7 @@ do
(
GIT_CEILING_DIRECTORIES=$(pwd) &&
export GIT_CEILING_DIRECTORIES &&
test_expect_code 129 git -C sub $builtin -h >output 2>err
git -C sub $builtin -h >output 2>err
) &&
test_must_be_empty err &&
test_grep usage output

View File

@ -68,7 +68,7 @@ Alias
EOF

test_expect_success 'test help' '
test_must_fail test-tool parse-options -h >output 2>output.err &&
test-tool parse-options -h >output 2>output.err &&
test_must_be_empty output.err &&
test_cmp expect output
'

View File

@ -29,7 +29,7 @@ help_to_synopsis () {
return 0
fi &&
mkdir -p "$out_dir" &&
test_expect_code 129 git $builtin -h >"$out.raw" 2>&1 &&
test_might_fail git $builtin -h >"$out.raw" 2>&1 &&
sed -n \
-e '1,/^$/ {
/^$/d;

View File

@ -15,9 +15,9 @@ export GIT_TEST_DEFAULT_REF_FORMAT
INVALID_OID=$(test_oid 001)

test_expect_success 'pack-refs does not crash with -h' '
test_expect_code 129 git pack-refs -h >usage &&
git pack-refs -h >usage &&
test_grep "[Uu]sage: git pack-refs " usage &&
test_expect_code 129 nongit git pack-refs -h >usage &&
nongit git pack-refs -h >usage &&
test_grep "[Uu]sage: git pack-refs " usage
'


View File

@ -165,7 +165,7 @@ test_expect_success 'show-ref --branches, --tags, --head, pattern' '
'

test_expect_success 'show-ref --heads is deprecated and hidden' '
test_expect_code 129 git show-ref -h >short-help &&
git show-ref -h >short-help &&
test_grep ! -e --heads short-help &&
git show-ref --heads >actual 2>warning &&
test_grep ! deprecated warning &&

View File

@ -107,12 +107,12 @@ test_expect_success setup '
'

test_expect_success 'correct usage on sub-command -h' '
test_expect_code 129 git reflog expire -h >err &&
git reflog expire -h >err &&
grep "git reflog expire" err
'

test_expect_success 'correct usage on "git reflog show -h"' '
test_expect_code 129 git reflog show -h >err &&
git reflog show -h >err &&
grep -F "git reflog [show]" err
'


View File

@ -12,7 +12,7 @@ test_expect_success 'setup' '

test_expect_success 'usage' '
test_expect_code 129 git reflog exists &&
test_expect_code 129 git reflog exists -h
git reflog exists -h
'

test_expect_success 'usage: unknown option' '

View File

@ -12,7 +12,7 @@ check_invalid_long_option () {
cat <<-\EOF &&
error: unknown option `'${opt#--}\''
EOF
sed -e 1d -e \$d <"$TEST_DIRECTORY/t1502/$spec.help"
sed -e 1d -e /EOF/d -e \$d <"$TEST_DIRECTORY/t1502/$spec.help"
} >expect &&
test_expect_code 129 git rev-parse --parseopt -- $opt \
2>output <"$TEST_DIRECTORY/t1502/$spec" &&
@ -75,7 +75,7 @@ EOF
'

test_expect_success 'test --parseopt help output' '
test_expect_code 129 git rev-parse --parseopt -- -h > output < optionspec &&
git rev-parse --parseopt -- -h > output < optionspec &&
test_cmp "$TEST_DIRECTORY/t1502/optionspec.help" output
'

@ -87,8 +87,9 @@ test_expect_success 'test --parseopt help output no switches' '
| some-command does foo and bar!
|
|EOF
|exit 0
END_EXPECT
test_expect_code 129 git rev-parse --parseopt -- -h > output < optionspec_no_switches &&
git rev-parse --parseopt -- -h > output < optionspec_no_switches &&
test_cmp expect output
'

@ -100,8 +101,9 @@ test_expect_success 'test --parseopt help output hidden switches' '
| some-command does foo and bar!
|
|EOF
|exit 0
END_EXPECT
test_expect_code 129 git rev-parse --parseopt -- -h > output < optionspec_only_hidden_switches &&
git rev-parse --parseopt -- -h > output < optionspec_only_hidden_switches &&
test_cmp expect output
'

@ -115,8 +117,9 @@ test_expect_success 'test --parseopt help-all output hidden switches' '
| --[no-]hidden1 A hidden switch
|
|EOF
|exit 0
END_EXPECT
test_expect_code 129 git rev-parse --parseopt -- --help-all > output < optionspec_only_hidden_switches &&
git rev-parse --parseopt -- --help-all > output < optionspec_only_hidden_switches &&
test_cmp expect output
'

@ -125,7 +128,7 @@ test_expect_success 'test --parseopt invalid switch help output' '
cat <<-\EOF &&
error: unknown option `does-not-exist'\''
EOF
sed -e 1d -e \$d <"$TEST_DIRECTORY/t1502/optionspec.help"
sed -e 1d -e /EOF/d -e \$d <"$TEST_DIRECTORY/t1502/optionspec.help"
} >expect &&
test_expect_code 129 git rev-parse --parseopt -- --does-not-exist 1>/dev/null 2>output < optionspec &&
test_cmp expect output
@ -252,9 +255,10 @@ test_expect_success 'test --parseopt help output: "wrapped" options normal "or:"
| -h, --help show the help
|
|EOF
|exit 0
END_EXPECT

test_must_fail git rev-parse --parseopt -- -h <spec >actual &&
git rev-parse --parseopt -- -h <spec >actual &&
test_cmp expect actual
'

@ -289,14 +293,15 @@ test_expect_success 'test --parseopt help output: multi-line blurb after empty l
| -h, --help show the help
|
|EOF
|exit 0
END_EXPECT

test_must_fail git rev-parse --parseopt -- -h <spec >actual &&
git rev-parse --parseopt -- -h <spec >actual &&
test_cmp expect actual
'

test_expect_success 'test --parseopt help output for optionspec-neg' '
test_expect_code 129 git rev-parse --parseopt -- \
git rev-parse --parseopt -- \
-h >output <"$TEST_DIRECTORY/t1502/optionspec-neg" &&
test_cmp "$TEST_DIRECTORY/t1502/optionspec-neg.help" output
'

View File

@ -10,3 +10,4 @@ usage: some-command [options] <args>...
--no-negative cannot be positivated

EOF
exit 0

View File

@ -34,3 +34,4 @@ Extras
--[no-]extra1 line above used to cause a segfault but no longer does

EOF
exit 0

View File

@ -4,6 +4,13 @@ test_description='check random commands outside repo'

. ./test-lib.sh

test_lazy_prereq SVN '
test_have_prereq PERL && test -z "$NO_SVN_TESTS" && perl -w -e "
use SVN::Core;
use SVN::Repos;
"
'

test_expect_success 'set up a non-repo directory and test file' '
GIT_CEILING_DIRECTORIES=$(pwd) &&
export GIT_CEILING_DIRECTORIES &&
@ -122,39 +129,48 @@ do
archimport | citool | credential-netrc | credential-libsecret | \
credential-osxkeychain | cvsexportcommit | cvsimport | cvsserver | \
daemon | \
difftool--helper | filter-branch | format-rev | fsck-objects | \
get-tar-commit-id | \
difftool--helper | format-rev | fsck-objects | get-tar-commit-id | \
gui | gui--askpass | \
http-backend | http-fetch | http-push | init-db | \
merge-octopus | merge-one-file | merge-resolve | mergetool | \
mktag | p4 | p4.py | pickaxe | remote-ftp | remote-ftps | \
remote-http | remote-https | replay | send-email | \
sh-i18n--envsubst | shell | show | stage | submodule | svn | \
upload-archive--writer | upload-pack | web--browse | whatchanged)
expect_outcome=expect_failure ;;
sh-i18n--envsubst | shell | show | stage | \
upload-archive--writer | upload-pack | whatchanged)
h_expect_outcome=expect_failure
all_expect_outcome=expect_failure
;;
filter-branch | merge-octopus | merge-one-file | merge-resolve | \
mergetool | submodule | svn | web--browse)
h_expect_outcome=expect_success
all_expect_outcome=expect_failure
;;
*)
expect_outcome=expect_success ;;
h_expect_outcome=expect_success
all_expect_outcome=expect_success
;;
esac
case "$cmd" in
instaweb)
prereq=PERL ;;
svn)
prereq=SVN ;;
*)
prereq= ;;
esac
test_$expect_outcome $prereq "'git $cmd -h' outside a repository" '
test_expect_code 129 nongit git $cmd -h >usage &&
test_$h_expect_outcome $prereq "'git $cmd -h' outside a repository" '
nongit git $cmd -h >usage &&
test_grep "[Uu]sage: git $cmd " usage
'
test_$expect_outcome $prereq "'git $cmd --help-all' outside a repository" '
test_expect_code 129 nongit git $cmd --help-all >usage &&
test_$all_expect_outcome $prereq "'git $cmd --help-all' outside a repository" '
nongit git $cmd --help-all >usage &&
test_grep "[Uu]sage: git $cmd " usage
'
done

test_expect_success 'fmt-merge-msg does not crash with -h' '
test_expect_code 129 git fmt-merge-msg -h >usage &&
git fmt-merge-msg -h >usage &&
test_grep "[Uu]sage: git fmt-merge-msg " usage &&
test_expect_code 129 nongit git fmt-merge-msg -h >usage &&
nongit git fmt-merge-msg -h >usage &&
test_grep "[Uu]sage: git fmt-merge-msg " usage
'


View File

@ -75,10 +75,10 @@ sentinel_detector () {
test_expect_success 'git hook usage' '
test_expect_code 129 git hook &&
test_expect_code 129 git hook run &&
test_expect_code 129 git hook run -h &&
git hook run -h &&
test_expect_code 129 git hook run --unknown 2>err &&
test_expect_code 129 git hook list &&
test_expect_code 129 git hook list -h &&
git hook list -h &&
grep "unknown option" err
'


View File

@ -150,7 +150,7 @@ test_expect_success 'git repo info --keys uses lines as its default output forma
'

test_expect_success 'git repo info -h shows only repo info usage' '
test_must_fail git repo info -h >actual &&
git repo info -h >actual &&
test_grep "git repo info" actual &&
test_grep ! "git repo structure" actual
'

View File

@ -225,7 +225,7 @@ test_expect_success 'progress meter option' '
'

test_expect_success 'git repo structure -h shows only repo structure usage' '
test_must_fail git repo structure -h >actual &&
git repo structure -h >actual &&
test_grep "git repo structure" actual &&
test_grep ! "git repo info" actual
'

View File

@ -16,15 +16,15 @@ test_expect_success 'checkout-index -h in broken repository' '
cd broken &&
git init &&
>.git/index &&
test_expect_code 129 git checkout-index -h >usage 2>&1
git checkout-index -h >usage 2>&1
) &&
test_grep "[Uu]sage" broken/usage
'

test_expect_success 'checkout-index does not crash with -h' '
test_expect_code 129 git checkout-index -h >usage &&
git checkout-index -h >usage &&
test_grep "[Uu]sage: git checkout-index " usage &&
test_expect_code 129 nongit git checkout-index -h >usage &&
nongit git checkout-index -h >usage &&
test_grep "[Uu]sage: git checkout-index " usage
'


View File

@ -23,7 +23,7 @@ test_expect_success 'update-index -h with corrupt index' '
cd broken &&
git init &&
>.git/index &&
test_expect_code 129 git update-index -h >usage 2>&1
git update-index -h >usage 2>&1
) &&
test_grep "[Uu]sage: git update-index" broken/usage
'

View File

@ -29,15 +29,15 @@ test_expect_success 'ls-files -h in corrupt repository' '
cd broken &&
git init &&
>.git/index &&
test_expect_code 129 git ls-files -h >usage 2>&1
git ls-files -h >usage 2>&1
) &&
test_grep "[Uu]sage: git ls-files " broken/usage
'

test_expect_success 'ls-files does not crash with -h' '
test_expect_code 129 git ls-files -h >usage &&
git ls-files -h >usage &&
test_grep "[Uu]sage: git ls-files " usage &&
test_expect_code 129 nongit git ls-files -h >usage &&
nongit git ls-files -h >usage &&
test_grep "[Uu]sage: git ls-files " usage
'


View File

@ -33,7 +33,7 @@ test_expect_success REFFILES 'branch -h in broken repository' '
cd broken &&
git init -b main &&
>.git/refs/heads/main &&
test_expect_code 129 git branch -h >usage 2>&1
git branch -h >usage 2>&1
) &&
test_grep "[Uu]sage" broken/usage
'

View File

@ -27,13 +27,13 @@ test_expect_success 'usage on cmd and subcommand invalid option' '
'

test_expect_success 'usage on main command -h emits a summary of subcommands' '
test_expect_code 129 git stash -h >usage &&
git stash -h >usage &&
grep -F "usage: git stash list" usage &&
grep -F "or: git stash show" usage
'

test_expect_success 'usage for subcommands should emit subcommand usage' '
test_expect_code 129 git stash push -h >usage &&
git stash push -h >usage &&
grep -F "usage: git stash [push" usage
'


View File

@ -438,7 +438,7 @@ test_expect_success 'rerere --no-no-rerere-autoupdate' '
'

test_expect_success 'rerere -h' '
test_must_fail git rerere -h >help &&
git rerere -h >help &&
test_grep [Uu]sage help
'


View File

@ -47,7 +47,7 @@ test_expect_success 'midx does not create duplicate pack entries' '
'

test_expect_success 'update-server-info does not crash with -h' '
test_expect_code 129 git update-server-info -h >usage &&
git update-server-info -h >usage &&
test_grep "[Uu]sage: git update-server-info " usage
'


View File

@ -365,7 +365,7 @@ test_expect_success 'gc.recentObjectsHook' '
'

test_expect_success 'prune does not crash with -h' '
test_expect_code 129 git prune -h >usage &&
git prune -h >usage &&
test_grep "[Uu]sage: git prune " usage
'


View File

@ -56,9 +56,9 @@ test_expect_success setup '
git log'

test_expect_success 'send-pack does not crash with -h' '
test_expect_code 129 git send-pack -h >usage &&
git send-pack -h >usage &&
test_grep "[Uu]sage: git send-pack " usage &&
test_expect_code 129 nongit git send-pack -h >usage &&
nongit git send-pack -h >usage &&
test_grep "[Uu]sage: git send-pack " usage
'


View File

@ -86,7 +86,7 @@ test_expect_success 'ls-remote -h is deprecated w/o warning' '
'

test_expect_success 'ls-remote --heads is deprecated and hidden w/o warning' '
test_expect_code 129 git ls-remote -h >short-help &&
git ls-remote -h >short-help &&
test_grep ! -e --head short-help &&
git ls-remote --heads self >actual 2>warning &&
test_cmp expected.branches actual &&

View File

@ -8,9 +8,9 @@ test_description='for-each-ref test'
. ./test-lib.sh

test_expect_success "for-each-ref does not crash with -h" '
test_expect_code 129 git for-each-ref -h >usage &&
git for-each-ref -h >usage &&
test_grep "[Uu]sage: git for-each-ref " usage &&
test_expect_code 129 nongit git for-each-ref -h >usage &&
nongit git for-each-ref -h >usage &&
test_grep "[Uu]sage: git for-each-ref " usage
'


View File

@ -35,7 +35,7 @@ test_expect_success 'gc -h with invalid configuration' '
cd broken &&
git init &&
echo "[gc] pruneexpire = CORRUPT" >>.git/config &&
test_expect_code 129 git gc -h >usage 2>&1
git gc -h >usage 2>&1
) &&
test_grep "[Uu]sage" broken/usage
'

View File

@ -8,9 +8,9 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. "$TEST_DIRECTORY/lib-gpg.sh"

test_expect_success GPG 'verify-tag does not crash with -h' '
test_expect_code 129 git verify-tag -h >usage &&
git verify-tag -h >usage &&
test_grep "[Uu]sage: git verify-tag " usage &&
test_expect_code 129 nongit git verify-tag -h >usage &&
nongit git verify-tag -h >usage &&
test_grep "[Uu]sage: git verify-tag " usage
'


View File

@ -16,7 +16,7 @@ test_expect_success 'status -h in broken repository' '
cd broken &&
git init &&
echo "[status] showuntrackedfiles = CORRUPT" >>.git/config &&
test_expect_code 129 git status -h >usage 2>&1
git status -h >usage 2>&1
) &&
test_grep "[Uu]sage" broken/usage
'
@ -28,7 +28,7 @@ test_expect_success 'commit -h in broken repository' '
cd broken &&
git init &&
echo "[status] showuntrackedfiles = CORRUPT" >>.git/config &&
test_expect_code 129 git commit -h >usage 2>&1
git commit -h >usage 2>&1
) &&
test_grep "[Uu]sage" broken/usage
'

View File

@ -9,9 +9,9 @@ GNUPGHOME_NOT_USED=$GNUPGHOME
. "$TEST_DIRECTORY/lib-gpg.sh"

test_expect_success GPG 'verify-commit does not crash with -h' '
test_expect_code 129 git verify-commit -h >usage &&
git verify-commit -h >usage &&
test_grep "[Uu]sage: git verify-commit " usage &&
test_expect_code 129 nongit git verify-commit -h >usage &&
nongit git verify-commit -h >usage &&
test_grep "[Uu]sage: git verify-commit " usage
'


View File

@ -173,7 +173,7 @@ test_expect_success 'merge -h with invalid index' '
cd broken &&
git init &&
>.git/index &&
test_expect_code 129 git merge -h >usage
git merge -h >usage
) &&
test_grep "[Uu]sage: git merge" broken/usage
'

View File

@ -27,12 +27,11 @@ prompt_given ()
}

test_expect_success 'basic usage requires no repo' '
test_expect_code 129 git difftool -h >output &&
git difftool -h >output &&
test_grep ^usage: output &&
# create a ceiling directory to prevent Git from finding a repo
mkdir -p not/repo &&
test_when_finished rm -r not &&
test_expect_code 129 \
env GIT_CEILING_DIRECTORIES="$(pwd)/not" \
git -C not/repo difftool -h >output &&
test_grep ^usage: output

View File

@ -35,7 +35,7 @@ test_systemd_analyze_verify () {
}

test_expect_success 'help text' '
test_expect_code 129 git maintenance -h >actual &&
git maintenance -h >actual &&
test_grep "usage: git maintenance <subcommand>" actual &&
test_expect_code 129 git maintenance barf 2>err &&
test_grep "unknown subcommand: \`barf'\''" err &&

View File

@ -188,7 +188,7 @@ static void show_usage_if_asked_helper(const char *err, ...)
va_start(params, err);
vfreportf(stdout, _("usage: "), err, params);
va_end(params);
exit(129);
exit(0);
}

void show_usage_if_asked(int ac, const char **av, const char *err)