Merge branch 'jc/boundary' into next
authorJunio C Hamano <junkio@cox.net>
Mon, 17 Apr 2006 05:07:28 +0000 (22:07 -0700)
committerJunio C Hamano <junkio@cox.net>
Mon, 17 Apr 2006 05:07:28 +0000 (22:07 -0700)
* jc/boundary:
rev-list --boundary: show boundary commits even when limited otherwise.
Makefile fixups.
gitk: Fix bug caused by missing commitlisted elements

1  2 
Makefile
http-push.c
rev-list.c
revision.c
revision.h
diff --combined Makefile
index 69ca05b2f96dac2ac72faf3a6ecf5328558f8156,8371f7f522b6b02039af2a9d1684a8137197526e..84a4b84226cef5ac058760935a2770a3c164f436
+++ b/Makefile
@@@ -606,9 -606,6 +606,9 @@@ test-date$X: test-date.c date.o ctype.
  test-delta$X: test-delta.c diff-delta.o patch-delta.o
        $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $^ -lz
  
 +test-gsimm$X: test-gsimm.c gsimm.o rabinpoly.o
 +      $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $^
 +
  check:
        for i in *.c; do sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; done
  
@@@ -656,8 -653,7 +656,8 @@@ rpm: dis
  clean:
        rm -f *.o mozilla-sha1/*.o arm/*.o ppc/*.o compat/*.o xdiff/*.o \
                $(LIB_FILE) $(XDIFF_LIB)
-       rm -f $(ALL_PROGRAMS) git$X
+       rm -f $(ALL_PROGRAMS) $(BUILT_INS) git$X
 +      rm -f test-date$X test-delta$X test-gsimm$X
        rm -f *.spec *.pyc *.pyo */*.pyc */*.pyo common-cmds.h TAGS tags
        rm -rf $(GIT_TARNAME)
        rm -f $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
diff --combined http-push.c
index 4a9dcf2bf64887735573d7c02b6b9f21ad4644f6,114d01bced1cb3f9a906c7c0df85bf5cd2b811e0..b4327d92438d9596b7286ead06152ad3156b6e2c
@@@ -60,12 -60,12 +60,12 @@@ enum XML_Status 
  #define LOCK_TIME 600
  #define LOCK_REFRESH 30
  
- /* bits #0-6 in revision.h */
+ /* bits #0-15 in revision.h */
  
- #define LOCAL    (1u << 7)
- #define REMOTE   (1u << 8)
- #define FETCHING (1u << 9)
- #define PUSHING  (1u << 10)
+ #define LOCAL    (1u<<16)
+ #define REMOTE   (1u<<17)
+ #define FETCHING (1u<<18)
+ #define PUSHING  (1u<<19)
  
  /* We allow "recursive" symbolic refs. Only within reason, though */
  #define MAXDEPTH 5
