Merge branch 'mh/retag'
[gitweb.git] / unpack-trees.c
index 5d1ffd1a32a56bdcf4f64b545abd6aa951914ffe..c527d7d049155d1808e0bf69aba42d49cea7b68f 100644 (file)
@@ -58,10 +58,17 @@ static int entcmp(const char *name1, int dir1, const char *name2, int dir2)
        return ret;
 }
 
+static inline void remove_entry(int remove)
+{
+       if (remove >= 0)
+               remove_cache_entry_at(remove);
+}
+
 static int unpack_trees_rec(struct tree_entry_list **posns, int len,
                            const char *base, struct unpack_trees_options *o,
                            struct tree_entry_list *df_conflict_list)
 {
+       int remove;
        int baselen = strlen(base);
        int src_size = len + 1;
        int i_stk = i_stk;
@@ -145,10 +152,11 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
 
                subposns = xcalloc(len, sizeof(struct tree_list_entry *));
 
+               remove = -1;
                if (cache_name && !strcmp(cache_name, first)) {
                        any_files = 1;
                        src[0] = active_cache[o->pos];
-                       remove_cache_entry_at(o->pos);
+                       remove = o->pos;
                }
 
                for (i = 0; i < len; i++) {
@@ -214,13 +222,14 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
                                                printf("\n");
                                }
 #endif
-                               ret = o->fn(src, o);
+                               ret = o->fn(src, o, remove);
 
 #if DBRT_DEBUG > 1
                                printf("Added %d entries\n", ret);
 #endif
                                o->pos += ret;
                        } else {
+                               remove_entry(remove);
                                for (i = 0; i < src_size; i++) {
                                        if (src[i]) {
                                                add_cache_entry(src[i], ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK);
@@ -288,7 +297,7 @@ static void check_updates(struct cache_entry **src, int nr,
 {
        unsigned short mask = htons(CE_UPDATE);
        unsigned cnt = 0, total = 0;
-       struct progress progress;
+       struct progress *progress = NULL;
        char last_symlink[PATH_MAX];
 
        if (o->update && o->verbose_update) {
@@ -298,8 +307,8 @@ static void check_updates(struct cache_entry **src, int nr,
                                total++;
                }
 
-               start_progress_delay(&progress, "Checking %u files out...",
-                                    "", total, 50, 2);
+               progress = start_progress_delay("Checking out files",
+                                               total, 50, 2);
                cnt = 0;
        }
 
@@ -307,9 +316,8 @@ static void check_updates(struct cache_entry **src, int nr,
        while (nr--) {
                struct cache_entry *ce = *src++;
 
-               if (total)
-                       if (!ce->ce_mode || ce->ce_flags & mask)
-                               display_progress(&progress, ++cnt);
+               if (!ce->ce_mode || ce->ce_flags & mask)
+                       display_progress(progress, ++cnt);
                if (!ce->ce_mode) {
                        if (o->update)
                                unlink_entry(ce->name, last_symlink);
@@ -323,8 +331,7 @@ static void check_updates(struct cache_entry **src, int nr,
                        }
                }
        }
-       if (total)
-               stop_progress(&progress);;
+       stop_progress(&progress);
 }
 
 int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options *o)
@@ -641,7 +648,8 @@ static void show_stage_entry(FILE *o,
 #endif
 
 int threeway_merge(struct cache_entry **stages,
-               struct unpack_trees_options *o)
+               struct unpack_trees_options *o,
+               int remove)
 {
        struct cache_entry *index;
        struct cache_entry *head;
@@ -719,8 +727,10 @@ int threeway_merge(struct cache_entry **stages,
        }
 
        /* #1 */
-       if (!head && !remote && any_anc_missing)
+       if (!head && !remote && any_anc_missing) {
+               remove_entry(remove);
                return 0;
+       }
 
        /* Under the new "aggressive" rule, we resolve mostly trivial
         * cases that we historically had git-merge-one-file resolve.
@@ -752,6 +762,7 @@ int threeway_merge(struct cache_entry **stages,
                if ((head_deleted && remote_deleted) ||
                    (head_deleted && remote && remote_match) ||
                    (remote_deleted && head && head_match)) {
+                       remove_entry(remove);
                        if (index)
                                return deleted_entry(index, index, o);
                        else if (ce && !head_deleted)
@@ -774,6 +785,7 @@ int threeway_merge(struct cache_entry **stages,
                verify_uptodate(index, o);
        }
 
+       remove_entry(remove);
        o->nontrivial_merge = 1;
 
        /* #2, #3, #4, #6, #7, #9, #10, #11. */
@@ -809,7 +821,8 @@ int threeway_merge(struct cache_entry **stages,
  *
  */
 int twoway_merge(struct cache_entry **src,
-               struct unpack_trees_options *o)
+               struct unpack_trees_options *o,
+               int remove)
 {
        struct cache_entry *current = src[0];
        struct cache_entry *oldtree = src[1];
@@ -837,6 +850,7 @@ int twoway_merge(struct cache_entry **src,
                }
                else if (oldtree && !newtree && same(current, oldtree)) {
                        /* 10 or 11 */
+                       remove_entry(remove);
                        return deleted_entry(oldtree, current, o);
                }
                else if (oldtree && newtree &&
@@ -846,6 +860,7 @@ int twoway_merge(struct cache_entry **src,
                }
                else {
                        /* all other failures */
+                       remove_entry(remove);
                        if (oldtree)
                                reject_merge(oldtree);
                        if (current)
@@ -857,8 +872,8 @@ int twoway_merge(struct cache_entry **src,
        }
        else if (newtree)
                return merged_entry(newtree, current, o);
-       else
-               return deleted_entry(oldtree, current, o);
+       remove_entry(remove);
+       return deleted_entry(oldtree, current, o);
 }
 
 /*
@@ -868,7 +883,8 @@ int twoway_merge(struct cache_entry **src,
  * stage0 does not have anything there.
  */
 int bind_merge(struct cache_entry **src,
-               struct unpack_trees_options *o)
+               struct unpack_trees_options *o,
+               int remove)
 {
        struct cache_entry *old = src[0];
        struct cache_entry *a = src[1];
@@ -891,7 +907,8 @@ int bind_merge(struct cache_entry **src,
  * - take the stat information from stage0, take the data from stage1
  */
 int oneway_merge(struct cache_entry **src,
-               struct unpack_trees_options *o)
+               struct unpack_trees_options *o,
+               int remove)
 {
        struct cache_entry *old = src[0];
        struct cache_entry *a = src[1];
@@ -900,8 +917,10 @@ int oneway_merge(struct cache_entry **src,
                return error("Cannot do a oneway merge of %d trees",
                             o->merge_size);
 
-       if (!a)
+       if (!a) {
+               remove_entry(remove);
                return deleted_entry(old, old, o);
+       }
        if (old && same(old, a)) {
                if (o->reset) {
                        struct stat st;