summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c071826)
raw | patch | inline | side by side (parent: c071826)
author | Junio C Hamano <junkio@cox.net> | |
Fri, 30 Mar 2007 08:55:37 +0000 (01:55 -0700) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Wed, 4 Apr 2007 07:19:28 +0000 (00:19 -0700) |
Similarly, removal of file foo/bar does not conflict with a file foo.
Signed-off-by: Junio C Hamano <junkio@cox.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
read-cache.c | patch | blob | history |
diff --git a/read-cache.c b/read-cache.c
index 6339a278da1ae1b323b5abf7d2604c7afdfde4e4..823c2c3b08e559a5b0a29dc30c00772301b8cb79 100644 (file)
--- a/read-cache.c
+++ b/read-cache.c
@@ -487,6 +487,8 @@ static int has_file_name(const struct cache_entry *ce, int pos, int ok_to_replac
continue;
if (p->name[len] != '/')
continue;
+ if (!ce_stage(p) && !p->ce_mode)
+ continue;
retval = -1;
if (!ok_to_replace)
break;
@@ -519,26 +521,37 @@ static int has_dir_name(const struct cache_entry *ce, int pos, int ok_to_replace
pos = cache_name_pos(name, ntohs(create_ce_flags(len, stage)));
if (pos >= 0) {
- retval = -1;
- if (!ok_to_replace)
- break;
- remove_cache_entry_at(pos);
- continue;
+ /*
+ * Found one, but not so fast. This could
+ * be a marker that says "I was here, but
+ * I am being removed". Such an entry is
+ * not a part of the resulting tree, and
+ * it is Ok to have a directory at the same
+ * path.
+ */
+ if (stage || active_cache[pos]->ce_mode) {
+ retval = -1;
+ if (!ok_to_replace)
+ break;
+ remove_cache_entry_at(pos);
+ continue;
+ }
}
+ else
+ pos = -pos-1;
/*
* Trivial optimization: if we find an entry that
* already matches the sub-directory, then we know
* we're ok, and we can exit.
*/
- pos = -pos-1;
while (pos < active_nr) {
struct cache_entry *p = active_cache[pos];
if ((ce_namelen(p) <= len) ||
(p->name[len] != '/') ||
memcmp(p->name, name, len))
break; /* not our subdirectory */
- if (ce_stage(p) == stage)
+ if (ce_stage(p) == stage && (stage || p->ce_mode))
/* p is at the same stage as our entry, and
* is a subdirectory of what we are looking
* at, so we cannot have conflicts at our
@@ -562,12 +575,21 @@ static int has_dir_name(const struct cache_entry *ce, int pos, int ok_to_replace
*/
static int check_file_directory_conflict(const struct cache_entry *ce, int pos, int ok_to_replace)
{
+ int retval;
+
+ /*
+ * When ce is an "I am going away" entry, we allow it to be added
+ */
+ if (!ce_stage(ce) && !ce->ce_mode)
+ return 0;
+
/*
* We check if the path is a sub-path of a subsequent pathname
* first, since removing those will not change the position
- * in the array
+ * in the array.
*/
- int retval = has_file_name(ce, pos, ok_to_replace);
+ retval = has_file_name(ce, pos, ok_to_replace);
+
/*
* Then check if the path might have a clashing sub-directory
* before it.