]> git.ipfire.org Git - thirdparty/git.git/commitdiff
reachable: add options to add_unseen_recent_objects_to_traversal
authorTaylor Blau <me@ttaylorr.com>
Fri, 20 May 2022 23:17:54 +0000 (19:17 -0400)
committerJunio C Hamano <gitster@pobox.com>
Thu, 26 May 2022 22:48:26 +0000 (15:48 -0700)
This function behaves very similarly to what we will need in
pack-objects in order to implement cruft packs with expiration. But it
is lacking a couple of things. Namely, it needs:

  - a mechanism to communicate the timestamps of individual recent
    objects to some external caller

  - and, in the case of packed objects, our future caller will also want
    to know the originating pack, as well as the offset within that pack
    at which the object can be found

  - finally, it needs a way to skip over packs which are marked as kept
    in-core.

To address the first two, add a callback interface in this patch which
reports the time of each recent object, as well as a (packed_git,
off_t) pair for packed objects.

Likewise, add a new option to the packed object iterators to skip over
packs which are marked as kept in core. This option will become
implicitly tested in a future patch.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/pack-objects.c
reachable.c
reachable.h

index 9cf89be673ba6b17dc630e7f59cd1d7d778fad2f..3b8bf6a3dd5776f1580004d58808b431ab06efd2 100644 (file)
@@ -3957,7 +3957,7 @@ static void get_object_list(struct rev_info *revs, int ac, const char **av)
        if (unpack_unreachable_expiration) {
                revs->ignore_missing_links = 1;
                if (add_unseen_recent_objects_to_traversal(revs,
-                               unpack_unreachable_expiration))
+                               unpack_unreachable_expiration, NULL, 0))
                        die(_("unable to add recent objects"));
                if (prepare_revision_walk(revs))
                        die(_("revision walk setup failed"));
index b9f4ad886eff72f75eaa45c40d8a75c6ae2d2008..d4507c427096525232cd6c6d6fdc8cde864c4476 100644 (file)
@@ -60,9 +60,13 @@ static void mark_commit(struct commit *c, void *data)
 struct recent_data {
        struct rev_info *revs;
        timestamp_t timestamp;
+       report_recent_object_fn *cb;
+       int ignore_in_core_kept_packs;
 };
 
 static void add_recent_object(const struct object_id *oid,
+                             struct packed_git *pack,
+                             off_t offset,
                              timestamp_t mtime,
                              struct recent_data *data)
 {
@@ -103,13 +107,29 @@ static void add_recent_object(const struct object_id *oid,
                die("unable to lookup %s", oid_to_hex(oid));
 
        add_pending_object(data->revs, obj, "");
+       if (data->cb)
+               data->cb(obj, pack, offset, mtime);
+}
+
+static int want_recent_object(struct recent_data *data,
+                             const struct object_id *oid)
+{
+       if (data->ignore_in_core_kept_packs &&
+           has_object_kept_pack(oid, IN_CORE_KEEP_PACKS))
+               return 0;
+       return 1;
 }
 
 static int add_recent_loose(const struct object_id *oid,
                            const char *path, void *data)
 {
        struct stat st;
-       struct object *obj = lookup_object(the_repository, oid);
+       struct object *obj;
+
+       if (!want_recent_object(data, oid))
+               return 0;
+
+       obj = lookup_object(the_repository, oid);
 
        if (obj && obj->flags & SEEN)
                return 0;
@@ -126,7 +146,7 @@ static int add_recent_loose(const struct object_id *oid,
                return error_errno("unable to stat %s", oid_to_hex(oid));
        }
 
-       add_recent_object(oid, st.st_mtime, data);
+       add_recent_object(oid, NULL, 0, st.st_mtime, data);
        return 0;
 }
 
@@ -134,29 +154,43 @@ static int add_recent_packed(const struct object_id *oid,
                             struct packed_git *p, uint32_t pos,
                             void *data)
 {
-       struct object *obj = lookup_object(the_repository, oid);
+       struct object *obj;
+
+       if (!want_recent_object(data, oid))
+               return 0;
+
+       obj = lookup_object(the_repository, oid);
 
        if (obj && obj->flags & SEEN)
                return 0;
-       add_recent_object(oid, p->mtime, data);
+       add_recent_object(oid, p, nth_packed_object_offset(p, pos), p->mtime, data);
        return 0;
 }
 
 int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
-                                          timestamp_t timestamp)
+                                          timestamp_t timestamp,
+                                          report_recent_object_fn *cb,
+                                          int ignore_in_core_kept_packs)
 {
        struct recent_data data;
+       enum for_each_object_flags flags;
        int r;
 
        data.revs = revs;
        data.timestamp = timestamp;
+       data.cb = cb;
+       data.ignore_in_core_kept_packs = ignore_in_core_kept_packs;
 
        r = for_each_loose_object(add_recent_loose, &data,
                                  FOR_EACH_OBJECT_LOCAL_ONLY);
        if (r)
                return r;
-       return for_each_packed_object(add_recent_packed, &data,
-                                     FOR_EACH_OBJECT_LOCAL_ONLY);
+
+       flags = FOR_EACH_OBJECT_LOCAL_ONLY | FOR_EACH_OBJECT_PACK_ORDER;
+       if (ignore_in_core_kept_packs)
+               flags |= FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS;
+
+       return for_each_packed_object(add_recent_packed, &data, flags);
 }
 
 static int mark_object_seen(const struct object_id *oid,
@@ -217,7 +251,8 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
 
        if (mark_recent) {
                revs->ignore_missing_links = 1;
-               if (add_unseen_recent_objects_to_traversal(revs, mark_recent))
+               if (add_unseen_recent_objects_to_traversal(revs, mark_recent,
+                                                          NULL, 0))
                        die("unable to mark recent objects");
                if (prepare_revision_walk(revs))
                        die("revision walk setup failed");
index 5df932ad8f54418927d30117ee0209ba91459bde..b776761baa12a93cbc0e654dbddb3df59d3abc9e 100644 (file)
@@ -1,11 +1,18 @@
 #ifndef REACHEABLE_H
 #define REACHEABLE_H
 
+#include "object.h"
+
 struct progress;
 struct rev_info;
 
+typedef void report_recent_object_fn(const struct object *, struct packed_git *,
+                                    off_t, time_t);
+
 int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
-                                          timestamp_t timestamp);
+                                          timestamp_t timestamp,
+                                          report_recent_object_fn cb,
+                                          int ignore_in_core_kept_packs);
 void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
                            timestamp_t mark_recent, struct progress *);