diff options
author | Junio C Hamano <junkio@cox.net> | 2007-03-30 01:55:37 -0700 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2007-04-04 00:19:28 -0700 |
commit | 21cd8d00b6908dd8e1d4a5d101c1ba49d3645053 (patch) | |
tree | 8648943fc09fce3d99754c0b7207aa933feece84 | |
parent | Merge branch 'jc/bisect' (diff) | |
download | tgif-21cd8d00b6908dd8e1d4a5d101c1ba49d3645053.tar.xz |
add_cache_entry(): removal of file foo does not conflict with foo/bar
Similarly, removal of file foo/bar does not conflict with a file foo.
Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r-- | read-cache.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/read-cache.c b/read-cache.c index 6339a278da..823c2c3b08 100644 --- 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. |