Teach Git to delete the current 'graph_head' file and the commit graph
it references. This is a good safety valve if somehow the file is
corrupted and needs to be recalculated. Since the commit graph is a
summary of contents already in the ODB, it can be regenerated.

Signed-off-by: Derrick Stolee <dsto...@microsoft.com>
---
 Documentation/git-commit-graph.txt | 16 ++++++++++++++--
 builtin/commit-graph.c             | 32 +++++++++++++++++++++++++++++++-
 t/t5318-commit-graph.sh            |  7 ++++++-
 3 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-commit-graph.txt 
b/Documentation/git-commit-graph.txt
index 99ced16ddc..33d6567f11 100644
--- a/Documentation/git-commit-graph.txt
+++ b/Documentation/git-commit-graph.txt
@@ -11,6 +11,7 @@ SYNOPSIS
 [verse]
 'git commit-graph' --write <options> [--pack-dir <pack_dir>]
 'git commit-graph' --read <options> [--pack-dir <pack_dir>]
+'git commit-graph' --clear [--pack-dir <pack_dir>]
 
 OPTIONS
 -------
@@ -18,16 +19,21 @@ OPTIONS
        Use given directory for the location of packfiles, graph-head,
        and graph files.
 
+--clear::
+       Delete the graph-head file and the graph file it references.
+       (Cannot be combined with --read or --write.)
+
 --read::
        Read a graph file given by the graph-head file and output basic
-       details about the graph file. (Cannot be combined with --write.)
+       details about the graph file. (Cannot be combined with --clear
+       or --write.)
 
 --graph-id::
        When used with --read, consider the graph file graph-<oid>.graph.
 
 --write::
        Write a new graph file to the pack directory. (Cannot be combined
-       with --read.)
+       with --clear or --read.)
 
 --update-head::
        When used with --write, update the graph-head file to point to
@@ -61,6 +67,12 @@ $ git commit-graph --write --update-head
 $ git commit-graph --read --graph-hash=<hash>
 ------------------------------------------------
 
+* Delete <dir>/graph-head and the file it references.
++
+------------------------------------------------
+$ git commit-graph --clear --pack-dir=<dir>
+------------------------------------------------
+
 GIT
 ---
 Part of the linkgit:git[1] suite
diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c
index d73cbc907d..4970dec133 100644
--- a/builtin/commit-graph.c
+++ b/builtin/commit-graph.c
@@ -10,6 +10,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]"),
        NULL
@@ -17,6 +18,7 @@ static char const * const builtin_commit_graph_usage[] = {
 
 static struct opts_commit_graph {
        const char *pack_dir;
+       int clear;
        int read;
        const char *graph_hash;
        int write;
@@ -25,6 +27,30 @@ static struct opts_commit_graph {
        struct object_id old_graph_hash;
 } opts;
 
+static int graph_clear(void)
+{
+       struct strbuf head_path = STRBUF_INIT;
+       char *old_path;
+
+       if (!opts.has_existing)
+               return 0;
+
+       strbuf_addstr(&head_path, opts.pack_dir);
+       strbuf_addstr(&head_path, "/");
+       strbuf_addstr(&head_path, "graph-head");
+       if (remove_path(head_path.buf))
+               die("failed to remove path %s", head_path.buf);
+       strbuf_release(&head_path);
+
+       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);
+
+       return 0;
+}
+
 static int graph_read(void)
 {
        struct object_id graph_hash;
@@ -105,6 +131,8 @@ int cmd_commit_graph(int argc, const char **argv, const 
char *prefix)
                { OPTION_STRING, 'p', "pack-dir", &opts.pack_dir,
                        N_("dir"),
                        N_("The pack directory to store the graph") },
+               OPT_BOOL('c', "clear", &opts.clear,
+                       N_("clear graph file and graph-head")),
                OPT_BOOL('r', "read", &opts.read,
                        N_("read graph file")),
                OPT_BOOL('w', "write", &opts.write,
@@ -126,7 +154,7 @@ int cmd_commit_graph(int argc, const char **argv, const 
char *prefix)
                             builtin_commit_graph_options,
                             builtin_commit_graph_usage, 0);
 
-       if (opts.write + opts.read > 1)
+       if (opts.write + opts.read + opts.clear > 1)
                usage_with_options(builtin_commit_graph_usage,
                                   builtin_commit_graph_options);
 
@@ -139,6 +167,8 @@ int cmd_commit_graph(int argc, const char **argv, const 
char *prefix)
 
        opts.has_existing = !!get_graph_head_hash(opts.pack_dir, 
&opts.old_graph_hash);
 
+       if (opts.clear)
+               return graph_clear();
        if (opts.read)
                return graph_read();
        if (opts.write)
diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh
index d1a23bcdaf..6e3b62b754 100755
--- a/t/t5318-commit-graph.sh
+++ b/t/t5318-commit-graph.sh
@@ -101,6 +101,11 @@ test_expect_success 'write graph with merges' \
      _graph_read_expect "18" "${packdir}" &&
      cmp expect output'
 
+test_expect_success 'clear graph' \
+    'git commit-graph --clear &&
+     test_path_is_missing ${packdir}/graph-${graph2}.graph &&
+     test_path_is_missing ${packdir}/graph-head'
+
 test_expect_success 'setup bare repo' \
     'cd .. &&
      git clone --bare full bare &&
@@ -110,7 +115,7 @@ test_expect_success 'setup bare repo' \
      baredir="./objects/pack"'
 
 test_expect_success 'write graph in bare repo' \
-    'graphbare=$(git commit-graph --write) &&
+    'graphbare=$(git commit-graph --write --update-head) &&
      test_path_is_file ${baredir}/graph-${graphbare}.graph &&
      test_path_is_file ${baredir}/graph-head &&
      echo ${graphbare} >expect &&
-- 
2.16.0.15.g9c3cf44.dirty

Reply via email to