Skip to content

Commit cff4e91

Browse files
derrickstoleegitster
authored andcommitted
sparse-checkout: check for dirty status
The index-merge performed by 'git sparse-checkout' will erase any staged changes, which can lead to data loss. Prevent these attempts by requiring a clean 'git status' output. Helped-by: Szeder Gábor <[email protected]> Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 416adc8 commit cff4e91

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

builtin/sparse-checkout.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "lockfile.h"
1313
#include "resolve-undo.h"
1414
#include "unpack-trees.h"
15+
#include "wt-status.h"
1516

1617
static const char *empty_base = "";
1718

@@ -256,6 +257,10 @@ static int sparse_checkout_init(int argc, const char **argv)
256257
OPT_END(),
257258
};
258259

260+
repo_read_index(the_repository);
261+
require_clean_work_tree(the_repository,
262+
N_("initialize sparse-checkout"), NULL, 1, 0);
263+
259264
argc = parse_options(argc, argv, NULL,
260265
builtin_sparse_checkout_init_options,
261266
builtin_sparse_checkout_init_usage, 0);
@@ -368,6 +373,10 @@ static int sparse_checkout_set(int argc, const char **argv, const char *prefix)
368373
OPT_END(),
369374
};
370375

376+
repo_read_index(the_repository);
377+
require_clean_work_tree(the_repository,
378+
N_("set sparse-checkout patterns"), NULL, 1, 0);
379+
371380
memset(&pl, 0, sizeof(pl));
372381

373382
argc = parse_options(argc, argv, prefix,
@@ -427,6 +436,10 @@ static int sparse_checkout_disable(int argc, const char **argv)
427436
struct pattern_list pl;
428437
struct strbuf match_all = STRBUF_INIT;
429438

439+
repo_read_index(the_repository);
440+
require_clean_work_tree(the_repository,
441+
N_("disable sparse-checkout"), NULL, 1, 0);
442+
430443
memset(&pl, 0, sizeof(pl));
431444
hashmap_init(&pl.recursive_hashmap, pl_hashmap_cmp, NULL, 0);
432445
hashmap_init(&pl.parent_hashmap, pl_hashmap_cmp, NULL, 0);

t/t1091-sparse-checkout-builtin.sh

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,10 +250,11 @@ test_expect_success 'cone mode: set with nested folders' '
250250
'
251251

252252
test_expect_success 'revert to old sparse-checkout on bad update' '
253+
test_when_finished git -C repo reset --hard &&
253254
echo update >repo/deep/deeper2/a &&
254255
cp repo/.git/info/sparse-checkout expect &&
255256
test_must_fail git -C repo sparse-checkout set deep/deeper1 2>err &&
256-
test_i18ngrep "Cannot update sparse checkout" err &&
257+
test_i18ngrep "cannot set sparse-checkout patterns" err &&
257258
test_cmp repo/.git/info/sparse-checkout expect &&
258259
ls repo/deep >dir &&
259260
cat >expect <<-EOF &&
@@ -291,4 +292,16 @@ test_expect_success '.gitignore should not warn about cone mode' '
291292
test_i18ngrep ! "disabling cone patterns" err
292293
'
293294

295+
test_expect_success 'sparse-checkout (init|set|disable) fails with dirty status' '
296+
git clone repo dirty &&
297+
echo dirty >dirty/folder1/a &&
298+
test_must_fail git -C dirty sparse-checkout init &&
299+
test_must_fail git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* &&
300+
test_must_fail git -C dirty sparse-checkout disable &&
301+
git -C dirty reset --hard &&
302+
git -C dirty sparse-checkout init &&
303+
git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* &&
304+
git -C dirty sparse-checkout disable
305+
'
306+
294307
test_done

0 commit comments

Comments
 (0)