From: Johannes Schindelin <hidden> Date: 2016-10-11 16:16:28
This feature was missing, and made it cumbersome for third-party
tools to reset a lot of paths in one go.
Support for --stdin has been added, following builtin/checkout-index.c's
example.
Johannes Schindelin (2):
reset: fix usage
reset: support the --stdin option
Documentation/git-reset.txt | 10 +++++++-
builtin/reset.c | 56 +++++++++++++++++++++++++++++++++++++++++++--
t/t7107-reset-stdin.sh | 33 ++++++++++++++++++++++++++
3 files changed, 96 insertions(+), 3 deletions(-)
create mode 100755 t/t7107-reset-stdin.sh
base-commit: 8a36cd87b7c85a651ab388d403629865ffa3ba0d
Published-As: https://github.com/dscho/git/releases/tag/reset-stdin-v1
Fetch-It-Via: git fetch https://github.com/dscho/git reset-stdin-v1
--
2.10.1.513.g00ef6dd
From: Johannes Schindelin <hidden> Date: 2016-10-11 16:15:52
The <tree-ish> parameter is actually optional (see man page).
Signed-off-by: Johannes Schindelin <redacted>
---
builtin/reset.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Johannes Schindelin <hidden> Date: 2016-10-11 16:19:24
Just like with other Git commands, this option makes it read the paths
from the standard input. It comes in handy when resetting many, many
paths at once and wildcards are not an option (e.g. when the paths are
generated by a tool).
Note: to keep things simple, we first parse the entire list and perform
the actual reset action only in a second phase.
Signed-off-by: Johannes Schindelin <redacted>
---
Documentation/git-reset.txt | 10 +++++++-
builtin/reset.c | 56 +++++++++++++++++++++++++++++++++++++++++++--
t/t7107-reset-stdin.sh | 33 ++++++++++++++++++++++++++
3 files changed, 96 insertions(+), 3 deletions(-)
create mode 100755 t/t7107-reset-stdin.sh
@@ -8,7 +8,7 @@ git-reset - Reset current HEAD to the specified state SYNOPSIS -------- [verse]-'git reset' [-q] [<tree-ish>] [--] <paths>...+'git reset' [-q] [--stdin [-z]] [<tree-ish>] [--] <paths>... 'git reset' (--patch | -p) [<tree-ish>] [--] [<paths>...] 'git reset' [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]
@@ -97,6 +97,14 @@ OPTIONS --quiet:: Be quiet, only report errors.+--stdin::+ Instead of taking list of paths from the command line,+ read list of paths from the standard input. Paths are+ separated by LF (i.e. one path per line) by default.++-z::+ Only meaningful with `--stdin`; paths are separated with+ NUL character instead of LF. EXAMPLES --------
@@ -286,6 +290,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)OPT_BOOL('p',"patch",&patch_mode,N_("select hunks interactively")),OPT_BOOL('N',"intent-to-add",&intent_to_add,N_("record only the fact that removed paths will be added later")),+OPT_BOOL('z',NULL,&nul_term_line,+N_("paths are separated with NUL character")),+OPT_BOOL(0,"stdin",&read_from_stdin,+N_("read paths from <stdin>")),OPT_END()};
@@ -295,6 +303,44 @@ int cmd_reset(int argc, const char **argv, const char *prefix)PARSE_OPT_KEEP_DASHDASH);parse_args(&pathspec,argv,prefix,patch_mode,&rev);+if(read_from_stdin){+strbuf_getline_fngetline_fn=nul_term_line?+strbuf_getline_nul:strbuf_getline_lf;+intflags=PATHSPEC_PREFER_FULL|+PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP;+structstrbufbuf=STRBUF_INIT;+structstrbufunquoted=STRBUF_INIT;++if(patch_mode)+die(_("--stdin is incompatible with --patch"));++if(pathspec.nr)+die(_("--stdin is incompatible with path arguments"));++if(patch_mode)+flags|=PATHSPEC_PREFIX_ORIGIN;++while(getline_fn(&buf,stdin)!=EOF){+if(!nul_term_line&&buf.buf[0]=='"'){+strbuf_reset(&unquoted);+if(unquote_c_style(&unquoted,buf.buf,NULL))+die(_("line is badly quoted"));+strbuf_swap(&buf,&unquoted);+}+ALLOC_GROW(stdin_paths,stdin_nr+1,stdin_alloc);+stdin_paths[stdin_nr++]=xstrdup(buf.buf);+strbuf_reset(&buf);+}+strbuf_release(&unquoted);+strbuf_release(&buf);++ALLOC_GROW(stdin_paths,stdin_nr+1,stdin_alloc);+stdin_paths[stdin_nr++]=NULL;+parse_pathspec(&pathspec,0,flags,prefix,+(constchar**)stdin_paths);+}elseif(nul_term_line)+die(_("-z requires --stdin"));+unborn=!strcmp(rev,"HEAD")&&get_sha1("HEAD",oid.hash);if(unborn){/* reset on unborn branch: treat as reset to empty tree */
From: Jeff King <hidden> Date: 2016-10-11 19:03:14
On Tue, Oct 11, 2016 at 06:08:56PM +0200, Johannes Schindelin wrote:
This feature was missing, and made it cumbersome for third-party
tools to reset a lot of paths in one go.
Support for --stdin has been added, following builtin/checkout-index.c's
example.
Is git-reset the right layer to add scripting features? I thought we
usually pushed people doing mass index manipulation to use update-index
or read-tree. Is there something that reset makes easy that is hard with
those tools (I could imagine "--hard", but I see it is not supported
with your patch).
Not that I'm necessarily opposed to the patch, I was just surprised.
-Peff
I think you meant here
+'git reset' [-q] [--stdin [-z]] [<tree-ish>]
Because you say "*Instead*" below.
quoted hunk
+--stdin::+ Instead of taking list of paths from the command line,+ read list of paths from the standard input. Paths are+ separated by LF (i.e. one path per line) by default.
And die if <paths> were supplied:
+ if (pathspec.nr)
+ die(_("--stdin is incompatible with path arguments"));
Of course you need to fix it in built-in synopsis as well:
From: Johannes Schindelin <hidden> Date: 2017-01-27 12:56:35
Just like with other Git commands, this option makes it read the paths
from the standard input. It comes in handy when resetting many, many
paths at once and wildcards are not an option (e.g. when the paths are
generated by a tool).
Note: we first parse the entire list and perform the actual reset action
only in a second phase. Not only does this make things simpler, it also
helps performance, as do_diff_cache() traverses the index and the
(sorted) pathspecs in simultaneously to avoid unnecessary lookups.
Signed-off-by: Johannes Schindelin <redacted>
---
Documentation/git-reset.txt | 9 ++++++++
builtin/reset.c | 54 ++++++++++++++++++++++++++++++++++++++++++++-
t/t7107-reset-stdin.sh | 33 +++++++++++++++++++++++++++
3 files changed, 95 insertions(+), 1 deletion(-)
create mode 100755 t/t7107-reset-stdin.sh
@@ -97,6 +98,14 @@ OPTIONS --quiet:: Be quiet, only report errors.+--stdin::+ Instead of taking list of paths from the command line,+ read list of paths from the standard input. Paths are+ separated by LF (i.e. one path per line) by default.++-z::+ Only meaningful with `--stdin`; paths are separated with+ NUL character instead of LF. EXAMPLES --------
@@ -286,6 +291,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)OPT_BOOL('p',"patch",&patch_mode,N_("select hunks interactively")),OPT_BOOL('N',"intent-to-add",&intent_to_add,N_("record only the fact that removed paths will be added later")),+OPT_BOOL('z',NULL,&nul_term_line,+N_("paths are separated with NUL character")),+OPT_BOOL(0,"stdin",&read_from_stdin,+N_("read paths from <stdin>")),OPT_END()};
@@ -295,6 +304,43 @@ int cmd_reset(int argc, const char **argv, const char *prefix)PARSE_OPT_KEEP_DASHDASH);parse_args(&pathspec,argv,prefix,patch_mode,&rev);+if(read_from_stdin){+strbuf_getline_fngetline_fn=nul_term_line?+strbuf_getline_nul:strbuf_getline_lf;+intflags=PATHSPEC_PREFER_FULL|+PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP;+structstrbufbuf=STRBUF_INIT;+structstrbufunquoted=STRBUF_INIT;++if(patch_mode)+die(_("--stdin is incompatible with --patch"));++if(pathspec.nr)+die(_("--stdin is incompatible with path arguments"));++while(getline_fn(&buf,stdin)!=EOF){+if(!nul_term_line&&buf.buf[0]=='"'){+strbuf_reset(&unquoted);+if(unquote_c_style(&unquoted,buf.buf,NULL))+die(_("line is badly quoted"));+strbuf_swap(&buf,&unquoted);+}+ALLOC_GROW(stdin_paths,stdin_nr+1,stdin_alloc);+stdin_paths[stdin_nr++]=xstrdup(buf.buf);+strbuf_reset(&buf);+}+strbuf_release(&unquoted);+strbuf_release(&buf);++ALLOC_GROW(stdin_paths,stdin_nr+1,stdin_alloc);+stdin_paths[stdin_nr++]=NULL;+flags|=PATHSPEC_LITERAL_PATH;+parse_pathspec(&pathspec,0,flags,prefix,+(constchar**)stdin_paths);++}elseif(nul_term_line)+die(_("-z requires --stdin"));+unborn=!strcmp(rev,"HEAD")&&get_sha1("HEAD",oid.hash);if(unborn){/* reset on unborn branch: treat as reset to empty tree */
From: Jeff King <hidden> Date: 2017-01-27 17:11:42
On Fri, Jan 27, 2017 at 01:38:55PM +0100, Johannes Schindelin wrote:
Just like with other Git commands, this option makes it read the paths
from the standard input. It comes in handy when resetting many, many
paths at once and wildcards are not an option (e.g. when the paths are
generated by a tool).
Note: we first parse the entire list and perform the actual reset action
only in a second phase. Not only does this make things simpler, it also
helps performance, as do_diff_cache() traverses the index and the
(sorted) pathspecs in simultaneously to avoid unnecessary lookups.
This looks OK to me. At first I wondered if using PATHSPEC_LITERAL_PATH
was consistent with other "--stdin" tools. I think it mostly is (or at
least consistent with checkout-index). The exception is "rev-list
--stdin", but that's probably fine. It is taking rev-list arguments in
the first place, not a list of paths.
A few minor suggestions:
quoted hunk
+--stdin::+ Instead of taking list of paths from the command line,+ read list of paths from the standard input. Paths are+ separated by LF (i.e. one path per line) by default.++-z::+ Only meaningful with `--stdin`; paths are separated with+ NUL character instead of LF.
Is it worth clarifying that these are paths, not pathspecs? The word
"paths" is used to refer to the pathspecs on the command-line elsewhere
in the document.
It might also be worth mentioning the quoting rules for the non-z case.
quoted hunk
@@ -267,7 +270,9 @@ static int reset_refs(const char *rev, const struct object_id *oid) int cmd_reset(int argc, const char **argv, const char *prefix) { int reset_type = NONE, update_ref_status = 0, quiet = 0;- int patch_mode = 0, unborn;+ int patch_mode = 0, nul_term_line = 0, read_from_stdin = 0, unborn;+ char **stdin_paths = NULL;+ int stdin_nr = 0, stdin_alloc = 0;
This list is a good candidate for an argv_array, I think. So:
struct argv_array stdin_paths = ARGV_ARRAY_INIT;
...and then one more here. They all seem to be set unconditionally, and
we never look at "flags" between the two lines. I think it would be more
obvious to set them all in the same place.
quoted hunk
+ } else if (nul_term_line)+ die(_("-z requires --stdin"));+
Hmm, there's our brace question coming up again. :)
From: Johannes Schindelin <hidden> Date: 2017-01-27 17:35:30
Hi Peff,
On Fri, 27 Jan 2017, Jeff King wrote:
On Fri, Jan 27, 2017 at 01:38:55PM +0100, Johannes Schindelin wrote:
A few minor suggestions:
quoted
+--stdin::+ Instead of taking list of paths from the command line,+ read list of paths from the standard input. Paths are+ separated by LF (i.e. one path per line) by default.++-z::+ Only meaningful with `--stdin`; paths are separated with+ NUL character instead of LF.
Is it worth clarifying that these are paths, not pathspecs? The word
"paths" is used to refer to the pathspecs on the command-line elsewhere
in the document.
It might also be worth mentioning the quoting rules for the non-z case.
I think this would be overkill. In reality, --stdin without -z does not
make much sense, anyway.
If you feel strongly about it, I encourage you to submit a follow-up
patch.
The rest of your suggestions have been implemented in v3.
Ciao,
Johannes
From: Johannes Schindelin <hidden> Date: 2017-01-27 17:40:35
Just like with other Git commands, this option makes it read the paths
from the standard input. It comes in handy when resetting many, many
paths at once and wildcards are not an option (e.g. when the paths are
generated by a tool).
Note: we first parse the entire list and perform the actual reset action
only in a second phase. Not only does this make things simpler, it also
helps performance, as do_diff_cache() traverses the index and the
(sorted) pathspecs in simultaneously to avoid unnecessary lookups.
Signed-off-by: Johannes Schindelin <redacted>
---
Documentation/git-reset.txt | 10 ++++++++++
builtin/reset.c | 47 ++++++++++++++++++++++++++++++++++++++++++++-
t/t7107-reset-stdin.sh | 33 +++++++++++++++++++++++++++++++
3 files changed, 89 insertions(+), 1 deletion(-)
create mode 100755 t/t7107-reset-stdin.sh
@@ -97,6 +98,15 @@ OPTIONS --quiet:: Be quiet, only report errors.+--stdin::+ Instead of taking list of paths from the command line,+ read list of paths from the standard input. The paths are+ read verbatim, i.e. not handled as pathspecs. Paths are+ separated by LF (i.e. one path per line) by default.++-z::+ Only meaningful with `--stdin`; paths are separated with+ NUL character instead of LF. EXAMPLES --------
@@ -286,6 +291,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)OPT_BOOL('p',"patch",&patch_mode,N_("select hunks interactively")),OPT_BOOL('N',"intent-to-add",&intent_to_add,N_("record only the fact that removed paths will be added later")),+OPT_BOOL('z',NULL,&nul_term_line,+N_("paths are separated with NUL character")),+OPT_BOOL(0,"stdin",&read_from_stdin,+N_("read paths from <stdin>")),OPT_END()};
@@ -295,6 +304,40 @@ int cmd_reset(int argc, const char **argv, const char *prefix)PARSE_OPT_KEEP_DASHDASH);parse_args(&pathspec,argv,prefix,patch_mode,&rev);+if(read_from_stdin){+strbuf_getline_fngetline_fn=nul_term_line?+strbuf_getline_nul:strbuf_getline_lf;+intflags=PATHSPEC_PREFER_FULL|+PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP;+structstrbufbuf=STRBUF_INIT;+structstrbufunquoted=STRBUF_INIT;++if(patch_mode)+die(_("--stdin is incompatible with --patch"));++if(pathspec.nr)+die(_("--stdin is incompatible with path arguments"));++while(getline_fn(&buf,stdin)!=EOF){+if(!nul_term_line&&buf.buf[0]=='"'){+strbuf_reset(&unquoted);+if(unquote_c_style(&unquoted,buf.buf,NULL))+die(_("line is badly quoted"));+strbuf_swap(&buf,&unquoted);+}+argv_array_push(&stdin_paths,buf.buf);+strbuf_reset(&buf);+}+strbuf_release(&unquoted);+strbuf_release(&buf);++flags|=PATHSPEC_LITERAL_PATH;+parse_pathspec(&pathspec,0,flags,prefix,+stdin_paths.argv);++}elseif(nul_term_line)+die(_("-z requires --stdin"));+unborn=!strcmp(rev,"HEAD")&&get_sha1("HEAD",oid.hash);if(unborn){/* reset on unborn branch: treat as reset to empty tree */
From: Jeff King <hidden> Date: 2017-01-27 17:58:35
On Fri, Jan 27, 2017 at 06:34:46PM +0100, Johannes Schindelin wrote:
quoted
Is it worth clarifying that these are paths, not pathspecs? The word
"paths" is used to refer to the pathspecs on the command-line elsewhere
in the document.
It might also be worth mentioning the quoting rules for the non-z case.
I think this would be overkill. In reality, --stdin without -z does not
make much sense, anyway.
I think with most Unix tools people tend to use the non-z forms until
they break, and then switch to the z form. :)
And in that sense, this transparently Just Works because the output will
often come from another git tool, which will quote as appropriate.
If you feel strongly about it, I encourage you to submit a follow-up
patch.
The rest of your suggestions have been implemented in v3.
Thanks. I think the path/pathspec thing was the more important of the
two suggestions.
-Peff