commit-graph: implement git-commit-graph write

Teach git-commit-graph to write graph files. Create new test script to verify this command succeeds without failure. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Derrick Stolee committed Apr 2, 2018 at 16:34 UTC f237c8b6feaa3bad352bd27c14f0d83d0a1c061a
3 files changed +198
Documentation/git-commit-graph.txt
+41
@@ -5,6 +5,47 @@ NAME
5 ----
6 git-commit-graph - Write and verify Git commit graph files
7
8 +
9 +SYNOPSIS
10 +--------
11 +[verse]
12 +'git commit-graph write' <options> [--object-dir <dir>]
13 +
14 +
15 +DESCRIPTION
16 +-----------
17 +
18 +Manage the serialized commit graph file.
19 +
20 +
21 +OPTIONS
22 +-------
23 +--object-dir::
24 + Use given directory for the location of packfiles and commit graph
25 + file. This parameter exists to specify the location of an alternate
26 + that only has the objects directory, not a full .git directory. The
27 + commit graph file is expected to be at <dir>/info/commit-graph and
28 + the packfiles are expected to be in <dir>/pack.
29 +
30 +
31 +COMMANDS
32 +--------
33 +'write'::
34 +
35 +Write a commit graph file based on the commits found in packfiles.
36 +Includes all commits from the existing commit graph file.
37 +
38 +
39 +EXAMPLES
40 +--------
41 +
42 +* Write a commit graph file for the packed commits in your local .git folder.
43 ++
44 +------------------------------------------------
45 +$ git commit-graph write
46 +------------------------------------------------
47 +
48 +
49 GIT
50 ---
51 Part of the linkgit:git[1] suite
builtin/commit-graph.c
+33
@@ -1,9 +1,18 @@
1 #include "builtin.h"
2 #include "config.h"
3 +#include "dir.h"
4 +#include "lockfile.h"
5 #include "parse-options.h"
6 +#include "commit-graph.h"
7
8 static char const * const builtin_commit_graph_usage[] = {
9 N_("git commit-graph [--object-dir <objdir>]"),
10 + N_("git commit-graph write [--object-dir <objdir>]"),
11 + NULL
12 +};
13 +
14 +static const char * const builtin_commit_graph_write_usage[] = {
15 + N_("git commit-graph write [--object-dir <objdir>]"),
16 NULL
17 };
18
@@ -11,6 +20,25 @@ static struct opts_commit_graph {
20 const char *obj_dir;
21 } opts;
22
23 +static int graph_write(int argc, const char **argv)
24 +{
25 + static struct option builtin_commit_graph_write_options[] = {
26 + OPT_STRING(0, "object-dir", &opts.obj_dir,
27 + N_("dir"),
28 + N_("The object directory to store the graph")),
29 + OPT_END(),
30 + };
31 +
32 + argc = parse_options(argc, argv, NULL,
33 + builtin_commit_graph_write_options,
34 + builtin_commit_graph_write_usage, 0);
35 +
36 + if (!opts.obj_dir)
37 + opts.obj_dir = get_object_directory();
38 +
39 + write_commit_graph(opts.obj_dir);
40 + return 0;
41 +}
42
43 int cmd_commit_graph(int argc, const char **argv, const char *prefix)
44 {
@@ -31,6 +59,11 @@ int cmd_commit_graph(int argc, const char **argv, const char *prefix)
59 builtin_commit_graph_usage,
60 PARSE_OPT_STOP_AT_NON_OPTION);
61
62 + if (argc > 0) {
63 + if (!strcmp(argv[0], "write"))
64 + return graph_write(argc, argv);
65 + }
66 +
67 usage_with_options(builtin_commit_graph_usage,
68 builtin_commit_graph_options);
69 }
t/t5318-commit-graph.sh new
+124
@@ -0,0 +1,124 @@
1 +#!/bin/sh
2 +
3 +test_description='commit graph'
4 +. ./test-lib.sh
5 +
6 +test_expect_success 'setup full repo' '
7 + mkdir full &&
8 + cd "$TRASH_DIRECTORY/full" &&
9 + git init &&
10 + objdir=".git/objects"
11 +'
12 +
13 +test_expect_success 'write graph with no packs' '
14 + cd "$TRASH_DIRECTORY/full" &&
15 + git commit-graph write --object-dir . &&
16 + test_path_is_file info/commit-graph
17 +'
18 +
19 +test_expect_success 'create commits and repack' '
20 + cd "$TRASH_DIRECTORY/full" &&
21 + for i in $(test_seq 3)
22 + do
23 + test_commit $i &&
24 + git branch commits/$i
25 + done &&
26 + git repack
27 +'
28 +
29 +test_expect_success 'write graph' '
30 + cd "$TRASH_DIRECTORY/full" &&
31 + graph1=$(git commit-graph write) &&
32 + test_path_is_file $objdir/info/commit-graph
33 +'
34 +
35 +test_expect_success 'Add more commits' '
36 + cd "$TRASH_DIRECTORY/full" &&
37 + git reset --hard commits/1 &&
38 + for i in $(test_seq 4 5)
39 + do
40 + test_commit $i &&
41 + git branch commits/$i
42 + done &&
43 + git reset --hard commits/2 &&
44 + for i in $(test_seq 6 7)
45 + do
46 + test_commit $i &&
47 + git branch commits/$i
48 + done &&
49 + git reset --hard commits/2 &&
50 + git merge commits/4 &&
51 + git branch merge/1 &&
52 + git reset --hard commits/4 &&
53 + git merge commits/6 &&
54 + git branch merge/2 &&
55 + git reset --hard commits/3 &&
56 + git merge commits/5 commits/7 &&
57 + git branch merge/3 &&
58 + git repack
59 +'
60 +
61 +# Current graph structure:
62 +#
63 +# __M3___
64 +# / | \
65 +# 3 M1 5 M2 7
66 +# |/ \|/ \|
67 +# 2 4 6
68 +# |___/____/
69 +# 1
70 +
71 +
72 +test_expect_success 'write graph with merges' '
73 + cd "$TRASH_DIRECTORY/full" &&
74 + git commit-graph write &&
75 + test_path_is_file $objdir/info/commit-graph
76 +'
77 +
78 +test_expect_success 'Add one more commit' '
79 + cd "$TRASH_DIRECTORY/full" &&
80 + test_commit 8 &&
81 + git branch commits/8 &&
82 + ls $objdir/pack | grep idx >existing-idx &&
83 + git repack &&
84 + ls $objdir/pack| grep idx | grep -v --file=existing-idx >new-idx
85 +'
86 +
87 +# Current graph structure:
88 +#
89 +# 8
90 +# |
91 +# __M3___
92 +# / | \
93 +# 3 M1 5 M2 7
94 +# |/ \|/ \|
95 +# 2 4 6
96 +# |___/____/
97 +# 1
98 +
99 +test_expect_success 'write graph with new commit' '
100 + cd "$TRASH_DIRECTORY/full" &&
101 + git commit-graph write &&
102 + test_path_is_file $objdir/info/commit-graph
103 +'
104 +
105 +test_expect_success 'write graph with nothing new' '
106 + cd "$TRASH_DIRECTORY/full" &&
107 + git commit-graph write &&
108 + test_path_is_file $objdir/info/commit-graph
109 +'
110 +
111 +test_expect_success 'setup bare repo' '
112 + cd "$TRASH_DIRECTORY" &&
113 + git clone --bare --no-local full bare &&
114 + cd bare &&
115 + baredir="./objects"
116 +'
117 +
118 +test_expect_success 'write graph in bare repo' '
119 + cd "$TRASH_DIRECTORY/bare" &&
120 + git commit-graph write &&
121 + test_path_is_file $baredir/info/commit-graph
122 +'
123 +
124 +test_done