9 #include "cache-tree.h"
 
  11 #include "list-objects.h"
 
  14 #include "object-store.h"
 
  15 #include "pack-bitmap.h"
 
  17 struct connectivity_progress {
 
  18         struct progress *progress;
 
  22 static void update_progress(struct connectivity_progress *cp)
 
  25         if ((cp->count & 1023) == 0)
 
  26                 display_progress(cp->progress, cp->count);
 
  29 static int add_one_ref(const char *path, const struct object_id *oid,
 
  30                        int flag, void *cb_data)
 
  32         struct rev_info *revs = (struct rev_info *)cb_data;
 
  33         struct object *object;
 
  35         if ((flag & REF_ISSYMREF) && (flag & REF_ISBROKEN)) {
 
  36                 warning("symbolic ref is dangling: %s", path);
 
  40         object = parse_object_or_die(oid, path);
 
  41         add_pending_object(revs, object, "");
 
  47  * The traversal will have already marked us as SEEN, so we
 
  48  * only need to handle any progress reporting here.
 
  50 static void mark_object(struct object *obj, const char *name, void *data)
 
  52         update_progress(data);
 
  55 static void mark_commit(struct commit *c, void *data)
 
  57         mark_object(&c->object, NULL, data);
 
  61         struct rev_info *revs;
 
  62         timestamp_t timestamp;
 
  65 static void add_recent_object(const struct object_id *oid,
 
  67                               struct recent_data *data)
 
  70         enum object_type type;
 
  72         if (mtime <= data->timestamp)
 
  76          * We do not want to call parse_object here, because
 
  77          * inflating blobs and trees could be very expensive.
 
  78          * However, we do need to know the correct type for
 
  79          * later processing, and the revision machinery expects
 
  80          * commits and tags to have been parsed.
 
  82         type = oid_object_info(the_repository, oid, NULL);
 
  84                 die("unable to get object info for %s", oid_to_hex(oid));
 
  89                 obj = parse_object_or_die(oid, NULL);
 
  92                 obj = (struct object *)lookup_tree(the_repository, oid);
 
  95                 obj = (struct object *)lookup_blob(the_repository, oid);
 
  98                 die("unknown object type for %s: %s",
 
  99                     oid_to_hex(oid), type_name(type));
 
 103                 die("unable to lookup %s", oid_to_hex(oid));
 
 105         add_pending_object(data->revs, obj, "");
 
 108 static int add_recent_loose(const struct object_id *oid,
 
 109                             const char *path, void *data)
 
 112         struct object *obj = lookup_object(the_repository, oid);
 
 114         if (obj && obj->flags & SEEN)
 
 117         if (stat(path, &st) < 0) {
 
 119                  * It's OK if an object went away during our iteration; this
 
 120                  * could be due to a simultaneous repack. But anything else
 
 121                  * we should abort, since we might then fail to mark objects
 
 122                  * which should not be pruned.
 
 126                 return error_errno("unable to stat %s", oid_to_hex(oid));
 
 129         add_recent_object(oid, st.st_mtime, data);
 
 133 static int add_recent_packed(const struct object_id *oid,
 
 134                              struct packed_git *p, uint32_t pos,
 
 137         struct object *obj = lookup_object(the_repository, oid);
 
 139         if (obj && obj->flags & SEEN)
 
 141         add_recent_object(oid, p->mtime, data);
 
 145 int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
 
 146                                            timestamp_t timestamp)
 
 148         struct recent_data data;
 
 152         data.timestamp = timestamp;
 
 154         r = for_each_loose_object(add_recent_loose, &data,
 
 155                                   FOR_EACH_OBJECT_LOCAL_ONLY);
 
 158         return for_each_packed_object(add_recent_packed, &data,
 
 159                                       FOR_EACH_OBJECT_LOCAL_ONLY);
 
 162 static void *lookup_object_by_type(struct repository *r,
 
 163                                    const struct object_id *oid,
 
 164                                    enum object_type type)
 
 168                 return lookup_commit(r, oid);
 
 170                 return lookup_tree(r, oid);
 
 172                 return lookup_tag(r, oid);
 
 174                 return lookup_blob(r, oid);
 
 176                 die("BUG: unknown object type %d", type);
 
 180 static int mark_object_seen(const struct object_id *oid,
 
 181                              enum object_type type,
 
 184                              struct packed_git *found_pack,
 
 187         struct object *obj = lookup_object_by_type(the_repository, oid, type);
 
 189                 die("unable to create object '%s'", oid_to_hex(oid));
 
 195 void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
 
 196                             timestamp_t mark_recent, struct progress *progress)
 
 198         struct connectivity_progress cp;
 
 199         struct bitmap_index *bitmap_git;
 
 202          * Set up revision parsing, and mark us as being interested
 
 203          * in all object types, not just commits.
 
 205         revs->tag_objects = 1;
 
 206         revs->blob_objects = 1;
 
 207         revs->tree_objects = 1;
 
 209         /* Add all refs from the index file */
 
 210         add_index_objects_to_pending(revs, 0);
 
 212         /* Add all external refs */
 
 213         for_each_ref(add_one_ref, revs);
 
 215         /* detached HEAD is not included in the list above */
 
 216         head_ref(add_one_ref, revs);
 
 217         other_head_refs(add_one_ref, revs);
 
 219         /* Add all reflog info */
 
 221                 add_reflogs_to_pending(revs, 0);
 
 223         cp.progress = progress;
 
 226         bitmap_git = prepare_bitmap_walk(revs);
 
 228                 traverse_bitmap_commit_list(bitmap_git, mark_object_seen);
 
 229                 free_bitmap_index(bitmap_git);
 
 234          * Set up the revision walk - this will move all commits
 
 235          * from the pending list to the commit walking list.
 
 237         if (prepare_revision_walk(revs))
 
 238                 die("revision walk setup failed");
 
 239         traverse_commit_list(revs, mark_commit, mark_object, &cp);
 
 242                 revs->ignore_missing_links = 1;
 
 243                 if (add_unseen_recent_objects_to_traversal(revs, mark_recent))
 
 244                         die("unable to mark recent objects");
 
 245                 if (prepare_revision_walk(revs))
 
 246                         die("revision walk setup failed");
 
 247                 traverse_commit_list(revs, mark_commit, mark_object, &cp);
 
 250         display_progress(cp.progress, cp.count);