@@@ -2498,7 -2498,6 +2498,7 @@@ int main(int argc, char **argv
                        commit_argv[3] = old_sha1_hex;
                        commit_argc++;
                }
 +              init_revisions(&revs);
                setup_revisions(commit_argc, commit_argv, &revs, NULL);
                free(new_sha1_hex);
                if (old_sha1_hex) {
diff --combined rev-list.c
index 33741ebbc4eec2ab7abdd9b5c045c7a6ec3cada6,f5511e72db103ea2b549b48e84985969a94c5485..b75da12408c58576264a72014c4791969c253308
@@@ -8,9 -8,9 +8,9 @@@
  #include "diff.h"
  #include "revision.h"
  
- /* bits #0-6 in revision.h */
+ /* bits #0-15 in revision.h */
  
- #define COUNTED               (1u<<7)
+ #define COUNTED               (1u<<16)
  
  static const char rev_list_usage[] =
  "git-rev-list [OPTION] <commit-id>... [ -- paths... ]\n"
  struct rev_info revs;
  
  static int bisect_list = 0;
 -static int verbose_header = 0;
 -static int abbrev = DEFAULT_ABBREV;
 -static int abbrev_commit = 0;
  static int show_timestamp = 0;
  static int hdr_termination = 0;
 -static const char *commit_prefix = "";
 -static enum cmit_fmt commit_format = CMIT_FMT_RAW;
  
  static void show_commit(struct commit *commit)
  {
        if (show_timestamp)
                printf("%lu ", commit->date);
 -      if (commit_prefix[0])
 -              fputs(commit_prefix, stdout);
 +      if (*revs.header_prefix)
 +              fputs(revs.header_prefix, stdout);
        if (commit->object.flags & BOUNDARY)
                putchar('-');
 -      if (abbrev_commit && abbrev)
 -              fputs(find_unique_abbrev(commit->object.sha1, abbrev), stdout);
 +      if (revs.abbrev_commit && revs.abbrev)
 +              fputs(find_unique_abbrev(commit->object.sha1, revs.abbrev),
 +                    stdout);
        else
                fputs(sha1_to_hex(commit->object.sha1), stdout);
        if (revs.parents) {
                     parents = parents->next)
                        parents->item->object.flags &= ~TMP_MARK;
        }
 -      if (commit_format == CMIT_FMT_ONELINE)
 +      if (revs.commit_format == CMIT_FMT_ONELINE)
                putchar(' ');
        else
                putchar('\n');
  
 -      if (verbose_header) {
 +      if (revs.verbose_header) {
                static char pretty_header[16384];
 -              pretty_print_commit(commit_format, commit, ~0, pretty_header, sizeof(pretty_header), abbrev);
 +              pretty_print_commit(revs.commit_format, commit, ~0,
 +                                  pretty_header, sizeof(pretty_header),
 +                                  revs.abbrev);
                printf("%s%c", pretty_header, hdr_termination);
        }
        fflush(stdout);
@@@ -295,16 -297,58 +295,16 @@@ int main(int argc, const char **argv
        struct commit_list *list;
        int i;
  
 +      init_revisions(&revs);
 +      revs.abbrev = 0;
 +      revs.commit_format = CMIT_FMT_UNSPECIFIED;
        argc = setup_revisions(argc, argv, &revs, NULL);
  
        for (i = 1 ; i < argc; i++) {
                const char *arg = argv[i];
  
 -              /* accept -<digit>, like traditilnal "head" */
 -              if ((*arg == '-') && isdigit(arg[1])) {
 -                      revs.max_count = atoi(arg + 1);
 -                      continue;
 -              }
 -              if (!strcmp(arg, "-n")) {
 -                      if (++i >= argc)
 -                              die("-n requires an argument");
 -                      revs.max_count = atoi(argv[i]);
 -                      continue;
 -              }
 -              if (!strncmp(arg,"-n",2)) {
 -                      revs.max_count = atoi(arg + 2);
 -                      continue;
 -              }
                if (!strcmp(arg, "--header")) {
 -                      verbose_header = 1;
 -                      continue;
 -              }
 -              if (!strcmp(arg, "--no-abbrev")) {
 -                      abbrev = 0;
 -                      continue;
 -              }
 -              if (!strcmp(arg, "--abbrev")) {
 -                      abbrev = DEFAULT_ABBREV;
 -                      continue;
 -              }
 -              if (!strcmp(arg, "--abbrev-commit")) {
 -                      abbrev_commit = 1;
 -                      continue;
 -              }
 -              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;
 -                      continue;
 -              }
 -              if (!strncmp(arg, "--pretty", 8)) {
 -                      commit_format = get_commit_format(arg+8);
 -                      verbose_header = 1;
 -                      hdr_termination = '\n';
 -                      if (commit_format == CMIT_FMT_ONELINE)
 -                              commit_prefix = "";
 -                      else
 -                              commit_prefix = "commit ";
 +                      revs.verbose_header = 1;
                        continue;
                }
                if (!strcmp(arg, "--timestamp")) {
                usage(rev_list_usage);
  
        }
 +      if (revs.commit_format != CMIT_FMT_UNSPECIFIED) {
 +              /* The command line has a --pretty  */
 +              hdr_termination = '\n';
 +              if (revs.commit_format == CMIT_FMT_ONELINE)
 +                      revs.header_prefix = "";
 +              else
 +                      revs.header_prefix = "commit ";
 +      }
  
        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;
 +      save_commit_buffer = revs.verbose_header;
        track_object_refs = 0;
 +      if (bisect_list)
 +              revs.limited = 1;
  
        prepare_revision_walk(&revs);
        if (revs.tree_objects)
diff --combined revision.c
index f8fb02885589e3243b4b44692594861f98843d69,e1f9816bd7e2f91b3c23dedd50f0a03d33c33dfc..3cd6a2ed9f978776b2a021747f3f0995ebb70b28
@@@ -116,27 -116,21 +116,27 @@@ static void add_pending_object(struct r
        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)
         */
        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) {
@@@ -246,7 -241,7 +246,7 @@@ int rev_compare_tree(struct rev_info *r
                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;
  }
@@@ -269,7 -264,7 +269,7 @@@ int rev_same_tree_as_empty(struct rev_i
        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;
@@@ -380,9 -375,6 +380,9 @@@ static void add_parents_to_list(struct 
        if (revs->prune_fn)
                revs->prune_fn(revs, commit);
  
 +      if (revs->no_walk)
 +              return;
 +
        parent = commit->parents;
        while (parent) {
                struct commit *p = parent->item;
@@@ -459,13 -451,21 +459,13 @@@ static void limit_list(struct rev_info 
        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;
  }
  
@@@ -479,12 -479,9 +479,12 @@@ static void handle_all(struct rev_info 
  void init_revisions(struct rev_info *revs)
  {
        memset(revs, 0, sizeof(*revs));
 -      revs->diffopt.recursive = 1;
 -      revs->diffopt.add_remove = file_add_remove;
 -      revs->diffopt.change = file_change;
 +
 +      revs->abbrev = DEFAULT_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();
  
        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);
  }
  
  /*
@@@ -517,6 -509,8 +517,6 @@@ int setup_revisions(int argc, const cha
        const char **unrecognized = argv + 1;
        int left = 1;
  
 -      init_revisions(revs);
 -
        /* First, search for "--" */
        seen_dashdash = 0;
        for (i = 1; i < argc; i++) {
  
        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;
                                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;
                                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 = '.';
                        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->no_walk)
 +              return;
        if (revs->limited)
                limit_list(revs);
        if (revs->topo_order)
@@@ -856,6 -750,17 +856,17 @@@ static void rewrite_parents(struct rev_
        }
  }
  
+ static void mark_boundary_to_show(struct commit *commit)
+ {
+       struct commit_list *p = commit->parents;
+       while (p) {
+               commit = p->item;
+               p = p->next;
+               if (commit->object.flags & BOUNDARY)
+                       commit->object.flags |= BOUNDARY_SHOW;
+       }
+ }
  struct commit *get_revision(struct rev_info *revs)
  {
        struct commit_list *list = revs->commits;
                }
                if (commit->object.flags & SHOWN)
                        continue;
-               if (!(commit->object.flags & BOUNDARY) &&
-                   (commit->object.flags & UNINTERESTING))
+               /* We want to show boundary commits only when their
+                * children are shown.  When path-limiter is in effect,
+                * rewrite_parents() drops some commits from getting shown,
+                * and there is no point showing boundary parents that
+                * are not shown.  After rewrite_parents() rewrites the
+                * parents of a commit that is shown, we mark the boundary
+                * parents with BOUNDARY_SHOW.
+                */
+               if (commit->object.flags & BOUNDARY_SHOW) {
+                       commit->object.flags |= SHOWN;
+                       return commit;
+               }
+               if (commit->object.flags & UNINTERESTING)
                        continue;
                if (revs->min_age != -1 && (commit->date > revs->min_age))
                        continue;
                        if (revs->parents)
                                rewrite_parents(revs, commit);
                }
+               if (revs->boundary)
+                       mark_boundary_to_show(commit);
                commit->object.flags |= SHOWN;
                return commit;
        } while (revs->commits);
diff --combined revision.h
index 74dc5ef179e9778b874ceee7aefc6162892b116a,4b270435109a8aefb4a85fa01d1f5d8a0f33f0bb..872bcd81725d08d20ece460a5898e0c9ea2ca3a1
@@@ -7,7 -7,8 +7,8 @@@
  #define SHOWN         (1u<<3)
  #define TMP_MARK      (1u<<4) /* for isolated cases; clean after use */
  #define BOUNDARY      (1u<<5)
- #define ADDED         (1u<<6) /* Parents already parsed and added? */
+ #define BOUNDARY_SHOW (1u<<6)
+ #define ADDED         (1u<<7) /* Parents already parsed and added? */
  
  struct rev_info;
  
@@@ -26,7 -27,6 +27,7 @@@ struct rev_info 
        /* Traversal flags */
        unsigned int    dense:1,
                        no_merges:1,
 +                      no_walk:1,
                        remove_empty_trees:1,
                        lifo:1,
                        topo_order:1,
                        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;
 +      const char      *use_precomputed_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;