shallow: offer to prune only non-existing entries
[gitweb.git] / shallow.c
index e53067cdede4865e144713502055a04cf230c926..c1b68533ca3d831afcef7fd655cce95d8db89547 100644 (file)
--- a/shallow.c
+++ b/shallow.c
@@ -31,7 +31,7 @@ int register_shallow(struct repository *r, const struct object_id *oid)
 {
        struct commit_graft *graft =
                xmalloc(sizeof(struct commit_graft));
-       struct commit *commit = lookup_commit(oid);
+       struct commit *commit = lookup_commit(the_repository, oid);
 
        oidcpy(&graft->oid, oid);
        graft->nr_parent = -1;
@@ -96,7 +96,9 @@ struct commit_list *get_shallow_commits(struct object_array *heads, int depth,
                        if (i < heads->nr) {
                                int **depth_slot;
                                commit = (struct commit *)
-                                       deref_tag(heads->objects[i++].item, NULL, 0);
+                                       deref_tag(the_repository,
+                                                 heads->objects[i++].item,
+                                                 NULL, 0);
                                if (!commit || commit->object.type != OBJ_COMMIT) {
                                        commit = NULL;
                                        continue;
@@ -244,6 +246,7 @@ static void check_shallow_file_for_update(struct repository *r)
 
 #define SEEN_ONLY 1
 #define VERBOSE   2
+#define QUICK 4
 
 struct write_shallow_data {
        struct strbuf *out;
@@ -258,8 +261,11 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
        const char *hex = oid_to_hex(&graft->oid);
        if (graft->nr_parent != -1)
                return 0;
-       if (data->flags & SEEN_ONLY) {
-               struct commit *c = lookup_commit(&graft->oid);
+       if (data->flags & QUICK) {
+               if (!has_object_file(&graft->oid))
+                       return 0;
+       } else if (data->flags & SEEN_ONLY) {
+               struct commit *c = lookup_commit(the_repository, &graft->oid);
                if (!c || !(c->object.flags & SEEN)) {
                        if (data->flags & VERBOSE)
                                printf("Removing %s from .git/shallow\n",
@@ -368,16 +374,23 @@ void advertise_shallow_grafts(int fd)
 
 /*
  * mark_reachable_objects() should have been run prior to this and all
- * reachable commits marked as "SEEN".
+ * reachable commits marked as "SEEN", except when quick_prune is non-zero,
+ * in which case lines are excised from the shallow file if they refer to
+ * commits that do not exist (any longer).
  */
-void prune_shallow(int show_only)
+void prune_shallow(unsigned options)
 {
        struct lock_file shallow_lock = LOCK_INIT;
        struct strbuf sb = STRBUF_INIT;
+       unsigned flags = SEEN_ONLY;
        int fd;
 
-       if (show_only) {
-               write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY | VERBOSE);
+       if (options & PRUNE_QUICK)
+               flags |= QUICK;
+
+       if (options & PRUNE_SHOW_ONLY) {
+               flags |= VERBOSE;
+               write_shallow_commits_1(&sb, 0, NULL, flags);
                strbuf_release(&sb);
                return;
        }
@@ -385,7 +398,7 @@ void prune_shallow(int show_only)
                                       git_path_shallow(the_repository),
                                       LOCK_DIE_ON_ERROR);
        check_shallow_file_for_update(the_repository);
-       if (write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY)) {
+       if (write_shallow_commits_1(&sb, 0, NULL, flags)) {
                if (write_in_full(fd, sb.buf, sb.len) < 0)
                        die_errno("failed to write to %s",
                                  get_lock_file_path(&shallow_lock));
@@ -492,7 +505,8 @@ static void paint_down(struct paint_info *info, const struct object_id *oid,
        struct commit_list *head = NULL;
        int bitmap_nr = DIV_ROUND_UP(info->nr_bits, 32);
        size_t bitmap_size = st_mult(sizeof(uint32_t), bitmap_nr);
-       struct commit *c = lookup_commit_reference_gently(oid, 1);
+       struct commit *c = lookup_commit_reference_gently(the_repository, oid,
+                                                         1);
        uint32_t *tmp; /* to be freed before return */
        uint32_t *bitmap;
 
@@ -554,7 +568,8 @@ static void paint_down(struct paint_info *info, const struct object_id *oid,
 static int mark_uninteresting(const char *refname, const struct object_id *oid,
                              int flags, void *cb_data)
 {
-       struct commit *commit = lookup_commit_reference_gently(oid, 1);
+       struct commit *commit = lookup_commit_reference_gently(the_repository,
+                                                              oid, 1);
        if (!commit)
                return 0;
        commit->object.flags |= UNINTERESTING;
@@ -622,7 +637,8 @@ void assign_shallow_commits_to_refs(struct shallow_info *info,
 
        /* Mark potential bottoms so we won't go out of bound */
        for (i = 0; i < nr_shallow; i++) {
-               struct commit *c = lookup_commit(&oid[shallow[i]]);
+               struct commit *c = lookup_commit(the_repository,
+                                                &oid[shallow[i]]);
                c->object.flags |= BOTTOM;
        }
 
@@ -633,7 +649,8 @@ void assign_shallow_commits_to_refs(struct shallow_info *info,
                int bitmap_size = DIV_ROUND_UP(pi.nr_bits, 32) * sizeof(uint32_t);
                memset(used, 0, sizeof(*used) * info->shallow->nr);
                for (i = 0; i < nr_shallow; i++) {
-                       const struct commit *c = lookup_commit(&oid[shallow[i]]);
+                       const struct commit *c = lookup_commit(the_repository,
+                                                              &oid[shallow[i]]);
                        uint32_t **map = ref_bitmap_at(&pi.ref_bitmap, c);
                        if (*map)
                                used[shallow[i]] = xmemdupz(*map, bitmap_size);
@@ -664,7 +681,8 @@ static int add_ref(const char *refname, const struct object_id *oid,
 {
        struct commit_array *ca = cb_data;
        ALLOC_GROW(ca->commits, ca->nr + 1, ca->alloc);
-       ca->commits[ca->nr] = lookup_commit_reference_gently(oid, 1);
+       ca->commits[ca->nr] = lookup_commit_reference_gently(the_repository,
+                                                            oid, 1);
        if (ca->commits[ca->nr])
                ca->nr++;
        return 0;
@@ -702,7 +720,7 @@ static void post_assign_shallow(struct shallow_info *info,
        for (i = dst = 0; i < info->nr_theirs; i++) {
                if (i != dst)
                        info->theirs[dst] = info->theirs[i];
-               c = lookup_commit(&oid[info->theirs[i]]);
+               c = lookup_commit(the_repository, &oid[info->theirs[i]]);
                bitmap = ref_bitmap_at(ref_bitmap, c);
                if (!*bitmap)
                        continue;
@@ -723,7 +741,7 @@ static void post_assign_shallow(struct shallow_info *info,
        for (i = dst = 0; i < info->nr_ours; i++) {
                if (i != dst)
                        info->ours[dst] = info->ours[i];
-               c = lookup_commit(&oid[info->ours[i]]);
+               c = lookup_commit(the_repository, &oid[info->ours[i]]);
                bitmap = ref_bitmap_at(ref_bitmap, c);
                if (!*bitmap)
                        continue;
@@ -745,7 +763,8 @@ static void post_assign_shallow(struct shallow_info *info,
 int delayed_reachability_test(struct shallow_info *si, int c)
 {
        if (si->need_reachability_test[c]) {
-               struct commit *commit = lookup_commit(&si->shallow->oid[c]);
+               struct commit *commit = lookup_commit(the_repository,
+                                                     &si->shallow->oid[c]);
 
                if (!si->commits) {
                        struct commit_array ca;