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>maint
parent
189645ca84
commit
a9307f5a68
107
unpack-trees.c
107
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
|
* 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!
|
* 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;
|
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);
|
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
|
* We do not want to remove or overwrite a working tree file that
|
||||||
* is not tracked, unless it is ignored.
|
* 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)))
|
if (has_symlink_or_noent_leading_path(ce->name, ce_namelen(ce)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!lstat(ce->name, &st)) {
|
if (!lstat(ce->name, &st))
|
||||||
int dtype = ce_to_dtype(ce);
|
return check_ok_to_remove(ce->name, ce_namelen(ce),
|
||||||
struct cache_entry *result;
|
ce_to_dtype(ce), ce, &st,
|
||||||
|
error_type, o);
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int verify_absent(struct cache_entry *ce,
|
static int verify_absent(struct cache_entry *ce,
|
||||||
enum unpack_trees_error_types error_type,
|
enum unpack_trees_error_types error_type,
|
||||||
struct unpack_trees_options *o)
|
struct unpack_trees_options *o)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue