tree/diff header cleanup.
authorJunio C Hamano <junkio@cox.net>
Thu, 30 Mar 2006 06:55:43 +0000 (22:55 -0800)
committerJunio C Hamano <junkio@cox.net>
Thu, 30 Mar 2006 07:54:13 +0000 (23:54 -0800)
Introduce tree-walk.[ch] and move "struct tree_desc" and
associated functions from various places.

Rename DIFF_FILE_CANON_MODE(mode) macro to canon_mode(mode) and
move it to cache.h.  This macro returns the canonicalized
st_mode value in the host byte order for files, symlinks and
directories -- to be compared with a tree_desc entry.
create_ce_mode(mode) in cache.h is similar but is intended to be
used for index entries (so it does not work for directories) and
returns the value in the network byte order.

Signed-off-by: Junio C Hamano <junkio@cox.net>
13 files changed:
Makefile
cache.h
combine-diff.c
diff-files.c
diff.c
diff.h
merge-tree.c
pack-objects.c
rev-list.c
tar-tree.c
tree-diff.c
tree-walk.c [new file with mode: 0644]
tree-walk.h [new file with mode: 0644]

index d945546..d78298a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -193,7 +193,8 @@ XDIFF_LIB=xdiff/lib.a
 LIB_H = \
        blob.h cache.h commit.h csum-file.h delta.h \
        diff.h object.h pack.h pkt-line.h quote.h refs.h \
-       run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h
+       run-command.h strbuf.h tag.h tree.h git-compat-util.h revision.h \
+       tree-walk.h
 
 DIFF_OBJS = \
        diff.o diffcore-break.o diffcore-order.o diffcore-pathspec.o \
@@ -207,7 +208,7 @@ LIB_OBJS = \
        quote.o read-cache.o refs.o run-command.o \
        server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
        tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
-       fetch-clone.o revision.o pager.o \
+       fetch-clone.o revision.o pager.o tree-walk.o \
        $(DIFF_OBJS)
 
 GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
diff --git a/cache.h b/cache.h
index 255e6b5..69801b0 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -106,6 +106,9 @@ static inline unsigned int create_ce_mode(unsigned int mode)
                return htonl(S_IFLNK);
        return htonl(S_IFREG | ce_permissions(mode));
 }
+#define canon_mode(mode) \
+       (S_ISREG(mode) ? (S_IFREG | ce_permissions(mode)) : \
+       S_ISLNK(mode) ? S_IFLNK : S_IFDIR)
 
 #define cache_entry_size(len) ((offsetof(struct cache_entry,name) + (len) + 8) & ~7)
 
index a23894d..f17aab3 100644 (file)
@@ -649,7 +649,7 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent,
                        int len = st.st_size;
                        int cnt = 0;
 
-                       elem->mode = DIFF_FILE_CANON_MODE(st.st_mode);
+                       elem->mode = canon_mode(st.st_mode);
                        size = len;
                        result = xmalloc(len + 1);
                        while (cnt < len) {
index b1c05b3..3e7f5f1 100644 (file)
@@ -149,7 +149,7 @@ int main(int argc, const char **argv)
                                        memcpy(combine.p.parent[stage-2].sha1,
                                               nce->sha1, 20);
                                        combine.p.parent[stage-2].mode =
-                                               DIFF_FILE_CANON_MODE(mode);
+                                               canon_mode(mode);
                                        combine.p.parent[stage-2].status =
                                                DIFF_STATUS_MODIFIED;
                                }
@@ -198,7 +198,7 @@ int main(int argc, const char **argv)
                        continue;
                oldmode = ntohl(ce->ce_mode);
 
-               newmode = DIFF_FILE_CANON_MODE(st.st_mode);
+               newmode = canon_mode(st.st_mode);
                if (!trust_executable_bit &&
                    S_ISREG(newmode) && S_ISREG(oldmode) &&
                    ((newmode ^ oldmode) == 0111))
