Skip to content

Commit 9b7f726

Browse files
committed
Merge branch 'am/pathspec-f-f-more'
"git rm" and "git stash" learns the new "--pathspec-from-file" option. * am/pathspec-f-f-more: stash push: support the --pathspec-from-file option stash: eliminate crude option parsing doc: stash: synchronize <pathspec> description doc: stash: document more options doc: stash: split options from description (2) doc: stash: split options from description (1) rm: support the --pathspec-from-file option doc: rm: synchronize <pathspec> description
2 parents 076cbdc + 8a98758 commit 9b7f726

File tree

7 files changed

+381
-115
lines changed

7 files changed

+381
-115
lines changed

Documentation/git-rm.txt

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,18 @@ git-rm - Remove files from the working tree and from the index
88
SYNOPSIS
99
--------
1010
[verse]
11-
'git rm' [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>...
11+
'git rm' [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch]
12+
[--quiet] [--pathspec-from-file=<file> [--pathspec-file-nul]]
13+
[--] [<pathspec>...]
1214

1315
DESCRIPTION
1416
-----------
15-
Remove files from the index, or from the working tree and the index.
16-
`git rm` will not remove a file from just your working directory.
17-
(There is no option to remove a file only from the working tree
18-
and yet keep it in the index; use `/bin/rm` if you want to do that.)
19-
The files being removed have to be identical to the tip of the branch,
20-
and no updates to their contents can be staged in the index,
17+
Remove files matching pathspec from the index, or from the working tree
18+
and the index. `git rm` will not remove a file from just your working
19+
directory. (There is no option to remove a file only from the working
20+
tree and yet keep it in the index; use `/bin/rm` if you want to do
21+
that.) The files being removed have to be identical to the tip of the
22+
branch, and no updates to their contents can be staged in the index,
2123
though that default behavior can be overridden with the `-f` option.
2224
When `--cached` is given, the staged content has to
2325
match either the tip of the branch or the file on disk,
@@ -26,15 +28,20 @@ allowing the file to be removed from just the index.
2628

2729
OPTIONS
2830
-------
29-
<file>...::
30-
Files to remove. Fileglobs (e.g. `*.c`) can be given to
31-
remove all matching files. If you want Git to expand
32-
file glob characters, you may need to shell-escape them.
33-
A leading directory name
34-
(e.g. `dir` to remove `dir/file1` and `dir/file2`) can be
35-
given to remove all files in the directory, and recursively
36-
all sub-directories,
37-
but this requires the `-r` option to be explicitly given.
31+
<pathspec>...::
32+
Files to remove. A leading directory name (e.g. `dir` to remove
33+
`dir/file1` and `dir/file2`) can be given to remove all files in
34+
the directory, and recursively all sub-directories, but this
35+
requires the `-r` option to be explicitly given.
36+
+
37+
The command removes only the paths that are known to Git.
38+
+
39+
File globbing matches across directory boundaries. Thus, given two
40+
directories `d` and `d2`, there is a difference between using
41+
`git rm 'd*'` and `git rm 'd/*'`, as the former will also remove all
42+
of directory `d2`.
43+
+
44+
For more details, see the 'pathspec' entry in linkgit:gitglossary[7].
3845

3946
-f::
4047
--force::
@@ -68,19 +75,19 @@ OPTIONS
6875
`git rm` normally outputs one line (in the form of an `rm` command)
6976
for each file removed. This option suppresses that output.
7077

78+
--pathspec-from-file=<file>::
79+
Pathspec is passed in `<file>` instead of commandline args. If
80+
`<file>` is exactly `-` then standard input is used. Pathspec
81+
elements are separated by LF or CR/LF. Pathspec elements can be
82+
quoted as explained for the configuration variable `core.quotePath`
83+
(see linkgit:git-config[1]). See also `--pathspec-file-nul` and
84+
global `--literal-pathspecs`.
7185

72-
DISCUSSION
73-
----------
74-
75-
The <file> list given to the command can be exact pathnames,
76-
file glob patterns, or leading directory names. The command
77-
removes only the paths that are known to Git. Giving the name of
78-
a file that you have not told Git about does not remove that file.
86+
--pathspec-file-nul::
87+
Only meaningful with `--pathspec-from-file`. Pathspec elements are
88+
separated with NUL character and all other characters are taken
89+
literally (including newlines and quotes).
7990

80-
File globbing matches across directory boundaries. Thus, given
81-
two directories `d` and `d2`, there is a difference between
82-
using `git rm 'd*'` and `git rm 'd/*'`, as the former will
83-
also remove all of directory `d2`.
8491

8592
REMOVING FILES THAT HAVE DISAPPEARED FROM THE FILESYSTEM
8693
--------------------------------------------------------

Documentation/git-stash.txt

Lines changed: 100 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ SYNOPSIS
1515
'git stash' branch <branchname> [<stash>]
1616
'git stash' [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]
1717
[-u|--include-untracked] [-a|--all] [-m|--message <message>]
18+
[--pathspec-from-file=<file> [--pathspec-file-nul]]
1819
[--] [<pathspec>...]]
1920
'git stash' clear
2021
'git stash' create [<message>]
@@ -43,10 +44,10 @@ created stash, `stash@{1}` is the one before it, `stash@{2.hours.ago}`
4344
is also possible). Stashes may also be referenced by specifying just the
4445
stash index (e.g. the integer `n` is equivalent to `stash@{n}`).
4546

