summaryrefslogtreecommitdiff
path: root/merge-recursive.c
diff options
context:
space:
mode:
authorJunio C Hamano <junkio@cox.net>2007-04-07 13:41:13 (GMT)
committerJunio C Hamano <junkio@cox.net>2007-04-10 19:55:51 (GMT)
commit4d50895a390658bf1b9a9385dbc0b9f90b48c803 (patch)
tree78c791b9717cd240d7c900b77ad572c62b637526 /merge-recursive.c
parentac7f0f436e4f45d616ca509f5163fddab104516b (diff)
downloadgit-4d50895a390658bf1b9a9385dbc0b9f90b48c803.zip
git-4d50895a390658bf1b9a9385dbc0b9f90b48c803.tar.gz
git-4d50895a390658bf1b9a9385dbc0b9f90b48c803.tar.bz2
merge-recursive: handle D/F conflict case more carefully.
When a path D that originally was blob in the ancestor was modified on our branch while it was removed on the other branch, we keep stages 1 and 2, and leave our version in the working tree. If the other branch created a path D/F, however, that path can cleanly be resolved in the index (after all, the ancestor nor we do not have it and only the other side added), but it cannot be checked out. The issue is the same when the other branch had D and we had renamed it to D/F, or the ancestor had D/F instead of D (so there are four combinations). Do not stop the merge, but leave both D and D/F paths in the index so that the user can clear things up. Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'merge-recursive.c')
-rw-r--r--merge-recursive.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/merge-recursive.c b/merge-recursive.c
index 0e25956..595b022 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -596,9 +596,31 @@ static void update_file_flags(const unsigned char *sha,
if (S_ISREG(mode) || (!has_symlinks && S_ISLNK(mode))) {
int fd;
- if (mkdir_p(path, 0777))
- die("failed to create path %s: %s", path, strerror(errno));
- unlink(path);
+ int status;
+ const char *msg = "failed to create path '%s'%s";
+
+ status = mkdir_p(path, 0777);
+ if (status) {
+ if (status == -3) {
+ /* something else exists */
+ error(msg, path, ": perhaps a D/F conflict?");
+ update_wd = 0;
+ goto update_index;
+ }
+ die(msg, path, "");
+ }
+ if (unlink(path)) {
+ if (errno == EISDIR) {
+ /* something else exists */
+ error(msg, path, ": perhaps a D/F conflict?");
+ update_wd = 0;
+ goto update_index;
+ }
+ if (errno != ENOENT)
+ die("failed to unlink %s "
+ "in preparation to update: %s",
+ path, strerror(errno));
+ }
if (mode & 0100)
mode = 0777;
else
@@ -620,6 +642,7 @@ static void update_file_flags(const unsigned char *sha,
die("do not know what to do with %06o %s '%s'",
mode, sha1_to_hex(sha), path);
}
+ update_index:
if (update_cache)
add_cacheinfo(mode, sha, path, 0, update_wd, ADD_CACHE_OK_TO_ADD);
}