diff --no-index: use strbuf for temporary pathnames
[gitweb.git] / revision.c
index 9bae329c153f33b5aa39f2dab2748dc56b2c3824..18be62b3169095b908cb521cf9be211a9339029d 100644 (file)
@@ -226,6 +226,13 @@ static struct object *get_reference(struct rev_info *revs, const char *name, con
        return object;
 }
 
+void add_pending_sha1(struct rev_info *revs, const char *name,
+                     const unsigned char *sha1, unsigned int flags)
+{
+       struct object *object = get_reference(revs, name, sha1, flags);
+       add_pending_object(revs, object, name);
+}
+
 static struct commit *handle_commit(struct rev_info *revs, struct object *object, const char *name)
 {
        unsigned long flags = object->flags;
@@ -409,7 +416,7 @@ static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit)
 static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
 {
        struct commit_list **pp, *parent;
-       int tree_changed = 0, tree_same = 0;
+       int tree_changed = 0, tree_same = 0, nth_parent = 0;
 
        /*
         * If we don't do pruning, everything is interesting
@@ -437,6 +444,14 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
        while ((parent = *pp) != NULL) {
                struct commit *p = parent->item;
 
+               /*
+                * Do not compare with later parents when we care only about
+                * the first parent chain, in order to avoid derailing the
+                * traversal to follow a side branch that brought everything
+                * in the path we are limited to by the pathspec.
+                */
+               if (revs->first_parent_only && nth_parent++)
+                       break;
                if (parse_commit(p) < 0)
                        die("cannot simplify commit %s (because of %s)",
                            sha1_to_hex(commit->object.sha1),
@@ -897,7 +912,7 @@ static int handle_one_ref(const char *path, const unsigned char *sha1, int flag,
        struct object *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_object(cb->all_revs, object, path);
+       add_pending_sha1(cb->all_revs, path, sha1, cb->all_flags);
        return 0;
 }
 
@@ -1052,10 +1067,12 @@ static void prepare_show_merge(struct rev_info *revs)
        const char **prune = NULL;
        int i, prune_num = 1; /* counting terminating NULL */
 
-       if (get_sha1("HEAD", sha1) || !(head = lookup_commit(sha1)))
+       if (get_sha1("HEAD", sha1))
                die("--merge without HEAD?");
-       if (get_sha1("MERGE_HEAD", sha1) || !(other = lookup_commit(sha1)))
+       head = lookup_commit_or_die(sha1, "HEAD");
+       if (get_sha1("MERGE_HEAD", sha1))
                die("--merge without MERGE_HEAD?");
+       other = lookup_commit_or_die(sha1, "MERGE_HEAD");
        add_pending_object(revs, &head->object, "HEAD");
        add_pending_object(revs, &other->object, "MERGE_HEAD");
        bases = get_merge_bases(head, other, 1);
@@ -1460,6 +1477,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
                revs->show_notes = 1;
                revs->show_notes_given = 1;
                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=")) {
                struct strbuf buf = STRBUF_INIT;
@@ -2048,7 +2067,8 @@ int prepare_revision_walk(struct rev_info *revs)
                }
                e++;
        }
-       free(list);
+       if (!revs->leak_pending)
+               free(list);
 
        if (revs->no_walk)
                return 0;
@@ -2116,7 +2136,6 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
        if (!opt->grep_filter.pattern_list && !opt->grep_filter.header_list)
                return 1;
        return grep_buffer(&opt->grep_filter,
-                          NULL, /* we say nothing, not even filename */
                           commit->buffer, strlen(commit->buffer));
 }