summaryrefslogtreecommitdiff
path: root/merge-recursive.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2009-01-13 01:13:56 -0800
committerJunio C Hamano <gitster@pobox.com>2009-01-13 01:13:56 -0800
commit9e8f6e7f6e8817db30a492e32fa92c1daf51b77c (patch)
tree9bd0d722d8f08422a0141a870a3772a1a8962d62 /merge-recursive.c
parentae5a97fdd0c553926aabdf324b6d9108b0699bee (diff)
parentc5ab03f26c992e30f355fba129f70db0f290fcd7 (diff)
downloadgit-9e8f6e7f6e8817db30a492e32fa92c1daf51b77c.tar.gz
Merge branch 'cb/maint-merge-recursive-fix' into maint
* cb/maint-merge-recursive-fix: merge-recursive: do not clobber untracked working tree garbage modify/delete conflict resolution overwrites untracked file Conflicts: builtin-merge-recursive.c
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;