Merge branch 'jc/log-stdin'
authorJunio C Hamano <gitster@pobox.com>
Tue, 24 Nov 2009 06:30:08 +0000 (22:30 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 24 Nov 2009 06:30:08 +0000 (22:30 -0800)
* jc/log-stdin:
Add trivial tests for --stdin option to log family
Make --stdin option to "log" family read also pathspecs
setup_revisions(): do not call get_pathspec() too early
Teach --stdin option to "log" family
read_revision_from_stdin(): use strbuf

Conflicts:
revision.c

1  2 
builtin-blame.c
builtin-rev-list.c
bundle.c
revision.c
revision.h
diff --combined builtin-blame.c
index dd16b2229763addfba8f02f3d9b3c42dcb995935,b0aa5305079715165508bd96e5c1b35de8ddd3e3..d4e25a595dadba43223e84b20759ab49343aa33a
@@@ -1604,9 -1604,6 +1604,9 @@@ static void emit_porcelain(struct score
                } while (ch != '\n' &&
                         cp < sb->final_buf + sb->final_buf_size);
        }
 +
 +      if (sb->final_buf_size && cp[-1] != '\n')
 +              putchar('\n');
  }
  
  static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
                } while (ch != '\n' &&
                         cp < sb->final_buf + sb->final_buf_size);
        }
 +
 +      if (sb->final_buf_size && cp[-1] != '\n')
 +              putchar('\n');
  }
  
  static void output(struct scoreboard *sb, int option)
@@@ -2358,6 -2352,7 +2358,7 @@@ parse_done
                        die_errno("cannot stat path '%s'", path);
        }
  
+       revs.disable_stdin = 1;
        setup_revisions(argc, argv, &revs, NULL);
        memset(&sb, 0, sizeof(sb));
  
diff --combined builtin-rev-list.c
index ac1136a3f5a6d61e8b5ae18ae32451674effb0d8,f6a56f34e18809f9feeee3bbd77c4b11cc08a6c6..91b604289dd59101cb6477fa49dd9c342e5b39e5
@@@ -306,7 -306,6 +306,6 @@@ int cmd_rev_list(int argc, const char *
        struct rev_info revs;
        struct rev_list_info info;
        int i;
-       int read_from_stdin = 0;
        int bisect_list = 0;
        int bisect_show_vars = 0;
        int bisect_find_all = 0;
  
        memset(&info, 0, sizeof(info));
        info.revs = &revs;
 +      if (revs.bisect)
 +              bisect_list = 1;
  
        quiet = DIFF_OPT_TST(&revs.diffopt, QUIET);
        for (i = 1 ; i < argc; i++) {
                        bisect_show_vars = 1;
                        continue;
                }
-               if (!strcmp(arg, "--stdin")) {
-                       if (read_from_stdin++)
-                               die("--stdin given twice?");
-                       read_revisions_from_stdin(&revs);
-                       continue;
-               }
                usage(rev_list_usage);
  
        }
