Teach git-commit-graph to delete the graph previously referenced by 'graph_head' when writing a new graph file and updating 'graph_head'. This prevents data creep by storing a list of useless graphs. Be careful to not delete the graph if the file did not change. Signed-off-by: Derrick Stolee <dstolee@xxxxxxxxxxxxx> --- Documentation/git-commit-graph.txt | 8 +++-- builtin/commit-graph.c | 16 ++++++++- t/t5318-commit-graph.sh | 66 +++++++++++++++++++++++++++++++++++++- 3 files changed, 86 insertions(+), 4 deletions(-) diff --git a/Documentation/git-commit-graph.txt b/Documentation/git-commit-graph.txt index 33d6567f11..7b376e9212 100644 --- a/Documentation/git-commit-graph.txt +++ b/Documentation/git-commit-graph.txt @@ -39,6 +39,10 @@ OPTIONS When used with --write, update the graph-head file to point to the written graph file. +--delete-expired:: + When used with --write and --update-head, delete the graph file + previously referenced by graph-head. + EXAMPLES -------- @@ -55,10 +59,10 @@ $ git commit-graph --write ------------------------------------------------ * Write a graph file for the packed commits in your local .git folder, -* and update graph-head. +* update graph-head, and delete the old graph-<oid>.graph file. + ------------------------------------------------ -$ git commit-graph --write --update-head +$ git commit-graph --write --update-head --delete-expired ------------------------------------------------ * Read basic information from a graph file. diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index 4970dec133..766f09e6fc 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -12,7 +12,7 @@ static char const * const builtin_commit_graph_usage[] = { N_("git commit-graph [--pack-dir <packdir>]"), N_("git commit-graph --clear [--pack-dir <packdir>]"), N_("git commit-graph --read [--graph-hash=<hash>]"), - N_("git commit-graph --write [--pack-dir <packdir>] [--update-head]"), + N_("git commit-graph --write [--pack-dir <packdir>] [--update-head] [--delete-expired]"), NULL }; @@ -23,6 +23,7 @@ static struct opts_commit_graph { const char *graph_hash; int write; int update_head; + int delete_expired; int has_existing; struct object_id old_graph_hash; } opts; @@ -121,6 +122,17 @@ static int graph_write(void) if (graph_hash) printf("%s\n", oid_to_hex(graph_hash)); + + if (opts.delete_expired && opts.update_head && opts.has_existing && + oidcmp(graph_hash, &opts.old_graph_hash)) { + char *old_path = get_commit_graph_filename_hash(opts.pack_dir, + &opts.old_graph_hash); + if (remove_path(old_path)) + die("failed to remove path %s", old_path); + + free(old_path); + } + free(graph_hash); return 0; } @@ -139,6 +151,8 @@ int cmd_commit_graph(int argc, const char **argv, const char *prefix) N_("write commit graph file")), OPT_BOOL('u', "update-head", &opts.update_head, N_("update graph-head to written graph file")), + OPT_BOOL('d', "delete-expired", &opts.delete_expired, + N_("delete expired head graph file")), { OPTION_STRING, 'H', "graph-hash", &opts.graph_hash, N_("hash"), N_("A hash for a specific graph file in the pack-dir."), diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index 6e3b62b754..b56a6d4217 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -101,9 +101,73 @@ test_expect_success 'write graph with merges' \ _graph_read_expect "18" "${packdir}" && cmp expect output' +test_expect_success 'Add more commits' \ + 'for i in $(test_seq 16 20) + do + echo $i >$i.txt && + git add $i.txt && + git commit -m "commit $i" && + git branch commits/$i + done && + git repack' + +# Current graph structure: +# +# 20 +# | +# 19 +# | +# 18 +# | +# 17 +# | +# 16 +# | +# M3 +# / |\_____ +# / 10 15 +# / | | +# / 9 M2 14 +# | |/ \ | +# | 8 M1 | 13 +# | |/ | \_| +# 5 7 | 12 +# | | \__| +# 4 6 11 +# |____/______/ +# 3 +# | +# 2 +# | +# 1 + +test_expect_success 'write graph with merges' \ + 'graph3=$(git commit-graph --write --update-head --delete-expired) && + test_path_is_file ${packdir}/graph-${graph3}.graph && + test_path_is_missing ${packdir}/graph-${graph2}.graph && + test_path_is_file ${packdir}/graph-${graph1}.graph && + test_path_is_file ${packdir}/graph-head && + echo ${graph3} >expect && + cmp -n 40 expect ${packdir}/graph-head && + git commit-graph --read --graph-hash=${graph3} >output && + _graph_read_expect "23" "${packdir}" && + cmp expect output' + +test_expect_success 'write graph with nothing new' \ + 'graph4=$(git commit-graph --write --update-head --delete-expired) && + test_path_is_file ${packdir}/graph-${graph4}.graph && + test_path_is_file ${packdir}/graph-${graph1}.graph && + test_path_is_file ${packdir}/graph-head && + echo ${graph4} >expect && + cmp -n 40 expect ${packdir}/graph-head && + git commit-graph --read --graph-hash=${graph4} >output && + _graph_read_expect "23" "${packdir}" && + cmp expect output' + test_expect_success 'clear graph' \ 'git commit-graph --clear && test_path_is_missing ${packdir}/graph-${graph2}.graph && + test_path_is_file ${packdir}/graph-${graph1}.graph && test_path_is_missing ${packdir}/graph-head' test_expect_success 'setup bare repo' \ @@ -121,7 +185,7 @@ test_expect_success 'write graph in bare repo' \ echo ${graphbare} >expect && cmp -n 40 expect ${baredir}/graph-head && git commit-graph --read --graph-hash=${graphbare} >output && - _graph_read_expect "18" "${baredir}" && + _graph_read_expect "23" "${baredir}" && cmp expect output' test_done -- 2.16.0.15.g9c3cf44.dirty