Skip to content

Commit 271b8d2

Browse files
Martin Koeglergitster
authored andcommitted
builtin-fsck: move away from object-refs to fsck_walk
Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 355885d commit 271b8d2

File tree

1 file changed

+71
-28
lines changed

1 file changed

+71
-28
lines changed

builtin-fsck.c

Lines changed: 71 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "pack.h"
99
#include "cache-tree.h"
1010
#include "tree-walk.h"
11+
#include "fsck.h"
1112
#include "parse-options.h"
1213

1314
#define REACHABLE 0x0001
@@ -63,13 +64,73 @@ static int objwarning(struct object *obj, const char *err, ...)
6364
return -1;
6465
}
6566

67+
static int mark_object(struct object *obj, int type, void *data)
68+
{
69+
struct tree *tree = NULL;
70+
struct object *parent = data;
71+
int result;
72+
73+
if (!obj) {
74+
printf("broken link from %7s %s\n",
75+
typename(parent->type), sha1_to_hex(parent->sha1));
76+
printf("broken link from %7s %s\n",
77+
(type == OBJ_ANY ? "unknown" : typename(type)), "unknown");
78+
errors_found |= ERROR_REACHABLE;
79+
return 1;
80+
}
81+
82+
if (type != OBJ_ANY && obj->type != type)
83+
objerror(parent, "wrong object type in link");
84+
85+
if (obj->flags & REACHABLE)
86+
return 0;
87+
obj->flags |= REACHABLE;
88+
if (!obj->parsed) {
89+
if (parent && !has_sha1_file(obj->sha1)) {
90+
printf("broken link from %7s %s\n",
91+
typename(parent->type), sha1_to_hex(parent->sha1));
92+
printf(" to %7s %s\n",
93+
typename(obj->type), sha1_to_hex(obj->sha1));
94+
errors_found |= ERROR_REACHABLE;
95+
}
96+
return 1;
97+
}
98+
99+
if (obj->type == OBJ_TREE) {
100+
obj->parsed = 0;
101+
tree = (struct tree *)obj;
102+
if (parse_tree(tree) < 0)
103+
return 1; /* error already displayed */
104+
}
105+
result = fsck_walk(obj, mark_object, obj);
106+
if (tree) {
107+
free(tree->buffer);
108+
tree->buffer = NULL;
109+
}
110+
if (result < 0)
111+
result = 1;
112+
113+
return result;
114+
}
115+
116+
static void mark_object_reachable(struct object *obj)
117+
{
118+
mark_object(obj, OBJ_ANY, 0);
119+
}
120+
121+
static int mark_used(struct object *obj, int type, void *data)
122+
{
123+
if (!obj)
124+
return 1;
125+
obj->used = 1;
126+
return 0;
127+
}
128+
66129
/*
67130
* Check a single reachable object
68131
*/
69132
static void check_reachable_object(struct object *obj)
70133
{
71-
const struct object_refs *refs;
72-
73134
/*
74135
* We obviously want the object to be parsed,
75136
* except if it was in a pack-file and we didn't
@@ -82,25 +143,6 @@ static void check_reachable_object(struct object *obj)
82143
errors_found |= ERROR_REACHABLE;
83144
return;
84145
}
85-
86-
/*
87-
* Check that everything that we try to reference is also good.
88-
*/
89-
refs = lookup_object_refs(obj);
90-
if (refs) {
91-
unsigned j;
92-
for (j = 0; j < refs->count; j++) {
93-
struct object *ref = refs->ref[j];
94-
if (ref->parsed ||
95-
(has_sha1_file(ref->sha1)))
96-
continue;
97-
printf("broken link from %7s %s\n",
98-
typename(obj->type), sha1_to_hex(obj->sha1));
99-
printf(" to %7s %s\n",
100-
typename(ref->type), sha1_to_hex(ref->sha1));
101-
errors_found |= ERROR_REACHABLE;
102-
}
103-
}
104146
}
105147

106148
/*
@@ -414,6 +456,8 @@ static int fsck_sha1(const unsigned char *sha1)
414456
if (obj->flags & SEEN)
415457
return 0;
416458
obj->flags |= SEEN;
459+
if (fsck_walk(obj, mark_used, 0))
460+
objerror(obj, "broken links");
417461
if (obj->type == OBJ_BLOB)
418462
return 0;
419463
if (obj->type == OBJ_TREE)
@@ -538,13 +582,13 @@ static int fsck_handle_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
538582
obj = lookup_object(osha1);
539583
if (obj) {
540584
obj->used = 1;
541-
mark_reachable(obj, REACHABLE);
585+
mark_object_reachable(obj);
542586
}
543587
}
544588
obj = lookup_object(nsha1);
545589
if (obj) {
546590
obj->used = 1;
547-
mark_reachable(obj, REACHABLE);
591+
mark_object_reachable(obj);
548592
}
549593
return 0;
550594
}
@@ -574,7 +618,7 @@ static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int f
574618
error("%s: not a commit", refname);
575619
default_refs++;
576620
obj->used = 1;
577-
mark_reachable(obj, REACHABLE);
621+
mark_object_reachable(obj);
578622

579623
return 0;
580624
}
@@ -660,7 +704,7 @@ static int fsck_cache_tree(struct cache_tree *it)
660704
sha1_to_hex(it->sha1));
661705
return 1;
662706
}
663-
mark_reachable(obj, REACHABLE);
707+
mark_object_reachable(obj);
664708
obj->used = 1;
665709
if (obj->type != OBJ_TREE)
666710
err |= objerror(obj, "non-tree in cache-tree");
@@ -693,7 +737,6 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
693737
{
694738
int i, heads;
695739

696-
track_object_refs = 1;
697740
errors_found = 0;
698741

699742
argc = parse_options(argc, argv, fsck_opts, fsck_usage, 0);
@@ -741,7 +784,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
741784
continue;
742785

743786
obj->used = 1;
744-
mark_reachable(obj, REACHABLE);
787+
mark_object_reachable(obj);
745788
heads++;
746789
continue;
747790
}
@@ -773,7 +816,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
773816
continue;
774817
obj = &blob->object;
775818
obj->used = 1;
776-
mark_reachable(obj, REACHABLE);
819+
mark_object_reachable(obj);
777820
}
778821
if (active_cache_tree)
779822
fsck_cache_tree(active_cache_tree);

0 commit comments

Comments
 (0)