46-
OPTIONS
47-
-------
47+
COMMANDS
48+
--------
4849

49-
push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-m|--message <message>] [--] [<pathspec>...]::
50+
push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-m|--message <message>] [--pathspec-from-file=<file> [--pathspec-file-nul]] [--] [<pathspec>...]::
5051

5152
Save your local modifications to a new 'stash entry' and roll them
5253
back to HEAD (in the working tree and in the index).
@@ -56,38 +57,13 @@ push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q
5657
For quickly making a snapshot, you can omit "push". In this mode,
5758
non-option arguments are not allowed to prevent a misspelled
5859
subcommand from making an unwanted stash entry. The two exceptions to this
59-
are `stash -p` which acts as alias for `stash push -p` and pathspecs,
60+
are `stash -p` which acts as alias for `stash push -p` and pathspec elements,
6061
which are allowed after a double hyphen `--` for disambiguation.
61-
+
62-
When pathspec is given to 'git stash push', the new stash entry records the
63-
modified states only for the files that match the pathspec. The index
64-
entries and working tree files are then rolled back to the state in
65-
HEAD only for these files, too, leaving files that do not match the
66-
pathspec intact.
67-
+
68-
If the `--keep-index` option is used, all changes already added to the
69-
index are left intact.
70-
+
71-
If the `--include-untracked` option is used, all untracked files are also
72-
stashed and then cleaned up with `git clean`, leaving the working directory
73-
in a very clean state. If the `--all` option is used instead then the
74-
ignored files are stashed and cleaned in addition to the untracked files.
75-
+
76-
With `--patch`, you can interactively select hunks from the diff
77-
between HEAD and the working tree to be stashed. The stash entry is
78-
constructed such that its index state is the same as the index state
79-
of your repository, and its worktree contains only the changes you
80-
selected interactively. The selected changes are then rolled back
81-
from your worktree. See the ``Interactive Mode'' section of
82-
linkgit:git-add[1] to learn how to operate the `--patch` mode.
83-
+
84-
The `--patch` option implies `--keep-index`. You can use
85-
`--no-keep-index` to override this.
8662

8763
save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>]::
8864

8965
This option is deprecated in favour of 'git stash push'. It
90-
differs from "stash push" in that it cannot take pathspecs.
66+
differs from "stash push" in that it cannot take pathspec.
9167
Instead, all non-option arguments are concatenated to form the stash
9268
message.
9369

@@ -111,7 +87,7 @@ show [<options>] [<stash>]::
11187

