summaryrefslogtreecommitdiff
path: root/merge-recursive.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2008-12-15 02:41:24 -0800
committerJunio C Hamano <gitster@pobox.com>2008-12-15 02:41:24 -0800
commit60c91181faf33316211970cd2f332b39acb48399 (patch)
tree0fa0c871b1b2d94e6852bcf2aaa247b07dbf99af /merge-recursive.c
parent8befc50c49e8a271fd3cd7fb34258fe88d1dfcad (diff)
parentc5ab03f26c992e30f355fba129f70db0f290fcd7 (diff)
downloadgit-60c91181faf33316211970cd2f332b39acb48399.tar.gz
Merge branch 'cb/maint-merge-recursive-fix' into cb/merge-recursive-fix
* cb/maint-merge-recursive-fix: merge-recursive: do not clobber untracked working tree garbage modify/delete conflict resolution overwrites untracked file
Diffstat (limited to 'merge-recursive.c')
-rw-r--r--merge-recursive.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/merge-recursive.c b/merge-recursive.c
index a0c804c817..2da4333439 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -447,6 +447,30 @@ static void flush_buffer(int fd, const char *buf, unsigned long size)
}
}
+static int would_lose_untracked(const char *path)
+{
+ int pos = cache_name_pos(path, strlen(path));
+
+ if (pos < 0)
+ pos = -1 - pos;
+ while (pos < active_nr &&
+ !strcmp(path, active_cache[pos]->name)) {
+ /*
+ * If stage #0, it is definitely tracked.
+ * If it has stage #2 then it was tracked
+ * before this merge started. All other
+ * cases the path was not tracked.
+ */
+ switch (ce_stage(active_cache[pos])) {
+ case 0:
+ case 2:
+ return 0;
+ }
+ pos++;
+ }
+ return file_exists(path);
+}
+
static int make_room_for_path(const char *path)
{
int status;
@@ -462,6 +486,14 @@ static int make_room_for_path(const char *path)
die(msg, path, "");
}
+ /*
+ * Do not unlink a file in the work tree if we are not
+ * tracking it.
+ */
+ if (would_lose_untracked(path))
+ return error("refusing to lose untracked file at '%s'",
+ path);
+
/* Successful unlink is good.. */
if (!unlink(path))
return 0;