Merge branch 'jk/warn-on-object-refname-ambiguity'
authorJunio C Hamano <gitster@pobox.com>
Tue, 25 Mar 2014 18:07:36 +0000 (11:07 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 25 Mar 2014 18:07:36 +0000 (11:07 -0700)
* jk/warn-on-object-refname-ambiguity:
rev-list: disable object/refname ambiguity check with --stdin
cat-file: restore warn_on_object_refname_ambiguity flag
cat-file: fix a minor memory leak in batch_objects
cat-file: refactor error handling of batch_objects

1  2 
builtin/cat-file.c
revision.c
diff --combined builtin/cat-file.c
index d5a93e0e911ccbe4560a03ed78436bfb174e0f68,cc863ff78c1b7f4029f8c3a2011c5bd0054a3b84..707330499fad66a0bddbb5cf96ff0569e2fe3433
@@@ -118,7 -118,6 +118,7 @@@ struct expand_data 
        unsigned long size;
        unsigned long disk_size;
        const char *rest;
 +      unsigned char delta_base_sha1[20];
  
        /*
         * If mark_query is true, we do not expand anything, but rather
@@@ -175,11 -174,6 +175,11 @@@ static void expand_atom(struct strbuf *
                        data->split_on_whitespace = 1;
                else if (data->rest)
                        strbuf_addstr(sb, data->rest);
 +      } else if (is_atom("deltabase", atom, len)) {
 +              if (data->mark_query)
 +                      data->info.delta_base_sha1 = data->delta_base_sha1;
 +              else
 +                      strbuf_addstr(sb, sha1_to_hex(data->delta_base_sha1));
        } else
                die("unknown format element: %.*s", len, atom);
  }
@@@ -199,28 -193,25 +199,28 @@@ static size_t expand_format(struct strb
        return end - start + 1;
  }
  
 -static void print_object_or_die(int fd, const unsigned char *sha1,
 -                              enum object_type type, unsigned long size)
 +static void print_object_or_die(int fd, struct expand_data *data)
  {
 -      if (type == OBJ_BLOB) {
 +      const unsigned char *sha1 = data->sha1;
 +
 +      assert(data->info.typep);
 +
 +      if (data->type == OBJ_BLOB) {
                if (stream_blob_to_fd(fd, sha1, NULL, 0) < 0)
                        die("unable to stream %s to stdout", sha1_to_hex(sha1));
        }
        else {
 -              enum object_type rtype;
 -              unsigned long rsize;
 +              enum object_type type;
 +              unsigned long size;
                void *contents;
  
 -              contents = read_sha1_file(sha1, &rtype, &rsize);
 +              contents = read_sha1_file(sha1, &type, &size);
                if (!contents)
                        die("object %s disappeared", sha1_to_hex(sha1));
 -              if (rtype != type)
 +              if (type != data->type)
                        die("object %s changed type!?", sha1_to_hex(sha1));
 -              if (rsize != size)
 -                      die("object %s change size!?", sha1_to_hex(sha1));
 +              if (data->info.sizep && size != data->size)
 +                      die("object %s changed size!?", sha1_to_hex(sha1));
  
                write_or_die(fd, contents, size);
                free(contents);
@@@ -247,7 -238,7 +247,7 @@@ static int batch_one_object(const char 
                return 0;
        }
  
 -      if (sha1_object_info_extended(data->sha1, &data->info) < 0) {
 +      if (sha1_object_info_extended(data->sha1, &data->info, LOOKUP_REPLACE_OBJECT) < 0) {
                printf("%s missing\n", obj_name);
                fflush(stdout);
                return 0;
        strbuf_release(&buf);
  
        if (opt->print_contents) {
 -              print_object_or_die(1, data->sha1, data->type, data->size);
 +              print_object_or_die(1, data);
                write_or_die(1, "\n", 1);
        }
        return 0;
@@@ -269,6 -260,8 +269,8 @@@ static int batch_objects(struct batch_o
  {
        struct strbuf buf = STRBUF_INIT;
        struct expand_data data;
+       int save_warning;
+       int retval = 0;
  
        if (!opt->format)
                opt->format = "%(objectname) %(objecttype) %(objectsize)";
        strbuf_expand(&buf, opt->format, expand_format, &data);
        data.mark_query = 0;
  
 +      /*
 +       * If we are printing out the object, then always fill in the type,
 +       * since we will want to decide whether or not to stream.
 +       */
 +      if (opt->print_contents)
 +              data.info.typep = &data.type;
 +
        /*
         * We are going to call get_sha1 on a potentially very large number of
         * objects. In most large cases, these will be actual object sha1s. The
         * warn) ends up dwarfing the actual cost of the object lookups
         * themselves. We can work around it by just turning off the warning.
         */
+       save_warning = warn_on_object_refname_ambiguity;
        warn_on_object_refname_ambiguity = 0;
  
        while (strbuf_getline(&buf, stdin, '\n') != EOF) {
-               int error;
                if (data.split_on_whitespace) {
                        /*
                         * Split at first whitespace, tying off the beginning
                        data.rest = p;
                }
  
-               error = batch_one_object(buf.buf, opt, &data);
-               if (error)
-                       return error;
+               retval = batch_one_object(buf.buf, opt, &data);
+               if (retval)
+                       break;
        }
  
-       return 0;
+       strbuf_release(&buf);
+       warn_on_object_refname_ambiguity = save_warning;
+       return retval;
  }
  
  static const char * const cat_file_usage[] = {
diff --combined revision.c
index 78b5c3ac0b2d7d436b35a69a3cf6c1b023c96dd5,d9cefd9a7974ae63eb1231cece2de1df1cbeaa79..85085501f66b02a9cff9b404f34c0925270cea7f
@@@ -16,7 -16,6 +16,7 @@@
  #include "line-log.h"
  #include "mailmap.h"
  #include "commit-slab.h"
 +#include "dir.h"
  
  volatile show_early_output_fn_t show_early_output;
  
@@@ -105,12 -104,17 +105,12 @@@ static void mark_blob_uninteresting(str
        blob->object.flags |= UNINTERESTING;
  }
  
 -void mark_tree_uninteresting(struct tree *tree)
 +static void mark_tree_contents_uninteresting(struct tree *tree)
  {
        struct tree_desc desc;
        struct name_entry entry;
        struct object *obj = &tree->object;
  
 -      if (!tree)
 -              return;
 -      if (obj->flags & UNINTERESTING)
 -              return;
 -      obj->flags |= UNINTERESTING;
        if (!has_sha1_file(obj->sha1))
                return;
        if (parse_tree(tree) < 0)
        free_tree_buffer(tree);
  }
  
 +void mark_tree_uninteresting(struct tree *tree)
 +{
 +      struct object *obj = &tree->object;
 +
 +      if (!tree)
 +              return;
 +      if (obj->flags & UNINTERESTING)
 +              return;
 +      obj->flags |= UNINTERESTING;
 +      mark_tree_contents_uninteresting(tree);
 +}
 +
  void mark_parents_uninteresting(struct commit *commit)
  {
        struct commit_list *parents = NULL, *l;
@@@ -284,7 -276,6 +284,7 @@@ static struct commit *handle_commit(str
                                return NULL;
                        die("bad object %s", sha1_to_hex(tag->tagged->sha1));
                }
 +              object->flags |= flags;
        }
  
        /*
                if (parse_commit(commit) < 0)
                        die("unable to parse commit %s", name);
                if (flags & UNINTERESTING) {
 -                      commit->object.flags |= UNINTERESTING;
                        mark_parents_uninteresting(commit);
                        revs->limited = 1;
                }
                if (!revs->tree_objects)
                        return NULL;
                if (flags & UNINTERESTING) {
 -                      mark_tree_uninteresting(tree);
 +                      mark_tree_contents_uninteresting(tree);
                        return NULL;
                }
                add_pending_object(revs, object, "");
         * Blob object? You know the drill by now..
         */
        if (object->type == OBJ_BLOB) {
 -              struct blob *blob = (struct blob *)object;
                if (!revs->blob_objects)
                        return NULL;
 -              if (flags & UNINTERESTING) {
 -                      mark_blob_uninteresting(blob);
 +              if (flags & UNINTERESTING)
                        return NULL;
 -              }
                add_pending_object(revs, object, "");
                return NULL;
        }
@@@ -497,14 -492,24 +497,14 @@@ static int rev_compare_tree(struct rev_
  static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit)
  {
        int retval;
 -      void *tree;
 -      unsigned long size;
 -      struct tree_desc empty, real;
        struct tree *t1 = commit->tree;
  
        if (!t1)
                return 0;
  
 -      tree = read_object_with_reference(t1->object.sha1, tree_type, &size, NULL);
 -      if (!tree)
 -              return 0;
 -      init_tree_desc(&real, tree, size);
 -      init_tree_desc(&empty, "", 0);
 -
        tree_difference = REV_TREE_SAME;
        DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES);
 -      retval = diff_tree(&empty, &real, "", &revs->pruning);
 -      free(tree);
 +      retval = diff_tree_sha1(NULL, t1->object.sha1, "", &revs->pruning);
  
        return retval >= 0 && (tree_difference == REV_TREE_SAME);
  }
@@@ -774,10 -779,6 +774,10 @@@ static int add_parents_to_list(struct r
                return 0;
        commit->object.flags |= ADDED;
  
 +      if (revs->include_check &&
 +          !revs->include_check(commit, revs->include_check_data))
 +              return 0;
 +
        /*
         * If the commit is uninteresting, don't try to
         * prune parents - we want the maximal uninteresting
@@@ -1179,28 -1180,11 +1179,28 @@@ struct all_refs_cb 
        const char *name_for_errormsg;
  };
  
 +int ref_excluded(struct string_list *ref_excludes, const char *path)
 +{
 +      struct string_list_item *item;
 +
 +      if (!ref_excludes)
 +              return 0;
 +      for_each_string_list_item(item, ref_excludes) {
 +              if (!wildmatch(item->string, path, 0, NULL))
 +                      return 1;
 +      }
 +      return 0;
 +}
 +
  static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data)
  {
        struct all_refs_cb *cb = cb_data;
 -      struct object *object = get_reference(cb->all_revs, path, sha1,
 -                                            cb->all_flags);
 +      struct object *object;
 +
 +      if (ref_excluded(cb->all_revs->ref_excludes, path))
 +          return 0;
 +
 +      object = get_reference(cb->all_revs, path, sha1, cb->all_flags);
        add_rev_cmdline(cb->all_revs, object, path, REV_CMD_REF, cb->all_flags);
        add_pending_sha1(cb->all_revs, path, sha1, cb->all_flags);
        return 0;
@@@ -1213,24 -1197,6 +1213,24 @@@ static void init_all_refs_cb(struct all
        cb->all_flags = flags;
  }
  
 +void clear_ref_exclusion(struct string_list **ref_excludes_p)
 +{
 +      if (*ref_excludes_p) {
 +              string_list_clear(*ref_excludes_p, 0);
 +              free(*ref_excludes_p);
 +      }
 +      *ref_excludes_p = NULL;
 +}
 +
 +void add_ref_exclusion(struct string_list **ref_excludes_p, const char *exclude)
 +{
 +      if (!*ref_excludes_p) {
 +              *ref_excludes_p = xcalloc(1, sizeof(**ref_excludes_p));
 +              (*ref_excludes_p)->strdup_strings = 1;
 +      }
 +      string_list_append(*ref_excludes_p, exclude);
 +}
 +
  static void handle_refs(const char *submodule, struct rev_info *revs, unsigned flags,
                int (*for_each)(const char *, each_ref_fn, void *))
  {
@@@ -1395,7 -1361,7 +1395,7 @@@ static void prepare_show_merge(struct r
                const struct cache_entry *ce = active_cache[i];
                if (!ce_stage(ce))
                        continue;
 -              if (ce_path_match(ce, &revs->prune_data)) {
 +              if (ce_path_match(ce, &revs->prune_data, NULL)) {
                        prune_num++;
                        prune = xrealloc(prune, sizeof(*prune) * prune_num);
                        prune[prune_num-2] = ce->name;
@@@ -1575,6 -1541,10 +1575,10 @@@ static void read_revisions_from_stdin(s
  {
        struct strbuf sb;
        int seen_dashdash = 0;
+       int save_warning;
+       save_warning = warn_on_object_refname_ambiguity;
+       warn_on_object_refname_ambiguity = 0;
  
        strbuf_init(&sb, 1000);
        while (strbuf_getwholeline(&sb, stdin, '\n') != EOF) {
        }
        if (seen_dashdash)
                read_pathspec_from_stdin(revs, &sb, prune);
        strbuf_release(&sb);
+       warn_on_object_refname_ambiguity = save_warning;
  }
  
  static void add_grep(struct rev_info *revs, const char *ptn, enum grep_pat_token what)
@@@ -1626,9 -1598,9 +1632,9 @@@ static int handle_revision_opt(struct r
            !strcmp(arg, "--tags") || !strcmp(arg, "--remotes") ||
            !strcmp(arg, "--reflog") || !strcmp(arg, "--not") ||
            !strcmp(arg, "--no-walk") || !strcmp(arg, "--do-walk") ||
 -          !strcmp(arg, "--bisect") || !prefixcmp(arg, "--glob=") ||
 -          !prefixcmp(arg, "--branches=") || !prefixcmp(arg, "--tags=") ||
 -          !prefixcmp(arg, "--remotes=") || !prefixcmp(arg, "--no-walk="))
 +          !strcmp(arg, "--bisect") || starts_with(arg, "--glob=") ||
 +          starts_with(arg, "--branches=") || starts_with(arg, "--tags=") ||
 +          starts_with(arg, "--remotes=") || starts_with(arg, "--no-walk="))
        {
                unkv[(*unkc)++] = arg;
                return 1;
                revs->max_count = atoi(argv[1]);
                revs->no_walk = 0;
                return 2;
 -      } else if (!prefixcmp(arg, "-n")) {
 +      } else if (starts_with(arg, "-n")) {
                revs->max_count = atoi(arg + 2);
                revs->no_walk = 0;
        } else if ((argcount = parse_long_opt("max-age", argv, &optarg))) {
        } else if (!strcmp(arg, "--author-date-order")) {
                revs->sort_order = REV_SORT_BY_AUTHOR_DATE;
                revs->topo_order = 1;
 -      } else if (!prefixcmp(arg, "--early-output")) {
 +      } else if (starts_with(arg, "--early-output")) {
                int count = 100;
                switch (arg[14]) {
                case '=':
                revs->min_parents = 2;
        } else if (!strcmp(arg, "--no-merges")) {
                revs->max_parents = 1;
 -      } else if (!prefixcmp(arg, "--min-parents=")) {
 +      } else if (starts_with(arg, "--min-parents=")) {
                revs->min_parents = atoi(arg+14);
 -      } else if (!prefixcmp(arg, "--no-min-parents")) {
 +      } else if (starts_with(arg, "--no-min-parents")) {
                revs->min_parents = 0;
 -      } else if (!prefixcmp(arg, "--max-parents=")) {
 +      } else if (starts_with(arg, "--max-parents=")) {
                revs->max_parents = atoi(arg+14);
 -      } else if (!prefixcmp(arg, "--no-max-parents")) {
 +      } else if (starts_with(arg, "--no-max-parents")) {
                revs->max_parents = -1;
        } else if (!strcmp(arg, "--boundary")) {
                revs->boundary = 1;
                revs->verify_objects = 1;
        } else if (!strcmp(arg, "--unpacked")) {
                revs->unpacked = 1;
 -      } else if (!prefixcmp(arg, "--unpacked=")) {
 +      } else if (starts_with(arg, "--unpacked=")) {
                die("--unpacked=<packfile> no longer supported.");
        } else if (!strcmp(arg, "-r")) {
                revs->diff = 1;
                revs->verbose_header = 1;
                revs->pretty_given = 1;
                get_commit_format(arg+8, revs);
 -      } else if (!prefixcmp(arg, "--pretty=") || !prefixcmp(arg, "--format=")) {
 +      } else if (starts_with(arg, "--pretty=") || starts_with(arg, "--format=")) {
                /*
                 * Detached form ("--pretty X" as opposed to "--pretty=X")
                 * not allowed, since the argument is optional.
                revs->notes_opt.use_default_notes = 1;
        } else if (!strcmp(arg, "--show-signature")) {
                revs->show_signature = 1;
 -      } else if (!prefixcmp(arg, "--show-notes=") ||
 -                 !prefixcmp(arg, "--notes=")) {
 +      } else if (starts_with(arg, "--show-notes=") ||
 +                 starts_with(arg, "--notes=")) {
                struct strbuf buf = STRBUF_INIT;
                revs->show_notes = 1;
                revs->show_notes_given = 1;
 -              if (!prefixcmp(arg, "--show-notes")) {
 +              if (starts_with(arg, "--show-notes")) {
                        if (revs->notes_opt.use_default_notes < 0)
                                revs->notes_opt.use_default_notes = 1;
                        strbuf_addstr(&buf, arg+13);
                revs->abbrev = 0;
        } else if (!strcmp(arg, "--abbrev")) {
                revs->abbrev = DEFAULT_ABBREV;
 -      } else if (!prefixcmp(arg, "--abbrev=")) {
 +      } else if (starts_with(arg, "--abbrev=")) {
                revs->abbrev = strtoul(arg + 9, NULL, 10);
                if (revs->abbrev < MINIMUM_ABBREV)
                        revs->abbrev = MINIMUM_ABBREV;
@@@ -2003,51 -1975,40 +2009,51 @@@ static int handle_revision_pseudo_opt(c
        if (!strcmp(arg, "--all")) {
                handle_refs(submodule, revs, *flags, for_each_ref_submodule);
                handle_refs(submodule, revs, *flags, head_ref_submodule);
 +              clear_ref_exclusion(&revs->ref_excludes);
        } else if (!strcmp(arg, "--branches")) {
                handle_refs(submodule, revs, *flags, for_each_branch_ref_submodule);
 +              clear_ref_exclusion(&revs->ref_excludes);
        } else if (!strcmp(arg, "--bisect")) {
                handle_refs(submodule, revs, *flags, for_each_bad_bisect_ref);
                handle_refs(submodule, revs, *flags ^ (UNINTERESTING | BOTTOM), for_each_good_bisect_ref);
                revs->bisect = 1;
        } else if (!strcmp(arg, "--tags")) {
                handle_refs(submodule, revs, *flags, for_each_tag_ref_submodule);
 +              clear_ref_exclusion(&revs->ref_excludes);
        } else if (!strcmp(arg, "--remotes")) {
                handle_refs(submodule, revs, *flags, for_each_remote_ref_submodule);
 +              clear_ref_exclusion(&revs->ref_excludes);
        } else if ((argcount = parse_long_opt("glob", argv, &optarg))) {
                struct all_refs_cb cb;
                init_all_refs_cb(&cb, revs, *flags);
                for_each_glob_ref(handle_one_ref, optarg, &cb);
 +              clear_ref_exclusion(&revs->ref_excludes);
 +              return argcount;
 +      } else if ((argcount = parse_long_opt("exclude", argv, &optarg))) {
 +              add_ref_exclusion(&revs->ref_excludes, optarg);
                return argcount;
 -      } else if (!prefixcmp(arg, "--branches=")) {
 +      } else if (starts_with(arg, "--branches=")) {
                struct all_refs_cb cb;
                init_all_refs_cb(&cb, revs, *flags);
                for_each_glob_ref_in(handle_one_ref, arg + 11, "refs/heads/", &cb);
 -      } else if (!prefixcmp(arg, "--tags=")) {
 +              clear_ref_exclusion(&revs->ref_excludes);
 +      } else if (starts_with(arg, "--tags=")) {
                struct all_refs_cb cb;
                init_all_refs_cb(&cb, revs, *flags);
                for_each_glob_ref_in(handle_one_ref, arg + 7, "refs/tags/", &cb);
 -      } else if (!prefixcmp(arg, "--remotes=")) {
 +              clear_ref_exclusion(&revs->ref_excludes);
 +      } else if (starts_with(arg, "--remotes=")) {
                struct all_refs_cb cb;
                init_all_refs_cb(&cb, revs, *flags);
                for_each_glob_ref_in(handle_one_ref, arg + 10, "refs/remotes/", &cb);
 +              clear_ref_exclusion(&revs->ref_excludes);
        } else if (!strcmp(arg, "--reflog")) {
                handle_reflog(revs, *flags);
        } else if (!strcmp(arg, "--not")) {
                *flags ^= UNINTERESTING | BOTTOM;
        } else if (!strcmp(arg, "--no-walk")) {
                revs->no_walk = REVISION_WALK_NO_WALK_SORTED;
 -      } else if (!prefixcmp(arg, "--no-walk=")) {
 +      } else if (starts_with(arg, "--no-walk=")) {
                /*
                 * Detached form ("--no-walk X" as opposed to "--no-walk=X")
                 * not allowed, since the argument is optional.