diff --combined bundle.c
index 717a712e9a6c125a684cd4ee39ce5cbfaecef91d,e04ab497111a15f96671d27e16fd901438d28e26..ff97adcb891caf98dcc655e71e29eaec5dae0135
+++ b/bundle.c
@@@ -204,7 -204,6 +204,6 @@@ int create_bundle(struct bundle_header 
        int i, ref_count = 0;
        char buffer[1024];
        struct rev_info revs;
-       int read_from_stdin = 0;
        struct child_process rls;
        FILE *rls_fout;
  
        /* write references */
        argc = setup_revisions(argc, argv, &revs, NULL);
  
-       for (i = 1; i < argc; i++) {
-               if (!strcmp(argv[i], "--stdin")) {
-                       if (read_from_stdin++)
-                               die("--stdin given twice?");
-                       read_revisions_from_stdin(&revs);
-                       continue;
-               }
-               return error("unrecognized argument: %s'", argv[i]);
-       }
+       if (argc > 1)
+               return error("unrecognized argument: %s'", argv[1]);
  
        object_array_remove_duplicates(&revs.pending);
  
  
        /* write pack */
        argv_pack[0] = "pack-objects";
 -      argv_pack[1] = "--all-progress";
 +      argv_pack[1] = "--all-progress-implied";
        argv_pack[2] = "--stdout";
        argv_pack[3] = "--thin";
        argv_pack[4] = NULL;
diff --combined revision.c
index a36c0d9bcd962665fc46fb2a1f75342e176f7773,8750c20e07d7b1533e948d93097a1e091f899bc7..a8a3c3a4bdf5bd9287cb820330e73e8c28b88564
@@@ -953,21 -953,59 +953,59 @@@ int handle_revision_arg(const char *arg
        return 0;
  }
  
void read_revisions_from_stdin(struct rev_info *revs)
static void read_pathspec_from_stdin(struct rev_info *revs, struct strbuf *sb, const char ***prune_data)
  {
-       char line[1000];
+       const char **prune = *prune_data;
+       int prune_nr;
+       int prune_alloc;
  
-       while (fgets(line, sizeof(line), stdin) != NULL) {
-               int len = strlen(line);
-               if (len && line[len - 1] == '\n')
-                       line[--len] = '\0';
+       /* count existing ones */
+       if (!prune)
+               prune_nr = 0;
+       else
+               for (prune_nr = 0; prune[prune_nr]; prune_nr++)
+                       ;
+       prune_alloc = prune_nr; /* not really, but we do not know */
+       while (strbuf_getwholeline(sb, stdin, '\n') != EOF) {
+               int len = sb->len;
+               if (len && sb->buf[len - 1] == '\n')
+                       sb->buf[--len] = '\0';
+               ALLOC_GROW(prune, prune_nr+1, prune_alloc);
+               prune[prune_nr++] = xstrdup(sb->buf);
+       }
+       if (prune) {
+               ALLOC_GROW(prune, prune_nr+1, prune_alloc);
+               prune[prune_nr] = NULL;
+       }
+       *prune_data = prune;
+ }
+ static void read_revisions_from_stdin(struct rev_info *revs, const char ***prune)
+ {
+       struct strbuf sb;
+       int seen_dashdash = 0;
+       strbuf_init(&sb, 1000);
+       while (strbuf_getwholeline(&sb, stdin, '\n') != EOF) {
+               int len = sb.len;
+               if (len && sb.buf[len - 1] == '\n')
+                       sb.buf[--len] = '\0';
                if (!len)
                        break;
-               if (line[0] == '-')
+               if (sb.buf[0] == '-') {
+                       if (len == 2 && sb.buf[1] == '-') {
+                               seen_dashdash = 1;
+                               break;
+                       }
                        die("options not supported in --stdin mode");
-               if (handle_revision_arg(line, revs, 0, 1))
-                       die("bad revision '%s'", line);
+               }
+               if (handle_revision_arg(sb.buf, revs, 0, 1))
+                       die("bad revision '%s'", sb.buf);
        }
+       if (seen_dashdash)
+               read_pathspec_from_stdin(revs, &sb, prune);
+       strbuf_release(&sb);
  }
  
  static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what)
@@@ -994,8 -1032,7 +1032,8 @@@ static int handle_revision_opt(struct r
        if (!strcmp(arg, "--all") || !strcmp(arg, "--branches") ||
            !strcmp(arg, "--tags") || !strcmp(arg, "--remotes") ||
            !strcmp(arg, "--reflog") || !strcmp(arg, "--not") ||
 -          !strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk"))
 +          !strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk") ||
 +          !strcmp(arg, "--bisect"))
        {
                unkv[(*unkc)++] = arg;
                return 1;
@@@ -1219,16 -1256,34 +1257,44 @@@ void parse_revision_opt(struct rev_inf
        ctx->argc -= n;
  }
  
 +static int for_each_bad_bisect_ref(each_ref_fn fn, void *cb_data)
 +{
 +      return for_each_ref_in("refs/bisect/bad", fn, cb_data);
 +}
 +
 +static int for_each_good_bisect_ref(each_ref_fn fn, void *cb_data)
 +{
 +      return for_each_ref_in("refs/bisect/good", fn, cb_data);
 +}
 +
+ static void append_prune_data(const char ***prune_data, const char **av)
+ {
+       const char **prune = *prune_data;
+       int prune_nr;
+       int prune_alloc;
+       if (!prune) {
+               *prune_data = av;
+               return;
+       }
+       /* count existing ones */
+       for (prune_nr = 0; prune[prune_nr]; prune_nr++)
+               ;
+       prune_alloc = prune_nr; /* not really, but we do not know */
+       while (*av) {
+               ALLOC_GROW(prune, prune_nr+1, prune_alloc);
+               prune[prune_nr++] = *av;
+               av++;
+       }
+       if (prune) {
+               ALLOC_GROW(prune, prune_nr+1, prune_alloc);
+               prune[prune_nr] = NULL;
+       }
+       *prune_data = prune;
+ }
  /*
   * Parse revision information, filling in the "rev_info" structure,
   * and removing the used arguments from the argument list.
   */
  int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def)
  {
-       int i, flags, left, seen_dashdash;
+       int i, flags, left, seen_dashdash, read_from_stdin;
+       const char **prune_data = NULL;
  
        /* First, search for "--" */
        seen_dashdash = 0;
                argv[i] = NULL;
                argc = i;
                if (argv[i + 1])
-                       revs->prune_data = get_pathspec(revs->prefix, argv + i + 1);
+                       prune_data = argv + i + 1;
                seen_dashdash = 1;
                break;
        }
  
        /* Second, deal with arguments and options */
        flags = 0;
+       read_from_stdin = 0;
        for (left = i = 1; i < argc; i++) {
                const char *arg = argv[i];
                if (*arg == '-') {
                                handle_refs(revs, flags, for_each_branch_ref);
                                continue;
                        }
 +                      if (!strcmp(arg, "--bisect")) {
 +                              handle_refs(revs, flags, for_each_bad_bisect_ref);
 +                              handle_refs(revs, flags ^ UNINTERESTING, for_each_good_bisect_ref);
 +                              revs->bisect = 1;
 +                              continue;
 +                      }
                        if (!strcmp(arg, "--tags")) {
                                handle_refs(revs, flags, for_each_tag_ref);
                                continue;
                                revs->no_walk = 0;
                                continue;
                        }
+                       if (!strcmp(arg, "--stdin")) {
+                               if (revs->disable_stdin) {
+                                       argv[left++] = arg;
+                                       continue;
+                               }
+                               if (read_from_stdin++)
+                                       die("--stdin given twice?");
+                               read_revisions_from_stdin(revs, &prune_data);
+                               continue;
+                       }
  
                        opts = handle_revision_opt(revs, argc - i, argv + i, &left, argv);
                        if (opts > 0) {
                        for (j = i; j < argc; j++)
                                verify_filename(revs->prefix, argv[j]);
  
-                       revs->prune_data = get_pathspec(revs->prefix,
-                                                       argv + i);
+                       append_prune_data(&prune_data, argv + i);
                        break;
                }
        }
  
+       if (prune_data)
+               revs->prune_data = get_pathspec(revs->prefix, prune_data);
        if (revs->def == NULL)
                revs->def = def;
        if (revs->show_merge)
diff --combined revision.h
index 921656aaabe74adaf24c8a14426f9533040a4669,f64637bcbdc0cfd36585cf93902d33bfc6002894..d368003159738570220c0e4713efd91f83303339
@@@ -63,7 -63,6 +63,7 @@@ struct rev_info 
                        reverse:1,
                        reverse_output_stage:1,
                        cherry_pick:1,
 +                      bisect:1,
                        first_parent_only:1;
  
        /* Diff flags */
@@@ -84,6 -83,8 +84,8 @@@
                        use_terminator:1,
                        missing_newline:1,
                        date_mode_explicit:1;
+       unsigned int    disable_stdin:1;
        enum date_mode date_mode;
  
        unsigned int    abbrev;
  #define REV_TREE_DIFFERENT    3       /* Mixed changes */
  
  /* revision.c */
- void read_revisions_from_stdin(struct rev_info *revs);
  typedef void (*show_early_output_fn_t)(struct rev_info *, struct commit_list *);
  extern volatile show_early_output_fn_t show_early_output;