diff --git a/diff.c b/diff.c
index 8b37477..e496905 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -300,7 +300,7 @@ void fill_filespec(struct diff_filespec *spec, const unsigned char *sha1,
                   unsigned short mode)
 {
        if (mode) {
-               spec->mode = DIFF_FILE_CANON_MODE(mode);
+               spec->mode = canon_mode(mode);
                memcpy(spec->sha1, sha1, 20);
                spec->sha1_valid = !!memcmp(sha1, null_sha1, 20);
        }
diff --git a/diff.h b/diff.h
index 8fac465..a268d16 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -4,17 +4,7 @@
 #ifndef DIFF_H
 #define DIFF_H
 
-#define DIFF_FILE_CANON_MODE(mode) \
-       (S_ISREG(mode) ? (S_IFREG | ce_permissions(mode)) : \
-       S_ISLNK(mode) ? S_IFLNK : S_IFDIR)
-
-struct tree_desc {
-       void *buf;
-       unsigned long size;
-};
-
-extern void update_tree_entry(struct tree_desc *);
-extern const unsigned char *tree_entry_extract(struct tree_desc *, const char **, unsigned int *);
+#include "tree-walk.h"
 
 struct diff_options;
 
index 768d83a..50528d5 100644 (file)
@@ -1,51 +1,11 @@
 #include "cache.h"
-#include "diff.h"
+#include "tree-walk.h"
 
 static const char merge_tree_usage[] = "git-merge-tree <base-tree> <branch1> <branch2>";
 static int resolve_directories = 1;
 
 static void merge_trees(struct tree_desc t[3], const char *base);
 
-static void *fill_tree_descriptor(struct tree_desc *desc, const unsigned char *sha1)
-{
-       unsigned long size = 0;
-       void *buf = NULL;
-
-       if (sha1) {
-               buf = read_object_with_reference(sha1, "tree", &size, NULL);
-               if (!buf)
-                       die("unable to read tree %s", sha1_to_hex(sha1));
-       }
-       desc->size = size;
-       desc->buf = buf;
-       return buf;
-}
-
-struct name_entry {
-       const unsigned char *sha1;
-       const char *path;
-       unsigned int mode;
-       int pathlen;
-};
-
-static void entry_clear(struct name_entry *a)
-{
-       memset(a, 0, sizeof(*a));
-}
-
-static int entry_compare(struct name_entry *a, struct name_entry *b)
-{
-       return base_name_compare(
-                       a->path, a->pathlen, a->mode,
-                       b->path, b->pathlen, b->mode);
-}
-
-static void entry_extract(struct tree_desc *t, struct name_entry *a)
-{
-       a->sha1 = tree_entry_extract(t, &a->path, &a->mode);
-       a->pathlen = strlen(a->path);
-}
-
 /* An empty entry never compares same, not even to another empty entry */
 static int same_entry(struct name_entry *a, struct name_entry *b)
 {
@@ -125,60 +85,6 @@ static void unresolved(const char *base, struct name_entry n[3])
                printf("3 %06o %s %s%s\n", n[2].mode, sha1_to_hex(n[2].sha1), base, n[2].path);
 }
 
-typedef void (*traverse_callback_t)(int n, unsigned long mask, struct name_entry *entry, const char *base);
-
-static void traverse_trees(int n, struct tree_desc *t, const char *base, traverse_callback_t callback)
-{
-       struct name_entry *entry = xmalloc(n*sizeof(*entry));
-
-       for (;;) {
-               struct name_entry entry[3];
-               unsigned long mask = 0;
-               int i, last;
-
-               last = -1;
-               for (i = 0; i < n; i++) {
-                       if (!t[i].size)
-                               continue;
-                       entry_extract(t+i, entry+i);
-                       if (last >= 0) {
-                               int cmp = entry_compare(entry+i, entry+last);
-
-                               /*
-                                * Is the new name bigger than the old one?
-                                * Ignore it
-                                */
-                               if (cmp > 0)
-                                       continue;
-                               /*
-                                * Is the new name smaller than the old one?
-                                * Ignore all old ones
-                                */
-                               if (cmp < 0)
-                                       mask = 0;
-                       }
-                       mask |= 1ul << i;
-                       last = i;
-               }
-               if (!mask)
-                       break;
-
-               /*
-                * Update the tree entries we've walked, and clear
-                * all the unused name-entries.
-                */
-               for (i = 0; i < n; i++) {
-                       if (mask & (1ul << i)) {
-                               update_tree_entry(t+i);
-                               continue;
-                       }
-                       entry_clear(entry + i);
-               }
-               callback(n, mask, entry, base);
-       }
-       free(entry);
-}
-
 /*
  * Merge two trees together (t[1] and t[2]), using a common base (t[0])
  * as the origin.
index 49357c6..ccfaa5f 100644 (file)
@@ -3,7 +3,7 @@
 #include "delta.h"
 #include "pack.h"
 #include "csum-file.h"
-#include "diff.h"
+#include "tree-walk.h"
 #include <sys/time.h>
 #include <signal.h>
 
index f3a989c..ee88f56 100644 (file)
@@ -4,7 +4,7 @@
 #include "commit.h"
 #include "tree.h"
 #include "blob.h"
-#include "diff.h"
+#include "tree-walk.h"
 #include "revision.h"
 
 /* bits #0-5 in revision.h */
index 8d9e31c..705b8fa 100644 (file)
@@ -3,7 +3,7 @@
  */
 #include <time.h>
 #include "cache.h"
-#include "diff.h"
+#include "tree-walk.h"
 #include "commit.h"
 #include "strbuf.h"
 #include "tar.h"
index d978428..7bb6109 100644 (file)
@@ -9,34 +9,6 @@ static int nr_paths = 0;
 static const char **paths = NULL;
 static int *pathlens = NULL;
 
-void update_tree_entry(struct tree_desc *desc)
-{
-       void *buf = desc->buf;
-       unsigned long size = desc->size;
-       int len = strlen(buf) + 1 + 20;
-
-       if (size < len)
-               die("corrupt tree file");
-       desc->buf = buf + len;
-       desc->size = size - len;
-}
-
-const unsigned char *tree_entry_extract(struct tree_desc *desc, const char **pathp, unsigned int *modep)
-{
-       void *tree = desc->buf;
-       unsigned long size = desc->size;
-       int len = strlen(tree)+1;
-       const unsigned char *sha1 = tree + len;
-       const char *path = strchr(tree, ' ');
-       unsigned int mode;
-
-       if (!path || size < len + 20 || sscanf(tree, "%o", &mode) != 1)
-               die("corrupt tree file");
-       *pathp = path+1;
-       *modep = DIFF_FILE_CANON_MODE(mode);
-       return sha1;
-}
-
 static char *malloc_base(const char *base, const char *path, int pathlen)
 {
        int baselen = strlen(base);
diff --git a/tree-walk.c b/tree-walk.c
new file mode 100644 (file)
index 0000000..0735f40
--- /dev/null
@@ -0,0 +1,116 @@
+#include "cache.h"
+#include "tree-walk.h"
+
+void *fill_tree_descriptor(struct tree_desc *desc, const unsigned char *sha1)
+{
+       unsigned long size = 0;
+       void *buf = NULL;
+
+       if (sha1) {
+               buf = read_object_with_reference(sha1, "tree", &size, NULL);
+               if (!buf)
+                       die("unable to read tree %s", sha1_to_hex(sha1));
+       }
+       desc->size = size;
+       desc->buf = buf;
+       return buf;
+}
+
+static int entry_compare(struct name_entry *a, struct name_entry *b)
+{
+       return base_name_compare(
+                       a->path, a->pathlen, a->mode,
+                       b->path, b->pathlen, b->mode);
+}
+
+static void entry_clear(struct name_entry *a)
+{
+       memset(a, 0, sizeof(*a));
+}
+
+static void entry_extract(struct tree_desc *t, struct name_entry *a)
+{
+       a->sha1 = tree_entry_extract(t, &a->path, &a->mode);
+       a->pathlen = strlen(a->path);
+}
+
+void update_tree_entry(struct tree_desc *desc)
+{
+       void *buf = desc->buf;
+       unsigned long size = desc->size;
+       int len = strlen(buf) + 1 + 20;
+
+       if (size < len)
+               die("corrupt tree file");
+       desc->buf = buf + len;
+       desc->size = size - len;
+}
+
+const unsigned char *tree_entry_extract(struct tree_desc *desc, const char **pathp, unsigned int *modep)
+{
+       void *tree = desc->buf;
+       unsigned long size = desc->size;
+       int len = strlen(tree)+1;
+       const unsigned char *sha1 = tree + len;
+       const char *path = strchr(tree, ' ');
+       unsigned int mode;
+
+       if (!path || size < len + 20 || sscanf(tree, "%o", &mode) != 1)
+               die("corrupt tree file");
+       *pathp = path+1;
+       *modep = canon_mode(mode);
+       return sha1;
+}
+
+void traverse_trees(int n, struct tree_desc *t, const char *base, traverse_callback_t callback)
+{
+       struct name_entry *entry = xmalloc(n*sizeof(*entry));
+
+       for (;;) {
+               struct name_entry entry[3];
+               unsigned long mask = 0;
+               int i, last;
+
+               last = -1;
+               for (i = 0; i < n; i++) {
+                       if (!t[i].size)
+                               continue;
+                       entry_extract(t+i, entry+i);
+                       if (last >= 0) {
+                               int cmp = entry_compare(entry+i, entry+last);
+
+                               /*
+                                * Is the new name bigger than the old one?
+                                * Ignore it
+                                */
+                               if (cmp > 0)
+                                       continue;
+                               /*
+                                * Is the new name smaller than the old one?
+                                * Ignore all old ones
+                                */
+                               if (cmp < 0)
+                                       mask = 0;
+                       }
+                       mask |= 1ul << i;
+                       last = i;
+               }
+               if (!mask)
+                       break;
+
+               /*
+                * Update the tree entries we've walked, and clear
+                * all the unused name-entries.
+                */
+               for (i = 0; i < n; i++) {
+                       if (mask & (1ul << i)) {
+                               update_tree_entry(t+i);
+                               continue;
+                       }
+                       entry_clear(entry + i);
+               }
+               callback(n, mask, entry, base);
+       }
+       free(entry);
+}
+
diff --git a/tree-walk.h b/tree-walk.h
new file mode 100644 (file)
index 0000000..76893e3
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef TREE_WALK_H
+#define TREE_WALK_H
+
+struct tree_desc {
+       void *buf;
+       unsigned long size;
+};
+
+struct name_entry {
+       const unsigned char *sha1;
+       const char *path;
+       unsigned int mode;
+       int pathlen;
+};
+
+void update_tree_entry(struct tree_desc *);
+const unsigned char *tree_entry_extract(struct tree_desc *, const char **, unsigned int *);
+
+void *fill_tree_descriptor(struct tree_desc *desc, const unsigned char *sha1);
+
+typedef void (*traverse_callback_t)(int n, unsigned long mask, struct name_entry *entry, const char *base);
+
+void traverse_trees(int n, struct tree_desc *t, const char *base, traverse_callback_t callback);
+
+#endif