Merge branch 'master' into next
authorJunio C Hamano <junkio@cox.net>
Sat, 15 Apr 2006 06:21:48 +0000 (23:21 -0700)
committerJunio C Hamano <junkio@cox.net>
Sat, 15 Apr 2006 06:21:48 +0000 (23:21 -0700)
* master:
GIT v1.3.0-rc4

diff-tree.c
git.c
log-tree.c
log-tree.h
rev-list.c
revision.c
revision.h
index 2b79dd0a68c30343d74e3e82c056fef6a355e82e..979f792b6758101cb490f36ba3acff5d7d4b4473 100644 (file)
@@ -3,7 +3,7 @@
 #include "commit.h"
 #include "log-tree.h"
 
-static struct log_tree_opt log_tree_opt;
+static struct rev_info log_tree_opt;
 
 static int diff_tree_commit_sha1(const unsigned char *sha1)
 {
@@ -62,47 +62,19 @@ int main(int argc, const char **argv)
 {
        int nr_sha1;
        char line[1000];
-       unsigned char sha1[2][20];
-       const char *prefix = setup_git_directory();
-       static struct log_tree_opt *opt = &log_tree_opt;
+       struct object *tree1, *tree2;
+       static struct rev_info *opt = &log_tree_opt;
+       struct object_list *list;
        int read_stdin = 0;
 
        git_config(git_diff_config);
        nr_sha1 = 0;
-       init_log_tree_opt(opt);
+       opt->abbrev = 0;
+       argc = setup_revisions(argc, argv, opt, NULL);
 
-       for (;;) {
-               int opt_cnt;
-               const char *arg;
+       while (--argc > 0) {
+               const char *arg = *++argv;
 
-               argv++;
-               argc--;
-               arg = *argv;
-               if (!arg)
-                       break;
-
-               if (*arg != '-') {
-                       if (nr_sha1 < 2 && !get_sha1(arg, sha1[nr_sha1])) {
-                               nr_sha1++;
-                               continue;
-                       }
-                       break;
-               }
-
-               opt_cnt = log_tree_opt_parse(opt, argv, argc);
-               if (opt_cnt < 0)
-                       usage(diff_tree_usage);
-               else if (opt_cnt) {
-                       argv += opt_cnt - 1;
-                       argc -= opt_cnt - 1;
-                       continue;
-               }
-
-               if (!strcmp(arg, "--")) {
-                       argv++;
-                       argc--;
-                       break;
-               }
                if (!strcmp(arg, "--stdin")) {
                        read_stdin = 1;
                        continue;
@@ -110,18 +82,36 @@ int main(int argc, const char **argv)
                usage(diff_tree_usage);
        }
 
-       if (opt->combine_merges)
-               opt->ignore_merges = 0;
-
-       /* We can only do dense combined merges with diff output */
-       if (opt->dense_combined_merges)
-               opt->diffopt.output_format = DIFF_FORMAT_PATCH;
-
-       if (opt->diffopt.output_format == DIFF_FORMAT_PATCH)
-               opt->diffopt.recursive = 1;
-
-       diff_tree_setup_paths(get_pathspec(prefix, argv), opt);
-       diff_setup_done(&opt->diffopt);
+       /*
+        * NOTE! "setup_revisions()" will have inserted the revisions
+        * it parsed in reverse order. So if you do
+        *
+        *      git-diff-tree a b
+        *
+        * the commit list will be "b" -> "a" -> NULL, so we reverse
+        * the order of the objects if the first one is not marked
+        * UNINTERESTING.
+        */
+       nr_sha1 = 0;
+       list = opt->pending_objects;
+       if (list) {
+               nr_sha1++;
+               tree1 = list->item;
+               list = list->next;
+               if (list) {
+                       nr_sha1++;
+                       tree2 = tree1;
+                       tree1 = list->item;
+                       if (list->next)
+                               usage(diff_tree_usage);
+                       /* Switch them around if the second one was uninteresting.. */
+                       if (tree2->flags & UNINTERESTING) {
+                               struct object *tmp = tree2;
+                               tree2 = tree1;
+                               tree1 = tmp;
+                       }
+               }
+       }
 
        switch (nr_sha1) {
        case 0:
@@ -129,10 +119,12 @@ int main(int argc, const char **argv)
                        usage(diff_tree_usage);
                break;
        case 1:
-               diff_tree_commit_sha1(sha1[0]);
+               diff_tree_commit_sha1(tree1->sha1);
                break;
        case 2:
-               diff_tree_sha1(sha1[0], sha1[1], "", &opt->diffopt);
+               diff_tree_sha1(tree1->sha1,
+                              tree2->sha1,
+                              "", &opt->diffopt);
                log_tree_diff_flush(opt);
                break;
        }
diff --git a/git.c b/git.c
index 78ed403ed121a84c3efe3a57fa7c24486d724953..9d885569d8451d73a4aaf01fefa994b31041efee 100644 (file)
--- a/git.c
+++ b/git.c
@@ -283,82 +283,26 @@ static int cmd_log(int argc, const char **argv, char **envp)
        struct rev_info rev;
        struct commit *commit;
        char *buf = xmalloc(LOGSIZE);
-       static enum cmit_fmt commit_format = CMIT_FMT_DEFAULT;
-       int abbrev = DEFAULT_ABBREV;
-       int abbrev_commit = 0;
        const char *commit_prefix = "commit ";
-       struct log_tree_opt opt;
        int shown = 0;
-       int do_diff = 0;
-       int full_diff = 0;
 
-       init_log_tree_opt(&opt);
+       rev.abbrev = DEFAULT_ABBREV;
        argc = setup_revisions(argc, argv, &rev, "HEAD");
-       while (1 < argc) {
-               const char *arg = argv[1];
-               if (!strncmp(arg, "--pretty", 8)) {
-                       commit_format = get_commit_format(arg + 8);
-                       if (commit_format == CMIT_FMT_ONELINE)
-                               commit_prefix = "";
-               }
-               else if (!strcmp(arg, "--no-abbrev")) {
-                       abbrev = 0;
-               }
-               else if (!strcmp(arg, "--abbrev")) {
-                       abbrev = DEFAULT_ABBREV;
-               }
-               else if (!strcmp(arg, "--abbrev-commit")) {
-                       abbrev_commit = 1;
-               }
-               else if (!strncmp(arg, "--abbrev=", 9)) {
-                       abbrev = strtoul(arg + 9, NULL, 10);
-                       if (abbrev && abbrev < MINIMUM_ABBREV)
-                               abbrev = MINIMUM_ABBREV;
-                       else if (40 < abbrev)
-                               abbrev = 40;
-               }
-               else if (!strcmp(arg, "--full-diff")) {
-                       do_diff = 1;
-                       full_diff = 1;
-               }
-               else {
-                       int cnt = log_tree_opt_parse(&opt, argv+1, argc-1);
-                       if (0 < cnt) {
-                               do_diff = 1;
-                               argv += cnt;
-                               argc -= cnt;
-                               continue;
-                       }
-                       die("unrecognized argument: %s", arg);
-               }
+       if (argc > 1)
+               die("unrecognized argument: %s", argv[1]);
 
-               argc--; argv++;
-       }
-
-       if (do_diff) {
-               opt.diffopt.abbrev = abbrev;
-               opt.verbose_header = 0;
-               opt.always_show_header = 0;
-               opt.no_commit_id = 1;
-               if (opt.combine_merges)
-                       opt.ignore_merges = 0;
-               if (opt.dense_combined_merges)
-                       opt.diffopt.output_format = DIFF_FORMAT_PATCH;
-               if (opt.diffopt.output_format == DIFF_FORMAT_PATCH)
-                       opt.diffopt.recursive = 1;
-               if (!full_diff && rev.prune_data)
-                       diff_tree_setup_paths(rev.prune_data, &opt.diffopt);
-               diff_setup_done(&opt.diffopt);
-       }
+       rev.no_commit_id = 1;
+       if (rev.commit_format == CMIT_FMT_ONELINE)
+               commit_prefix = "";
 
        prepare_revision_walk(&rev);
        setup_pager();
        while ((commit = get_revision(&rev)) != NULL) {
-               if (shown && do_diff && commit_format != CMIT_FMT_ONELINE)
+               if (shown && rev.diff && rev.commit_format != CMIT_FMT_ONELINE)
                        putchar('\n');
                fputs(commit_prefix, stdout);
-               if (abbrev_commit && abbrev)
-                       fputs(find_unique_abbrev(commit->object.sha1, abbrev),
+               if (rev.abbrev_commit && rev.abbrev)
+                       fputs(find_unique_abbrev(commit->object.sha1, rev.abbrev),
                              stdout);
                else
                        fputs(sha1_to_hex(commit->object.sha1), stdout);
@@ -381,15 +325,15 @@ static int cmd_log(int argc, const char **argv, char **envp)
                             parents = parents->next)
                                parents->item->object.flags &= ~TMP_MARK;
                }
-               if (commit_format == CMIT_FMT_ONELINE)
+               if (rev.commit_format == CMIT_FMT_ONELINE)
                        putchar(' ');
                else
                        putchar('\n');
-               pretty_print_commit(commit_format, commit, ~0, buf,
-                                   LOGSIZE, abbrev);
+               pretty_print_commit(rev.commit_format, commit, ~0, buf,
+                                   LOGSIZE, rev.abbrev);
                printf("%s\n", buf);
-               if (do_diff)
-                       log_tree_commit(&opt, commit);
+               if (rev.diff)
+                       log_tree_commit(&rev, commit);
                shown = 1;
                free(commit->buffer);
                commit->buffer = NULL;
index 3d404824a172c34c7ce0224de3b355f6c97eb52f..04a68e0f570dee3701c1879c4190473880aa540b 100644 (file)
@@ -3,57 +3,7 @@
 #include "commit.h"
 #include "log-tree.h"
 
-void init_log_tree_opt(struct log_tree_opt *opt)
-{
-       memset(opt, 0, sizeof *opt);
-       opt->ignore_merges = 1;
-       opt->header_prefix = "";
-       opt->commit_format = CMIT_FMT_RAW;
-       diff_setup(&opt->diffopt);
-}
-
-int log_tree_opt_parse(struct log_tree_opt *opt, const char **av, int ac)
-{
-       const char *arg;
-       int cnt = diff_opt_parse(&opt->diffopt, av, ac);
-       if (0 < cnt)
-               return cnt;
-       arg = *av;
-       if (!strcmp(arg, "-r"))
-               opt->diffopt.recursive = 1;
-       else if (!strcmp(arg, "-t")) {
-               opt->diffopt.recursive = 1;
-               opt->diffopt.tree_in_recursive = 1;
-       }
-       else if (!strcmp(arg, "-m"))
-               opt->ignore_merges = 0;
-       else if (!strcmp(arg, "-c"))
-               opt->combine_merges = 1;
-       else if (!strcmp(arg, "--cc")) {
-               opt->dense_combined_merges = 1;
-               opt->combine_merges = 1;
-       }
-       else if (!strcmp(arg, "-v")) {
-               opt->verbose_header = 1;
-               opt->header_prefix = "diff-tree ";
-       }
-       else if (!strncmp(arg, "--pretty", 8)) {
-               opt->verbose_header = 1;
-               opt->header_prefix = "diff-tree ";
-               opt->commit_format = get_commit_format(arg+8);
-       }
-       else if (!strcmp(arg, "--root"))
-               opt->show_root_diff = 1;
-       else if (!strcmp(arg, "--no-commit-id"))
-               opt->no_commit_id = 1;
-       else if (!strcmp(arg, "--always"))
-               opt->always_show_header = 1;
-       else
-               return 0;
-       return 1;
-}
-
-int log_tree_diff_flush(struct log_tree_opt *opt)
+int log_tree_diff_flush(struct rev_info *opt)
 {
        diffcore_std(&opt->diffopt);
        if (diff_queue_is_empty()) {
@@ -73,7 +23,7 @@ int log_tree_diff_flush(struct log_tree_opt *opt)
        return 1;
 }
 
-static int diff_root_tree(struct log_tree_opt *opt,
+static int diff_root_tree(struct rev_info *opt,
                          const unsigned char *new, const char *base)
 {
        int retval;
@@ -93,7 +43,7 @@ static int diff_root_tree(struct log_tree_opt *opt,
        return retval;
 }
 
-static const char *generate_header(struct log_tree_opt *opt,
+static const char *generate_header(struct rev_info *opt,
                                   const unsigned char *commit_sha1,
                                   const unsigned char *parent_sha1,
                                   const struct commit *commit)
@@ -129,7 +79,7 @@ static const char *generate_header(struct log_tree_opt *opt,
        return this_header;
 }
 
-static int do_diff_combined(struct log_tree_opt *opt, struct commit *commit)
+static int do_diff_combined(struct rev_info *opt, struct commit *commit)
 {
        unsigned const char *sha1 = commit->object.sha1;
 
@@ -142,7 +92,7 @@ static int do_diff_combined(struct log_tree_opt *opt, struct commit *commit)
        return 0;
 }
 
-int log_tree_commit(struct log_tree_opt *opt, struct commit *commit)
+int log_tree_commit(struct rev_info *opt, struct commit *commit)
 {
        struct commit_list *parents;
        unsigned const char *sha1 = commit->object.sha1;
index da166c6f2c7b3a0fae80fbe63c8cde38eb609054..91a909be73130b8542ed9092e120084bb263105b 100644 (file)
@@ -1,23 +1,11 @@
 #ifndef LOG_TREE_H
 #define LOG_TREE_H
 
-struct log_tree_opt {
-       struct diff_options diffopt;
-       int show_root_diff;
-       int no_commit_id;
-       int verbose_header;
-       int ignore_merges;
-       int combine_merges;
-       int dense_combined_merges;
-       int always_show_header;
-       const char *header_prefix;
-       const char *header;
-       enum cmit_fmt commit_format;
-};
+#include "revision.h"
 
-void init_log_tree_opt(struct log_tree_opt *);
-int log_tree_diff_flush(struct log_tree_opt *);
-int log_tree_commit(struct log_tree_opt *, struct commit *);
-int log_tree_opt_parse(struct log_tree_opt *, const char **, int);
+void init_log_tree_opt(struct rev_info *);
+int log_tree_diff_flush(struct rev_info *);
+int log_tree_commit(struct rev_info *, struct commit *);
+int log_tree_opt_parse(struct rev_info *, const char **, int);
 
 #endif
index 963707a495092405c3eb5b155c195b2968afdac7..b7aee1abb2850566e6329dd3179cee8e36085170 100644 (file)
@@ -365,12 +365,16 @@ int main(int argc, const char **argv)
 
        list = revs.commits;
 
-       if (!list &&
-           (!(revs.tag_objects||revs.tree_objects||revs.blob_objects) && !revs.pending_objects))
+       if ((!list &&
+            (!(revs.tag_objects||revs.tree_objects||revs.blob_objects) &&
+             !revs.pending_objects)) ||
+           revs.diff)
                usage(rev_list_usage);
 
        save_commit_buffer = verbose_header;
        track_object_refs = 0;
+       if (bisect_list)
+               revs.limited = 1;
 
        prepare_revision_walk(&revs);
        if (revs.tree_objects)
index 0505f3f455151ac2fafc7fe2df2e6fd147d20f08..bdf8005aec6428f274ad02af04366aaa5339bb18 100644 (file)
@@ -116,21 +116,27 @@ static void add_pending_object(struct rev_info *revs, struct object *obj, const
        add_object(obj, &revs->pending_objects, NULL, name);
 }
 
-static struct commit *get_commit_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags)
+static struct object *get_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags)
 {
        struct object *object;
 
        object = parse_object(sha1);
        if (!object)
                die("bad object %s", name);
+       object->flags |= flags;
+       return object;
+}
+
+static struct commit *handle_commit(struct rev_info *revs, struct object *object, const char *name)
+{
+       unsigned long flags = object->flags;
 
        /*
         * Tag object? Look what it points to..
         */
        while (object->type == tag_type) {
                struct tag *tag = (struct tag *) object;
-               object->flags |= flags;
-               if (revs->tag_objects && !(object->flags & UNINTERESTING))
+               if (revs->tag_objects && !(flags & UNINTERESTING))
                        add_pending_object(revs, object, tag->tag);
                object = parse_object(tag->tagged->sha1);
                if (!object)
@@ -143,7 +149,6 @@ static struct commit *get_commit_reference(struct rev_info *revs, const char *na
         */
        if (object->type == commit_type) {
                struct commit *commit = (struct commit *)object;
-               object->flags |= flags;
                if (parse_commit(commit) < 0)
                        die("unable to parse commit %s", name);
                if (flags & UNINTERESTING) {
@@ -241,7 +246,7 @@ int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2)
                return REV_TREE_DIFFERENT;
        tree_difference = REV_TREE_SAME;
        if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "",
-                          &revs->diffopt) < 0)
+                          &revs->pruning) < 0)
                return REV_TREE_DIFFERENT;
        return tree_difference;
 }
@@ -264,7 +269,7 @@ int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1)
        empty.size = 0;
 
        tree_difference = 0;
-       retval = diff_tree(&empty, &real, "", &revs->diffopt);
+       retval = diff_tree(&empty, &real, "", &revs->pruning);
        free(tree);
 
        return retval >= 0 && !tree_difference;
@@ -451,21 +456,13 @@ static void limit_list(struct rev_info *revs)
        revs->commits = newlist;
 }
 
-static void add_one_commit(struct commit *commit, struct rev_info *revs)
-{
-       if (!commit || (commit->object.flags & SEEN))
-               return;
-       commit->object.flags |= SEEN;
-       commit_list_insert(commit, &revs->commits);
-}
-
 static int all_flags;
 static struct rev_info *all_revs;
 
 static int handle_one_ref(const char *path, const unsigned char *sha1)
 {
-       struct commit *commit = get_commit_reference(all_revs, path, sha1, all_flags);
-       add_one_commit(commit, all_revs);
+       struct object *object = get_reference(all_revs, path, sha1, all_flags);
+       add_pending_object(all_revs, object, "");
        return 0;
 }
 
@@ -478,10 +475,15 @@ static void handle_all(struct rev_info *revs, unsigned flags)
 
 void init_revisions(struct rev_info *revs)
 {
+       unsigned abbrev = revs->abbrev;
+
        memset(revs, 0, sizeof(*revs));
-       revs->diffopt.recursive = 1;
-       revs->diffopt.add_remove = file_add_remove;
-       revs->diffopt.change = file_change;
+
+       revs->abbrev = abbrev;
+       revs->ignore_merges = 1;
+       revs->pruning.recursive = 1;
+       revs->pruning.add_remove = file_add_remove;
+       revs->pruning.change = file_change;
        revs->lifo = 1;
        revs->dense = 1;
        revs->prefix = setup_git_directory();
@@ -494,6 +496,11 @@ void init_revisions(struct rev_info *revs)
 
        revs->topo_setter = topo_sort_default_setter;
        revs->topo_getter = topo_sort_default_getter;
+
+       revs->header_prefix = "";
+       revs->commit_format = CMIT_FMT_DEFAULT;
+
+       diff_setup(&revs->diffopt);
 }
 
 /*
@@ -526,13 +533,14 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
 
        flags = 0;
        for (i = 1; i < argc; i++) {
-               struct commit *commit;
+               struct object *object;
                const char *arg = argv[i];
                unsigned char sha1[20];
                char *dotdot;
                int local_flags;
 
                if (*arg == '-') {
+                       int opts;
                        if (!strncmp(arg, "--max-count=", 12)) {
                                revs->max_count = atoi(arg + 12);
                                continue;
@@ -640,6 +648,78 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                                revs->unpacked = 1;
                                continue;
                        }
+                       if (!strcmp(arg, "-r")) {
+                               revs->diff = 1;
+                               revs->diffopt.recursive = 1;
+                               continue;
+                       }
+                       if (!strcmp(arg, "-t")) {
+                               revs->diff = 1;
+                               revs->diffopt.recursive = 1;
+                               revs->diffopt.tree_in_recursive = 1;
+                               continue;
+                       }
+                       if (!strcmp(arg, "-m")) {
+                               revs->ignore_merges = 0;
+                               continue;
+                       }
+                       if (!strcmp(arg, "-c")) {
+                               revs->diff = 1;
+                               revs->combine_merges = 1;
+                               continue;
+                       }
+                       if (!strcmp(arg, "--cc")) {
+                               revs->diff = 1;
+                               revs->dense_combined_merges = 1;
+                               revs->combine_merges = 1;
+                               continue;
+                       }
+                       if (!strcmp(arg, "-v")) {
+                               revs->verbose_header = 1;
+                               revs->header_prefix = "diff-tree ";
+                               continue;
+                       }
+                       if (!strncmp(arg, "--pretty", 8)) {
+                               revs->verbose_header = 1;
+                               revs->header_prefix = "diff-tree ";
+                               revs->commit_format = get_commit_format(arg+8);
+                               continue;
+                       }
+                       if (!strcmp(arg, "--root")) {
+                               revs->show_root_diff = 1;
+                               continue;
+                       }
+                       if (!strcmp(arg, "--no-commit-id")) {
+                               revs->no_commit_id = 1;
+                               continue;
+                       }
+                       if (!strcmp(arg, "--always")) {
+                               revs->always_show_header = 1;
+                               continue;
+                       }
+                       if (!strcmp(arg, "--no-abbrev")) {
+                               revs->abbrev = 0;
+                               continue;
+                       }
+                       if (!strcmp(arg, "--abbrev")) {
+                               revs->abbrev = DEFAULT_ABBREV;
+                               continue;
+                       }
+                       if (!strcmp(arg, "--abbrev-commit")) {
+                               revs->abbrev_commit = 1;
+                               continue;
+                       }
+                       if (!strcmp(arg, "--full-diff")) {
+                               revs->diff = 1;
+                               revs->full_diff = 1;
+                               continue;
+                       }
+                       opts = diff_opt_parse(&revs->diffopt, argv+i, argc-i);
+                       if (opts > 0) {
+                               revs->diff = 1;
+                               i += opts - 1;
+                               continue;
+                       }
                        *unrecognized++ = arg;
                        left++;
                        continue;
@@ -656,15 +736,15 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                                this = "HEAD";
                        if (!get_sha1(this, from_sha1) &&
                            !get_sha1(next, sha1)) {
-                               struct commit *exclude;
-                               struct commit *include;
+                               struct object *exclude;
+                               struct object *include;
 
-                               exclude = get_commit_reference(revs, this, from_sha1, flags ^ UNINTERESTING);
-                               include = get_commit_reference(revs, next, sha1, flags);
+                               exclude = get_reference(revs, this, from_sha1, flags ^ UNINTERESTING);
+                               include = get_reference(revs, next, sha1, flags);
                                if (!exclude || !include)
                                        die("Invalid revision range %s..%s", arg, next);
-                               add_one_commit(exclude, revs);
-                               add_one_commit(include, revs);
+                               add_pending_object(revs, exclude, this);
+                               add_pending_object(revs, include, next);
                                continue;
                        }
                        *dotdot = '.';
@@ -689,32 +769,57 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                        revs->prune_data = get_pathspec(revs->prefix, argv + i);
                        break;
                }
-               commit = get_commit_reference(revs, arg, sha1, flags ^ local_flags);
-               add_one_commit(commit, revs);
+               object = get_reference(revs, arg, sha1, flags ^ local_flags);
+               add_pending_object(revs, object, arg);
        }
-       if (def && !revs->commits) {
+       if (def && !revs->pending_objects) {
                unsigned char sha1[20];
-               struct commit *commit;
+               struct object *object;
                if (get_sha1(def, sha1) < 0)
                        die("bad default revision '%s'", def);
-               commit = get_commit_reference(revs, def, sha1, 0);
-               add_one_commit(commit, revs);
+               object = get_reference(revs, def, sha1, 0);
+               add_pending_object(revs, object, def);
        }
 
        if (revs->topo_order || revs->unpacked)
                revs->limited = 1;
 
        if (revs->prune_data) {
-               diff_tree_setup_paths(revs->prune_data, &revs->diffopt);
+               diff_tree_setup_paths(revs->prune_data, &revs->pruning);
                revs->prune_fn = try_to_simplify_commit;
+               if (!revs->full_diff)
+                       diff_tree_setup_paths(revs->prune_data, &revs->diffopt);
+       }
+       if (revs->combine_merges) {
+               revs->ignore_merges = 0;
+               if (revs->dense_combined_merges)
+                       revs->diffopt.output_format = DIFF_FORMAT_PATCH;
        }
+       if (revs->diffopt.output_format == DIFF_FORMAT_PATCH)
+               revs->diffopt.recursive = 1;
+       revs->diffopt.abbrev = revs->abbrev;
+       diff_setup_done(&revs->diffopt);
 
        return left;
 }
 
 void prepare_revision_walk(struct rev_info *revs)
 {
-       sort_by_date(&revs->commits);
+       struct object_list *list;
+
+       list = revs->pending_objects;
+       revs->pending_objects = NULL;
+       while (list) {
+               struct commit *commit = handle_commit(revs, list->item, list->name);
+               if (commit) {
+                       if (!(commit->object.flags & SEEN)) {
+                               commit->object.flags |= SEEN;
+                               insert_by_date(commit, &revs->commits);
+                       }
+               }
+               list = list->next;
+       }
+
        if (revs->limited)
                limit_list(revs);
        if (revs->topo_order)
index 8970b57e3c7e2ca8d213258f1befb84ac06e3a13..6eaa9048a93ec152346a335de8af604aafa0faf5 100644 (file)
@@ -38,13 +38,32 @@ struct rev_info {
                        boundary:1,
                        parents:1;
 
+       /* Diff flags */
+       unsigned int    diff:1,
+                       full_diff:1,
+                       show_root_diff:1,
+                       no_commit_id:1,
+                       verbose_header:1,
+                       ignore_merges:1,
+                       combine_merges:1,
+                       dense_combined_merges:1,
+                       always_show_header:1;
+
+       /* Format info */
+       unsigned int    abbrev_commit:1;
+       unsigned int    abbrev;
+       enum cmit_fmt   commit_format;
+       const char      *header_prefix;
+       const char      *header;
+
        /* special limits */
        int max_count;
        unsigned long max_age;
        unsigned long min_age;
 
-       /* paths limiting */
+       /* diff info for patches and for paths limiting */
        struct diff_options diffopt;
+       struct diff_options pruning;
 
        topo_sort_set_fn_t topo_setter;
        topo_sort_get_fn_t topo_getter;