33#include "dir.h"
44#include "lockfile.h"
55#include "parse-options.h"
6+ #include "repository.h"
67#include "commit-graph.h"
78
89static char const * const builtin_commit_graph_usage [] = {
910 N_ ("git commit-graph [--object-dir <objdir>]" ),
1011 N_ ("git commit-graph read [--object-dir <objdir>]" ),
11- N_ ("git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--stdin-commits]" ),
12+ N_ ("git commit-graph verify [--object-dir <objdir>]" ),
13+ N_ ("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|--stdin-packs|--stdin-commits]" ),
14+ NULL
15+ };
16+
17+ static const char * const builtin_commit_graph_verify_usage [] = {
18+ N_ ("git commit-graph verify [--object-dir <objdir>]" ),
1219 NULL
1320};
1421
@@ -18,17 +25,48 @@ static const char * const builtin_commit_graph_read_usage[] = {
1825};
1926
2027static const char * const builtin_commit_graph_write_usage [] = {
21- N_ ("git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--stdin-commits]" ),
28+ N_ ("git commit-graph write [--object-dir <objdir>] [--append] [--reachable|-- stdin-packs|--stdin-commits]" ),
2229 NULL
2330};
2431
2532static struct opts_commit_graph {
2633 const char * obj_dir ;
34+ int reachable ;
2735 int stdin_packs ;
2836 int stdin_commits ;
2937 int append ;
3038} opts ;
3139
40+
41+ static int graph_verify (int argc , const char * * argv )
42+ {
43+ struct commit_graph * graph = NULL ;
44+ char * graph_name ;
45+
46+ static struct option builtin_commit_graph_verify_options [] = {
47+ OPT_STRING (0 , "object-dir" , & opts .obj_dir ,
48+ N_ ("dir" ),
49+ N_ ("The object directory to store the graph" )),
50+ OPT_END (),
51+ };
52+
53+ argc = parse_options (argc , argv , NULL ,
54+ builtin_commit_graph_verify_options ,
55+ builtin_commit_graph_verify_usage , 0 );
56+
57+ if (!opts .obj_dir )
58+ opts .obj_dir = get_object_directory ();
59+
60+ graph_name = get_commit_graph_filename (opts .obj_dir );
61+ graph = load_commit_graph_one (graph_name );
62+ FREE_AND_NULL (graph_name );
63+
64+ if (!graph )
65+ return 0 ;
66+
67+ return verify_commit_graph (the_repository , graph );
68+ }
69+
3270static int graph_read (int argc , const char * * argv )
3371{
3472 struct commit_graph * graph = NULL ;
@@ -51,8 +89,11 @@ static int graph_read(int argc, const char **argv)
5189 graph_name = get_commit_graph_filename (opts .obj_dir );
5290 graph = load_commit_graph_one (graph_name );
5391
54- if (!graph )
92+ if (!graph ) {
93+ UNLEAK (graph_name );
5594 die ("graph file %s does not exist" , graph_name );
95+ }
96+
5697 FREE_AND_NULL (graph_name );
5798
5899 printf ("header: %08x %d %d %d %d\n" ,
@@ -79,18 +120,16 @@ static int graph_read(int argc, const char **argv)
79120
80121static int graph_write (int argc , const char * * argv )
81122{
82- const char * * pack_indexes = NULL ;
83- int packs_nr = 0 ;
84- const char * * commit_hex = NULL ;
85- int commits_nr = 0 ;
86- const char * * lines = NULL ;
87- int lines_nr = 0 ;
88- int lines_alloc = 0 ;
123+ struct string_list * pack_indexes = NULL ;
124+ struct string_list * commit_hex = NULL ;
125+ struct string_list lines ;
89126
90127 static struct option builtin_commit_graph_write_options [] = {
91128 OPT_STRING (0 , "object-dir" , & opts .obj_dir ,
92129 N_ ("dir" ),
93130 N_ ("The object directory to store the graph" )),
131+ OPT_BOOL (0 , "reachable" , & opts .reachable ,
132+ N_ ("start walk at all refs" )),
94133 OPT_BOOL (0 , "stdin-packs" , & opts .stdin_packs ,
95134 N_ ("scan pack-indexes listed by stdin for commits" )),
96135 OPT_BOOL (0 , "stdin-commits" , & opts .stdin_commits ,
@@ -104,39 +143,35 @@ static int graph_write(int argc, const char **argv)
104143 builtin_commit_graph_write_options ,
105144 builtin_commit_graph_write_usage , 0 );
106145
107- if (opts .stdin_packs && opts .stdin_commits )
108- die (_ ("cannot use both -- stdin-commits and --stdin-packs" ));
146+ if (opts .reachable + opts . stdin_packs + opts .stdin_commits > 1 )
147+ die (_ ("use at most one of --reachable, -- stdin-commits, or --stdin-packs" ));
109148 if (!opts .obj_dir )
110149 opts .obj_dir = get_object_directory ();
111150
151+ if (opts .reachable ) {
152+ write_commit_graph_reachable (opts .obj_dir , opts .append );
153+ return 0 ;
154+ }
155+
156+ string_list_init (& lines , 0 );
112157 if (opts .stdin_packs || opts .stdin_commits ) {
113158 struct strbuf buf = STRBUF_INIT ;
114- lines_nr = 0 ;
115- lines_alloc = 128 ;
116- ALLOC_ARRAY (lines , lines_alloc );
117-
118- while (strbuf_getline (& buf , stdin ) != EOF ) {
119- ALLOC_GROW (lines , lines_nr + 1 , lines_alloc );
120- lines [lines_nr ++ ] = strbuf_detach (& buf , NULL );
121- }
122-
123- if (opts .stdin_packs ) {
124- pack_indexes = lines ;
125- packs_nr = lines_nr ;
126- }
127- if (opts .stdin_commits ) {
128- commit_hex = lines ;
129- commits_nr = lines_nr ;
130- }
159+
160+ while (strbuf_getline (& buf , stdin ) != EOF )
161+ string_list_append (& lines , strbuf_detach (& buf , NULL ));
162+
163+ if (opts .stdin_packs )
164+ pack_indexes = & lines ;
165+ if (opts .stdin_commits )
166+ commit_hex = & lines ;
131167 }
132168
133169 write_commit_graph (opts .obj_dir ,
134170 pack_indexes ,
135- packs_nr ,
136171 commit_hex ,
137- commits_nr ,
138172 opts .append );
139173
174+ string_list_clear (& lines , 0 );
140175 return 0 ;
141176}
142177
@@ -162,6 +197,8 @@ int cmd_commit_graph(int argc, const char **argv, const char *prefix)
162197 if (argc > 0 ) {
163198 if (!strcmp (argv [0 ], "read" ))
164199 return graph_read (argc , argv );
200+ if (!strcmp (argv [0 ], "verify" ))
201+ return graph_verify (argc , argv );
165202 if (!strcmp (argv [0 ], "write" ))
166203 return graph_write (argc , argv );
167204 }
0 commit comments