Skip to content

Commit 416adc8

Browse files
derrickstoleegitster
authored andcommitted
sparse-checkout: update working directory in-process for 'init'
The 'git sparse-checkout init' subcommand previously wrote directly to the sparse-checkout file and then updated the working directory. This may fail if there are modified files not included in the initial pattern set. However, that left a populated sparse-checkout file. Use the in-process working directory update to guarantee that the init subcommand only changes the sparse-checkout file if the working directory update succeeds. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f75a69f commit 416adc8

File tree

1 file changed

+20
-16
lines changed

1 file changed

+20
-16
lines changed

builtin/sparse-checkout.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include "resolve-undo.h"
1414
#include "unpack-trees.h"
1515

16+
static const char *empty_base = "";
17+
1618
static char const * const builtin_sparse_checkout_usage[] = {
1719
N_("git sparse-checkout (init|list|set|disable) <options>"),
1820
NULL
@@ -243,10 +245,10 @@ static int sparse_checkout_init(int argc, const char **argv)
243245
{
244246
struct pattern_list pl;
245247
char *sparse_filename;
246-
FILE *fp;
247248
int res;
248249
struct object_id oid;
249250
int mode;
251+
struct strbuf pattern = STRBUF_INIT;
250252

251253
static struct option builtin_sparse_checkout_init_options[] = {
252254
OPT_BOOL(0, "cone", &init_opts.cone_mode,
@@ -275,26 +277,30 @@ static int sparse_checkout_init(int argc, const char **argv)
275277
/* If we already have a sparse-checkout file, use it. */
276278
if (res >= 0) {
277279
free(sparse_filename);
278-
goto reset_dir;
280+
core_apply_sparse_checkout = 1;
281+
return update_working_directory(NULL);
279282
}
280283

281-
/* initial mode: all blobs at root */
282-
fp = xfopen(sparse_filename, "w");
283-
if (!fp)
284-
die(_("failed to open '%s'"), sparse_filename);
284+
if (get_oid("HEAD", &oid)) {
285+
FILE *fp;
285286

286-
free(sparse_filename);
287-
fprintf(fp, "/*\n!/*/\n");
288-
fclose(fp);
287+
/* assume we are in a fresh repo, but update the sparse-checkout file */
288+
fp = xfopen(sparse_filename, "w");
289+
if (!fp)
290+
die(_("failed to open '%s'"), sparse_filename);
289291

290-
if (get_oid("HEAD", &oid)) {
291-
/* assume we are in a fresh repo */
292+
free(sparse_filename);
293+
fprintf(fp, "/*\n!/*/\n");
294+
fclose(fp);
292295
return 0;
293296
}
294297

295-
reset_dir:
296-
core_apply_sparse_checkout = 1;
297-
return update_working_directory(NULL);
298+
strbuf_addstr(&pattern, "/*");
299+
add_pattern(strbuf_detach(&pattern, NULL), empty_base, 0, &pl, 0);
300+
strbuf_addstr(&pattern, "!/*/");
301+
add_pattern(strbuf_detach(&pattern, NULL), empty_base, 0, &pl, 0);
302+
303+
return write_patterns_and_update(&pl);
298304
}
299305

300306
static void insert_recursive_pattern(struct pattern_list *pl, struct strbuf *path)
@@ -351,7 +357,6 @@ static struct sparse_checkout_set_opts {
351357

352358
static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
353359
{
354-
static const char *empty_base = "";
355360
int i;
356361
struct pattern_list pl;
357362
int result;
@@ -419,7 +424,6 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
419424

420425
static int sparse_checkout_disable(int argc, const char **argv)
421426
{
422-
static const char *empty_base = "";
423427
struct pattern_list pl;
424428
struct strbuf match_all = STRBUF_INIT;
425429

0 commit comments

Comments
 (0)