diff options
author | Clemens Buchacher <drizzd@aon.at> | 2010-10-09 15:53:00 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2010-12-14 08:55:12 -0800 |
commit | b1735b1ab7743700064af528a998cdc952c8b9a1 (patch) | |
tree | 6b2b26f56f394b0f2de5d1242476b65cc68c7d41 /unpack-trees.c | |
parent | f7e3bd37fb9355ee036da4cf11d6e8186b506d5f (diff) | |
download | git-b1735b1ab7743700064af528a998cdc952c8b9a1.tar.gz git-b1735b1ab7743700064af528a998cdc952c8b9a1.tar.xz |
do not overwrite files in leading path
If the work tree contains an untracked file x, and
unpack-trees wants to checkout a path x/*, the
file x is removed unconditionally.
Instead, apply the same checks that are normally
used for untracked files, and abort if the file
cannot be removed.
Signed-off-by: Clemens Buchacher <drizzd@aon.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'unpack-trees.c')
-rw-r--r-- | unpack-trees.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/unpack-trees.c b/unpack-trees.c index df1c9209d..681611342 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -182,7 +182,7 @@ static void display_error_msgs(struct unpack_trees_options *o) */ static void unlink_entry(struct cache_entry *ce) { - if (has_symlink_or_noent_leading_path(ce->name, ce_namelen(ce))) + if (!check_leading_path(ce->name, ce_namelen(ce))) return; if (remove_or_warn(ce->ce_mode, ce->name)) return; @@ -1194,18 +1194,28 @@ static int verify_absent_1(struct cache_entry *ce, enum unpack_trees_error_types error_type, struct unpack_trees_options *o) { + int len; struct stat st; if (o->index_only || o->reset || !o->update) return 0; - if (has_symlink_or_noent_leading_path(ce->name, ce_namelen(ce))) + len = check_leading_path(ce->name, ce_namelen(ce)); + if (!len) return 0; + else if (len > 0) { + char path[PATH_MAX + 1]; + memcpy(path, ce->name, len); + path[len] = 0; + lstat(path, &st); - if (!lstat(ce->name, &st)) + return check_ok_to_remove(path, len, DT_UNKNOWN, NULL, &st, + error_type, o); + } else 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; } |