Merge branch 'lt/tree-2'
authorJunio C Hamano <junkio@cox.net>
Sun, 4 Jun 2006 06:59:27 +0000 (23:59 -0700)
committerJunio C Hamano <junkio@cox.net>
Sun, 4 Jun 2006 06:59:27 +0000 (23:59 -0700)
* lt/tree-2:
  fetch.c: do not call process_tree() from process_tree().
  tree_entry(): new tree-walking helper function
  adjust to the rebased series by Linus.
  Remove "tree->entries" tree-entry list from tree parser
  Switch "read_tree_recursive()" over to tree-walk functionality
  Make "tree_entry" have a SHA1 instead of a union of object pointers
  Add raw tree buffer info to "struct tree"
  Remove last vestiges of generic tree_entry_list
  Convert fetch.c: process_tree() to raw tree walker
  Convert "mark_tree_uninteresting()" to raw tree walker
  Remove unused "zeropad" entry from tree_list_entry
  fsck-objects: avoid unnecessary tree_entry_list usage
  Remove "tree->entries" tree-entry list from tree parser
  builtin-read-tree.c: avoid tree_entry_list in prime_cache_tree_rec()
  Switch "read_tree_recursive()" over to tree-walk functionality
  Make "tree_entry" have a SHA1 instead of a union of object pointers
  Make "struct tree" contain the pointer to the tree buffer

1  2 
builtin-read-tree.c
fetch.c

diff --combined builtin-read-tree.c
@@@ -9,6 -9,7 +9,7 @@@
  
  #include "object.h"
  #include "tree.h"
+ #include "tree-walk.h"
  #include "cache-tree.h"
  #include <sys/time.h>
  #include <signal.h>
@@@ -29,7 -30,17 +30,17 @@@ static int merge_size = 0
  
  static struct object_list *trees = NULL;
  
