6
6
#include "repository.h"
7
7
#include "run-command.h"
8
8
#include "strbuf.h"
9
+ #include "string-list.h"
9
10
10
11
static char const * const builtin_sparse_checkout_usage [] = {
11
12
N_ ("git sparse-checkout [init|add|list|disable]" ),
12
13
NULL
13
14
};
14
15
16
+ static const char * const builtin_sparse_checkout_init_usage [] = {
17
+ N_ ("git sparse-checkout init [--cone]" ),
18
+ NULL
19
+ };
20
+
15
21
struct opts_sparse_checkout {
16
22
const char * subcommand ;
17
23
int read_stdin ;
24
+ int cone ;
18
25
} opts ;
19
26
20
27
static char * get_sparse_checkout_filename (void )
@@ -41,6 +48,60 @@ static void write_excludes_to_file(FILE *fp, struct exclude_list *el)
41
48
}
42
49
}
43
50
51
+ static void write_cone_to_file (FILE * fp , struct exclude_list * el )
52
+ {
53
+ int i ;
54
+ struct exclude_entry * entry ;
55
+ struct hashmap_iter iter ;
56
+ struct string_list sl = STRING_LIST_INIT_DUP ;
57
+
58
+ hashmap_iter_init (& el -> parent_hashmap , & iter );
59
+ while ((entry = hashmap_iter_next (& iter ))) {
60
+ char * pattern = xstrdup (entry -> pattern );
61
+ char * converted = pattern ;
62
+ if (pattern [0 ] == '/' )
63
+ converted ++ ;
64
+ if (pattern [entry -> patternlen - 1 ] == '/' )
65
+ pattern [entry -> patternlen - 1 ] = 0 ;
66
+ string_list_insert (& sl , converted );
67
+ free (pattern );
68
+ }
69
+
70
+ string_list_sort (& sl );
71
+ string_list_remove_duplicates (& sl , 0 );
72
+
73
+ for (i = 0 ; i < sl .nr ; i ++ ) {
74
+ char * pattern = sl .items [i ].string ;
75
+
76
+ if (!strcmp (pattern , "" ))
77
+ fprintf (fp , "/*\n!/*/*\n" );
78
+ else
79
+ fprintf (fp , "/%s/*\n!/%s/*/*\n" , pattern , pattern );
80
+ }
81
+
82
+ string_list_clear (& sl , 0 );
83
+
84
+ hashmap_iter_init (& el -> recursive_hashmap , & iter );
85
+ while ((entry = hashmap_iter_next (& iter ))) {
86
+ char * pattern = xstrdup (entry -> pattern );
87
+ char * converted = pattern ;
88
+ if (pattern [0 ] == '/' )
89
+ converted ++ ;
90
+ if (pattern [entry -> patternlen - 1 ] == '/' )
91
+ pattern [entry -> patternlen - 1 ] = 0 ;
92
+ string_list_insert (& sl , converted );
93
+ free (pattern );
94
+ }
95
+
96
+ string_list_sort (& sl );
97
+ string_list_remove_duplicates (& sl , 0 );
98
+
99
+ for (i = 0 ; i < sl .nr ; i ++ ) {
100
+ char * pattern = sl .items [i ].string ;
101
+ fprintf (fp , "/%s/*\n" , pattern );
102
+ }
103
+ }
104
+
44
105
static int sparse_checkout_list (int argc , const char * * argv )
45
106
{
46
107
struct exclude_list el ;
@@ -141,8 +202,21 @@ static int sparse_checkout_init(int argc, const char **argv)
141
202
char * sparse_filename ;
142
203
FILE * fp ;
143
204
int res ;
205
+ enum sparse_checkout_mode mode ;
144
206
145
- if (sc_set_config (SPARSE_CHECKOUT_FULL ))
207
+ static struct option builtin_sparse_checkout_init_options [] = {
208
+ OPT_BOOL (0 , "cone" , & opts .cone ,
209
+ N_ ("initialize the sparse-checkout in cone mode" )),
210
+ OPT_END (),
211
+ };
212
+
213
+ argc = parse_options (argc , argv , NULL ,
214
+ builtin_sparse_checkout_init_options ,
215
+ builtin_sparse_checkout_init_usage , 0 );
216
+
217
+ mode = opts .cone ? SPARSE_CHECKOUT_CONE : SPARSE_CHECKOUT_FULL ;
218
+
219
+ if (sc_set_config (mode ))
146
220
return 1 ;
147
221
148
222
memset (& el , 0 , sizeof (el ));
@@ -183,6 +257,34 @@ static int sparse_checkout_init(int argc, const char **argv)
183
257
return sc_read_tree ();
184
258
}
185
259
260
+ static void insert_recursive_pattern (struct exclude_list * el , struct strbuf * path )
261
+ {
262
+ struct exclude_entry * e = xmalloc (sizeof (struct exclude_entry ));
263
+ e -> patternlen = path -> len ;
264
+ e -> pattern = strbuf_detach (path , NULL );
265
+ hashmap_entry_init (e , memhash (e -> pattern , e -> patternlen ));
266
+
267
+ hashmap_add (& el -> recursive_hashmap , e );
268
+
269
+ while (e -> patternlen ) {
270
+ char * slash = strrchr (e -> pattern , '/' );
271
+ char * oldpattern = e -> pattern ;
272
+ size_t newlen ;
273
+
274
+ if (!slash )
275
+ break ;
276
+
277
+ newlen = slash - e -> pattern ;
278
+ e = xmalloc (sizeof (struct exclude_entry ));
279
+ e -> patternlen = newlen ;
280
+ e -> pattern = xstrndup (oldpattern , newlen );
281
+ hashmap_entry_init (e , memhash (e -> pattern , e -> patternlen ));
282
+
283
+ if (!hashmap_get (& el -> parent_hashmap , e , NULL ))
284
+ hashmap_add (& el -> parent_hashmap , e );
285
+ }
286
+ }
287
+
186
288
static int sparse_checkout_add (int argc , const char * * argv )
187
289
{
188
290
struct exclude_list el ;
@@ -196,11 +298,33 @@ static int sparse_checkout_add(int argc, const char **argv)
196
298
add_excludes_from_file_to_list (sparse_filename , "" , 0 , & el , NULL );
197
299
198
300
fp = fopen (sparse_filename , "w" );
199
- write_excludes_to_file (fp , & el );
200
301
201
- while (!strbuf_getline (& line , stdin )) {
202
- strbuf_trim (& line );
203
- fprintf (fp , "%s\n" , line .buf );
302
+ if (core_sparse_checkout == SPARSE_CHECKOUT_FULL ) {
303
+ write_excludes_to_file (fp , & el );
304
+
305
+ while (!strbuf_getline (& line , stdin )) {
306
+ strbuf_trim (& line );
307
+ fprintf (fp , "%s\n" , line .buf );
308
+ }
309
+ } else if (core_sparse_checkout == SPARSE_CHECKOUT_CONE ) {
310
+ while (!strbuf_getline (& line , stdin )) {
311
+ strbuf_trim (& line );
312
+
313
+ strbuf_trim_trailing_dir_sep (& line );
314
+
315
+ if (!line .len )
316
+ continue ;
317
+
318
+ if (line .buf [0 ] == '/' )
319
+ strbuf_remove (& line , 0 , 1 );
320
+
321
+ if (!line .len )
322
+ continue ;
323
+
324
+ insert_recursive_pattern (& el , & line );
325
+ }
326
+
327
+ write_cone_to_file (fp , & el );
204
328
}
205
329
206
330
fclose (fp );
0 commit comments