add function check_ok_to_remove()
This wraps some inline code into the function check_ok_to_remove(), which will later be used for leading path components as well. Signed-off-by: Clemens Buchacher <drizzd@aon.at> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
175659b4cc
commit
6838d1ad6b
105
unpack-trees.c
105
unpack-trees.c
@ -1127,14 +1127,65 @@ static int verify_clean_subdirectory(struct cache_entry *ce,
|
||||
* See if we can find a case-insensitive match in the index that also
|
||||
* matches the stat information, and assume it's that other file!
|
||||
*/
|
||||
static int icase_exists(struct unpack_trees_options *o, struct cache_entry *dst, struct stat *st)
|
||||
static int icase_exists(struct unpack_trees_options *o, const char *name, int len, struct stat *st)
|
||||
{
|
||||
struct cache_entry *src;
|
||||
|
||||
src = index_name_exists(o->src_index, dst->name, ce_namelen(dst), 1);
|
||||
src = index_name_exists(o->src_index, name, len, 1);
|
||||
return src && !ie_match_stat(o->src_index, src, st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
|
||||
}
|
||||
|
||||
static int check_ok_to_remove(const char *name, int len, int dtype,
|
||||
struct cache_entry *ce, struct stat *st,
|
||||
enum unpack_trees_error_types error_type,
|
||||
struct unpack_trees_options *o)
|
||||
{
|
||||
struct cache_entry *result;
|
||||
|
||||
/*
|
||||
* It may be that the 'lstat()' succeeded even though
|
||||
* target 'ce' was absent, because there is an old
|
||||
* entry that is different only in case..
|
||||
*
|
||||
* Ignore that lstat() if it matches.
|
||||
*/
|
||||
if (ignore_case && icase_exists(o, name, len, st))
|
||||
return 0;
|
||||
|
||||
if (o->dir && excluded(o->dir, name, &dtype))
|
||||
/*
|
||||
* ce->name is explicitly excluded, so it is Ok to
|
||||
* overwrite it.
|
||||
*/
|
||||
return 0;
|
||||
if (S_ISDIR(st->st_mode)) {
|
||||
/*
|
||||
* We are checking out path "foo" and
|
||||
* found "foo/." in the working tree.
|
||||
* This is tricky -- if we have modified
|
||||
* files that are in "foo/" we would lose
|
||||
* them.
|
||||
*/
|
||||
if (verify_clean_subdirectory(ce, error_type, o) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The previous round may already have decided to
|
||||
* delete this path, which is in a subdirectory that
|
||||
* is being replaced with a blob.
|
||||
*/
|
||||
result = index_name_exists(&o->result, name, len, 0);
|
||||
if (result) {
|
||||
if (result->ce_flags & CE_REMOVE)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return o->gently ? -1 :
|
||||
add_rejected_path(o, error_type, name);
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not want to remove or overwrite a working tree file that
|
||||
* is not tracked, unless it is ignored.
|
||||
@ -1151,55 +1202,13 @@ static int verify_absent_1(struct cache_entry *ce,
|
||||
if (has_symlink_or_noent_leading_path(ce->name, ce_namelen(ce)))
|
||||
return 0;
|
||||
|
||||
if (!lstat(ce->name, &st)) {
|
||||
int dtype = ce_to_dtype(ce);
|
||||
struct cache_entry *result;
|
||||
|
||||
/*
|
||||
* It may be that the 'lstat()' succeeded even though
|
||||
* target 'ce' was absent, because there is an old
|
||||
* entry that is different only in case..
|
||||
*
|
||||
* Ignore that lstat() if it matches.
|
||||
*/
|
||||
if (ignore_case && icase_exists(o, ce, &st))
|
||||
return 0;
|
||||
|
||||
if (o->dir && excluded(o->dir, ce->name, &dtype))
|
||||
/*
|
||||
* ce->name is explicitly excluded, so it is Ok to
|
||||
* overwrite it.
|
||||
*/
|
||||
return 0;
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
/*
|
||||
* We are checking out path "foo" and
|
||||
* found "foo/." in the working tree.
|
||||
* This is tricky -- if we have modified
|
||||
* files that are in "foo/" we would lose
|
||||
* them.
|
||||
*/
|
||||
if (verify_clean_subdirectory(ce, error_type, o) < 0)
|
||||
return -1;
|
||||
if (!lstat(ce->name, &st))
|
||||
return check_ok_to_remove(ce->name, ce_namelen(ce),
|
||||
ce_to_dtype(ce), ce, &st,
|
||||
error_type, o);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The previous round may already have decided to
|
||||
* delete this path, which is in a subdirectory that
|
||||
* is being replaced with a blob.
|
||||
*/
|
||||
result = index_name_exists(&o->result, ce->name, ce_namelen(ce), 0);
|
||||
if (result) {
|
||||
if (result->ce_flags & CE_REMOVE)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return o->gently ? -1 :
|
||||
add_rejected_path(o, error_type, ce->name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int verify_absent(struct cache_entry *ce,
|
||||
enum unpack_trees_error_types error_type,
|
||||
struct unpack_trees_options *o)
|
||||
|
Loading…
Reference in New Issue
Block a user