The four commands prune, rev-list, pack-objects and repack are updated to not consider backup-log's blobs as unreachable and either delete them outright or not repack them. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- backup-log.c | 65 ++++++++++++++++++++++++++++++++++++++++++ backup-log.h | 2 ++ builtin/pack-objects.c | 9 +++++- builtin/repack.c | 1 + reachable.c | 3 ++ revision.c | 3 ++ 6 files changed, 82 insertions(+), 1 deletion(-) diff --git a/backup-log.c b/backup-log.c index dbb6d5487e..37fa71e4e0 100644 --- a/backup-log.c +++ b/backup-log.c @@ -3,6 +3,7 @@ #include "blob.h" #include "lockfile.h" #include "object-store.h" +#include "revision.h" #include "strbuf.h" #include "worktree.h" @@ -321,3 +322,67 @@ void bkl_prune_all_or_die(struct repository *r, timestamp_t expire) } free_worktrees(worktrees); } + +struct pending_cb { + struct rev_info *revs; + unsigned flags; +}; + +static void add_blob_to_pending(const struct object_id *oid, + const char *path, + struct pending_cb *cb) +{ + struct blob *blob; + + if (!good_oid(cb->revs->repo, oid)) + return; + + blob = lookup_blob(cb->revs->repo, oid); + blob->object.flags |= cb->flags; + add_pending_object(cb->revs, &blob->object, path); +} + +static int add_pending(struct strbuf *line, void *cb) +{ + struct bkl_entry entry; + + if (bkl_parse_entry(line, &entry)) + return -1; + + add_blob_to_pending(&entry.old_oid, entry.path, cb); + add_blob_to_pending(&entry.new_oid, entry.path, cb); + return 0; +} + +static void add_backup_log_to_pending(const char *path, struct pending_cb *cb) +{ + bkl_parse_file(path, add_pending, cb); +} + +void add_backup_logs_to_pending(struct rev_info *revs, unsigned flags) +{ + struct worktree **worktrees, **p; + char *path; + struct pending_cb cb; + + cb.revs = revs; + cb.flags = flags; + + worktrees = get_worktrees(0); + for (p = worktrees; *p; p++) { + struct worktree *wt = *p; + + path = xstrdup(worktree_git_path(wt, "index.bkl")); + add_backup_log_to_pending(path, &cb); + free(path); + + path = xstrdup(worktree_git_path(wt, "worktree.bkl")); + add_backup_log_to_pending(path, &cb); + free(path); + } + free_worktrees(worktrees); + + path = git_pathdup("common/gitdir.bkl"); + add_backup_log_to_pending(path, &cb); + free(path); +} diff --git a/backup-log.h b/backup-log.h index 6572ce9c93..aaa76b7fe2 100644 --- a/backup-log.h +++ b/backup-log.h @@ -4,6 +4,7 @@ #include "cache.h" struct repository; +struct rev_info; struct strbuf; struct bkl_entry @@ -30,6 +31,7 @@ int bkl_parse_file(const char *path, int (*parse)(struct strbuf *line, void *data), void *data); +void add_backup_logs_to_pending(struct rev_info *revs, unsigned flags); int bkl_prune(struct repository *r, const char *id, timestamp_t expire); void bkl_prune_all_or_die(struct repository *r, timestamp_t expire); diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 411aefd687..940eb0c768 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -3230,7 +3230,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) int all_progress_implied = 0; struct argv_array rp = ARGV_ARRAY_INIT; int rev_list_unpacked = 0, rev_list_all = 0, rev_list_reflog = 0; - int rev_list_index = 0; + int rev_list_index = 0, rev_list_backuplog = 0; struct string_list keep_pack_list = STRING_LIST_INIT_NODUP; struct option pack_objects_options[] = { OPT_SET_INT('q', "quiet", &progress, @@ -3278,6 +3278,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) OPT_SET_INT_F(0, "reflog", &rev_list_reflog, N_("include objects referred by reflog entries"), 1, PARSE_OPT_NONEG), + OPT_SET_INT_F(0, "backup-log", &rev_list_backuplog, + N_("include objects referred by backup-log entries"), + 1, PARSE_OPT_NONEG), OPT_SET_INT_F(0, "indexed-objects", &rev_list_index, N_("include objects referred to by the index"), 1, PARSE_OPT_NONEG), @@ -3366,6 +3369,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) use_internal_rev_list = 1; argv_array_push(&rp, "--reflog"); } + if (rev_list_backuplog) { + use_internal_rev_list = 1; + argv_array_push(&rp, "--backup-log"); + } if (rev_list_index) { use_internal_rev_list = 1; argv_array_push(&rp, "--indexed-objects"); diff --git a/builtin/repack.c b/builtin/repack.c index 45583683ee..a8a9fad9c6 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -365,6 +365,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) argv_array_push(&cmd.args, "--non-empty"); argv_array_push(&cmd.args, "--all"); argv_array_push(&cmd.args, "--reflog"); + argv_array_push(&cmd.args, "--backup-log"); argv_array_push(&cmd.args, "--indexed-objects"); if (repository_format_partial_clone) argv_array_push(&cmd.args, "--exclude-promisor-objects"); diff --git a/reachable.c b/reachable.c index 6e9b810d2a..61f6560b54 100644 --- a/reachable.c +++ b/reachable.c @@ -12,6 +12,7 @@ #include "packfile.h" #include "worktree.h" #include "object-store.h" +#include "backup-log.h" struct connectivity_progress { struct progress *progress; @@ -185,6 +186,8 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog, if (mark_reflog) add_reflogs_to_pending(revs, 0); + add_backup_logs_to_pending(revs, 0); + cp.progress = progress; cp.count = 0; diff --git a/revision.c b/revision.c index 13e0519c02..755edea61e 100644 --- a/revision.c +++ b/revision.c @@ -27,6 +27,7 @@ #include "commit-reach.h" #include "commit-graph.h" #include "prio-queue.h" +#include "backup-log.h" volatile show_early_output_fn_t show_early_output; @@ -2286,6 +2287,8 @@ static int handle_revision_pseudo_opt(const char *submodule, clear_ref_exclusion(&revs->ref_excludes); } else if (!strcmp(arg, "--reflog")) { add_reflogs_to_pending(revs, *flags); + } else if (!strcmp(arg, "--backup-log")) { + add_backup_logs_to_pending(revs, *flags); } else if (!strcmp(arg, "--indexed-objects")) { add_index_objects_to_pending(revs, *flags); } else if (!strcmp(arg, "--not")) { -- 2.20.0.rc2.486.g9832c05c3d