summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: f220fb6)
raw | patch | inline | side by side (parent: f220fb6)
author | Linus Torvalds <torvalds@ppc970.osdl.org> | |
Mon, 2 May 2005 23:13:18 +0000 (16:13 -0700) | ||
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | |
Mon, 2 May 2005 23:13:18 +0000 (16:13 -0700) |
We check the ordering of the entries, and we verify that none
of the entries has a slash in it (this allows us to remove the
hacky "has_full_path" member from the tree structure, since we
now just test it by walking the tree entries instead).
of the entries has a slash in it (this allows us to remove the
hacky "has_full_path" member from the tree structure, since we
now just test it by walking the tree entries instead).
fsck-cache.c | patch | blob | history | |
tree.c | patch | blob | history | |
tree.h | patch | blob | history |
diff --git a/fsck-cache.c b/fsck-cache.c
index cb010957479976b9d8fdec6dc76e7a6c30e83a1b..7dda9c3eb790ef57ee14c479a8730f0312dea744 100644 (file)
--- a/fsck-cache.c
+++ b/fsck-cache.c
}
}
+/*
+ * The entries in a tree are ordered in the _path_ order,
+ * which means that a directory entry is ordered by adding
+ * a slash to the end of it.
+ *
+ * So a directory called "a" is ordered _after_ a file
+ * called "a.c", because "a/" sorts after "a.c".
+ */
+static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b)
+{
+ int len1 = strlen(a->name);
+ int len2 = strlen(b->name);
+ int len = len1 < len2 ? len1 : len2;
+ unsigned char c1, c2;
+ int cmp;
+
+ cmp = memcmp(a->name, b->name, len);
+ if (cmp < 0)
+ return 0;
+ if (cmp > 0)
+ return -1;
+
+ /*
+ * Ok, the first <len> characters are the same.
+ * Now we need to order the next one, but turn
+ * a '\0' into a '/' for a directory entry.
+ */
+ c1 = a->name[len];
+ c2 = b->name[len];
+ if (!c1 && a->directory)
+ c1 = '/';
+ if (!c2 && b->directory)
+ c2 = '/';
+ return c1 < c2 ? 0 : -1;
+}
+
static int fsck_tree(struct tree *item)
{
- if (item->has_full_path) {
+ int has_full_path = 0;
+ struct tree_entry_list *entry, *last;
+
+ last = NULL;
+ for (entry = item->entries; entry; entry = entry->next) {
+ if (strchr(entry->name, '/'))
+ has_full_path = 1;
+
+ if (last) {
+ if (verify_ordered(last, entry) < 0) {
+ fprintf(stderr, "tree %s not ordered\n",
+ sha1_to_hex(item->object.sha1));
+ return -1;
+ }
+ }
+
+ last = entry;
+ }
+
+ if (has_full_path) {
fprintf(stderr, "warning: fsck-cache: tree %s "
"has full pathnames in it\n",
sha1_to_hex(item->object.sha1));
}
+
return 0;
}
index 15a16d560619aee80e41bf816dd8474a3253b1a5..72305a357b6694cdb1b29dad9975902fdef86457 100644 (file)
--- a/tree.c
+++ b/tree.c
entry->executable = mode & S_IXUSR;
entry->next = NULL;
- /* Warn about trees that don't do the recursive thing.. */
- if (strchr(path, '/')) {
- item->has_full_path = 1;
- }
-
bufptr += len + 20;
size -= len + 20;