Skip to content

Commit 135365d

Browse files
committed
Merge branch 'am/pathspec-f-f-checkout'
A few more commands learned the "--pathspec-from-file" command line option. * am/pathspec-f-f-checkout: checkout, restore: support the --pathspec-from-file option doc: restore: synchronize <pathspec> description doc: checkout: synchronize <pathspec> description doc: checkout: fix broken text reference doc: checkout: remove duplicate synopsis add: support the --pathspec-from-file option cmd_add: prepare for next patch
2 parents ff0cb70 + a9aecc7 commit 135365d

9 files changed

+548
-42
lines changed

Documentation/git-add.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ SYNOPSIS
1111
'git add' [--verbose | -v] [--dry-run | -n] [--force | -f] [--interactive | -i] [--patch | -p]
1212
[--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]]
1313
[--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing] [--renormalize]
14-
[--chmod=(+|-)x] [--] [<pathspec>...]
14+
[--chmod=(+|-)x] [--pathspec-from-file=<file> [--pathspec-file-nul]]
15+
[--] [<pathspec>...]
1516

1617
DESCRIPTION
1718
-----------
@@ -187,6 +188,19 @@ for "git add --no-all <pathspec>...", i.e. ignored removed files.
187188
bit is only changed in the index, the files on disk are left
188189
unchanged.
189190

