Merge branch 'maint-1.5.5' into maint-1.5.6
authorJunio C Hamano <gitster@pobox.com>
Wed, 11 Feb 2009 09:41:22 +0000 (01:41 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 11 Feb 2009 09:41:22 +0000 (01:41 -0800)
* maint-1.5.5:
revision traversal and pack: notice and die on missing commit

Conflicts:
revision.c

1  2 
revision.c
diff --combined revision.c
index a68abec3f203d751db3eb4bce9c8e958abf3cc9e,07e5fcd86cfe6292bc21bbf0d6cc786e81ae02cc..3861470389cc8f154c071500a0f4cd169f0fc10d
@@@ -6,7 -6,6 +6,7 @@@
  #include "diff.h"
  #include "refs.h"
  #include "revision.h"
 +#include "graph.h"
  #include "grep.h"
  #include "reflog-walk.h"
  #include "patch-ids.h"
@@@ -259,7 -258,7 +259,7 @@@ static int tree_difference = REV_TREE_S
  static void file_add_remove(struct diff_options *options,
                    int addremove, unsigned mode,
                    const unsigned char *sha1,
 -                  const char *base, const char *path)
 +                  const char *fullpath)
  {
        int diff = REV_TREE_DIFFERENT;
  
@@@ -285,7 -284,7 +285,7 @@@ static void file_change(struct diff_opt
                 unsigned old_mode, unsigned new_mode,
                 const unsigned char *old_sha1,
                 const unsigned char *new_sha1,
 -               const char *base, const char *path)
 +               const char *fullpath)
  {
        tree_difference = REV_TREE_DIFFERENT;
        DIFF_OPT_SET(options, HAS_CHANGES);
@@@ -412,26 -411,11 +412,26 @@@ static void try_to_simplify_commit(stru
        commit->object.flags |= TREESAME;
  }
  
 -static int add_parents_to_list(struct rev_info *revs, struct commit *commit, struct commit_list **list)
 +static void insert_by_date_cached(struct commit *p, struct commit_list **head,
 +                  struct commit_list *cached_base, struct commit_list **cache)
 +{
 +      struct commit_list *new_entry;
 +
 +      if (cached_base && p->date < cached_base->item->date)
 +              new_entry = insert_by_date(p, &cached_base->next);
 +      else
 +              new_entry = insert_by_date(p, head);
 +
 +      if (cache && (!*cache || p->date < (*cache)->item->date))
 +              *cache = new_entry;
 +}
 +
 +static int add_parents_to_list(struct rev_info *revs, struct commit *commit,
 +                  struct commit_list **list, struct commit_list **cache_ptr)
  {
        struct commit_list *parent = commit->parents;
        unsigned left_flag;
 -      int add, rest;
 +      struct commit_list *cached_base = cache_ptr ? *cache_ptr : NULL;
  
        if (commit->object.flags & ADDED)
                return 0;
                        if (p->object.flags & SEEN)
                                continue;
                        p->object.flags |= SEEN;
 -                      insert_by_date(p, list);
 +                      insert_by_date_cached(p, list, cached_base, cache_ptr);
                }
                return 0;
        }
  
        left_flag = (commit->object.flags & SYMMETRIC_LEFT);
  
 -      rest = !revs->first_parent_only;
 -      for (parent = commit->parents, add = 1; parent; add = rest) {
 +      for (parent = commit->parents; parent; parent = parent->next) {
                struct commit *p = parent->item;
  
 -              parent = parent->next;
                if (parse_commit(p) < 0)
                        return -1;
                p->object.flags |= left_flag;
 -              if (p->object.flags & SEEN)
 -                      continue;
 -              p->object.flags |= SEEN;
 -              if (add)
 -                      insert_by_date(p, list);
 +              if (!(p->object.flags & SEEN)) {
 +                      p->object.flags |= SEEN;
 +                      insert_by_date_cached(p, list, cached_base, cache_ptr);
 +              }
 +              if(revs->first_parent_only)
 +                      break;
        }
        return 0;
  }
