enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit) { if (commit->object.flags & SHOWN) return commit_ignore; if (revs->unpacked && has_sha1_pack(commit->object.sha1, revs->ignore_packed)) return commit_ignore; if (revs->show_all) return commit_show; if (commit->object.flags & UNINTERESTING) return commit_ignore; if (revs->min_age != -1 && (commit->date > revs->min_age)) return commit_ignore; if (revs->no_merges && commit->parents && commit->parents->next) return commit_ignore; if (!commit_match(commit, revs)) return commit_ignore; if (revs->prune && revs->dense) { /* Commit without changes? */ if (commit->object.flags & TREESAME) { /* drop merges unless we want parenthood */ if (!want_ancestry(revs)) return commit_ignore; /* non-merge - always ignore it */ if (!commit->parents || !commit->parents->next) return commit_ignore; } if (want_ancestry(revs) && rewrite_parents(revs, commit) < 0) return commit_error; } return commit_show; }
static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts) { struct dirent *de; char hex[40]; sprintf(hex, "%02x", i); while ((de = readdir(dir)) != NULL) { unsigned char sha1[20]; if (strlen(de->d_name) != 38) continue; memcpy(hex+2, de->d_name, 38); if (get_sha1_hex(hex, sha1)) continue; if (!has_sha1_pack(sha1)) continue; memcpy(pathname + len, de->d_name, 38); if (opts & DRY_RUN) printf("rm -f %s\n", pathname); else if (unlink(pathname) < 0) error("unable to unlink %s", pathname); display_progress(progress, i + 1); } pathname[len] = 0; rmdir(pathname); }
static void count_objects(DIR *d, char *path, int len, int verbose, unsigned long *loose, unsigned long *loose_size, unsigned long *packed_loose, unsigned long *garbage) { struct dirent *ent; while ((ent = readdir(d)) != NULL) { char hex[41]; unsigned char sha1[20]; const char *cp; int bad = 0; if ((ent->d_name[0] == '.') && (ent->d_name[1] == 0 || ((ent->d_name[1] == '.') && (ent->d_name[2] == 0)))) continue; for (cp = ent->d_name; *cp; cp++) { int ch = *cp; if (('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f')) continue; bad = 1; break; } if (cp - ent->d_name != 38) bad = 1; else { struct stat st; memcpy(path + len + 3, ent->d_name, 38); path[len + 2] = '/'; path[len + 41] = 0; if (lstat(path, &st) || !S_ISREG(st.st_mode)) bad = 1; else (*loose_size) += xsize_t(st.st_blocks); } if (bad) { if (verbose) { error("garbage found: %.*s/%s", len + 2, path, ent->d_name); (*garbage)++; } continue; } (*loose)++; if (!verbose) continue; memcpy(hex, path+len, 2); memcpy(hex+2, ent->d_name, 38); hex[40] = 0; if (get_sha1_hex(hex, sha1)) die("internal error"); if (has_sha1_pack(sha1, NULL)) (*packed_loose)++; } }
static int prune_object(const struct object_id *oid, const char *path, void *data) { int *opts = data; if (!has_sha1_pack(oid->hash)) return 0; if (*opts & PRUNE_PACKED_DRY_RUN) printf("rm -f %s\n", path); else unlink_or_warn(path); return 0; }
static int count_loose(const unsigned char *sha1, const char *path, void *data) { struct stat st; if (lstat(path, &st) || !S_ISREG(st.st_mode)) loose_garbage(path); else { loose_size += on_disk_bytes(st); loose++; if (verbose && has_sha1_pack(sha1)) packed_loose++; } return 0; }
/* * Check a single reachable object */ static void check_reachable_object(struct object *obj) { /* * We obviously want the object to be parsed, * except if it was in a pack-file and we didn't * do a full fsck */ if (!(obj->flags & HAS_OBJ)) { if (is_promisor_object(&obj->oid)) return; if (has_sha1_pack(obj->oid.hash)) return; /* it is in pack - forget about it */ printf("missing %s %s\n", printable_type(obj), describe_object(obj)); errors_found |= ERROR_REACHABLE; return; } }