This patch teaches "prune" to remove shallow roots that are no longer reachable from any refs (e.g. when the relevant refs are removed).
Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com> --- builtin/gc.c | 1 + builtin/prune.c | 4 ++++ commit.h | 1 + shallow.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/builtin/gc.c b/builtin/gc.c index c14190f..cec8ecd 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -16,6 +16,7 @@ #include "run-command.h" #include "sigchain.h" #include "argv-array.h" +#include "commit.h" #define FAILED_RUN "failed to run %s" diff --git a/builtin/prune.c b/builtin/prune.c index 6366917..023aea8 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -170,5 +170,9 @@ int cmd_prune(int argc, const char **argv, const char *prefix) s = mkpathdup("%s/pack", get_object_directory()); remove_temporary_files(s); free(s); + + if (!show_only && is_repository_shallow()) + prune_shallow(); + return 0; } diff --git a/commit.h b/commit.h index 0ff70fa..ff93a59 100644 --- a/commit.h +++ b/commit.h @@ -215,6 +215,7 @@ extern void remove_reachable_shallow_points(struct extra_have_objects *out, extern int mark_new_shallow_refs(const struct extra_have_objects *ref, int *ref_status, uint32_t **used, const struct extra_have_objects *shallow); +extern void prune_shallow(void); int is_descendant_of(struct commit *, struct commit_list *); int in_merge_bases(struct commit *, struct commit *); diff --git a/shallow.c b/shallow.c index abb04db..0eda40f 100644 --- a/shallow.c +++ b/shallow.c @@ -157,6 +157,7 @@ struct write_shallow_data { struct strbuf *out; int use_pack_protocol; int count; + int seen_only; }; static int write_one_shallow(const struct commit_graft *graft, void *cb_data) @@ -165,6 +166,11 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data) const char *hex = sha1_to_hex(graft->sha1); if (graft->nr_parent != -1) return 0; + if (data->seen_only) { + struct commit *c = lookup_commit(graft->sha1); + if (!c || !(c->object.flags & SEEN)) + return 0; + } data->count++; if (data->use_pack_protocol) packet_buf_write(data->out, "shallow %s", hex); @@ -175,14 +181,16 @@ static int write_one_shallow(const struct commit_graft *graft, void *cb_data) return 0; } -int write_shallow_commits(struct strbuf *out, int use_pack_protocol, - const struct extra_have_objects *extra) +static int write_shallow_commits_1(struct strbuf *out, int use_pack_protocol, + const struct extra_have_objects *extra, + int seen_only) { struct write_shallow_data data; int i; data.out = out; data.use_pack_protocol = use_pack_protocol; data.count = 0; + data.seen_only = seen_only; for_each_commit_graft(write_one_shallow, &data); if (!extra) return data.count; @@ -194,6 +202,12 @@ int write_shallow_commits(struct strbuf *out, int use_pack_protocol, return data.count; } +int write_shallow_commits(struct strbuf *out, int use_pack_protocol, + const struct extra_have_objects *extra) +{ + return write_shallow_commits_1(out, use_pack_protocol, extra, 0); +} + char *setup_temporary_shallow(const struct extra_have_objects *extra) { struct strbuf sb = STRBUF_INIT; @@ -515,3 +529,28 @@ int mark_new_shallow_refs(const struct extra_have_objects *ref, return ret; } + +/* + * mark_reachable_objects() should have been run prior to this and all + * reachable commits marked as "SEEN". + */ +void prune_shallow(void) +{ + static struct lock_file shallow_lock; + struct strbuf sb = STRBUF_INIT; + int fd; + + check_shallow_file_for_update(); + fd = hold_lock_file_for_update(&shallow_lock, git_path("shallow"), + LOCK_DIE_ON_ERROR); + if (write_shallow_commits_1(&sb, 0, NULL, 1)) { + if (write_in_full(fd, sb.buf, sb.len) != sb.len) + die_errno("failed to write to %s", + shallow_lock.filename); + commit_lock_file(&shallow_lock); + } else { + unlink(git_path("shallow")); + rollback_lock_file(&shallow_lock); + } + strbuf_release(&sb); +} -- 1.8.2.83.gc99314b -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html