2525#include "cache-tree.h"
2626#include "submodule.h"
2727#include "submodule-config.h"
28+ #include "strbuf.h"
29+ #include "quote.h"
2830
2931#define REFRESH_INDEX_DELAY_WARNING_IN_MS (2 * 1000)
3032
3133static const char * const git_reset_usage [] = {
3234 N_ ("git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]" ),
3335 N_ ("git reset [-q] [<tree-ish>] [--] <paths>..." ),
36+ N_ ("EXPERIMENTAL: git reset [-q] [--stdin [-z]] [<tree-ish>]" ),
3437 N_ ("git reset --patch [<tree-ish>] [--] [<paths>...]" ),
3538 NULL
3639};
@@ -284,7 +287,9 @@ static int git_reset_config(const char *var, const char *value, void *cb)
284287int cmd_reset (int argc , const char * * argv , const char * prefix )
285288{
286289 int reset_type = NONE , update_ref_status = 0 , quiet = 0 ;
287- int patch_mode = 0 , unborn ;
290+ int patch_mode = 0 , nul_term_line = 0 , read_from_stdin = 0 , unborn ;
291+ char * * stdin_paths = NULL ;
292+ int stdin_nr = 0 , stdin_alloc = 0 ;
288293 const char * rev ;
289294 struct object_id oid ;
290295 struct pathspec pathspec ;
@@ -306,6 +311,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
306311 OPT_BOOL ('p' , "patch" , & patch_mode , N_ ("select hunks interactively" )),
307312 OPT_BOOL ('N' , "intent-to-add" , & intent_to_add ,
308313 N_ ("record only the fact that removed paths will be added later" )),
314+ OPT_BOOL ('z' , NULL , & nul_term_line ,
315+ N_ ("EXPERIMENTAL: paths are separated with NUL character" )),
316+ OPT_BOOL (0 , "stdin" , & read_from_stdin ,
317+ N_ ("EXPERIMENTAL: read paths from <stdin>" )),
309318 OPT_END ()
310319 };
311320
@@ -316,6 +325,42 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
316325 PARSE_OPT_KEEP_DASHDASH );
317326 parse_args (& pathspec , argv , prefix , patch_mode , & rev );
318327
328+ if (read_from_stdin ) {
329+ strbuf_getline_fn getline_fn = nul_term_line ?
330+ strbuf_getline_nul : strbuf_getline_lf ;
331+ int flags = PATHSPEC_PREFER_FULL ;
332+ struct strbuf buf = STRBUF_INIT ;
333+ struct strbuf unquoted = STRBUF_INIT ;
334+
335+ if (patch_mode )
336+ die (_ ("--stdin is incompatible with --patch" ));
337+
338+ if (pathspec .nr )
339+ die (_ ("--stdin is incompatible with path arguments" ));
340+
341+ while (getline_fn (& buf , stdin ) != EOF ) {
342+ if (!nul_term_line && buf .buf [0 ] == '"' ) {
343+ strbuf_reset (& unquoted );
344+ if (unquote_c_style (& unquoted , buf .buf , NULL ))
345+ die (_ ("line is badly quoted" ));
346+ strbuf_swap (& buf , & unquoted );
347+ }
348+ ALLOC_GROW (stdin_paths , stdin_nr + 1 , stdin_alloc );
349+ stdin_paths [stdin_nr ++ ] = xstrdup (buf .buf );
350+ strbuf_reset (& buf );
351+ }
352+ strbuf_release (& unquoted );
353+ strbuf_release (& buf );
354+
355+ ALLOC_GROW (stdin_paths , stdin_nr + 1 , stdin_alloc );
356+ stdin_paths [stdin_nr ++ ] = NULL ;
357+ flags |= PATHSPEC_LITERAL_PATH ;
358+ parse_pathspec (& pathspec , 0 , flags , prefix ,
359+ (const char * * )stdin_paths );
360+
361+ } else if (nul_term_line )
362+ die (_ ("-z requires --stdin" ));
363+
319364 unborn = !strcmp (rev , "HEAD" ) && get_oid ("HEAD" , & oid );
320365 if (unborn ) {
321366 /* reset on unborn branch: treat as reset to empty tree */
@@ -423,5 +468,11 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
423468 if (!pathspec .nr )
424469 remove_branch_state (the_repository );
425470
471+ if (stdin_paths ) {
472+ while (stdin_nr )
473+ free (stdin_paths [-- stdin_nr ]);
474+ free (stdin_paths );
475+ }
476+
426477 return update_ref_status ;
427478}
0 commit comments