builtin/commit-graph.c: remove subcommand-less usage string
[git] / builtin / commit-graph.c
1 #include "builtin.h"
2 #include "config.h"
3 #include "dir.h"
4 #include "lockfile.h"
5 #include "parse-options.h"
6 #include "repository.h"
7 #include "commit-graph.h"
8 #include "object-store.h"
9
10 static char const * const builtin_commit_graph_usage[] = {
11         N_("git commit-graph read [--object-dir <objdir>]"),
12         N_("git commit-graph verify [--object-dir <objdir>] [--shallow]"),
13         N_("git commit-graph write [--object-dir <objdir>] [--append|--split] [--reachable|--stdin-packs|--stdin-commits] <split options>"),
14         NULL
15 };
16
17 static const char * const builtin_commit_graph_verify_usage[] = {
18         N_("git commit-graph verify [--object-dir <objdir>] [--shallow]"),
19         NULL
20 };
21
22 static const char * const builtin_commit_graph_read_usage[] = {
23         N_("git commit-graph read [--object-dir <objdir>]"),
24         NULL
25 };
26
27 static const char * const builtin_commit_graph_write_usage[] = {
28         N_("git commit-graph write [--object-dir <objdir>] [--append|--split] [--reachable|--stdin-packs|--stdin-commits] <split options>"),
29         NULL
30 };
31
32 static struct opts_commit_graph {
33         const char *obj_dir;
34         int reachable;
35         int stdin_packs;
36         int stdin_commits;
37         int append;
38         int split;
39         int shallow;
40 } opts;
41
42 static int graph_verify(int argc, const char **argv)
43 {
44         struct commit_graph *graph = NULL;
45         char *graph_name;
46         int open_ok;
47         int fd;
48         struct stat st;
49         int flags = 0;
50
51         static struct option builtin_commit_graph_verify_options[] = {
52                 OPT_STRING(0, "object-dir", &opts.obj_dir,
53                            N_("dir"),
54                            N_("The object directory to store the graph")),
55                 OPT_BOOL(0, "shallow", &opts.shallow,
56                          N_("if the commit-graph is split, only verify the tip file")),
57                 OPT_END(),
58         };
59
60         argc = parse_options(argc, argv, NULL,
61                              builtin_commit_graph_verify_options,
62                              builtin_commit_graph_verify_usage, 0);
63
64         if (!opts.obj_dir)
65                 opts.obj_dir = get_object_directory();
66         if (opts.shallow)
67                 flags |= COMMIT_GRAPH_VERIFY_SHALLOW;
68
69         graph_name = get_commit_graph_filename(opts.obj_dir);
70         open_ok = open_commit_graph(graph_name, &fd, &st);
71         if (!open_ok && errno != ENOENT)
72                 die_errno(_("Could not open commit-graph '%s'"), graph_name);
73
74         FREE_AND_NULL(graph_name);
75
76         if (open_ok)
77                 graph = load_commit_graph_one_fd_st(fd, &st);
78          else
79                 graph = read_commit_graph_one(the_repository, opts.obj_dir);
80
81         /* Return failure if open_ok predicted success */
82         if (!graph)
83                 return !!open_ok;
84
85         UNLEAK(graph);
86         return verify_commit_graph(the_repository, graph, flags);
87 }
88
89 static int graph_read(int argc, const char **argv)
90 {
91         struct commit_graph *graph = NULL;
92         char *graph_name;
93         int open_ok;
94         int fd;
95         struct stat st;
96
97         static struct option builtin_commit_graph_read_options[] = {
98                 OPT_STRING(0, "object-dir", &opts.obj_dir,
99                         N_("dir"),
100                         N_("The object directory to store the graph")),
101                 OPT_END(),
102         };
103
104         argc = parse_options(argc, argv, NULL,
105                              builtin_commit_graph_read_options,
106                              builtin_commit_graph_read_usage, 0);
107
108         if (!opts.obj_dir)
109                 opts.obj_dir = get_object_directory();
110
111         graph_name = get_commit_graph_filename(opts.obj_dir);
112
113         open_ok = open_commit_graph(graph_name, &fd, &st);
114         if (!open_ok)
115                 die_errno(_("Could not open commit-graph '%s'"), graph_name);
116
117         graph = load_commit_graph_one_fd_st(fd, &st);
118         if (!graph)
119                 return 1;
120
121         FREE_AND_NULL(graph_name);
122
123         printf("header: %08x %d %d %d %d\n",
124                 ntohl(*(uint32_t*)graph->data),
125                 *(unsigned char*)(graph->data + 4),
126                 *(unsigned char*)(graph->data + 5),
127                 *(unsigned char*)(graph->data + 6),
128                 *(unsigned char*)(graph->data + 7));
129         printf("num_commits: %u\n", graph->num_commits);
130         printf("chunks:");
131
132         if (graph->chunk_oid_fanout)
133                 printf(" oid_fanout");
134         if (graph->chunk_oid_lookup)
135                 printf(" oid_lookup");
136         if (graph->chunk_commit_data)
137                 printf(" commit_metadata");
138         if (graph->chunk_extra_edges)
139                 printf(" extra_edges");
140         printf("\n");
141
142         UNLEAK(graph);
143
144         return 0;
145 }
146
147 extern int read_replace_refs;
148 static struct split_commit_graph_opts split_opts;
149
150 static int graph_write(int argc, const char **argv)
151 {
152         struct string_list *pack_indexes = NULL;
153         struct string_list *commit_hex = NULL;
154         struct string_list lines;
155         int result = 0;
156         unsigned int flags = COMMIT_GRAPH_PROGRESS;
157
158         static struct option builtin_commit_graph_write_options[] = {
159                 OPT_STRING(0, "object-dir", &opts.obj_dir,
160                         N_("dir"),
161                         N_("The object directory to store the graph")),
162                 OPT_BOOL(0, "reachable", &opts.reachable,
163                         N_("start walk at all refs")),
164                 OPT_BOOL(0, "stdin-packs", &opts.stdin_packs,
165                         N_("scan pack-indexes listed by stdin for commits")),
166                 OPT_BOOL(0, "stdin-commits", &opts.stdin_commits,
167                         N_("start walk at commits listed by stdin")),
168                 OPT_BOOL(0, "append", &opts.append,
169                         N_("include all commits already in the commit-graph file")),
170                 OPT_BOOL(0, "split", &opts.split,
171                         N_("allow writing an incremental commit-graph file")),
172                 OPT_INTEGER(0, "max-commits", &split_opts.max_commits,
173                         N_("maximum number of commits in a non-base split commit-graph")),
174                 OPT_INTEGER(0, "size-multiple", &split_opts.size_multiple,
175                         N_("maximum ratio between two levels of a split commit-graph")),
176                 OPT_EXPIRY_DATE(0, "expire-time", &split_opts.expire_time,
177                         N_("maximum number of commits in a non-base split commit-graph")),
178                 OPT_END(),
179         };
180
181         split_opts.size_multiple = 2;
182         split_opts.max_commits = 0;
183         split_opts.expire_time = 0;
184
185         argc = parse_options(argc, argv, NULL,
186                              builtin_commit_graph_write_options,
187                              builtin_commit_graph_write_usage, 0);
188
189         if (opts.reachable + opts.stdin_packs + opts.stdin_commits > 1)
190                 die(_("use at most one of --reachable, --stdin-commits, or --stdin-packs"));
191         if (!opts.obj_dir)
192                 opts.obj_dir = get_object_directory();
193         if (opts.append)
194                 flags |= COMMIT_GRAPH_APPEND;
195         if (opts.split)
196                 flags |= COMMIT_GRAPH_SPLIT;
197
198         read_replace_refs = 0;
199
200         if (opts.reachable) {
201                 if (write_commit_graph_reachable(opts.obj_dir, flags, &split_opts))
202                         return 1;
203                 return 0;
204         }
205
206         string_list_init(&lines, 0);
207         if (opts.stdin_packs || opts.stdin_commits) {
208                 struct strbuf buf = STRBUF_INIT;
209
210                 while (strbuf_getline(&buf, stdin) != EOF)
211                         string_list_append(&lines, strbuf_detach(&buf, NULL));
212
213                 if (opts.stdin_packs)
214                         pack_indexes = &lines;
215                 if (opts.stdin_commits)
216                         commit_hex = &lines;
217
218                 UNLEAK(buf);
219         }
220
221         if (write_commit_graph(opts.obj_dir,
222                                pack_indexes,
223                                commit_hex,
224                                flags,
225                                &split_opts))
226                 result = 1;
227
228         UNLEAK(lines);
229         return result;
230 }
231
232 int cmd_commit_graph(int argc, const char **argv, const char *prefix)
233 {
234         static struct option builtin_commit_graph_options[] = {
235                 OPT_STRING(0, "object-dir", &opts.obj_dir,
236                         N_("dir"),
237                         N_("The object directory to store the graph")),
238                 OPT_END(),
239         };
240
241         if (argc == 2 && !strcmp(argv[1], "-h"))
242                 usage_with_options(builtin_commit_graph_usage,
243                                    builtin_commit_graph_options);
244
245         git_config(git_default_config, NULL);
246         argc = parse_options(argc, argv, prefix,
247                              builtin_commit_graph_options,
248                              builtin_commit_graph_usage,
249                              PARSE_OPT_STOP_AT_NON_OPTION);
250
251         if (argc > 0) {
252                 if (!strcmp(argv[0], "read"))
253                         return graph_read(argc, argv);
254                 if (!strcmp(argv[0], "verify"))
255                         return graph_verify(argc, argv);
256                 if (!strcmp(argv[0], "write"))
257                         return graph_write(argc, argv);
258         }
259
260         usage_with_options(builtin_commit_graph_usage,
261                            builtin_commit_graph_options);
262 }