diff options
Diffstat (limited to 'unpack-trees.c')
-rw-r--r-- | unpack-trees.c | 47 |
1 files changed, 24 insertions, 23 deletions
diff --git a/unpack-trees.c b/unpack-trees.c index 54f301da67..e547282ed5 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -61,7 +61,7 @@ static void unlink_entry(struct cache_entry *ce) char *cp, *prev; char *name = ce->name; - if (has_symlink_leading_path(ce_namelen(ce), ce->name)) + if (has_symlink_or_noent_leading_path(ce_namelen(ce), ce->name)) return; if (unlink(name)) return; @@ -240,8 +240,11 @@ static struct cache_entry *create_ce_entry(const struct traverse_info *info, con return ce; } -static int unpack_nondirectories(int n, unsigned long mask, unsigned long dirmask, struct cache_entry *src[5], - const struct name_entry *names, const struct traverse_info *info) +static int unpack_nondirectories(int n, unsigned long mask, + unsigned long dirmask, + struct cache_entry **src, + const struct name_entry *names, + const struct traverse_info *info) { int i; struct unpack_trees_options *o = info->data; @@ -291,7 +294,7 @@ static int unpack_nondirectories(int n, unsigned long mask, unsigned long dirmas static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, struct name_entry *names, struct traverse_info *info) { - struct cache_entry *src[5] = { NULL, }; + struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, }; struct unpack_trees_options *o = info->data; const struct name_entry *p = names; @@ -494,7 +497,7 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action, * anything in the existing directory there. */ int namelen; - int pos, i; + int i; struct dir_struct d; char *pathbuf; int cnt = 0; @@ -515,24 +518,20 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action, * in that directory. */ namelen = strlen(ce->name); - pos = index_name_pos(o->src_index, ce->name, namelen); - if (0 <= pos) - return cnt; /* we have it as nondirectory */ - pos = -pos - 1; - for (i = pos; i < o->src_index->cache_nr; i++) { - struct cache_entry *ce = o->src_index->cache[i]; - int len = ce_namelen(ce); + for (i = o->pos; i < o->src_index->cache_nr; i++) { + struct cache_entry *ce2 = o->src_index->cache[i]; + int len = ce_namelen(ce2); if (len < namelen || - strncmp(ce->name, ce->name, namelen) || - ce->name[namelen] != '/') + strncmp(ce->name, ce2->name, namelen) || + ce2->name[namelen] != '/') break; /* - * ce->name is an entry in the subdirectory. + * ce2->name is an entry in the subdirectory. */ - if (!ce_stage(ce)) { - if (verify_uptodate(ce, o)) + if (!ce_stage(ce2)) { + if (verify_uptodate(ce2, o)) return -1; - add_entry(o, ce, CE_REMOVE, 0); + add_entry(o, ce2, CE_REMOVE, 0); } cnt++; } @@ -584,11 +583,11 @@ static int verify_absent(struct cache_entry *ce, const char *action, if (o->index_only || o->reset || !o->update) return 0; - if (has_symlink_leading_path(ce_namelen(ce), ce->name)) + if (has_symlink_or_noent_leading_path(ce_namelen(ce), ce->name)) return 0; if (!lstat(ce->name, &st)) { - int cnt; + int ret; int dtype = ce_to_dtype(ce); struct cache_entry *result; @@ -616,13 +615,15 @@ static int verify_absent(struct cache_entry *ce, const char *action, * files that are in "foo/" we would lose * it. */ - cnt = verify_clean_subdirectory(ce, action, o); + ret = verify_clean_subdirectory(ce, action, o); + if (ret < 0) + return ret; /* * If this removed entries from the index, * what that means is: * - * (1) the caller unpack_trees_rec() saw path/foo + * (1) the caller unpack_callback() saw path/foo * in the index, and it has not removed it because * it thinks it is handling 'path' as blob with * D/F conflict; @@ -635,7 +636,7 @@ static int verify_absent(struct cache_entry *ce, const char *action, * We need to increment it by the number of * deleted entries here. */ - o->pos += cnt; + o->pos += ret; return 0; } |