summaryrefslogtreecommitdiff
path: root/unpack-trees.c
diff options
context:
space:
mode:
authorClemens Buchacher <drizzd@aon.at>2010-10-09 13:53:00 (GMT)
committerJunio C Hamano <gitster@pobox.com>2010-12-14 16:55:12 (GMT)
commitb1735b1ab7743700064af528a998cdc952c8b9a1 (patch)
tree6b2b26f56f394b0f2de5d1242476b65cc68c7d41 /unpack-trees.c
parentf7e3bd37fb9355ee036da4cf11d6e8186b506d5f (diff)
downloadgit-b1735b1ab7743700064af528a998cdc952c8b9a1.zip
git-b1735b1ab7743700064af528a998cdc952c8b9a1.tar.gz
git-b1735b1ab7743700064af528a998cdc952c8b9a1.tar.bz2
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.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/unpack-trees.c b/unpack-trees.c
index df1c920..6816113 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;
}