builtin/am: introduce write_state_*() helper functions
[gitweb.git] / builtin / fsck.c
index 6dc2f9487409397b3654adf108b18fe04c22dba1..f4b87e9b33710e5ae67ec8886aad5259fdb0177f 100644 (file)
@@ -23,6 +23,7 @@ static int show_tags;
 static int show_unreachable;
 static int include_reflogs = 1;
 static int check_full = 1;
+static int connectivity_only;
 static int check_strict;
 static int keep_cache_objects;
 static struct fsck_options fsck_walk_options = FSCK_OPTIONS_DEFAULT;
@@ -48,6 +49,19 @@ static int show_dangling = 1;
 
 static int fsck_config(const char *var, const char *value, void *cb)
 {
+       if (strcmp(var, "fsck.skiplist") == 0) {
+               const char *path;
+               struct strbuf sb = STRBUF_INIT;
+
+               if (git_config_pathname(&path, var, value))
+                       return 1;
+               strbuf_addf(&sb, "skiplist=%s", path);
+               free((char *)path);
+               fsck_set_msg_types(&fsck_obj_options, sb.buf);
+               strbuf_release(&sb);
+               return 0;
+       }
+
        if (skip_prefix(var, "fsck.", &var)) {
                fsck_set_msg_type(&fsck_obj_options, var, value);
                return 0;
@@ -181,6 +195,8 @@ static void check_reachable_object(struct object *obj)
        if (!(obj->flags & HAS_OBJ)) {
                if (has_sha1_pack(obj->sha1))
                        return; /* it is in pack - forget about it */
+               if (connectivity_only && has_sha1_file(obj->sha1))
+                       return;
                printf("missing %s %s\n", typename(obj->type), sha1_to_hex(obj->sha1));
                errors_found |= ERROR_REACHABLE;
                return;
@@ -453,35 +469,41 @@ static void fsck_dir(int i, char *path)
 
 static int default_refs;
 
+static void fsck_handle_reflog_sha1(const char *refname, unsigned char *sha1)
+{
+       struct object *obj;
+
+       if (!is_null_sha1(sha1)) {
+               obj = lookup_object(sha1);
+               if (obj) {
+                       obj->used = 1;
+                       mark_object_reachable(obj);
+               } else {
+                       error("%s: invalid reflog entry %s", refname, sha1_to_hex(sha1));
+                       errors_found |= ERROR_REACHABLE;
+               }
+       }
+}
+
 static int fsck_handle_reflog_ent(unsigned char *osha1, unsigned char *nsha1,
                const char *email, unsigned long timestamp, int tz,
                const char *message, void *cb_data)
 {
-       struct object *obj;
+       const char *refname = cb_data;
 
        if (verbose)
                fprintf(stderr, "Checking reflog %s->%s\n",
                        sha1_to_hex(osha1), sha1_to_hex(nsha1));
 
-       if (!is_null_sha1(osha1)) {
-               obj = lookup_object(osha1);
-               if (obj) {
-                       obj->used = 1;
-                       mark_object_reachable(obj);
-               }
-       }
-       obj = lookup_object(nsha1);
-       if (obj) {
-               obj->used = 1;
-               mark_object_reachable(obj);
-       }
+       fsck_handle_reflog_sha1(refname, osha1);
+       fsck_handle_reflog_sha1(refname, nsha1);
        return 0;
 }
 
 static int fsck_handle_reflog(const char *logname, const struct object_id *oid,
                              int flag, void *cb_data)
 {
-       for_each_reflog_ent(logname, fsck_handle_reflog_ent, NULL);
+       for_each_reflog_ent(logname, fsck_handle_reflog_ent, (void *)logname);
        return 0;
 }
 
@@ -617,6 +639,7 @@ static struct option fsck_opts[] = {
        OPT_BOOL(0, "cache", &keep_cache_objects, N_("make index objects head nodes")),
        OPT_BOOL(0, "reflogs", &include_reflogs, N_("make reflogs head nodes (default)")),
        OPT_BOOL(0, "full", &check_full, N_("also consider packs and alternate objects")),
+       OPT_BOOL(0, "connectivity-only", &connectivity_only, N_("check only connectivity")),
        OPT_BOOL(0, "strict", &check_strict, N_("enable more strict checking")),
        OPT_BOOL(0, "lost-found", &write_lost_and_found,
                                N_("write dangling objects in .git/lost-found")),
@@ -653,7 +676,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
        git_config(fsck_config, NULL);
 
        fsck_head_link();
-       fsck_object_dir(get_object_directory());
+       if (!connectivity_only)
+               fsck_object_dir(get_object_directory());
 
        prepare_alt_odb();
        for (alt = alt_odb_list; alt; alt = alt->next) {