advice.h: add advise_on_moving_dirty_path()

Add an advice. When the user use `git mv --sparse <dirty-path> <destination>`, Git will warn the user to use `git add --sparse <paths>` then use `git sparse-checkout reapply` to apply the sparsity rules. Add a few lines to previous "move dirty path" tests so we can test this new advice is working. Suggested-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Shaoxuan Yuan <shaoxuan.yuan02@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Shaoxuan Yuan committed Aug 9, 2022 at 20:09 UTC 5efd533ed8896592740afe22ac07271497d6db36
4 files changed +46 -1
advice.c
+19
@@ -261,3 +261,22 @@ void detach_advice(const char *new_name)
261
262 fprintf(stderr, fmt, new_name);
263 }
264 +
265 +void advise_on_moving_dirty_path(struct string_list *pathspec_list)
266 +{
267 + struct string_list_item *item;
268 +
269 + if (!pathspec_list->nr)
270 + return;
271 +
272 + fprintf(stderr, _("The following paths have been moved outside the\n"
273 + "sparse-checkout definition but are not sparse due to local\n"
274 + "modifications.\n"));
275 + for_each_string_list_item(item, pathspec_list)
276 + fprintf(stderr, "%s\n", item->string);
277 +
278 + advise_if_enabled(ADVICE_UPDATE_SPARSE_PATH,
279 + _("To correct the sparsity of these paths, do the following:\n"
280 + "* Use \"git add --sparse <paths>\" to update the index\n"
281 + "* Use \"git sparse-checkout reapply\" to apply the sparsity rules"));
282 +}
advice.h
+1
@@ -74,5 +74,6 @@ void NORETURN die_conclude_merge(void);
74 void NORETURN die_ff_impossible(void);
75 void advise_on_updating_sparse_paths(struct string_list *pathspec_list);
76 void detach_advice(const char *new_name);
77 +void advise_on_moving_dirty_path(struct string_list *pathspec_list);
78
79 #endif /* ADVICE_H */
builtin/mv.c
+3
@@ -532,6 +532,9 @@ remove_entry:
532 strbuf_release(&a_src_dir);
533 free(src_dir);
534
535 + if (dirty_paths.nr)
536 + advise_on_moving_dirty_path(&dirty_paths);
537 +
538 if (gitmodules_modified)
539 stage_updated_gitmodules(&the_index);
540
t/t7002-mv-sparse-checkout.sh
+23 -1
@@ -28,12 +28,25 @@ test_expect_success 'setup' "
28 updated in the index:
29 EOF
30
31 - cat >sparse_hint <<-EOF
31 + cat >sparse_hint <<-EOF &&
32 hint: If you intend to update such entries, try one of the following:
33 hint: * Use the --sparse option.
34 hint: * Disable or modify the sparsity rules.
35 hint: Disable this message with \"git config advice.updateSparsePath false\"
36 EOF
37 +
38 + cat >dirty_error_header <<-EOF &&
39 + The following paths have been moved outside the
40 + sparse-checkout definition but are not sparse due to local
41 + modifications.
42 + EOF
43 +
44 + cat >dirty_hint <<-EOF
45 + hint: To correct the sparsity of these paths, do the following:
46 + hint: * Use \"git add --sparse <paths>\" to update the index
47 + hint: * Use \"git sparse-checkout reapply\" to apply the sparsity rules
48 + hint: Disable this message with \"git config advice.updateSparsePath false\"
49 + EOF
50 "
51
52 test_expect_success 'mv refuses to move sparse-to-sparse' '
@@ -431,6 +444,10 @@ test_expect_success 'move dirty path from in-cone to out-of-cone' '
444 test_cmp expect stderr &&
445
446 git mv --sparse sub/d folder1 2>stderr &&
447 + cat dirty_error_header >expect &&
448 + echo "folder1/d" >>expect &&
449 + cat dirty_hint >>expect &&
450 + test_cmp expect stderr &&
451
452 test_path_is_missing sub/d &&
453 test_path_is_file folder1/d &&
@@ -478,6 +495,11 @@ test_expect_success 'move partially-dirty dir from in-cone to out-of-cone' '
495 test_cmp expect stderr &&
496
497 git mv --sparse sub/dir folder1 2>stderr &&
498 + cat dirty_error_header >expect &&
499 + echo "folder1/dir/e2" >>expect &&
500 + echo "folder1/dir/e3" >>expect &&
501 + cat dirty_hint >>expect &&
502 + test_cmp expect stderr &&
503
504 test_path_is_missing sub/dir &&
505 test_path_is_missing folder1/dir/e &&