mv: check if <destination> exists in index to handle overwriting

Originally, moving a sparse file into cone can result in unwarned overwrite of existing entry. The expected behavior is that if the <destination> exists in the entry, user should be prompted to supply a [-f|--force] to carry out the operation, or the operation should fail. Add a check mechanism to do that. Signed-off-by: Shaoxuan Yuan <shaoxuan.yuan02@gmail.com> Acked-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Shaoxuan Yuan committed Jun 30, 2022 at 10:37 UTC 8a26a3915fbe1aab9786b28c535c8541f8df2a19
2 files changed +14 -5
builtin/mv.c
+12 -3
@@ -202,11 +202,20 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
202 bad = _("bad source");
203 goto act_on_entry;
204 }
205 -
206 - if (!ignore_sparse)
205 + if (!ignore_sparse) {
206 string_list_append(&only_match_skip_worktree, src);
208 - else
207 + goto act_on_entry;
208 + }
209 + /* Check if dst exists in index */
210 + if (cache_name_pos(dst, strlen(dst)) < 0) {
211 modes[i] = SPARSE;
212 + goto act_on_entry;
213 + }
214 + if (!force) {
215 + bad = _("destination exists");
216 + goto act_on_entry;
217 + }
218 + modes[i] = SPARSE;
219 goto act_on_entry;
220 }
221 if (!strncmp(src, dst, length) &&
t/t7002-mv-sparse-checkout.sh
+2 -2
@@ -262,7 +262,7 @@ test_expect_success 'can move out-of-cone file with --sparse' '
262 test_path_is_file sub/file1
263 '
264
265 -test_expect_failure 'refuse to move sparse file to existing destination' '
265 +test_expect_success 'refuse to move sparse file to existing destination' '
266 test_when_finished "cleanup_sparse_checkout" &&
267 mkdir folder1 &&
268 touch folder1/file1 &&
@@ -275,7 +275,7 @@ test_expect_failure 'refuse to move sparse file to existing destination' '
275 test_cmp expect stderr
276 '
277
278 -test_expect_failure 'move sparse file to existing destination with --force and --sparse' '
278 +test_expect_success 'move sparse file to existing destination with --force and --sparse' '
279 test_when_finished "cleanup_sparse_checkout" &&
280 mkdir folder1 &&
281 touch folder1/file1 &&