git-mergetool documentaiton: show toolnames in typewriter font
[gitweb.git] / unpack-trees.c
index f462a56ad26a05d88ac8e2eebf3587b862762e2e..3e448d8974eb6d738fec2c35cc5a9ffbc8764411 100644 (file)
@@ -85,6 +85,7 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
                int any_dirs = 0;
                char *cache_name;
                int ce_stage;
+               int skip_entry = 0;
 
                /* Find the first name in the input. */
 
@@ -153,6 +154,8 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
                        any_files = 1;
                        src[0] = active_cache[o->pos];
                        remove = o->pos;
+                       if (o->skip_unmerged && ce_stage(src[0]))
+                               skip_entry = 1;
                }
 
                for (i = 0; i < len; i++) {
@@ -181,6 +184,12 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
                                continue;
                        }
 
+                       if (skip_entry) {
+                               subposns[i] = df_conflict_list;
+                               posns[i] = posns[i]->next;
+                               continue;
+                       }
+
                        if (!o->merge)
                                ce_stage = 0;
                        else if (i + 1 < o->head_idx)
@@ -205,7 +214,13 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
                        posns[i] = posns[i]->next;
                }
                if (any_files) {
-                       if (o->merge) {
+                       if (skip_entry) {
+                               o->pos++;
+                               while (o->pos < active_nr &&
+                                      !strcmp(active_cache[o->pos]->name,
+                                              src[0]->name))
+                                       o->pos++;
+                       } else if (o->merge) {
                                int ret;
 
 #if DBRT_DEBUG > 1
@@ -288,34 +303,36 @@ static void unlink_entry(char *name, char *last_symlink)
 }
 
 static struct checkout state;
-static void check_updates(struct cache_entry **src, int nr,
-                       struct unpack_trees_options *o)
+static void check_updates(struct unpack_trees_options *o)
 {
        unsigned cnt = 0, total = 0;
        struct progress *progress = NULL;
        char last_symlink[PATH_MAX];
+       int i;
 
        if (o->update && o->verbose_update) {
-               for (total = cnt = 0; cnt < nr; cnt++) {
-                       struct cache_entry *ce = src[cnt];
+               for (total = cnt = 0; cnt < active_nr; cnt++) {
+                       struct cache_entry *ce = active_cache[cnt];
                        if (ce->ce_flags & (CE_UPDATE | CE_REMOVE))
                                total++;
                }
 
                progress = start_progress_delay("Checking out files",
-                                               total, 50, 2);
+                                               total, 50, 1);
                cnt = 0;
        }
 
        *last_symlink = '\0';
-       while (nr--) {
-               struct cache_entry *ce = *src++;
+       for (i = 0; i < active_nr; i++) {
+               struct cache_entry *ce = active_cache[i];
 
                if (ce->ce_flags & (CE_UPDATE | CE_REMOVE))
                        display_progress(progress, ++cnt);
                if (ce->ce_flags & CE_REMOVE) {
                        if (o->update)
                                unlink_entry(ce->name, last_symlink);
+                       remove_cache_entry_at(i);
+                       i--;
                        continue;
                }
                if (ce->ce_flags & CE_UPDATE) {
@@ -374,7 +391,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
                        error("Merge requires file-level merging");
        }
 
-       check_updates(active_cache, active_nr, o);
+       check_updates(o);
        return 0;
 }
 
@@ -537,8 +554,9 @@ static int verify_absent(struct cache_entry *ce, const char *action,
 
        if (!lstat(ce->name, &st)) {
                int cnt;
+               int dtype = ce_to_dtype(ce);
 
-               if (o->dir && excluded(o->dir, ce->name))
+               if (o->dir && excluded(o->dir, ce->name, &dtype))
                        /*
                         * ce->name is explicitly excluded, so it is Ok to
                         * overwrite it.
@@ -607,7 +625,7 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
                 * a match.
                 */
                if (same(old, merge)) {
-                       memcpy(merge, old, offsetof(struct cache_entry, name));
+                       copy_cache_entry(merge, old);
                } else {
                        if (verify_uptodate(old, o))
                                return -1;
@@ -728,9 +746,8 @@ int threeway_merge(struct cache_entry **stages,
         * If we have an entry in the index cache, then we want to
         * make sure that it matches head.
         */
-       if (index && !same(index, head)) {
+       if (index && !same(index, head))
                return o->gently ? -1 : reject_merge(index);
-       }
 
        if (head) {
                /* #5ALT, #15 */