commit: support the --pathspec-from-file option
Decisions taken for simplicity: 1) For now, `--pathspec-from-file` is declared incompatible with `--interactive/--patch`, even when <file> is not `stdin`. Such use case it not really expected. Also, it would require changes to `interactive_add()`. 2) It is not allowed to pass pathspec in both args and file. Signed-off-by: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
66a25a7242
commit
e440fc5888
@ -13,7 +13,8 @@ SYNOPSIS
|
|||||||
[-F <file> | -m <msg>] [--reset-author] [--allow-empty]
|
[-F <file> | -m <msg>] [--reset-author] [--allow-empty]
|
||||||
[--allow-empty-message] [--no-verify] [-e] [--author=<author>]
|
[--allow-empty-message] [--no-verify] [-e] [--author=<author>]
|
||||||
[--date=<date>] [--cleanup=<mode>] [--[no-]status]
|
[--date=<date>] [--cleanup=<mode>] [--[no-]status]
|
||||||
[-i | -o] [-S[<keyid>]] [--] [<pathspec>...]
|
[-i | -o] [--pathspec-from-file=<file> [--pathspec-file-nul]]
|
||||||
|
[-S[<keyid>]] [--] [<pathspec>...]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
@ -278,6 +279,19 @@ FROM UPSTREAM REBASE" section in linkgit:git-rebase[1].)
|
|||||||
already been staged. If used together with `--allow-empty`
|
already been staged. If used together with `--allow-empty`
|
||||||
paths are also not required, and an empty commit will be created.
|
paths are also not required, and an empty commit will be created.
|
||||||
|
|
||||||
|
--pathspec-from-file=<file>::
|
||||||
|
Pathspec is passed in `<file>` instead of commandline args. If
|
||||||
|
`<file>` is exactly `-` then standard input is used. Pathspec
|
||||||
|
elements are separated by LF or CR/LF. Pathspec elements can be
|
||||||
|
quoted as explained for the configuration variable `core.quotePath`
|
||||||
|
(see linkgit:git-config[1]). See also `--pathspec-file-nul` and
|
||||||
|
global `--literal-pathspecs`.
|
||||||
|
|
||||||
|
--pathspec-file-nul::
|
||||||
|
Only meaningful with `--pathspec-from-file`. Pathspec elements are
|
||||||
|
separated with NUL character and all other characters are taken
|
||||||
|
literally (including newlines and quotes).
|
||||||
|
|
||||||
-u[<mode>]::
|
-u[<mode>]::
|
||||||
--untracked-files[=<mode>]::
|
--untracked-files[=<mode>]::
|
||||||
Show untracked files.
|
Show untracked files.
|
||||||
|
@ -107,9 +107,9 @@ static int all, also, interactive, patch_interactive, only, amend, signoff;
|
|||||||
static int edit_flag = -1; /* unspecified */
|
static int edit_flag = -1; /* unspecified */
|
||||||
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
|
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
|
||||||
static int config_commit_verbose = -1; /* unspecified */
|
static int config_commit_verbose = -1; /* unspecified */
|
||||||
static int no_post_rewrite, allow_empty_message;
|
static int no_post_rewrite, allow_empty_message, pathspec_file_nul;
|
||||||
static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;
|
static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg;
|
||||||
static char *sign_commit;
|
static char *sign_commit, *pathspec_from_file;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The default commit message cleanup mode will remove the lines
|
* The default commit message cleanup mode will remove the lines
|
||||||
@ -343,6 +343,23 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix
|
|||||||
PATHSPEC_PREFER_FULL,
|
PATHSPEC_PREFER_FULL,
|
||||||
prefix, argv);
|
prefix, argv);
|
||||||
|
|
||||||
|
if (pathspec_from_file) {
|
||||||
|
if (interactive)
|
||||||
|
die(_("--pathspec-from-file is incompatible with --interactive/--patch"));
|
||||||
|
|
||||||
|
if (pathspec.nr)
|
||||||
|
die(_("--pathspec-from-file is incompatible with pathspec arguments"));
|
||||||
|
|
||||||
|
parse_pathspec_file(&pathspec, 0,
|
||||||
|
PATHSPEC_PREFER_FULL,
|
||||||
|
prefix, pathspec_from_file, pathspec_file_nul);
|
||||||
|
} else if (pathspec_file_nul) {
|
||||||
|
die(_("--pathspec-file-nul requires --pathspec-from-file"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pathspec.nr && (also || (only && !amend && !allow_empty)))
|
||||||
|
die(_("No paths with --include/--only does not make sense."));
|
||||||
|
|
||||||
if (read_cache_preload(&pathspec) < 0)
|
if (read_cache_preload(&pathspec) < 0)
|
||||||
die(_("index file corrupt"));
|
die(_("index file corrupt"));
|
||||||
|
|
||||||
@ -1198,8 +1215,6 @@ static int parse_and_validate_options(int argc, const char *argv[],
|
|||||||
|
|
||||||
if (also + only + all + interactive > 1)
|
if (also + only + all + interactive > 1)
|
||||||
die(_("Only one of --include/--only/--all/--interactive/--patch can be used."));
|
die(_("Only one of --include/--only/--all/--interactive/--patch can be used."));
|
||||||
if (argc == 0 && (also || (only && !amend && !allow_empty)))
|
|
||||||
die(_("No paths with --include/--only does not make sense."));
|
|
||||||
cleanup_mode = get_cleanup_mode(cleanup_arg, use_editor);
|
cleanup_mode = get_cleanup_mode(cleanup_arg, use_editor);
|
||||||
|
|
||||||
handle_untracked_files_arg(s);
|
handle_untracked_files_arg(s);
|
||||||
@ -1535,6 +1550,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
|||||||
OPT_BOOL(0, "amend", &amend, N_("amend previous commit")),
|
OPT_BOOL(0, "amend", &amend, N_("amend previous commit")),
|
||||||
OPT_BOOL(0, "no-post-rewrite", &no_post_rewrite, N_("bypass post-rewrite hook")),
|
OPT_BOOL(0, "no-post-rewrite", &no_post_rewrite, N_("bypass post-rewrite hook")),
|
||||||
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, N_("mode"), N_("show untracked files, optional modes: all, normal, no. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
|
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, N_("mode"), N_("show untracked files, optional modes: all, normal, no. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
|
||||||
|
OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
|
||||||
|
OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
|
||||||
/* end commit contents options */
|
/* end commit contents options */
|
||||||
|
|
||||||
OPT_HIDDEN_BOOL(0, "allow-empty", &allow_empty,
|
OPT_HIDDEN_BOOL(0, "allow-empty", &allow_empty,
|
||||||
|
130
t/t7526-commit-pathspec-file.sh
Executable file
130
t/t7526-commit-pathspec-file.sh
Executable file
@ -0,0 +1,130 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
test_description='commit --pathspec-from-file'
|
||||||
|
|
||||||
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
test_tick
|
||||||
|
|
||||||
|
test_expect_success setup '
|
||||||
|
test_commit file0 &&
|
||||||
|
git tag checkpoint &&
|
||||||
|
|
||||||
|
echo A >fileA.t &&
|
||||||
|
echo B >fileB.t &&
|
||||||
|
echo C >fileC.t &&
|
||||||
|
echo D >fileD.t &&
|
||||||
|
git add fileA.t fileB.t fileC.t fileD.t
|
||||||
|
'
|
||||||
|
|
||||||
|
restore_checkpoint () {
|
||||||
|
git reset --soft checkpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
verify_expect () {
|
||||||
|
git diff-tree --no-commit-id --name-status -r HEAD >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
}
|
||||||
|
|
||||||
|
test_expect_success '--pathspec-from-file from stdin' '
|
||||||
|
restore_checkpoint &&
|
||||||
|
|
||||||
|
echo fileA.t | git commit --pathspec-from-file=- -m "Commit" &&
|
||||||
|
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
A fileA.t
|
||||||
|
EOF
|
||||||
|
verify_expect
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '--pathspec-from-file from file' '
|
||||||
|
restore_checkpoint &&
|
||||||
|
|
||||||
|
echo fileA.t >list &&
|
||||||
|
git commit --pathspec-from-file=list -m "Commit" &&
|
||||||
|
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
A fileA.t
|
||||||
|
EOF
|
||||||
|
verify_expect
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'NUL delimiters' '
|
||||||
|
restore_checkpoint &&
|
||||||
|
|
||||||
|
printf "fileA.t\0fileB.t\0" | git commit --pathspec-from-file=- --pathspec-file-nul -m "Commit" &&
|
||||||
|
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
A fileA.t
|
||||||
|
A fileB.t
|
||||||
|
EOF
|
||||||
|
verify_expect
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'LF delimiters' '
|
||||||
|
restore_checkpoint &&
|
||||||
|
|
||||||
|
printf "fileA.t\nfileB.t\n" | git commit --pathspec-from-file=- -m "Commit" &&
|
||||||
|
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
A fileA.t
|
||||||
|
A fileB.t
|
||||||
|
EOF
|
||||||
|
verify_expect
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'no trailing delimiter' '
|
||||||
|
restore_checkpoint &&
|
||||||
|
|
||||||
|
printf "fileA.t\nfileB.t" | git commit --pathspec-from-file=- -m "Commit" &&
|
||||||
|
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
A fileA.t
|
||||||
|
A fileB.t
|
||||||
|
EOF
|
||||||
|
verify_expect
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'CRLF delimiters' '
|
||||||
|
restore_checkpoint &&
|
||||||
|
|
||||||
|
printf "fileA.t\r\nfileB.t\r\n" | git commit --pathspec-from-file=- -m "Commit" &&
|
||||||
|
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
A fileA.t
|
||||||
|
A fileB.t
|
||||||
|
EOF
|
||||||
|
verify_expect
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'quotes' '
|
||||||
|
restore_checkpoint &&
|
||||||
|
|
||||||
|
printf "\"file\\101.t\"" | git commit --pathspec-from-file=- -m "Commit" &&
|
||||||
|
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
A fileA.t
|
||||||
|
EOF
|
||||||
|
verify_expect expect
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'quotes not compatible with --pathspec-file-nul' '
|
||||||
|
restore_checkpoint &&
|
||||||
|
|
||||||
|
printf "\"file\\101.t\"" >list &&
|
||||||
|
test_must_fail git commit --pathspec-from-file=list --pathspec-file-nul -m "Commit"
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'only touches what was listed' '
|
||||||
|
restore_checkpoint &&
|
||||||
|
|
||||||
|
printf "fileB.t\nfileC.t\n" | git commit --pathspec-from-file=- -m "Commit" &&
|
||||||
|
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
A fileB.t
|
||||||
|
A fileC.t
|
||||||
|
EOF
|
||||||
|
verify_expect
|
||||||
|
'
|
||||||
|
|
||||||
|
test_done
|
Loading…
Reference in New Issue
Block a user