Skip to content

Commit 8500349

Browse files
author
Linus Torvalds
committed
Make fsck-cache do better tree checking.
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).
1 parent f220fb6 commit 8500349

File tree

3 files changed

+57
-7
lines changed

3 files changed

+57
-7
lines changed

fsck-cache.c

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,69 @@ static void check_connectivity(void)
5353
}
5454
}
5555

56+
/*
57+
* The entries in a tree are ordered in the _path_ order,
58+
* which means that a directory entry is ordered by adding
59+
* a slash to the end of it.
60+
*
61+
* So a directory called "a" is ordered _after_ a file
62+
* called "a.c", because "a/" sorts after "a.c".
63+
*/
64+
static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b)
65+
{
66+
int len1 = strlen(a->name);
67+
int len2 = strlen(b->name);
68+
int len = len1 < len2 ? len1 : len2;
69+
unsigned char c1, c2;
70+
int cmp;
71+
72+
cmp = memcmp(a->name, b->name, len);
73+
if (cmp < 0)
74+
return 0;
75+
if (cmp > 0)
76+
return -1;
77+
78+
/*
79+
* Ok, the first <len> characters are the same.
80+
* Now we need to order the next one, but turn
81+
* a '\0' into a '/' for a directory entry.
82+
*/
83+
c1 = a->name[len];
84+
c2 = b->name[len];
85+
if (!c1 && a->directory)
86+
c1 = '/';
87+
if (!c2 && b->directory)
88+
c2 = '/';
89+
return c1 < c2 ? 0 : -1;
90+
}
91+
5692
static int fsck_tree(struct tree *item)
5793
{
58-
if (item->has_full_path) {
94+
int has_full_path = 0;
95+
struct tree_entry_list *entry, *last;
96+
97+
last = NULL;
98+
for (entry = item->entries; entry; entry = entry->next) {
99+
if (strchr(entry->name, '/'))
100+
has_full_path = 1;
101+
102+
if (last) {
103+
if (verify_ordered(last, entry) < 0) {
104+
fprintf(stderr, "tree %s not ordered\n",
105+
sha1_to_hex(item->object.sha1));
106+
return -1;
107+
}
108+
}
109+
110+
last = entry;
111+
}
112+
113+
if (has_full_path) {
59114
fprintf(stderr, "warning: fsck-cache: tree %s "
60115
"has full pathnames in it\n",
61116
sha1_to_hex(item->object.sha1));
62117
}
118+
63119
return 0;
64120
}
65121

tree.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,6 @@ int parse_tree(struct tree *item)
122122
entry->executable = mode & S_IXUSR;
123123
entry->next = NULL;
124124

125-
/* Warn about trees that don't do the recursive thing.. */
126-
if (strchr(path, '/')) {
127-
item->has_full_path = 1;
128-
}
129-
130125
bufptr += len + 20;
131126
size -= len + 20;
132127

tree.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ struct tree_entry_list {
1818

1919
struct tree {
2020
struct object object;
21-
unsigned has_full_path : 1;
2221
struct tree_entry_list *entries;
2322
};
2423

0 commit comments

Comments
 (0)