191+
--pathspec-from-file=<file>::
192+
Pathspec is passed in `<file>` instead of commandline args. If
193+
`<file>` is exactly `-` then standard input is used. Pathspec
194+
elements are separated by LF or CR/LF. Pathspec elements can be
195+
quoted as explained for the configuration variable `core.quotePath`
196+
(see linkgit:git-config[1]). See also `--pathspec-file-nul` and
197+
global `--literal-pathspecs`.
198+
199+
--pathspec-file-nul::
200+
Only meaningful with `--pathspec-from-file`. Pathspec elements are
201+
separated with NUL character and all other characters are taken
202+
literally (including newlines and quotes).
203+
190204
\--::
191205
This option can be used to separate command-line options from
192206
the list of files, (useful when filenames might be mistaken

Documentation/git-checkout.txt

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ SYNOPSIS
1212
'git checkout' [-q] [-f] [-m] --detach [<branch>]
1313
'git checkout' [-q] [-f] [-m] [--detach] <commit>
1414
'git checkout' [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
15-
'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...
16-
'git checkout' [<tree-ish>] [--] <pathspec>...
17-
'git checkout' (-p|--patch) [<tree-ish>] [--] [<paths>...]
15+
'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>...
16+
'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]
17+
'git checkout' (-p|--patch) [<tree-ish>] [--] [<pathspec>...]
1818

1919
DESCRIPTION
2020
-----------
2121
Updates files in the working tree to match the version in the index
22-
or the specified tree. If no paths are given, 'git checkout' will
22+
or the specified tree. If no pathspec was given, 'git checkout' will
2323
also update `HEAD` to set the specified branch as the current
2424
branch.
2525

@@ -79,13 +79,14 @@ be used to detach `HEAD` at the tip of the branch (`git checkout
7979
+
8080
Omitting `<branch>` detaches `HEAD` at the tip of the current branch.
8181

82-
'git checkout' [<tree-ish>] [--] <pathspec>...::
82+
'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>...::
83+
'git checkout' [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]::
8384

84-
Overwrite paths in the working tree by replacing with the
85-
contents in the index or in the `<tree-ish>` (most often a
86-
commit). When a `<tree-ish>` is given, the paths that
87-
match the `<pathspec>` are updated both in the index and in
88-
the working tree.
85+
Overwrite the contents of the files that match the pathspec.
86+
When the `<tree-ish>` (most often a commit) is not given,
87+
overwrite working tree with the contents in the index.
88+
When the `<tree-ish>` is given, overwrite both the index and
89+
the working tree with the contents at the `<tree-ish>`.
8990
+
9091
The index may contain unmerged entries because of a previous failed merge.
9192
By default, if you try to check out such an entry from the index, the
@@ -96,12 +97,10 @@ using `--ours` or `--theirs`. With `-m`, changes made to the working tree
9697
file can be discarded to re-create the original conflicted merge result.
9798

9899
'git checkout' (-p|--patch) [<tree-ish>] [--] [<pathspec>...]::
99-
This is similar to the "check out paths to the working tree
100-
from either the index or from a tree-ish" mode described
101-
above, but lets you use the interactive interface to show
102-
the "diff" output and choose which hunks to use in the
103-
result. See below for the description of `--patch` option.
104-
100+
This is similar to the previous mode, but lets you use the
101+
interactive interface to show the "diff" output and choose which
102+
hunks to use in the result. See below for the description of
103+
`--patch` option.
105104

106105
OPTIONS
107106
-------
@@ -309,6 +308,19 @@ Note that this option uses the no overlay mode by default (see also
309308
working tree, but not in `<tree-ish>` are removed, to make them
310309
match `<tree-ish>` exactly.
311310

311+
--pathspec-from-file=<file>::
312+
Pathspec is passed in `<file>` instead of commandline args. If
313+
`<file>` is exactly `-` then standard input is used. Pathspec
314+
elements are separated by LF or CR/LF. Pathspec elements can be
315+
quoted as explained for the configuration variable `core.quotePath`
316+
(see linkgit:git-config[1]). See also `--pathspec-file-nul` and
317+
global `--literal-pathspecs`.
318+
319+
--pathspec-file-nul::
320+
Only meaningful with `--pathspec-from-file`. Pathspec elements are
321+
separated with NUL character and all other characters are taken
322+
literally (including newlines and quotes).
323+
312324
<branch>::
313325
Branch to checkout; if it refers to a branch (i.e., a name that,
314326
when prepended with "refs/heads/", is a valid ref), then that
@@ -339,7 +351,13 @@ leave out at most one of `A` and `B`, in which case it defaults to `HEAD`.
339351
Tree to checkout from (when paths are given). If not specified,
340352
the index will be used.
341353

354+
\--::
355+
Do not interpret any more arguments as options.
342356

357+
<pathspec>...::
358+
Limits the paths affected by the operation.
359+
+
360+
For more details, see the 'pathspec' entry in linkgit:gitglossary[7].
343361

344362
DETACHED HEAD
345363
-------------

Documentation/git-restore.txt

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ git-restore - Restore working tree files
88
SYNOPSIS
99
--------
1010
[verse]
11-
'git restore' [<options>] [--source=<tree>] [--staged] [--worktree] <pathspec>...
12-
'git restore' (-p|--patch) [<options>] [--source=<tree>] [--staged] [--worktree] [<pathspec>...]
11+
'git restore' [<options>] [--source=<tree>] [--staged] [--worktree] [--] <pathspec>...
12+
'git restore' [<options>] [--source=<tree>] [--staged] [--worktree] --pathspec-from-file=<file> [--pathspec-file-nul]
13+
'git restore' (-p|--patch) [<options>] [--source=<tree>] [--staged] [--worktree] [--] [<pathspec>...]
1314

1415
DESCRIPTION
1516
-----------
@@ -113,6 +114,27 @@ in linkgit:git-checkout[1] for details.
113114
appear in the `--source` tree are removed, to make them match
114115
`<tree>` exactly. The default is no-overlay mode.
115116

117+
--pathspec-from-file=<file>::
118+
Pathspec is passed in `<file>` instead of commandline args. If
119+
`<file>` is exactly `-` then standard input is used. Pathspec
120+
elements are separated by LF or CR/LF. Pathspec elements can be
121+
quoted as explained for the configuration variable `core.quotePath`
122+
(see linkgit:git-config[1]). See also `--pathspec-file-nul` and
123+
global `--literal-pathspecs`.
124+
125+
--pathspec-file-nul::
126+
Only meaningful with `--pathspec-from-file`. Pathspec elements are
127+
separated with NUL character and all other characters are taken
128+
literally (including newlines and quotes).
129+
130+
\--::
131+
Do not interpret any more arguments as options.
132+
133+
<pathspec>...::
134+
Limits the paths affected by the operation.
135+
+
136+
For more details, see the 'pathspec' entry in linkgit:gitglossary[7].
137+
116138
EXAMPLES
117139
--------
118140

builtin/add.c

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ static const char * const builtin_add_usage[] = {
2929
static int patch_interactive, add_interactive, edit_interactive;
3030
static int take_worktree_changes;
3131
static int add_renormalize;
32+
static int pathspec_file_nul;
33+
static const char *pathspec_from_file;
3234

3335
struct update_callback_data {
3436
int flags;
@@ -320,6 +322,8 @@ static struct option builtin_add_options[] = {
320322
N_("override the executable bit of the listed files")),
321323
OPT_HIDDEN_BOOL(0, "warn-embedded-repo", &warn_on_embedded_repo,
322324
N_("warn when adding an embedded repository")),
325+
OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
326+
OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
323327
OPT_END(),
324328
};
325329

@@ -414,11 +418,17 @@ int cmd_add(int argc, const char **argv, const char *prefix)
414418
builtin_add_usage, PARSE_OPT_KEEP_ARGV0);
415419
if (patch_interactive)
416420
add_interactive = 1;
417-
if (add_interactive)
421+
if (add_interactive) {
422+
if (pathspec_from_file)
423+
die(_("--pathspec-from-file is incompatible with --interactive/--patch"));
418424
exit(interactive_add(argc - 1, argv + 1, prefix, patch_interactive));
425+
}
419426

420-
if (edit_interactive)
427+
if (edit_interactive) {
428+
if (pathspec_from_file)
429+
die(_("--pathspec-from-file is incompatible with --edit"));
421430
return(edit_patch(argc, argv, prefix));
431+
}
422432
argc--;
423433
argv++;
424434

@@ -430,10 +440,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)
430440
if (addremove && take_worktree_changes)
431441
die(_("-A and -u are mutually incompatible"));
432442

433-
if (!take_worktree_changes && addremove_explicit < 0 && argc)
434-
/* Turn "git add pathspec..." to "git add -A pathspec..." */
435-
addremove = 1;
436-
437443
if (!show_only && ignore_missing)
438444
die(_("Option --ignore-missing can only be used together with --dry-run"));
439445

@@ -446,19 +452,6 @@ int cmd_add(int argc, const char **argv, const char *prefix)
446452

447453
hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
448454

449-
flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
450-
(show_only ? ADD_CACHE_PRETEND : 0) |
451-
(intent_to_add ? ADD_CACHE_INTENT : 0) |
452-
(ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
453-
(!(addremove || take_worktree_changes)
454-
? ADD_CACHE_IGNORE_REMOVAL : 0));
455-
456-
if (require_pathspec && argc == 0) {
457-
fprintf(stderr, _("Nothing specified, nothing added.\n"));
458-
fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
459-
return 0;
460-
}
461-
462455
/*
463456
* Check the "pathspec '%s' did not match any files" block
464457
* below before enabling new magic.
@@ -468,6 +461,35 @@ int cmd_add(int argc, const char **argv, const char *prefix)
468461
PATHSPEC_SYMLINK_LEADING_PATH,
469462
prefix, argv);
470463

464+
if (pathspec_from_file) {
465+
if (pathspec.nr)
466+
die(_("--pathspec-from-file is incompatible with pathspec arguments"));
467+
468+
parse_pathspec_file(&pathspec, PATHSPEC_ATTR,
469+
PATHSPEC_PREFER_FULL |
470+
PATHSPEC_SYMLINK_LEADING_PATH,
471+
prefix, pathspec_from_file, pathspec_file_nul);
472+
} else if (pathspec_file_nul) {
473+
die(_("--pathspec-file-nul requires --pathspec-from-file"));
474+
}
475+
476+
if (require_pathspec && pathspec.nr == 0) {
477+
fprintf(stderr, _("Nothing specified, nothing added.\n"));
478+
fprintf(stderr, _("Maybe you wanted to say 'git add .'?\n"));
479+
return 0;
480+
}
481+
482+
if (!take_worktree_changes && addremove_explicit < 0 && pathspec.nr)
483+
/* Turn "git add pathspec..." to "git add -A pathspec..." */
484+
addremove = 1;
485+
486+
flags = ((verbose ? ADD_CACHE_VERBOSE : 0) |
487+
(show_only ? ADD_CACHE_PRETEND : 0) |
488+
(intent_to_add ? ADD_CACHE_INTENT : 0) |
489+
(ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) |
490+
(!(addremove || take_worktree_changes)
491+
? ADD_CACHE_IGNORE_REMOVAL : 0));
492+
471493
if (read_cache_preload(&pathspec) < 0)
472494
die(_("index file corrupt"));
473495

builtin/checkout.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ struct checkout_opts {
7070
int checkout_worktree;
7171
const char *ignore_unmerged_opt;
7272
int ignore_unmerged;
73+
int pathspec_file_nul;
74+
const char *pathspec_from_file;
7375

7476
const char *new_branch;
7577
const char *new_branch_force;
@@ -1480,6 +1482,8 @@ static struct option *add_checkout_path_options(struct checkout_opts *opts,
14801482
OPT_BOOL('p', "patch", &opts->patch_mode, N_("select hunks interactively")),
14811483
OPT_BOOL(0, "ignore-skip-worktree-bits", &opts->ignore_skipworktree,
14821484
N_("do not limit pathspecs to sparse entries only")),
1485+
OPT_PATHSPEC_FROM_FILE(&opts->pathspec_from_file),
1486+
OPT_PATHSPEC_FILE_NUL(&opts->pathspec_file_nul),
14831487
OPT_END()
14841488
};
14851489
struct option *newopts = parse_options_concat(prevopts, options);
@@ -1618,10 +1622,6 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
16181622
die(_("reference is not a tree: %s"), opts->from_treeish);
16191623
}
16201624

1621-
if (opts->accept_pathspec && !opts->empty_pathspec_ok && !argc &&
1622-
!opts->patch_mode) /* patch mode is special */
1623-
die(_("you must specify path(s) to restore"));
1624-
16251625
if (argc) {
16261626
parse_pathspec(&opts->pathspec, 0,
16271627
opts->patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0,
@@ -1641,10 +1641,33 @@ static int checkout_main(int argc, const char **argv, const char *prefix,
16411641
if (opts->force_detach)
16421642
die(_("git checkout: --detach does not take a path argument '%s'"),
16431643
argv[0]);
1644+
}
1645+
1646+
if (opts->pathspec_from_file) {
1647+
if (opts->pathspec.nr)
1648+
die(_("--pathspec-from-file is incompatible with pathspec arguments"));
1649+
1650+
if (opts->force_detach)
1651+
die(_("--pathspec-from-file is incompatible with --detach"));
16441652

1653+
if (opts->patch_mode)
1654+
die(_("--pathspec-from-file is incompatible with --patch"));
1655+
1656+
parse_pathspec_file(&opts->pathspec, 0,
1657+
0,
1658+
prefix, opts->pathspec_from_file, opts->pathspec_file_nul);
1659+
} else if (opts->pathspec_file_nul) {
1660+
die(_("--pathspec-file-nul requires --pathspec-from-file"));
1661+
}
1662+
1663+
if (opts->pathspec.nr) {
16451664
if (1 < !!opts->writeout_stage + !!opts->force + !!opts->merge)
16461665
die(_("git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
16471666
"checking out of the index."));
1667+
} else {
1668+
if (opts->accept_pathspec && !opts->empty_pathspec_ok &&
1669+
!opts->patch_mode) /* patch mode is special */
1670+
die(_("you must specify path(s) to restore"));
16481671
}
16491672

16501673
if (opts->new_branch) {

0 commit comments

Comments
 (0)