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:
Clemens Buchacher 2010-10-09 15:52:58 +02:00 committed by Junio C Hamano
parent 175659b4cc
commit 6838d1ad6b

View File

@ -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;
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);
}
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;
}
static int verify_absent(struct cache_entry *ce,
enum unpack_trees_error_types error_type,
struct unpack_trees_options *o)