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

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

diff --git a/Documentation/git-graph.txt b/Documentation/git-graph.txt
index ac20aa67a9..f690699570 100644
--- a/Documentation/git-graph.txt
+++ b/Documentation/git-graph.txt
@@ -11,6 +11,7 @@ SYNOPSIS
 [verse]
 'git graph' --write <options> [--pack-dir <pack_dir>]
 'git graph' --read <options> [--pack-dir <pack_dir>]
+'git 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 graph --write --update-head
 $ git graph --read --graph-id=<oid>
 ------------------------------------------------
 
+* Delete <dir>/graph-head and the file it references.
++
+------------------------------------------------
+$ git graph --clear --pack-dir=<dir>
+------------------------------------------------
+
 CONFIGURATION
 -------------
 
diff --git a/builtin/graph.c b/builtin/graph.c
index 0760d99f43..ac15febc46 100644
--- a/builtin/graph.c
+++ b/builtin/graph.c
@@ -10,6 +10,7 @@
 
 static char const * const builtin_graph_usage[] ={
        N_("git graph [--pack-dir <packdir>]"),
+       N_("git graph --clear [--pack-dir <packdir>]"),
        N_("git graph --read [--graph-id=<oid>]"),
        N_("git graph --write [--pack-dir <packdir>] [--update-head]"),
        NULL
@@ -17,6 +18,7 @@ static char const * const builtin_graph_usage[] ={
 
 static struct opts_graph {
        const char *pack_dir;
+       int clear;
        int read;
        const char *graph_id;
        int write;
@@ -25,6 +27,29 @@ static struct opts_graph {
        struct object_id old_graph_oid;
 } 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_graph_filename_oid(opts.pack_dir, &opts.old_graph_oid);
+       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_oid;
@@ -105,6 +130,8 @@ int cmd_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,
@@ -129,7 +156,7 @@ int cmd_graph(int argc, const char **argv, const char 
*prefix)
                             builtin_graph_options,
                             builtin_graph_usage, 0);
 
-       if (opts.write + opts.read > 1)
+       if (opts.write + opts.read + opts.clear > 1)
                usage_with_options(builtin_graph_usage, builtin_graph_options);
 
        if (!opts.pack_dir) {
@@ -141,6 +168,8 @@ int cmd_graph(int argc, const char **argv, const char 
*prefix)
 
        opts.has_existing = !!get_graph_head_oid(opts.pack_dir, 
&opts.old_graph_oid);
 
+       if (opts.clear)
+               return graph_clear();
        if (opts.read)
                return graph_read();
        if (opts.write)
diff --git a/t/t5319-graph.sh b/t/t5319-graph.sh
index 3919a3ad73..311fb9dd67 100755
--- a/t/t5319-graph.sh
+++ b/t/t5319-graph.sh
@@ -80,6 +80,11 @@ test_expect_success 'write graph with merges' \
      _graph_read_expect "18" "${packdir}" &&
      cmp expect output'
 
+test_expect_success 'clear graph' \
+    'git 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 &&
@@ -89,7 +94,7 @@ test_expect_success 'setup bare repo' \
      baredir="./objects/pack"'
 
 test_expect_success 'write graph in bare repo' \
-    'graphbare=$(git graph --write) &&
+    'graphbare=$(git 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

Reply via email to