shallow: offer to prune only non-existing entries
The `prune_shallow()` function wants a full reachability check to be completed before it goes to work, to ensure that all unreachable entries are removed from the shallow file. However, in the upcoming patch we do not even want to go that far. We really only need to remove entries corresponding to pruned commits, i.e. to commits that no longer exist. Let's support that use case. Rather than extending the signature of `prune_shallow()` to accept another Boolean, let's turn it into a bit field and declare constants, for readability. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Schindelin committed
Oct 24, 2018 at 08:56 UTC
2588f6ed8bd4e31c1ea1ae35f9f668452b46f1ef
3 files changed
+21
-8
builtin/prune.c
+1
-1
@@ -161,7 +161,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
161
free(s);
162
163
if (is_repository_shallow(the_repository))
164
- prune_shallow(show_only);
164
+ prune_shallow(show_only ? PRUNE_SHOW_ONLY : 0);
165
166
return 0;
167
}
commit.h
+3
-1
@@ -255,7 +255,9 @@ extern void assign_shallow_commits_to_refs(struct shallow_info *info,
255
uint32_t **used,
256
int *ref_status);
257
extern int delayed_reachability_test(struct shallow_info *si, int c);
258
-extern void prune_shallow(int show_only);
258
+#define PRUNE_SHOW_ONLY 1
259
+#define PRUNE_QUICK 2
260
+extern void prune_shallow(unsigned options);
261
extern struct trace_key trace_shallow;
262
263
int is_descendant_of(struct commit *, struct commit_list *);
shallow.c
+17
-6
@@ -246,6 +246,7 @@ static void check_shallow_file_for_update(struct repository *r)
246
247
#define SEEN_ONLY 1
248
#define VERBOSE 2
249
+#define QUICK 4
250
251
struct write_shallow_data {
252
struct strbuf *out;
@@ -260,7 +261,10 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data)
261
const char *hex = oid_to_hex(&graft->oid);
262
if (graft->nr_parent != -1)
263
return 0;
263
- if (data->flags & SEEN_ONLY) {
264
+ if (data->flags & QUICK) {
265
+ if (!has_object_file(&graft->oid))
266
+ return 0;
267
+ } else if (data->flags & SEEN_ONLY) {
268
struct commit *c = lookup_commit(the_repository, &graft->oid);
269
if (!c || !(c->object.flags & SEEN)) {
270
if (data->flags & VERBOSE)
@@ -370,16 +374,23 @@ void advertise_shallow_grafts(int fd)
374
375
/*
376
* mark_reachable_objects() should have been run prior to this and all
373
- * reachable commits marked as "SEEN".
377
+ * reachable commits marked as "SEEN", except when quick_prune is non-zero,
378
+ * in which case lines are excised from the shallow file if they refer to
379
+ * commits that do not exist (any longer).
380
*/
375
-void prune_shallow(int show_only)
381
+void prune_shallow(unsigned options)
382
{
383
struct lock_file shallow_lock = LOCK_INIT;
384
struct strbuf sb = STRBUF_INIT;
385
+ unsigned flags = SEEN_ONLY;
386
int fd;
387
381
- if (show_only) {
382
- write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY | VERBOSE);
388
+ if (options & PRUNE_QUICK)
389
+ flags |= QUICK;
390
+
391
+ if (options & PRUNE_SHOW_ONLY) {
392
+ flags |= VERBOSE;
393
+ write_shallow_commits_1(&sb, 0, NULL, flags);
394
strbuf_release(&sb);
395
return;
396
}
@@ -387,7 +398,7 @@ void prune_shallow(int show_only)
398
git_path_shallow(the_repository),
399
LOCK_DIE_ON_ERROR);
400
check_shallow_file_for_update(the_repository);
390
- if (write_shallow_commits_1(&sb, 0, NULL, SEEN_ONLY)) {
401
+ if (write_shallow_commits_1(&sb, 0, NULL, flags)) {
402
if (write_in_full(fd, sb.buf, sb.len) < 0)
403
die_errno("failed to write to %s",
404
get_lock_file_path(&shallow_lock));