зеркало из https://github.com/microsoft/git.git
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>
This commit is contained in:
Родитель
c0718268e8
Коммит
21cd8d00b6
40
read-cache.c
40
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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче