git-fsck-cache: be stricter about "tree" objects
In particular, warn about things like zero-padding of the mode bits, which is a big no-no, since it makes otherwise identical trees have different representations (and thus different SHA1 numbers). Also make the warnings more regular. Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
4e81304afc
commit
64071805ed
47
fsck-cache.c
47
fsck-cache.c
@ -109,13 +109,19 @@ static int verify_ordered(struct tree_entry_list *a, struct tree_entry_list *b)
|
|||||||
|
|
||||||
static int fsck_tree(struct tree *item)
|
static int fsck_tree(struct tree *item)
|
||||||
{
|
{
|
||||||
|
int retval;
|
||||||
int has_full_path = 0;
|
int has_full_path = 0;
|
||||||
|
int has_zero_pad = 0;
|
||||||
|
int has_bad_modes = 0;
|
||||||
|
int has_dup_entries = 0;
|
||||||
|
int not_properly_sorted = 0;
|
||||||
struct tree_entry_list *entry, *last;
|
struct tree_entry_list *entry, *last;
|
||||||
|
|
||||||
last = NULL;
|
last = NULL;
|
||||||
for (entry = item->entries; entry; entry = entry->next) {
|
for (entry = item->entries; entry; entry = entry->next) {
|
||||||
if (strchr(entry->name, '/'))
|
if (strchr(entry->name, '/'))
|
||||||
has_full_path = 1;
|
has_full_path = 1;
|
||||||
|
has_zero_pad |= entry->zeropad;
|
||||||
|
|
||||||
switch (entry->mode) {
|
switch (entry->mode) {
|
||||||
/*
|
/*
|
||||||
@ -135,22 +141,17 @@ static int fsck_tree(struct tree *item)
|
|||||||
if (!check_strict)
|
if (!check_strict)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("tree %s has entry %o %s\n",
|
has_bad_modes = 1;
|
||||||
sha1_to_hex(item->object.sha1),
|
|
||||||
entry->mode, entry->name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last) {
|
if (last) {
|
||||||
switch (verify_ordered(last, entry)) {
|
switch (verify_ordered(last, entry)) {
|
||||||
case TREE_UNORDERED:
|
case TREE_UNORDERED:
|
||||||
fprintf(stderr, "tree %s not ordered\n",
|
not_properly_sorted = 1;
|
||||||
sha1_to_hex(item->object.sha1));
|
break;
|
||||||
return -1;
|
|
||||||
case TREE_HAS_DUPS:
|
case TREE_HAS_DUPS:
|
||||||
fprintf(stderr, "tree %s has duplicate entries for '%s'\n",
|
has_dup_entries = 1;
|
||||||
sha1_to_hex(item->object.sha1),
|
break;
|
||||||
entry->name);
|
|
||||||
return -1;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -159,13 +160,35 @@ static int fsck_tree(struct tree *item)
|
|||||||
last = entry;
|
last = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retval = 0;
|
||||||
if (has_full_path) {
|
if (has_full_path) {
|
||||||
fprintf(stderr, "warning: git-fsck-cache: tree %s "
|
fprintf(stderr, "warning: git-fsck-cache: tree %s "
|
||||||
"has full pathnames in it\n",
|
"has full pathnames in it\n",
|
||||||
sha1_to_hex(item->object.sha1));
|
sha1_to_hex(item->object.sha1));
|
||||||
}
|
}
|
||||||
|
if (has_zero_pad) {
|
||||||
return 0;
|
fprintf(stderr, "warning: git-fsck-cache: tree %s "
|
||||||
|
"has zero-padded file modes in it\n",
|
||||||
|
sha1_to_hex(item->object.sha1));
|
||||||
|
}
|
||||||
|
if (has_bad_modes) {
|
||||||
|
fprintf(stderr, "warning: git-fsck-cache: tree %s "
|
||||||
|
"has bad file modes in it\n",
|
||||||
|
sha1_to_hex(item->object.sha1));
|
||||||
|
}
|
||||||
|
if (has_dup_entries) {
|
||||||
|
fprintf(stderr, "error: git-fsck-cache: tree %s "
|
||||||
|
"has duplicate file entries\n",
|
||||||
|
sha1_to_hex(item->object.sha1));
|
||||||
|
retval = -1;
|
||||||
|
}
|
||||||
|
if (not_properly_sorted) {
|
||||||
|
fprintf(stderr, "error: git-fsck-cache: tree %s "
|
||||||
|
"is not properly sorted\n",
|
||||||
|
sha1_to_hex(item->object.sha1));
|
||||||
|
retval = -1;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fsck_commit(struct commit *commit)
|
static int fsck_commit(struct commit *commit)
|
||||||
|
1
tree.c
1
tree.c
@ -167,6 +167,7 @@ int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
|
|||||||
entry->directory = S_ISDIR(mode) != 0;
|
entry->directory = S_ISDIR(mode) != 0;
|
||||||
entry->executable = (mode & S_IXUSR) != 0;
|
entry->executable = (mode & S_IXUSR) != 0;
|
||||||
entry->symlink = S_ISLNK(mode) != 0;
|
entry->symlink = S_ISLNK(mode) != 0;
|
||||||
|
entry->zeropad = *(char *)bufptr == '0';
|
||||||
entry->mode = mode;
|
entry->mode = mode;
|
||||||
entry->next = NULL;
|
entry->next = NULL;
|
||||||
|
|
||||||
|
1
tree.h
1
tree.h
@ -10,6 +10,7 @@ struct tree_entry_list {
|
|||||||
unsigned directory : 1;
|
unsigned directory : 1;
|
||||||
unsigned executable : 1;
|
unsigned executable : 1;
|
||||||
unsigned symlink : 1;
|
unsigned symlink : 1;
|
||||||
|
unsigned zeropad : 1;
|
||||||
unsigned int mode;
|
unsigned int mode;
|
||||||
char *name;
|
char *name;
|
||||||
union {
|
union {
|
||||||
|
Loading…
Reference in New Issue
Block a user