11288
Show the changes recorded in the stash entry as a diff between the
11389
stashed contents and the commit back when the stash entry was first
114-
created. When no `<stash>` is given, it shows the latest one.
90+
created.
11591
By default, the command shows the diffstat, but it will accept any
11692
format known to 'git diff' (e.g., `git stash show -p stash@{1}`
11793
to view the second most recent entry in patch form).
@@ -128,14 +104,6 @@ pop [--index] [-q|--quiet] [<stash>]::
128104
Applying the state can fail with conflicts; in this case, it is not
129105
removed from the stash list. You need to resolve the conflicts by hand
130106
and call `git stash drop` manually afterwards.
131-
+
132-
If the `--index` option is used, then tries to reinstate not only the working
133-
tree's changes, but also the index's ones. However, this can fail, when you
134-
have conflicts (which are stored in the index, where you therefore can no
135-
longer apply the changes as they were originally).
136-
+
137-
When no `<stash>` is given, `stash@{0}` is assumed, otherwise `<stash>` must
138-
be a reference of the form `stash@{<revision>}`.
139107

140108
apply [--index] [-q|--quiet] [<stash>]::
141109

@@ -149,8 +117,7 @@ branch <branchname> [<stash>]::
149117
the commit at which the `<stash>` was originally created, applies the
150118
changes recorded in `<stash>` to the new working tree and index.
151119
If that succeeds, and `<stash>` is a reference of the form
152-
`stash@{<revision>}`, it then drops the `<stash>`. When no `<stash>`
153-
is given, applies the latest one.
120+
`stash@{<revision>}`, it then drops the `<stash>`.
154121
+
155122
This is useful if the branch on which you ran `git stash push` has
156123
changed enough that `git stash apply` fails due to conflicts. Since
@@ -166,9 +133,6 @@ clear::
166133
drop [-q|--quiet] [<stash>]::
167134

168135
Remove a single stash entry from the list of stash entries.
169-
When no `<stash>` is given, it removes the latest one.
170-
i.e. `stash@{0}`, otherwise `<stash>` must be a valid stash
171-
log reference of the form `stash@{<revision>}`.
172136

173137
create::
174138

@@ -185,6 +149,98 @@ store::
185149
reflog. This is intended to be useful for scripts. It is
186150
probably not the command you want to use; see "push" above.
187151

152+
OPTIONS
153+
-------
154+
-a::
155+
--all::
156+
This option is only valid for `push` and `save` commands.
157+
+
158+
All ignored and untracked files are also stashed and then cleaned
159+
up with `git clean`.
160+
161+
-u::
162+
--include-untracked::
163+
This option is only valid for `push` and `save` commands.
164+
+
165+
All untracked files are also stashed and then cleaned up with
166+
`git clean`.
167+
168+
--index::
169+
This option is only valid for `pop` and `apply` commands.
170+
+
171+
Tries to reinstate not only the working tree's changes, but also
172+
the index's ones. However, this can fail, when you have conflicts
173+
(which are stored in the index, where you therefore can no longer
174+
apply the changes as they were originally).
175+
176+
-k::
177+
--keep-index::
178+
--no-keep-index::
179+
This option is only valid for `push` and `save` commands.
180+
+
181+
All changes already added to the index are left intact.
182+
183+
-p::
184+
--patch::
185+
This option is only valid for `push` and `save` commands.
186+
+
187+
Interactively select hunks from the diff between HEAD and the
188+
working tree to be stashed. The stash entry is constructed such
189+
that its index state is the same as the index state of your
190+
repository, and its worktree contains only the changes you selected
191+
interactively. The selected changes are then rolled back from your
192+
worktree. See the ``Interactive Mode'' section of linkgit:git-add[1]
193+
to learn how to operate the `--patch` mode.
194+
+
195+
The `--patch` option implies `--keep-index`. You can use
196+
`--no-keep-index` to override this.
197+
198+
--pathspec-from-file=<file>::
199+
This option is only valid for `push` command.
200+
+
201+
Pathspec is passed in `<file>` instead of commandline args. If
202+
`<file>` is exactly `-` then standard input is used. Pathspec
203+
elements are separated by LF or CR/LF. Pathspec elements can be
204+
quoted as explained for the configuration variable `core.quotePath`
205+
(see linkgit:git-config[1]). See also `--pathspec-file-nul` and
206+
global `--literal-pathspecs`.
207+
208+
--pathspec-file-nul::
209+
This option is only valid for `push` command.
210+
+
211+
Only meaningful with `--pathspec-from-file`. Pathspec elements are
212+
separated with NUL character and all other characters are taken
213+
literally (including newlines and quotes).
214+
215+
-q::
216+
--quiet::
217+
This option is only valid for `apply`, `drop`, `pop`, `push`,
218+
`save`, `store` commands.
219+
+
220+
Quiet, suppress feedback messages.
221+
222+
\--::
223+
This option is only valid for `push` command.
224+
+
225+
Separates pathspec from options for disambiguation purposes.
226+
227+
<pathspec>...::
228+
This option is only valid for `push` command.
229+
+
230+
The new stash entry records the modified states only for the files
231+
that match the pathspec. The index entries and working tree files
232+
are then rolled back to the state in HEAD only for these files,
233+
too, leaving files that do not match the pathspec intact.
234+
+
235+
For more details, see the 'pathspec' entry in linkgit:gitglossary[7].
236+
237+
<stash>::
238+
This option is only valid for `apply`, `branch`, `drop`, `pop`,
239+
`show` commands.
240+
+
241+
A reference of the form `stash@{<revision>}`. When no `<stash>` is
242+
given, the latest stash is assumed (that is, `stash@{0}`).
243+
188244
DISCUSSION
189245
----------
190246

