X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=unpack-trees.c;h=a59f47557a2b3760c27b93fa678697c35211f952;hb=995e8df4a9de9cf7c1b98dac922d96dc6606946d;hp=be89d52e8c55d71fe7dff2e7e2f6d6d5f8a7ca16;hpb=20a16eb33eee99fd3eab00c72f012b98d4eeee76;p=git.git diff --git a/unpack-trees.c b/unpack-trees.c index be89d52e8..a59f47557 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -54,13 +54,14 @@ static void unlink_entry(char *name, char *last_symlink) } static struct checkout state; -static void check_updates(struct unpack_trees_options *o) +static int check_updates(struct unpack_trees_options *o) { unsigned cnt = 0, total = 0; struct progress *progress = NULL; char last_symlink[PATH_MAX]; struct index_state *index = &o->result; int i; + int errs = 0; if (o->update && o->verbose_update) { for (total = cnt = 0; cnt < index->cache_nr; cnt++) { @@ -90,12 +91,13 @@ static void check_updates(struct unpack_trees_options *o) if (ce->ce_flags & CE_UPDATE) { ce->ce_flags &= ~CE_UPDATE; if (o->update) { - checkout_entry(ce, &state, NULL); + errs |= checkout_entry(ce, &state, NULL); *last_symlink = '\0'; } } } stop_progress(&progress); + return errs != 0; } static inline int call_unpack_fn(struct cache_entry **src, struct unpack_trees_options *o) @@ -123,7 +125,7 @@ static int unpack_index_entry(struct cache_entry *ce, struct unpack_trees_option int traverse_trees_recursive(int n, unsigned long dirmask, unsigned long df_conflicts, struct name_entry *names, struct traverse_info *info) { int i; - struct tree_desc t[3]; + struct tree_desc t[MAX_UNPACK_TREES]; struct traverse_info newinfo; struct name_entry *p; @@ -327,8 +329,8 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options { static struct cache_entry *dfc; - if (len > 4) - die("unpack_trees takes at most four trees"); + if (len > MAX_UNPACK_TREES) + die("unpack_trees takes at most %d trees", MAX_UNPACK_TREES); memset(&state, 0, sizeof(state)); state.base_dir = ""; state.force = 1; @@ -336,6 +338,8 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options state.refresh_cache = 1; memset(&o->result, 0, sizeof(o->result)); + if (o->src_index) + o->result.timestamp = o->src_index->timestamp; o->merge_size = len; if (!dfc) @@ -367,7 +371,8 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options return unpack_failed(o, "Merge requires file-level merging"); o->src_index = NULL; - check_updates(o); + if (check_updates(o)) + return -1; if (o->dst_index) *o->dst_index = o->result; return 0; @@ -593,16 +598,19 @@ static int verify_absent(struct cache_entry *ce, const char *action, static int merged_entry(struct cache_entry *merge, struct cache_entry *old, struct unpack_trees_options *o) { + int update = CE_UPDATE; + if (old) { /* * See if we can re-use the old CE directly? * That way we get the uptodate stat info. * - * This also removes the UPDATE flag on - * a match. + * This also removes the UPDATE flag on a match; otherwise + * we will end up overwriting local changes in the work tree. */ if (same(old, merge)) { copy_cache_entry(merge, old); + update = 0; } else { if (verify_uptodate(old, o)) return -1; @@ -615,7 +623,7 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old, invalidate_ce_path(merge, o); } - add_entry(o, merge, CE_UPDATE, CE_STAGEMASK); + add_entry(o, merge, update, CE_STAGEMASK); return 1; }