@matheusbsbs / matheus-bagliano / commits / c5ab03f26c
Fork 0

merge-recursive: do not clobber untracked working tree garbage

When merge-recursive wanted to create a new file in the work tree (either as the final result, or a hint for reference purposes while delete/modify conflicts), it unconditionally overwrote an untracked file in the working tree. Be careful not to lose whatever the user has that is not tracked. Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Dec 14, 2008 at 19:40 UTC c5ab03f26c992e30f355fba129f70db0f290fcd7
2 files changed +33 -1
builtin-merge-recursive.c
+32
@@ -471,6 +471,30 @@ static void flush_buffer(int fd, const char *buf, unsigned long size)
471 }
472 }
473
474 +static int would_lose_untracked(const char *path)
475 +{
476 + int pos = cache_name_pos(path, strlen(path));
477 +
478 + if (pos < 0)
479 + pos = -1 - pos;
480 + while (pos < active_nr &&
481 + !strcmp(path, active_cache[pos]->name)) {
482 + /*
483 + * If stage #0, it is definitely tracked.
484 + * If it has stage #2 then it was tracked
485 + * before this merge started. All other
486 + * cases the path was not tracked.
487 + */
488 + switch (ce_stage(active_cache[pos])) {
489 + case 0:
490 + case 2:
491 + return 0;
492 + }
493 + pos++;
494 + }
495 + return file_exists(path);
496 +}
497 +
498 static int make_room_for_path(const char *path)
499 {
500 int status;
@@ -486,6 +510,14 @@ static int make_room_for_path(const char *path)
510 die(msg, path, "");
511 }
512
513 + /*
514 + * Do not unlink a file in the work tree if we are not
515 + * tracking it.
516 + */
517 + if (would_lose_untracked(path))
518 + return error("refusing to lose untracked file at '%s'",
519 + path);
520 +
521 /* Successful unlink is good.. */
522 if (!unlink(path))
523 return 0;
t/t7607-merge-overwrite.sh
+1 -1
@@ -53,7 +53,7 @@ test_expect_success 'will not overwrite staged changes' '
53 test_cmp important c2.c
54 '
55
56 -test_expect_failure 'will not overwrite removed file' '
56 +test_expect_success 'will not overwrite removed file' '
57 git reset --hard c1 &&
58 git rm c1.c &&
59 git commit -m "rm c1.c" &&