22
22
#include "unpack-trees.h"
23
23
#include "cache-tree.h"
24
24
#include "resolve-undo.h"
25
+ #include "strbuf.h"
26
+ #include "quote.h"
25
27
26
28
static const char * const git_reset_usage [] = {
27
29
N_ ("git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]" ),
28
30
N_ ("git reset [-q] [<tree-ish>] [--] <paths>..." ),
31
+ N_ ("EXPERIMENTAL: git reset [-q] [--stdin [-z]] [<tree-ish>]" ),
29
32
N_ ("git reset --patch [<tree-ish>] [--] [<paths>...]" ),
30
33
NULL
31
34
};
@@ -268,7 +271,9 @@ static int reset_refs(const char *rev, const struct object_id *oid)
268
271
int cmd_reset (int argc , const char * * argv , const char * prefix )
269
272
{
270
273
int reset_type = NONE , update_ref_status = 0 , quiet = 0 ;
271
- int patch_mode = 0 , unborn ;
274
+ int patch_mode = 0 , nul_term_line = 0 , read_from_stdin = 0 , unborn ;
275
+ char * * stdin_paths = NULL ;
276
+ int stdin_nr = 0 , stdin_alloc = 0 ;
272
277
const char * rev ;
273
278
struct object_id oid ;
274
279
struct pathspec pathspec ;
@@ -290,6 +295,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
290
295
N_ ("record only the fact that removed paths will be added later" )),
291
296
OPT_BOOL (0 , "unmerge" , & unmerge ,
292
297
N_ ("recover conflicted stages from an earlier 'git add'" )),
298
+ OPT_BOOL ('z' , NULL , & nul_term_line ,
299
+ N_ ("EXPERIMENTAL: paths are separated with NUL character" )),
300
+ OPT_BOOL (0 , "stdin" , & read_from_stdin ,
301
+ N_ ("EXPERIMENTAL: read paths from <stdin>" )),
293
302
OPT_END ()
294
303
};
295
304
@@ -299,6 +308,43 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
299
308
PARSE_OPT_KEEP_DASHDASH );
300
309
parse_args (& pathspec , argv , prefix , patch_mode , & rev );
301
310
311
+ if (read_from_stdin ) {
312
+ strbuf_getline_fn getline_fn = nul_term_line ?
313
+ strbuf_getline_nul : strbuf_getline_lf ;
314
+ int flags = PATHSPEC_PREFER_FULL |
315
+ PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP ;
316
+ struct strbuf buf = STRBUF_INIT ;
317
+ struct strbuf unquoted = STRBUF_INIT ;
318
+
319
+ if (patch_mode )
320
+ die (_ ("--stdin is incompatible with --patch" ));
321
+
322
+ if (pathspec .nr )
323
+ die (_ ("--stdin is incompatible with path arguments" ));
324
+
325
+ while (getline_fn (& buf , stdin ) != EOF ) {
326
+ if (!nul_term_line && buf .buf [0 ] == '"' ) {
327
+ strbuf_reset (& unquoted );
328
+ if (unquote_c_style (& unquoted , buf .buf , NULL ))
329
+ die (_ ("line is badly quoted" ));
330
+ strbuf_swap (& buf , & unquoted );
331
+ }
332
+ ALLOC_GROW (stdin_paths , stdin_nr + 1 , stdin_alloc );
333
+ stdin_paths [stdin_nr ++ ] = xstrdup (buf .buf );
334
+ strbuf_reset (& buf );
335
+ }
336
+ strbuf_release (& unquoted );
337
+ strbuf_release (& buf );
338
+
339
+ ALLOC_GROW (stdin_paths , stdin_nr + 1 , stdin_alloc );
340
+ stdin_paths [stdin_nr ++ ] = NULL ;
341
+ flags |= PATHSPEC_LITERAL_PATH ;
342
+ parse_pathspec (& pathspec , 0 , flags , prefix ,
343
+ (const char * * )stdin_paths );
344
+
345
+ } else if (nul_term_line )
346
+ die (_ ("-z requires --stdin" ));
347
+
302
348
unborn = !strcmp (rev , "HEAD" ) && get_sha1 ("HEAD" , oid .hash );
303
349
if (unborn ) {
304
350
/* reset on unborn branch: treat as reset to empty tree */
@@ -391,5 +437,11 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
391
437
if (!pathspec .nr )
392
438
remove_branch_state ();
393
439
440
+ if (stdin_paths ) {
441
+ while (stdin_nr )
442
+ free (stdin_paths [-- stdin_nr ]);
443
+ free (stdin_paths );
444
+ }
445
+
394
446
return update_ref_status ;
395
447
}
0 commit comments