]>
Commit | Line | Data |
---|---|---|
1 | #ifndef GIT_FSCK_H | |
2 | #define GIT_FSCK_H | |
3 | ||
4 | #include "object.h" | |
5 | #include "oidset.h" | |
6 | ||
7 | enum fsck_msg_type { | |
8 | /* for internal use only */ | |
9 | FSCK_IGNORE, | |
10 | FSCK_INFO, | |
11 | FSCK_FATAL, | |
12 | /* "public", fed to e.g. error_func callbacks */ | |
13 | FSCK_ERROR, | |
14 | FSCK_WARN, | |
15 | }; | |
16 | ||
17 | /* | |
18 | * Documentation/fsck-msgids.adoc documents these; when | |
19 | * modifying this list in any way, make sure to keep the | |
20 | * two in sync. | |
21 | */ | |
22 | ||
23 | #define FOREACH_FSCK_MSG_ID(FUNC) \ | |
24 | /* fatal errors */ \ | |
25 | FUNC(NUL_IN_HEADER, FATAL) \ | |
26 | FUNC(UNTERMINATED_HEADER, FATAL) \ | |
27 | /* errors */ \ | |
28 | FUNC(BAD_DATE, ERROR) \ | |
29 | FUNC(BAD_DATE_OVERFLOW, ERROR) \ | |
30 | FUNC(BAD_EMAIL, ERROR) \ | |
31 | FUNC(BAD_NAME, ERROR) \ | |
32 | FUNC(BAD_OBJECT_SHA1, ERROR) \ | |
33 | FUNC(BAD_PACKED_REF_ENTRY, ERROR) \ | |
34 | FUNC(BAD_PACKED_REF_HEADER, ERROR) \ | |
35 | FUNC(BAD_PARENT_SHA1, ERROR) \ | |
36 | FUNC(BAD_REF_CONTENT, ERROR) \ | |
37 | FUNC(BAD_REF_FILETYPE, ERROR) \ | |
38 | FUNC(BAD_REF_NAME, ERROR) \ | |
39 | FUNC(BAD_REFERENT_NAME, ERROR) \ | |
40 | FUNC(BAD_TIMEZONE, ERROR) \ | |
41 | FUNC(BAD_TREE, ERROR) \ | |
42 | FUNC(BAD_TREE_SHA1, ERROR) \ | |
43 | FUNC(BAD_TYPE, ERROR) \ | |
44 | FUNC(DUPLICATE_ENTRIES, ERROR) \ | |
45 | FUNC(MISSING_AUTHOR, ERROR) \ | |
46 | FUNC(MISSING_COMMITTER, ERROR) \ | |
47 | FUNC(MISSING_EMAIL, ERROR) \ | |
48 | FUNC(MISSING_NAME_BEFORE_EMAIL, ERROR) \ | |
49 | FUNC(MISSING_OBJECT, ERROR) \ | |
50 | FUNC(MISSING_SPACE_BEFORE_DATE, ERROR) \ | |
51 | FUNC(MISSING_SPACE_BEFORE_EMAIL, ERROR) \ | |
52 | FUNC(MISSING_TAG, ERROR) \ | |
53 | FUNC(MISSING_TAG_ENTRY, ERROR) \ | |
54 | FUNC(MISSING_TREE, ERROR) \ | |
55 | FUNC(MISSING_TYPE, ERROR) \ | |
56 | FUNC(MISSING_TYPE_ENTRY, ERROR) \ | |
57 | FUNC(MULTIPLE_AUTHORS, ERROR) \ | |
58 | FUNC(PACKED_REF_ENTRY_NOT_TERMINATED, ERROR) \ | |
59 | FUNC(PACKED_REF_UNSORTED, ERROR) \ | |
60 | FUNC(TREE_NOT_SORTED, ERROR) \ | |
61 | FUNC(UNKNOWN_TYPE, ERROR) \ | |
62 | FUNC(ZERO_PADDED_DATE, ERROR) \ | |
63 | FUNC(GITMODULES_MISSING, ERROR) \ | |
64 | FUNC(GITMODULES_BLOB, ERROR) \ | |
65 | FUNC(GITMODULES_LARGE, ERROR) \ | |
66 | FUNC(GITMODULES_NAME, ERROR) \ | |
67 | FUNC(GITMODULES_SYMLINK, ERROR) \ | |
68 | FUNC(GITMODULES_URL, ERROR) \ | |
69 | FUNC(GITMODULES_PATH, ERROR) \ | |
70 | FUNC(GITMODULES_UPDATE, ERROR) \ | |
71 | FUNC(GITATTRIBUTES_MISSING, ERROR) \ | |
72 | FUNC(GITATTRIBUTES_LARGE, ERROR) \ | |
73 | FUNC(GITATTRIBUTES_LINE_LENGTH, ERROR) \ | |
74 | FUNC(GITATTRIBUTES_BLOB, ERROR) \ | |
75 | /* warnings */ \ | |
76 | FUNC(EMPTY_NAME, WARN) \ | |
77 | FUNC(FULL_PATHNAME, WARN) \ | |
78 | FUNC(HAS_DOT, WARN) \ | |
79 | FUNC(HAS_DOTDOT, WARN) \ | |
80 | FUNC(HAS_DOTGIT, WARN) \ | |
81 | FUNC(NULL_SHA1, WARN) \ | |
82 | FUNC(ZERO_PADDED_FILEMODE, WARN) \ | |
83 | FUNC(NUL_IN_COMMIT, WARN) \ | |
84 | FUNC(LARGE_PATHNAME, WARN) \ | |
85 | /* infos (reported as warnings, but ignored by default) */ \ | |
86 | FUNC(BAD_FILEMODE, INFO) \ | |
87 | FUNC(EMPTY_PACKED_REFS_FILE, INFO) \ | |
88 | FUNC(GITMODULES_PARSE, INFO) \ | |
89 | FUNC(GITIGNORE_SYMLINK, INFO) \ | |
90 | FUNC(GITATTRIBUTES_SYMLINK, INFO) \ | |
91 | FUNC(MAILMAP_SYMLINK, INFO) \ | |
92 | FUNC(BAD_TAG_NAME, INFO) \ | |
93 | FUNC(MISSING_TAGGER_ENTRY, INFO) \ | |
94 | FUNC(SYMLINK_REF, INFO) \ | |
95 | FUNC(REF_MISSING_NEWLINE, INFO) \ | |
96 | FUNC(SYMREF_TARGET_IS_NOT_A_REF, INFO) \ | |
97 | FUNC(TRAILING_REF_CONTENT, INFO) \ | |
98 | /* ignored (elevated when requested) */ \ | |
99 | FUNC(EXTRA_HEADER_ENTRY, IGNORE) | |
100 | ||
101 | #define MSG_ID(id, msg_type) FSCK_MSG_##id, | |
102 | enum fsck_msg_id { | |
103 | FOREACH_FSCK_MSG_ID(MSG_ID) | |
104 | FSCK_MSG_MAX | |
105 | }; | |
106 | #undef MSG_ID | |
107 | ||
108 | struct fsck_options; | |
109 | struct object; | |
110 | ||
111 | void fsck_set_msg_type_from_ids(struct fsck_options *options, | |
112 | enum fsck_msg_id msg_id, | |
113 | enum fsck_msg_type msg_type); | |
114 | void fsck_set_msg_type(struct fsck_options *options, | |
115 | const char *msg_id, const char *msg_type); | |
116 | void fsck_set_msg_types(struct fsck_options *options, const char *values); | |
117 | int is_valid_msg_type(const char *msg_id, const char *msg_type); | |
118 | ||
119 | /* | |
120 | * callback function for fsck_walk | |
121 | * type is the expected type of the object or OBJ_ANY | |
122 | * the return value is: | |
123 | * 0 everything OK | |
124 | * <0 error signaled and abort | |
125 | * >0 error signaled and do not abort | |
126 | */ | |
127 | typedef int (*fsck_walk_func)(struct object *obj, enum object_type object_type, | |
128 | void *data, struct fsck_options *options); | |
129 | ||
130 | /* | |
131 | * Callback for reporting errors either for objects or refs. The "fsck_report" | |
132 | * is a generic pointer that can be used to pass any information. | |
133 | */ | |
134 | typedef int (*fsck_error)(struct fsck_options *o, | |
135 | void *fsck_report, | |
136 | enum fsck_msg_type msg_type, enum fsck_msg_id msg_id, | |
137 | const char *message); | |
138 | ||
139 | int fsck_objects_error_function(struct fsck_options *o, | |
140 | void *fsck_report, | |
141 | enum fsck_msg_type msg_type, enum fsck_msg_id msg_id, | |
142 | const char *message); | |
143 | int fsck_objects_error_cb_print_missing_gitmodules(struct fsck_options *o, | |
144 | void *fsck_report, | |
145 | enum fsck_msg_type msg_type, | |
146 | enum fsck_msg_id msg_id, | |
147 | const char *message); | |
148 | ||
149 | int fsck_refs_error_function(struct fsck_options *options, | |
150 | void *fsck_report, | |
151 | enum fsck_msg_type msg_type, | |
152 | enum fsck_msg_id msg_id, | |
153 | const char *message); | |
154 | ||
155 | struct fsck_object_report { | |
156 | const struct object_id *oid; | |
157 | enum object_type object_type; | |
158 | }; | |
159 | ||
160 | struct fsck_ref_report { | |
161 | const char *path; | |
162 | const struct object_id *oid; | |
163 | const char *referent; | |
164 | }; | |
165 | ||
166 | struct fsck_options { | |
167 | fsck_walk_func walk; | |
168 | fsck_error error_func; | |
169 | unsigned strict; | |
170 | unsigned verbose; | |
171 | enum fsck_msg_type *msg_type; | |
172 | struct oidset skip_oids; | |
173 | struct oidset gitmodules_found; | |
174 | struct oidset gitmodules_done; | |
175 | struct oidset gitattributes_found; | |
176 | struct oidset gitattributes_done; | |
177 | kh_oid_map_t *object_names; | |
178 | }; | |
179 | ||
180 | #define FSCK_OPTIONS_DEFAULT { \ | |
181 | .skip_oids = OIDSET_INIT, \ | |
182 | .gitmodules_found = OIDSET_INIT, \ | |
183 | .gitmodules_done = OIDSET_INIT, \ | |
184 | .gitattributes_found = OIDSET_INIT, \ | |
185 | .gitattributes_done = OIDSET_INIT, \ | |
186 | .error_func = fsck_objects_error_function \ | |
187 | } | |
188 | #define FSCK_OPTIONS_STRICT { \ | |
189 | .strict = 1, \ | |
190 | .gitmodules_found = OIDSET_INIT, \ | |
191 | .gitmodules_done = OIDSET_INIT, \ | |
192 | .gitattributes_found = OIDSET_INIT, \ | |
193 | .gitattributes_done = OIDSET_INIT, \ | |
194 | .error_func = fsck_objects_error_function, \ | |
195 | } | |
196 | #define FSCK_OPTIONS_MISSING_GITMODULES { \ | |
197 | .strict = 1, \ | |
198 | .gitmodules_found = OIDSET_INIT, \ | |
199 | .gitmodules_done = OIDSET_INIT, \ | |
200 | .gitattributes_found = OIDSET_INIT, \ | |
201 | .gitattributes_done = OIDSET_INIT, \ | |
202 | .error_func = fsck_objects_error_cb_print_missing_gitmodules, \ | |
203 | } | |
204 | #define FSCK_REFS_OPTIONS_DEFAULT { \ | |
205 | .error_func = fsck_refs_error_function, \ | |
206 | } | |
207 | ||
208 | /* descend in all linked child objects | |
209 | * the return value is: | |
210 | * -1 error in processing the object | |
211 | * <0 return value of the callback, which lead to an abort | |
212 | * >0 return value of the first signaled error >0 (in the case of no other errors) | |
213 | * 0 everything OK | |
214 | */ | |
215 | int fsck_walk(struct object *obj, void *data, struct fsck_options *options); | |
216 | ||
217 | /* | |
218 | * Blob objects my pass a NULL data pointer, which indicates they are too large | |
219 | * to fit in memory. All other types must pass a real buffer. | |
220 | */ | |
221 | int fsck_object(struct object *obj, void *data, unsigned long size, | |
222 | struct fsck_options *options); | |
223 | ||
224 | /* | |
225 | * Same as fsck_object(), but for when the caller doesn't have an object | |
226 | * struct. | |
227 | */ | |
228 | int fsck_buffer(const struct object_id *oid, enum object_type, | |
229 | const void *data, unsigned long size, | |
230 | struct fsck_options *options); | |
231 | ||
232 | /* | |
233 | * fsck a tag, and pass info about it back to the caller. This is | |
234 | * exposed fsck_object() internals for git-mktag(1). | |
235 | */ | |
236 | int fsck_tag_standalone(const struct object_id *oid, const char *buffer, | |
237 | unsigned long size, struct fsck_options *options, | |
238 | struct object_id *tagged_oid, | |
239 | int *tag_type); | |
240 | ||
241 | /* | |
242 | * Some fsck checks are context-dependent, and may end up queued; run this | |
243 | * after completing all fsck_object() calls in order to resolve any remaining | |
244 | * checks. | |
245 | */ | |
246 | int fsck_finish(struct fsck_options *options); | |
247 | ||
248 | /* | |
249 | * Clear the fsck_options struct, freeing any allocated memory. | |
250 | */ | |
251 | void fsck_options_clear(struct fsck_options *options); | |
252 | ||
253 | /* | |
254 | * Report an error or warning for refs. | |
255 | */ | |
256 | __attribute__((format (printf, 4, 5))) | |
257 | int fsck_report_ref(struct fsck_options *options, | |
258 | struct fsck_ref_report *report, | |
259 | enum fsck_msg_id msg_id, | |
260 | const char *fmt, ...); | |
261 | ||
262 | ||
263 | /* | |
264 | * Subsystem for storing human-readable names for each object. | |
265 | * | |
266 | * If fsck_enable_object_names() has not been called, all other functions are | |
267 | * noops. | |
268 | * | |
269 | * Use fsck_put_object_name() to seed initial names (e.g. from refnames); the | |
270 | * fsck code will extend that while walking trees, etc. | |
271 | * | |
272 | * Use fsck_get_object_name() to get a single name (or NULL if none). Or the | |
273 | * more convenient describe_object(), which always produces an output string | |
274 | * with the oid combined with the name (if any). Note that the return value | |
275 | * points to a rotating array of static buffers, and may be invalidated by a | |
276 | * subsequent call. | |
277 | */ | |
278 | void fsck_enable_object_names(struct fsck_options *options); | |
279 | const char *fsck_get_object_name(struct fsck_options *options, | |
280 | const struct object_id *oid); | |
281 | __attribute__((format (printf,3,4))) | |
282 | void fsck_put_object_name(struct fsck_options *options, | |
283 | const struct object_id *oid, | |
284 | const char *fmt, ...); | |
285 | const char *fsck_describe_object(struct fsck_options *options, | |
286 | const struct object_id *oid); | |
287 | ||
288 | struct key_value_info; | |
289 | /* | |
290 | * git_config() callback for use by fsck-y tools that want to support | |
291 | * fsck.<msg> fsck.skipList etc. | |
292 | */ | |
293 | int git_fsck_config(const char *var, const char *value, | |
294 | const struct config_context *ctx, void *cb); | |
295 | ||
296 | #endif |