@@ -17,6 +17,7 @@ struct batch_options {
1717 int print_contents ;
1818 int buffer_output ;
1919 int all_objects ;
20+ int cmdmode ; /* may be 'w' or 'c' for --filters or --textconv */
2021 const char * format ;
2122};
2223
@@ -280,7 +281,32 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
280281 if (data -> type == OBJ_BLOB ) {
281282 if (opt -> buffer_output )
282283 fflush (stdout );
283- if (stream_blob_to_fd (1 , sha1 , NULL , 0 ) < 0 )
284+ if (opt -> cmdmode ) {
285+ char * contents ;
286+ unsigned long size ;
287+
288+ if (!data -> rest )
289+ die ("missing path for '%s'" , sha1_to_hex (sha1 ));
290+
291+ if (opt -> cmdmode == 'w' ) {
292+ if (filter_object (data -> rest , 0100644 , sha1 ,
293+ & contents , & size ))
294+ die ("could not convert '%s' %s" ,
295+ sha1_to_hex (sha1 ), data -> rest );
296+ } else if (opt -> cmdmode == 'c' ) {
297+ enum object_type type ;
298+ if (!textconv_object (data -> rest , 0100644 , sha1 ,
299+ 1 , & contents , & size ))
300+ contents = read_sha1_file (sha1 , & type ,
301+ & size );
302+ if (!contents )
303+ die ("could not convert '%s' %s" ,
304+ sha1_to_hex (sha1 ), data -> rest );
305+ } else
306+ die ("BUG: invalid cmdmode: %c" , opt -> cmdmode );
307+ batch_write (opt , contents , size );
308+ free (contents );
309+ } else if (stream_blob_to_fd (1 , sha1 , NULL , 0 ) < 0 )
284310 die ("unable to stream %s to stdout" , sha1_to_hex (sha1 ));
285311 }
286312 else {
@@ -417,6 +443,8 @@ static int batch_objects(struct batch_options *opt)
417443 data .mark_query = 1 ;
418444 strbuf_expand (& buf , opt -> format , expand_format , & data );
419445 data .mark_query = 0 ;
446+ if (opt -> cmdmode )
447+ data .split_on_whitespace = 1 ;
420448
421449 if (opt -> all_objects ) {
422450 struct object_info empty ;
@@ -482,7 +510,7 @@ static int batch_objects(struct batch_options *opt)
482510
483511static const char * const cat_file_usage [] = {
484512 N_ ("git cat-file (-t [--allow-unknown-type]|-s [--allow-unknown-type]|-e|-p|<type>|--textconv|--filters) [--path=<path>] <object>" ),
485- N_ ("git cat-file (--batch | --batch-check) [--follow-symlinks]" ),
513+ N_ ("git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv|--filters] " ),
486514 NULL
487515};
488516
@@ -553,7 +581,9 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
553581 argc = parse_options (argc , argv , prefix , options , cat_file_usage , 0 );
554582
555583 if (opt ) {
556- if (argc == 1 )
584+ if (batch .enabled && (opt == 'c' || opt == 'w' ))
585+ batch .cmdmode = opt ;
586+ else if (argc == 1 )
557587 obj_name = argv [0 ];
558588 else
559589 usage_with_options (cat_file_usage , options );
@@ -565,8 +595,12 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
565595 } else
566596 usage_with_options (cat_file_usage , options );
567597 }
568- if (batch .enabled && (opt || argc )) {
569- usage_with_options (cat_file_usage , options );
598+ if (batch .enabled ) {
599+ if (batch .cmdmode != opt || argc )
600+ usage_with_options (cat_file_usage , options );
601+ if (batch .cmdmode && batch .all_objects )
602+ die ("--batch-all-objects cannot be combined with "
603+ "--textconv nor with --filters" );
570604 }
571605
572606 if ((batch .follow_symlinks || batch .all_objects ) && !batch .enabled ) {
@@ -578,6 +612,11 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
578612 usage_with_options (cat_file_usage , options );
579613 }
580614
615+ if (force_path && batch .enabled ) {
616+ error ("--path=<path> incompatible with --batch" );
617+ usage_with_options (cat_file_usage , options );
618+ }
619+
581620 if (batch .buffer_output < 0 )
582621 batch .buffer_output = batch .all_objects ;
583622
0 commit comments