- static struct cache_entry df_conflict_entry = { 
+ static struct cache_entry df_conflict_entry = {
+ };
+ struct tree_entry_list {
+       struct tree_entry_list *next;
+       unsigned directory : 1;
+       unsigned executable : 1;
+       unsigned symlink : 1;
+       unsigned int mode;
+       const char *name;
+       const unsigned char *sha1;
  };
  
  static struct tree_entry_list df_conflict_list = {
  
  typedef int (*merge_fn_t)(struct cache_entry **src);
  
- static int entcmp(char *name1, int dir1, char *name2, int dir2)
+ static struct tree_entry_list *create_tree_entry_list(struct tree *tree)
+ {
+       struct tree_desc desc;
+       struct name_entry one;
+       struct tree_entry_list *ret = NULL;
+       struct tree_entry_list **list_p = &ret;
+       desc.buf = tree->buffer;
+       desc.size = tree->size;
+       while (tree_entry(&desc, &one)) {
+               struct tree_entry_list *entry;
+               entry = xmalloc(sizeof(struct tree_entry_list));
+               entry->name = one.path;
+               entry->sha1 = one.sha1;
+               entry->mode = one.mode;
+               entry->directory = S_ISDIR(one.mode) != 0;
+               entry->executable = (one.mode & S_IXUSR) != 0;
+               entry->symlink = S_ISLNK(one.mode) != 0;
+               entry->next = NULL;
+               *list_p = entry;
+               list_p = &entry->next;
+       }
+       return ret;
+ }
+ static int entcmp(const char *name1, int dir1, const char *name2, int dir2)
  {
        int len1 = strlen(name1);
        int len2 = strlen(name2);
@@@ -67,7 -106,7 +106,7 @@@ static int unpack_trees_rec(struct tree
        int src_size = len + 1;
        do {
                int i;
-               char *first;
+               const char *first;
                int firstdir = 0;
                int pathlen;
                unsigned ce_size;
                        }
  
                        if (posns[i]->directory) {
+                               struct tree *tree = lookup_tree(posns[i]->sha1);
                                any_dirs = 1;
-                               parse_tree(posns[i]->item.tree);
-                               subposns[i] = posns[i]->item.tree->entries;
+                               parse_tree(tree);
+                               subposns[i] = create_tree_entry_list(tree);
                                posns[i] = posns[i]->next;
                                src[i + merge] = &df_conflict_entry;
                                continue;
  
                        any_files = 1;
  
-                       memcpy(ce->sha1, posns[i]->item.any->sha1, 20);
+                       memcpy(ce->sha1, posns[i]->sha1, 20);
                        src[i + merge] = ce;
                        subposns[i] = &df_conflict_list;
                        posns[i] = posns[i]->next;
@@@ -368,7 -408,7 +408,7 @@@ static int unpack_trees(merge_fn_t fn
        if (len) {
                posns = xmalloc(len * sizeof(struct tree_entry_list *));
                for (i = 0; i < len; i++) {
-                       posns[i] = ((struct tree *) posn->item)->entries;
+                       posns[i] = create_tree_entry_list((struct tree *) posn->item);
                        posn = posn->next;
                }
                if (unpack_trees_rec(posns, len, "", fn, &indpos))
@@@ -751,43 -791,46 +791,47 @@@ static int oneway_merge(struct cache_en
  
  static int read_cache_unmerged(void)
  {
 -      int i, deleted;
 +      int i;
        struct cache_entry **dst;
 +      struct cache_entry *last = NULL;
  
        read_cache();
        dst = active_cache;
 -      deleted = 0;
        for (i = 0; i < active_nr; i++) {
                struct cache_entry *ce = active_cache[i];
                if (ce_stage(ce)) {
 -                      deleted++;
 +                      if (last && !strcmp(ce->name, last->name))
 +                              continue;
                        invalidate_ce_path(ce);
 -                      continue;
 +                      last = ce;
 +                      ce->ce_mode = 0;
 +                      ce->ce_flags &= ~htons(CE_STAGEMASK);
                }
 -              if (deleted)
 -                      *dst = ce;
 -              dst++;
 +              *dst++ = ce;
        }
 -      active_nr -= deleted;
 -      return deleted;
 +      active_nr = dst - active_cache;
 +      return !!last;
  }
  
  static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)
  {
-       struct tree_entry_list *ent;
+       struct tree_desc desc;
+       struct name_entry entry;
        int cnt;
  
        memcpy(it->sha1, tree->object.sha1, 20);
-       for (cnt = 0, ent = tree->entries; ent; ent = ent->next) {
-               if (!ent->directory)
+       desc.buf = tree->buffer;
+       desc.size = tree->size;
+       cnt = 0;
+       while (tree_entry(&desc, &entry)) {
+               if (!S_ISDIR(entry.mode))
                        cnt++;
                else {
                        struct cache_tree_sub *sub;
-                       struct tree *subtree = (struct tree *)ent->item.tree;
+                       struct tree *subtree = lookup_tree(entry.sha1);
                        if (!subtree->object.parsed)
                                parse_tree(subtree);
-                       sub = cache_tree_sub(it, ent->name);
+                       sub = cache_tree_sub(it, entry.path);
                        sub->cache_tree = cache_tree();
                        prime_cache_tree_rec(sub->cache_tree, subtree);
                        cnt += sub->cache_tree->entry_count;
@@@ -851,10 -894,7 +895,10 @@@ int cmd_read_tree(int argc, const char 
                        continue;
                }
  
 -              /* This differs from "-m" in that we'll silently ignore unmerged entries */
 +              /* This differs from "-m" in that we'll silently ignore
 +               * unmerged entries and overwrite working tree files that
 +               * correspond to them.
 +               */
                if (!strcmp(arg, "--reset")) {
                        if (stage || merge)
                                usage(read_tree_usage);
diff --combined fetch.c
+++ b/fetch.c
@@@ -3,12 -3,12 +3,13 @@@
  #include "cache.h"
  #include "commit.h"
  #include "tree.h"
+ #include "tree-walk.h"
  #include "tag.h"
  #include "blob.h"
  #include "refs.h"
  
  const char *write_ref = NULL;
 +const char *write_ref_log_details = NULL;
  
  int get_tree = 0;
  int get_history = 0;
@@@ -37,21 -37,33 +38,33 @@@ static int process(struct object *obj)
  
  static int process_tree(struct tree *tree)
  {
-       struct tree_entry_list *entry;
+       struct tree_desc desc;
+       struct name_entry entry;
  
        if (parse_tree(tree))
                return -1;
  
-       entry = tree->entries;
-       tree->entries = NULL;
-       while (entry) {
-               struct tree_entry_list *next = entry->next;
-               if (process(entry->item.any))
+       desc.buf = tree->buffer;
+       desc.size = tree->size;
+       while (tree_entry(&desc, &entry)) {
+               struct object *obj = NULL;
+               if (S_ISDIR(entry.mode)) {
+                       struct tree *tree = lookup_tree(entry.sha1);
+                       if (tree)
+                               obj = &tree->object;
+               }
+               else {
+                       struct blob *blob = lookup_blob(entry.sha1);
+                       if (blob)
+                               obj = &blob->object;
+               }
+               if (!obj || process(obj))
                        return -1;
-               free(entry->name);
-               free(entry);
-               entry = next;
        }
+       free(tree->buffer);
+       tree->buffer = NULL;
+       tree->size = 0;
        return 0;
  }
  
@@@ -203,51 -215,23 +216,51 @@@ static int mark_complete(const char *pa
  
  int pull(char *target)
  {
 +      struct ref_lock *lock = NULL;
        unsigned char sha1[20];
 +      char *msg;
 +      int ret;
  
        save_commit_buffer = 0;
        track_object_refs = 0;
 +      if (write_ref) {
 +              lock = lock_ref_sha1(write_ref, NULL, 0);
 +              if (!lock) {
 +                      error("Can't lock ref %s", write_ref);
 +                      return -1;
 +              }
 +      }
  
        if (!get_recover)
                for_each_ref(mark_complete);
  
 -      if (interpret_target(target, sha1))
 -              return error("Could not interpret %s as something to pull",
 -                           target);
 -      if (process(lookup_unknown_object(sha1)))
 +      if (interpret_target(target, sha1)) {
 +              error("Could not interpret %s as something to pull", target);
 +              if (lock)
 +                      unlock_ref(lock);
                return -1;
 -      if (loop())
 +      }
 +      if (process(lookup_unknown_object(sha1))) {
 +              if (lock)
 +                      unlock_ref(lock);
                return -1;
 -      
 -      if (write_ref)
 -              write_ref_sha1_unlocked(write_ref, sha1);
 +      }
 +      if (loop()) {
 +              if (lock)
 +                      unlock_ref(lock);
 +              return -1;
 +      }
 +
 +      if (write_ref) {
 +              if (write_ref_log_details) {
 +                      msg = xmalloc(strlen(write_ref_log_details) + 12);
 +                      sprintf(msg, "fetch from %s", write_ref_log_details);
 +              } else
 +                      msg = NULL;
 +              ret = write_ref_sha1(lock, sha1, msg ? msg : "fetch (unknown)");
 +              if (msg)
 +                      free(msg);
 +              return ret;
 +      }
        return 0;
  }