summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e464f4c)
raw | patch | inline | side by side (parent: e464f4c)
author | Junio C Hamano <junkio@cox.net> | |
Thu, 30 Mar 2006 06:55:43 +0000 (22:55 -0800) | ||
committer | Junio 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>
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 | patch | blob | history | |
cache.h | patch | blob | history | |
combine-diff.c | patch | blob | history | |
diff-files.c | patch | blob | history | |
diff.c | patch | blob | history | |
diff.h | patch | blob | history | |
merge-tree.c | patch | blob | history | |
pack-objects.c | patch | blob | history | |
rev-list.c | patch | blob | history | |
tar-tree.c | patch | blob | history | |
tree-diff.c | patch | blob | history | |
tree-walk.c | [new file with mode: 0644] | patch | blob |
tree-walk.h | [new file with mode: 0644] | patch | blob |
diff --git a/Makefile b/Makefile
index d945546eb88db19e8c56280f11711743d89a6d2b..d78298ae62000ef165c08e2007899b7d58248b4b 100644 (file)
--- a/Makefile
+++ b/Makefile
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 \
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)
index 255e6b5cc7aa799eee892dcd3632cd0656e6dd1e..69801b02d535dbbe49535c876979cd093c6db2e1 100644 (file)
--- a/cache.h
+++ b/cache.h
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)
diff --git a/combine-diff.c b/combine-diff.c
index a23894d86927ccf3fcf4a9c720df49ff2364b749..f17aab33f1d241097a16e2cfd8a1ab3361e45902 100644 (file)
--- a/combine-diff.c
+++ b/combine-diff.c
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) {
diff --git a/diff-files.c b/diff-files.c
index b1c05b325a8f171fc67c204471db2cb5e98b0b50..3e7f5f105b19fd47fd8b3716617592ec2a60da47 100644 (file)
--- a/diff-files.c
+++ b/diff-files.c
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;
}
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))
index 8b37477afc3bf8555f0b6c9f0d6f116a39784817..e496905bad9853f912e1bbcc081c544524f8cb77 100644 (file)
--- a/diff.c
+++ b/diff.c
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);
}
index 8fac465a9df9b1d8789d17f008968295baa27ad1..a268d16ff712e29fbccab779824551757f99837d 100644 (file)
--- a/diff.h
+++ b/diff.h
#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;
diff --git a/merge-tree.c b/merge-tree.c
index 768d83a7c23d948dc85ada30a5226078d105ab08..50528d5e438c62be409a9f7d252cedadfd52b15e 100644 (file)
--- a/merge-tree.c
+++ b/merge-tree.c
#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)
{
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.
diff --git a/pack-objects.c b/pack-objects.c
index 49357c67357fdc96e0d98b193b88e2137453c7c8..ccfaa5f609431490c886abe0e0af842987428bf6 100644 (file)
--- a/pack-objects.c
+++ b/pack-objects.c
#include "delta.h"
#include "pack.h"
#include "csum-file.h"
-#include "diff.h"
+#include "tree-walk.h"
#include <sys/time.h>
#include <signal.h>
diff --git a/rev-list.c b/rev-list.c
index f3a989ccede991744061728532c25efbcb1716d5..ee88f567a7c9413376669c01050a210241701012 100644 (file)
--- a/rev-list.c
+++ b/rev-list.c
#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 */
diff --git a/tar-tree.c b/tar-tree.c
index 8d9e31c20612f09f641a53b7876591b744eb0cea..705b8fa1c76dc665333f180278dca929e2a971f7 100644 (file)
--- a/tar-tree.c
+++ b/tar-tree.c
*/
#include <time.h>
#include "cache.h"
-#include "diff.h"
+#include "tree-walk.h"
#include "commit.h"
#include "strbuf.h"
#include "tar.h"
diff --git a/tree-diff.c b/tree-diff.c
index d978428910a33ee9443343beeb1574e79d2a71ad..7bb6109111c0e8d4de11597fd64acb2a8b346879 100644 (file)
--- a/tree-diff.c
+++ b/tree-diff.c
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
--- /dev/null
+++ b/tree-walk.c
@@ -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
--- /dev/null
+++ b/tree-walk.h
@@ -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