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>
Martin Koegler committed
Feb 25, 2008 at 22:46 UTC
271b8d25b25e49b367087440e093e755e5f35aa9
1 file changed
+71
-28
builtin-fsck.c
+71
-28
@@ -8,6 +8,7 @@
8
#include "pack.h"
9
#include "cache-tree.h"
10
#include "tree-walk.h"
11
+#include "fsck.h"
12
#include "parse-options.h"
13
14
#define REACHABLE 0x0001
@@ -63,13 +64,73 @@ static int objwarning(struct object *obj, const char *err, ...)
64
return -1;
65
}
66
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
+
129
/*
130
* Check a single reachable object
131
*/
132
static void check_reachable_object(struct object *obj)
133
{
71
- const struct object_refs *refs;
72
-
134
/*
135
* We obviously want the object to be parsed,
136
* except if it was in a pack-file and we didn't
@@ -82,25 +143,6 @@ static void check_reachable_object(struct object *obj)
143
errors_found |= ERROR_REACHABLE;
144
return;
145
}
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
- }
146
}
147
148
/*
@@ -414,6 +456,8 @@ static int fsck_sha1(const unsigned char *sha1)
456
if (obj->flags & SEEN)
457
return 0;
458
obj->flags |= SEEN;
459
+ if (fsck_walk(obj, mark_used, 0))
460
+ objerror(obj, "broken links");
461
if (obj->type == OBJ_BLOB)
462
return 0;
463
if (obj->type == OBJ_TREE)
@@ -538,13 +582,13 @@ static int fsck_handle_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
582
obj = lookup_object(osha1);
583
if (obj) {
584
obj->used = 1;
541
- mark_reachable(obj, REACHABLE);
585
+ mark_object_reachable(obj);
586
}
587
}
588
obj = lookup_object(nsha1);
589
if (obj) {
590
obj->used = 1;
547
- mark_reachable(obj, REACHABLE);
591
+ mark_object_reachable(obj);
592
}
593
return 0;
594
}
@@ -574,7 +618,7 @@ static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int f
618
error("%s: not a commit", refname);
619
default_refs++;
620
obj->used = 1;
577
- mark_reachable(obj, REACHABLE);
621
+ mark_object_reachable(obj);
622
623
return 0;
624
}
@@ -660,7 +704,7 @@ static int fsck_cache_tree(struct cache_tree *it)
704
sha1_to_hex(it->sha1));
705
return 1;
706
}
663
- mark_reachable(obj, REACHABLE);
707
+ mark_object_reachable(obj);
708
obj->used = 1;
709
if (obj->type != OBJ_TREE)
710
err |= objerror(obj, "non-tree in cache-tree");
@@ -693,7 +737,6 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
737
{
738
int i, heads;
739
696
- track_object_refs = 1;
740
errors_found = 0;
741
742
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)
784
continue;
785
786
obj->used = 1;
744
- mark_reachable(obj, REACHABLE);
787
+ mark_object_reachable(obj);
788
heads++;
789
continue;
790
}
@@ -773,7 +816,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
816
continue;
817
obj = &blob->object;
818
obj->used = 1;
776
- mark_reachable(obj, REACHABLE);
819
+ mark_object_reachable(obj);
820
}
821
if (active_cache_tree)
822
fsck_cache_tree(active_cache_tree);