From: Junio C Hamano Date: Thu, 11 Sep 2014 17:33:35 +0000 (-0700) Subject: Merge branch 'jn/unpack-trees-checkout-m-carry-deletion' X-Git-Tag: v2.2.0-rc0~132 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/f28763d7561f66c0c6ff9b5d48146a0f923781d3?ds=inline;hp=-c Merge branch 'jn/unpack-trees-checkout-m-carry-deletion' "git checkout -m" did not switch to another branch while carrying the local changes forward when a path was deleted from the index. * jn/unpack-trees-checkout-m-carry-deletion: checkout -m: attempt merge when deletion of path was staged unpack-trees: use 'cuddled' style for if-else cascade unpack-trees: simplify 'all other failures' case --- f28763d7561f66c0c6ff9b5d48146a0f923781d3 diff --combined unpack-trees.c index c6aa8fb993,6c45af7248..629c658c46 --- a/unpack-trees.c +++ b/unpack-trees.c @@@ -8,7 -8,6 +8,7 @@@ #include "progress.h" #include "refs.h" #include "attr.h" +#include "split-index.h" /* * Error messages expected by scripts out of plumbing commands such as @@@ -57,15 -56,17 +57,15 @@@ void setup_unpack_trees_porcelain(struc int i; const char **msgs = opts->msgs; const char *msg; - char *tmp; const char *cmd2 = strcmp(cmd, "checkout") ? cmd : "switch branches"; + if (advice_commit_before_merge) msg = "Your local changes to the following files would be overwritten by %s:\n%%s" "Please, commit your changes or stash them before you can %s."; else msg = "Your local changes to the following files would be overwritten by %s:\n%%s"; - tmp = xmalloc(strlen(msg) + strlen(cmd) + strlen(cmd2) - 2); - sprintf(tmp, msg, cmd, cmd2); - msgs[ERROR_WOULD_OVERWRITE] = tmp; - msgs[ERROR_NOT_UPTODATE_FILE] = tmp; + msgs[ERROR_WOULD_OVERWRITE] = msgs[ERROR_NOT_UPTODATE_FILE] = + xstrfmt(msg, cmd, cmd2); msgs[ERROR_NOT_UPTODATE_DIR] = "Updating the following directories would lose untracked files in it:\n%s"; @@@ -75,9 -76,12 +75,9 @@@ "Please move or remove them before you can %s."; else msg = "The following untracked working tree files would be %s by %s:\n%%s"; - tmp = xmalloc(strlen(msg) + strlen(cmd) + strlen("removed") + strlen(cmd2) - 4); - sprintf(tmp, msg, "removed", cmd, cmd2); - msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] = tmp; - tmp = xmalloc(strlen(msg) + strlen(cmd) + strlen("overwritten") + strlen(cmd2) - 4); - sprintf(tmp, msg, "overwritten", cmd, cmd2); - msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] = tmp; + + msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] = xstrfmt(msg, "removed", cmd, cmd2); + msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] = xstrfmt(msg, "overwritten", cmd, cmd2); /* * Special case: ERROR_BIND_OVERLAP refers to a pair of paths, we @@@ -101,11 -105,12 +101,11 @@@ static void do_add_entry(struct unpack_trees_options *o, struct cache_entry *ce, unsigned int set, unsigned int clear) { - clear |= CE_HASHED | CE_UNHASHED; + clear |= CE_HASHED; if (set & CE_REMOVE) set |= CE_WT_REMOVE; - ce->next = NULL; ce->ce_flags = (ce->ce_flags & ~clear) | set; add_index_entry(&o->result, ce, ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE); @@@ -199,7 -204,7 +199,7 @@@ static int check_updates(struct unpack_ total++; } - progress = start_progress_delay("Checking out files", + progress = start_progress_delay(_("Checking out files"), total, 50, 1); cnt = 0; } @@@ -242,9 -247,7 +242,9 @@@ static int verify_absent_sparse(const s enum unpack_trees_error_types, struct unpack_trees_options *o); -static int apply_sparse_checkout(struct cache_entry *ce, struct unpack_trees_options *o) +static int apply_sparse_checkout(struct index_state *istate, + struct cache_entry *ce, + struct unpack_trees_options *o) { int was_skip_worktree = ce_skip_worktree(ce); @@@ -252,10 -255,6 +252,10 @@@ ce->ce_flags |= CE_SKIP_WORKTREE; else ce->ce_flags &= ~CE_SKIP_WORKTREE; + if (was_skip_worktree != ce_skip_worktree(ce)) { + ce->ce_flags |= CE_UPDATE_IN_BASE; + istate->cache_changed |= CE_ENTRY_CHANGED; + } /* * if (!was_skip_worktree && !ce_skip_worktree()) { @@@ -624,6 -623,17 +624,6 @@@ static int unpack_failed(struct unpack_ return -1; } -/* NEEDSWORK: give this a better name and share with tree-walk.c */ -static int name_compare(const char *a, int a_len, - const char *b, int b_len) -{ - int len = (a_len < b_len) ? a_len : b_len; - int cmp = memcmp(a, b, len); - if (cmp) - return cmp; - return (a_len - b_len); -} - /* * The tree traversal is looking at name p. If we have a matching entry, * return it. If name p is a directory in the index, do not return @@@ -820,24 -830,23 +820,24 @@@ static int unpack_callback(int n, unsig } static int clear_ce_flags_1(struct cache_entry **cache, int nr, - char *prefix, int prefix_len, + struct strbuf *prefix, int select_mask, int clear_mask, struct exclude_list *el, int defval); /* Whole directory matching */ static int clear_ce_flags_dir(struct cache_entry **cache, int nr, - char *prefix, int prefix_len, + struct strbuf *prefix, char *basename, int select_mask, int clear_mask, struct exclude_list *el, int defval) { struct cache_entry **cache_end; int dtype = DT_DIR; - int ret = is_excluded_from_list(prefix, prefix_len, + int ret = is_excluded_from_list(prefix->buf, prefix->len, basename, &dtype, el); + int rc; - prefix[prefix_len++] = '/'; + strbuf_addch(prefix, '/'); /* If undecided, use matching result of parent dir in defval */ if (ret < 0) @@@ -845,7 -854,7 +845,7 @@@ for (cache_end = cache; cache_end != cache + nr; cache_end++) { struct cache_entry *ce = *cache_end; - if (strncmp(ce->name, prefix, prefix_len)) + if (strncmp(ce->name, prefix->buf, prefix->len)) break; } @@@ -856,12 -865,10 +856,12 @@@ * calling clear_ce_flags_1(). That function will call * the expensive is_excluded_from_list() on every entry. */ - return clear_ce_flags_1(cache, cache_end - cache, - prefix, prefix_len, - select_mask, clear_mask, - el, ret); + rc = clear_ce_flags_1(cache, cache_end - cache, + prefix, + select_mask, clear_mask, + el, ret); + strbuf_setlen(prefix, prefix->len - 1); + return rc; } /* @@@ -880,7 -887,7 +880,7 @@@ * Top level path has prefix_len zero. */ static int clear_ce_flags_1(struct cache_entry **cache, int nr, - char *prefix, int prefix_len, + struct strbuf *prefix, int select_mask, int clear_mask, struct exclude_list *el, int defval) { @@@ -900,10 -907,10 +900,10 @@@ continue; } - if (prefix_len && strncmp(ce->name, prefix, prefix_len)) + if (prefix->len && strncmp(ce->name, prefix->buf, prefix->len)) break; - name = ce->name + prefix_len; + name = ce->name + prefix->len; slash = strchr(name, '/'); /* If it's a directory, try whole directory match first */ @@@ -911,26 -918,29 +911,26 @@@ int processed; len = slash - name; - memcpy(prefix + prefix_len, name, len); + strbuf_add(prefix, name, len); - /* - * terminate the string (no trailing slash), - * clear_c_f_dir needs it - */ - prefix[prefix_len + len] = '\0'; processed = clear_ce_flags_dir(cache, cache_end - cache, - prefix, prefix_len + len, - prefix + prefix_len, + prefix, + prefix->buf + prefix->len - len, select_mask, clear_mask, el, defval); /* clear_c_f_dir eats a whole dir already? */ if (processed) { cache += processed; + strbuf_setlen(prefix, prefix->len - len); continue; } - prefix[prefix_len + len++] = '/'; + strbuf_addch(prefix, '/'); cache += clear_ce_flags_1(cache, cache_end - cache, - prefix, prefix_len + len, + prefix, select_mask, clear_mask, el, defval); + strbuf_setlen(prefix, prefix->len - len - 1); continue; } @@@ -951,12 -961,9 +951,12 @@@ static int clear_ce_flags(struct cache_ int select_mask, int clear_mask, struct exclude_list *el) { - char prefix[PATH_MAX]; + static struct strbuf prefix = STRBUF_INIT; + + strbuf_reset(&prefix); + return clear_ce_flags_1(cache, nr, - prefix, 0, + &prefix, select_mask, clear_mask, el, 0); } @@@ -1016,7 -1023,6 +1016,7 @@@ int unpack_trees(unsigned len, struct t state.force = 1; state.quiet = 1; state.refresh_cache = 1; + state.istate = &o->result; memset(&el, 0, sizeof(el)); if (!core_apply_sparse_checkout || !o->update) @@@ -1033,10 -1039,6 +1033,10 @@@ o->result.timestamp.sec = o->src_index->timestamp.sec; o->result.timestamp.nsec = o->src_index->timestamp.nsec; o->result.version = o->src_index->version; + o->result.split_index = o->src_index->split_index; + if (o->result.split_index) + o->result.split_index->refcount++; + hashcpy(o->result.sha1, o->src_index->sha1); o->merge_size = len; mark_all_ce_unused(o->src_index); @@@ -1127,7 -1129,7 +1127,7 @@@ ret = -1; } - if (apply_sparse_checkout(ce, o)) { + if (apply_sparse_checkout(&o->result, ce, o)) { if (!o->show_all_errors) goto return_failed; ret = -1; @@@ -1176,7 -1178,8 +1176,8 @@@ return_failed static int reject_merge(const struct cache_entry *ce, struct unpack_trees_options *o) { - return add_rejected_path(o, ERROR_WOULD_OVERWRITE, ce->name); + return o->gently ? -1 : + add_rejected_path(o, ERROR_WOULD_OVERWRITE, ce->name); } static int same(const struct cache_entry *a, const struct cache_entry *b) @@@ -1255,7 -1258,7 +1256,7 @@@ static void invalidate_ce_path(const st struct unpack_trees_options *o) { if (ce) - cache_tree_invalidate_path(o->src_index->cache_tree, ce->name); + cache_tree_invalidate_path(o->src_index, ce->name); } /* @@@ -1631,7 -1634,7 +1632,7 @@@ int threeway_merge(const struct cache_e /* #14, #14ALT, #2ALT */ if (remote && !df_conflict_head && head_match && !remote_match) { if (index && !same(index, remote) && !same(index, head)) - return o->gently ? -1 : reject_merge(index, o); + return reject_merge(index, o); return merged_entry(remote, index, o); } /* @@@ -1639,7 -1642,7 +1640,7 @@@ * make sure that it matches head. */ if (index && !same(index, head)) - return o->gently ? -1 : reject_merge(index, o); + return reject_merge(index, o); if (head) { /* #5ALT, #15 */ @@@ -1768,9 -1771,8 +1769,8 @@@ int twoway_merge(const struct cache_ent else return merged_entry(newtree, current, o); } - return o->gently ? -1 : reject_merge(current, o); - } - else if ((!oldtree && !newtree) || /* 4 and 5 */ + return reject_merge(current, o); + } else if ((!oldtree && !newtree) || /* 4 and 5 */ (!oldtree && newtree && same(current, newtree)) || /* 6 and 7 */ (oldtree && newtree && @@@ -1779,26 -1781,15 +1779,15 @@@ !same(oldtree, newtree) && /* 18 and 19 */ same(current, newtree))) { return keep_entry(current, o); - } - else if (oldtree && !newtree && same(current, oldtree)) { + } else if (oldtree && !newtree && same(current, oldtree)) { /* 10 or 11 */ return deleted_entry(oldtree, current, o); - } - else if (oldtree && newtree && + } else if (oldtree && newtree && same(current, oldtree) && !same(current, newtree)) { /* 20 or 21 */ return merged_entry(newtree, current, o); - } - else { - /* all other failures */ - if (oldtree) - return o->gently ? -1 : reject_merge(oldtree, o); - if (current) - return o->gently ? -1 : reject_merge(current, o); - if (newtree) - return o->gently ? -1 : reject_merge(newtree, o); - return -1; - } + } else + return reject_merge(current, o); } else if (newtree) { if (oldtree && !o->initial_checkout) {