builtin/rm.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,8 @@ static int check_local_mod(struct object_id *head, int index_only)
235235
}
236236

237237
static int show_only = 0, force = 0, index_only = 0, recursive = 0, quiet = 0;
238-
static int ignore_unmatch = 0;
238+
static int ignore_unmatch = 0, pathspec_file_nul;
239+
static char *pathspec_from_file;
239240

240241
static struct option builtin_rm_options[] = {
241242
OPT__DRY_RUN(&show_only, N_("dry run")),
@@ -245,6 +246,8 @@ static struct option builtin_rm_options[] = {
245246
OPT_BOOL('r', NULL, &recursive, N_("allow recursive removal")),
246247
OPT_BOOL( 0 , "ignore-unmatch", &ignore_unmatch,
247248
N_("exit with a zero status even if nothing matched")),
249+
OPT_PATHSPEC_FROM_FILE(&pathspec_from_file),
250+
OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
248251
OPT_END(),
249252
};
250253

@@ -259,8 +262,24 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
259262

260263
argc = parse_options(argc, argv, prefix, builtin_rm_options,
261264
builtin_rm_usage, 0);
262-
if (!argc)
263-
usage_with_options(builtin_rm_usage, builtin_rm_options);
265+
266+
parse_pathspec(&pathspec, 0,
267+
PATHSPEC_PREFER_CWD,
268+
prefix, argv);
269+
270+
if (pathspec_from_file) {
271+
if (pathspec.nr)
272+
die(_("--pathspec-from-file is incompatible with pathspec arguments"));
273+
274+
parse_pathspec_file(&pathspec, 0,
275+
PATHSPEC_PREFER_CWD,
276+
prefix, pathspec_from_file, pathspec_file_nul);
277+
} else if (pathspec_file_nul) {
278+
die(_("--pathspec-file-nul requires --pathspec-from-file"));
279+
}
280+
281+
if (!pathspec.nr)
282+
die(_("No pathspec was given. Which files should I remove?"));
264283

265284
if (!index_only)
266285
setup_work_tree();
@@ -270,9 +289,6 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
270289
if (read_cache() < 0)
271290
die(_("index file corrupt"));
272291

273-
parse_pathspec(&pathspec, 0,
274-
PATHSPEC_PREFER_CWD,
275-
prefix, argv);
276292
refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED, &pathspec, NULL, NULL);
277293

278294
seen = xcalloc(pathspec.nr, 1);

0 commit comments

Comments
 (0)