@@ -953,21 +953,59 @@ int handle_revision_arg(const char *arg, struct rev_info *revs,
953953 return 0 ;
954954}
955955
956- void read_revisions_from_stdin (struct rev_info * revs )
956+ static void read_pathspec_from_stdin (struct rev_info * revs , struct strbuf * sb , const char * * * prune_data )
957957{
958- char line [1000 ];
958+ const char * * prune = * prune_data ;
959+ int prune_nr ;
960+ int prune_alloc ;
959961
960- while (fgets (line , sizeof (line ), stdin ) != NULL ) {
961- int len = strlen (line );
962- if (len && line [len - 1 ] == '\n' )
963- line [-- len ] = '\0' ;
962+ /* count existing ones */
963+ if (!prune )
964+ prune_nr = 0 ;
965+ else
966+ for (prune_nr = 0 ; prune [prune_nr ]; prune_nr ++ )
967+ ;
968+ prune_alloc = prune_nr ; /* not really, but we do not know */
969+
970+ while (strbuf_getwholeline (sb , stdin , '\n' ) != EOF ) {
971+ int len = sb -> len ;
972+ if (len && sb -> buf [len - 1 ] == '\n' )
973+ sb -> buf [-- len ] = '\0' ;
974+ ALLOC_GROW (prune , prune_nr + 1 , prune_alloc );
975+ prune [prune_nr ++ ] = xstrdup (sb -> buf );
976+ }
977+ if (prune ) {
978+ ALLOC_GROW (prune , prune_nr + 1 , prune_alloc );
979+ prune [prune_nr ] = NULL ;
980+ }
981+ * prune_data = prune ;
982+ }
983+
984+ static void read_revisions_from_stdin (struct rev_info * revs , const char * * * prune )
985+ {
986+ struct strbuf sb ;
987+ int seen_dashdash = 0 ;
988+
989+ strbuf_init (& sb , 1000 );
990+ while (strbuf_getwholeline (& sb , stdin , '\n' ) != EOF ) {
991+ int len = sb .len ;
992+ if (len && sb .buf [len - 1 ] == '\n' )
993+ sb .buf [-- len ] = '\0' ;
964994 if (!len )
965995 break ;
966- if (line [0 ] == '-' )
996+ if (sb .buf [0 ] == '-' ) {
997+ if (len == 2 && sb .buf [1 ] == '-' ) {
998+ seen_dashdash = 1 ;
999+ break ;
1000+ }
9671001 die ("options not supported in --stdin mode" );
968- if (handle_revision_arg (line , revs , 0 , 1 ))
969- die ("bad revision '%s'" , line );
1002+ }
1003+ if (handle_revision_arg (sb .buf , revs , 0 , 1 ))
1004+ die ("bad revision '%s'" , sb .buf );
9701005 }
1006+ if (seen_dashdash )
1007+ read_pathspec_from_stdin (revs , & sb , prune );
1008+ strbuf_release (& sb );
9711009}
9721010
9731011static void add_grep (struct rev_info * revs , const char * ptn , enum grep_pat_token what )
@@ -1229,6 +1267,34 @@ static int for_each_good_bisect_ref(each_ref_fn fn, void *cb_data)
12291267 return for_each_ref_in ("refs/bisect/good" , fn , cb_data );
12301268}
12311269
1270+ static void append_prune_data (const char * * * prune_data , const char * * av )
1271+ {
1272+ const char * * prune = * prune_data ;
1273+ int prune_nr ;
1274+ int prune_alloc ;
1275+
1276+ if (!prune ) {
1277+ * prune_data = av ;
1278+ return ;
1279+ }
1280+
1281+ /* count existing ones */
1282+ for (prune_nr = 0 ; prune [prune_nr ]; prune_nr ++ )
1283+ ;
1284+ prune_alloc = prune_nr ; /* not really, but we do not know */
1285+
1286+ while (* av ) {
1287+ ALLOC_GROW (prune , prune_nr + 1 , prune_alloc );
1288+ prune [prune_nr ++ ] = * av ;
1289+ av ++ ;
1290+ }
1291+ if (prune ) {
1292+ ALLOC_GROW (prune , prune_nr + 1 , prune_alloc );
1293+ prune [prune_nr ] = NULL ;
1294+ }
1295+ * prune_data = prune ;
1296+ }
1297+
12321298/*
12331299 * Parse revision information, filling in the "rev_info" structure,
12341300 * and removing the used arguments from the argument list.
@@ -1238,7 +1304,8 @@ static int for_each_good_bisect_ref(each_ref_fn fn, void *cb_data)
12381304 */
12391305int setup_revisions (int argc , const char * * argv , struct rev_info * revs , const char * def )
12401306{
1241- int i , flags , left , seen_dashdash ;
1307+ int i , flags , left , seen_dashdash , read_from_stdin ;
1308+ const char * * prune_data = NULL ;
12421309
12431310 /* First, search for "--" */
12441311 seen_dashdash = 0 ;
@@ -1249,13 +1316,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
12491316 argv [i ] = NULL ;
12501317 argc = i ;
12511318 if (argv [i + 1 ])
1252- revs -> prune_data = get_pathspec ( revs -> prefix , argv + i + 1 ) ;
1319+ prune_data = argv + i + 1 ;
12531320 seen_dashdash = 1 ;
12541321 break ;
12551322 }
12561323
12571324 /* Second, deal with arguments and options */
12581325 flags = 0 ;
1326+ read_from_stdin = 0 ;
12591327 for (left = i = 1 ; i < argc ; i ++ ) {
12601328 const char * arg = argv [i ];
12611329 if (* arg == '-' ) {
@@ -1300,6 +1368,16 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
13001368 revs -> no_walk = 0 ;
13011369 continue ;
13021370 }
1371+ if (!strcmp (arg , "--stdin" )) {
1372+ if (revs -> disable_stdin ) {
1373+ argv [left ++ ] = arg ;
1374+ continue ;
1375+ }
1376+ if (read_from_stdin ++ )
1377+ die ("--stdin given twice?" );
1378+ read_revisions_from_stdin (revs , & prune_data );
1379+ continue ;
1380+ }
13031381
13041382 opts = handle_revision_opt (revs , argc - i , argv + i , & left , argv );
13051383 if (opts > 0 ) {
@@ -1325,12 +1403,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
13251403 for (j = i ; j < argc ; j ++ )
13261404 verify_filename (revs -> prefix , argv [j ]);
13271405
1328- revs -> prune_data = get_pathspec (revs -> prefix ,
1329- argv + i );
1406+ append_prune_data (& prune_data , argv + i );
13301407 break ;
13311408 }
13321409 }
13331410
1411+ if (prune_data )
1412+ revs -> prune_data = get_pathspec (revs -> prefix , prune_data );
1413+
13341414 if (revs -> def == NULL )
13351415 revs -> def = def ;
13361416 if (revs -> show_merge )
0 commit comments