@@@ -627,7 -612,7 +627,7 @@@ static int limit_list(struct rev_info *
  
                if (revs->max_age != -1 && (commit->date < revs->max_age))
                        obj->flags |= UNINTERESTING;
 -              if (add_parents_to_list(revs, commit, &list) < 0)
 +              if (add_parents_to_list(revs, commit, &list, NULL) < 0)
                        return -1;
                if (obj->flags & UNINTERESTING) {
                        mark_parents_uninteresting(commit);
@@@ -1120,8 -1105,7 +1120,8 @@@ int setup_revisions(int argc, const cha
                                }
                        }
                        if (!strcmp(arg, "--parents")) {
 -                              revs->parents = 1;
 +                              revs->rewrite_parents = 1;
 +                              revs->print_parents = 1;
                                continue;
                        }
                        if (!strcmp(arg, "--dense")) {
                                revs->verbose_header = 1;
                                continue;
                        }
 -                      if (!prefixcmp(arg, "--pretty")) {
 +                      if (!strcmp(arg, "--pretty")) {
 +                              revs->verbose_header = 1;
 +                              get_commit_format(arg+8, revs);
 +                              continue;
 +                      }
 +                      if (!prefixcmp(arg, "--pretty=")) {
                                revs->verbose_header = 1;
 -                              revs->commit_format = get_commit_format(arg+8);
 +                              get_commit_format(arg+9, revs);
 +                              continue;
 +                      }
 +                      if (!strcmp(arg, "--graph")) {
 +                              revs->topo_order = 1;
 +                              revs->rewrite_parents = 1;
 +                              revs->graph = graph_init(revs);
                                continue;
                        }
                        if (!strcmp(arg, "--root")) {
        if (revs->reverse && revs->reflog_info)
                die("cannot combine --reverse with --walk-reflogs");
  
 +      /*
 +       * Limitations on the graph functionality
 +       */
 +      if (revs->reverse && revs->graph)
 +              die("cannot combine --reverse with --graph");
 +
 +      if (revs->reflog_info && revs->graph)
 +              die("cannot combine --walk-reflogs with --graph");
 +
        return left;
  }
  
@@@ -1474,12 -1438,10 +1474,12 @@@ enum rewrite_result 
  
  static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp)
  {
 +      struct commit_list *cache = NULL;
 +
        for (;;) {
                struct commit *p = *pp;
                if (!revs->limited)
 -                      if (add_parents_to_list(revs, p, &revs->commits) < 0)
 +                      if (add_parents_to_list(revs, p, &revs->commits, &cache) < 0)
                                return rewrite_one_error;
                if (p->parents && p->parents->next)
                        return rewrite_one_ok;
@@@ -1562,13 -1524,13 +1562,13 @@@ enum commit_action simplify_commit(stru
                /* Commit without changes? */
                if (commit->object.flags & TREESAME) {
                        /* drop merges unless we want parenthood */
 -                      if (!revs->parents)
 +                      if (!revs->rewrite_parents)
                                return commit_ignore;
                        /* non-merge - always ignore it */
                        if (!commit->parents || !commit->parents->next)
                                return commit_ignore;
                }
 -              if (revs->parents && rewrite_parents(revs, commit) < 0)
 +              if (revs->rewrite_parents && rewrite_parents(revs, commit) < 0)
                        return commit_error;
        }
        return commit_show;
@@@ -1598,15 -1560,17 +1598,17 @@@ static struct commit *get_revision_1(st
                        if (revs->max_age != -1 &&
                            (commit->date < revs->max_age))
                                continue;
 -                      if (add_parents_to_list(revs, commit, &revs->commits) < 0)
 +                      if (add_parents_to_list(revs, commit, &revs->commits, NULL) < 0)
-                               return NULL;
+                               die("Failed to traverse parents of commit %s",
+                                   sha1_to_hex(commit->object.sha1));
                }
  
                switch (simplify_commit(revs, commit)) {
                case commit_ignore:
                        continue;
                case commit_error:
-                       return NULL;
+                       die("Failed to simplify parents of commit %s",
+                           sha1_to_hex(commit->object.sha1));
                default:
                        return commit;
                }
@@@ -1635,62 -1599,28 +1637,62 @@@ static void gc_boundary(struct object_a
        }
  }
  
 -struct commit *get_revision(struct rev_info *revs)
 +static void create_boundary_commit_list(struct rev_info *revs)
 +{
 +      unsigned i;
 +      struct commit *c;
 +      struct object_array *array = &revs->boundary_commits;
 +      struct object_array_entry *objects = array->objects;
 +
 +      /*
 +       * If revs->commits is non-NULL at this point, an error occurred in
 +       * get_revision_1().  Ignore the error and continue printing the
 +       * boundary commits anyway.  (This is what the code has always
 +       * done.)
 +       */
 +      if (revs->commits) {
 +              free_commit_list(revs->commits);
 +              revs->commits = NULL;
 +      }
 +
 +      /*
 +       * Put all of the actual boundary commits from revs->boundary_commits
 +       * into revs->commits
 +       */
 +      for (i = 0; i < array->nr; i++) {
 +              c = (struct commit *)(objects[i].item);
 +              if (!c)
 +                      continue;
 +              if (!(c->object.flags & CHILD_SHOWN))
 +                      continue;
 +              if (c->object.flags & (SHOWN | BOUNDARY))
 +                      continue;
 +              c->object.flags |= BOUNDARY;
 +              commit_list_insert(c, &revs->commits);
 +      }
 +
 +      /*
 +       * If revs->topo_order is set, sort the boundary commits
 +       * in topological order
 +       */
 +      sort_in_topological_order(&revs->commits, revs->lifo);
 +}
 +
 +static struct commit *get_revision_internal(struct rev_info *revs)
  {
        struct commit *c = NULL;
        struct commit_list *l;
  
        if (revs->boundary == 2) {
 -              unsigned i;
 -              struct object_array *array = &revs->boundary_commits;
 -              struct object_array_entry *objects = array->objects;
 -              for (i = 0; i < array->nr; i++) {
 -                      c = (struct commit *)(objects[i].item);
 -                      if (!c)
 -                              continue;
 -                      if (!(c->object.flags & CHILD_SHOWN))
 -                              continue;
 -                      if (!(c->object.flags & SHOWN))
 -                              break;
 -              }
 -              if (array->nr <= i)
 -                      return NULL;
 -
 -              c->object.flags |= SHOWN | BOUNDARY;
 +              /*
 +               * All of the normal commits have already been returned,
 +               * and we are now returning boundary commits.
 +               * create_boundary_commit_list() has populated
 +               * revs->commits with the remaining commits to return.
 +               */
 +              c = pop_commit(&revs->commits);
 +              if (c)
 +                      c->object.flags |= SHOWN;
                return c;
        }
  
                 * switch to boundary commits output mode.
                 */
                revs->boundary = 2;
 -              return get_revision(revs);
 +
 +              /*
 +               * Update revs->commits to contain the list of
 +               * boundary commits.
 +               */
 +              create_boundary_commit_list(revs);
 +
 +              return get_revision_internal(revs);
        }
  
        /*
  
        return c;
  }
 +
 +struct commit *get_revision(struct rev_info *revs)
 +{
 +      struct commit *c = get_revision_internal(revs);
 +      if (c && revs->graph)
 +              graph_update(revs->graph, c);
 +      return c;
 +}