git-mergetool documentaiton: show toolnames in typewriter font
[gitweb.git] / unpack-trees.c
index 3b32718436ea4da838c98b53b3dba25bb99e3e9a..3e448d8974eb6d738fec2c35cc5a9ffbc8764411 100644 (file)
@@ -16,19 +16,13 @@ struct tree_entry_list {
        const unsigned char *sha1;
 };
 
-static struct tree_entry_list *create_tree_entry_list(struct tree *tree)
+static struct tree_entry_list *create_tree_entry_list(struct tree_desc *desc)
 {
-       struct tree_desc desc;
        struct name_entry one;
        struct tree_entry_list *ret = NULL;
        struct tree_entry_list **list_p = &ret;
 
-       if (!tree->object.parsed)
-               parse_tree(tree);
-
-       init_tree_desc(&desc, tree->buffer, tree->size);
-
-       while (tree_entry(&desc, &one)) {
+       while (tree_entry(desc, &one)) {
                struct tree_entry_list *entry;
 
                entry = xmalloc(sizeof(struct tree_entry_list));
@@ -64,18 +58,21 @@ 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;
        int retval = 0;
 
-       if (o->dir)
-               i_stk = push_exclude_per_directory(o->dir, base, strlen(base));
-
        do {
                int i;
                const char *first;
@@ -88,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. */
 
@@ -125,13 +123,13 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
 
 #if DBRT_DEBUG > 1
                if (first)
-                       printf("index %s\n", first);
+                       fprintf(stderr, "index %s\n", first);
 #endif
                for (i = 0; i < len; i++) {
                        if (!posns[i] || posns[i] == df_conflict_list)
                                continue;
 #if DBRT_DEBUG > 1
-                       printf("%d %s\n", i + 1, posns[i]->name);
+                       fprintf(stderr, "%d %s\n", i + 1, posns[i]->name);
 #endif
                        if (!first || entcmp(first, firstdir,
                                             posns[i]->name,
@@ -151,10 +149,13 @@ 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;
+                       if (o->skip_unmerged && ce_stage(src[0]))
+                               skip_entry = 1;
                }
 
                for (i = 0; i < len; i++) {
@@ -173,14 +174,22 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
 
                        if (S_ISDIR(posns[i]->mode)) {
                                struct tree *tree = lookup_tree(posns[i]->sha1);
+                               struct tree_desc t;
                                any_dirs = 1;
                                parse_tree(tree);
-                               subposns[i] = create_tree_entry_list(tree);
+                               init_tree_desc(&t, tree->buffer, tree->size);
+                               subposns[i] = create_tree_entry_list(&t);
                                posns[i] = posns[i]->next;
                                src[i + o->merge] = o->df_conflict_entry;
                                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,26 +214,35 @@ 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
-                               printf("%s:\n", first);
+                               fprintf(stderr, "%s:\n", first);
                                for (i = 0; i < src_size; i++) {
-                                       printf(" %d ", i);
+                                       fprintf(stderr, " %d ", i);
                                        if (src[i])
-                                               printf("%s\n", sha1_to_hex(src[i]->sha1));
+                                               fprintf(stderr, "%06x %s\n", src[i]->ce_mode, sha1_to_hex(src[i]->sha1));
                                        else
-                                               printf("\n");
+                                               fprintf(stderr, "\n");
                                }
 #endif
-                               ret = o->fn(src, o);
+                               ret = o->fn(src, o, remove);
+                               if (ret < 0)
+                                       return ret;
 
 #if DBRT_DEBUG > 1
-                               printf("Added %d entries\n", ret);
+                               fprintf(stderr, "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);
@@ -250,8 +268,6 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
        } while (1);
 
  leave_directory:
-       if (o->dir)
-               pop_exclude_per_directory(o->dir, i_stk);
        return retval;
 }
 
@@ -287,56 +303,53 @@ 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 short mask = htons(CE_UPDATE);
        unsigned cnt = 0, total = 0;
-       struct progress progress;
+       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];
-                       if (!ce->ce_mode || ce->ce_flags & mask)
+               for (total = cnt = 0; cnt < active_nr; cnt++) {
+                       struct cache_entry *ce = active_cache[cnt];
+                       if (ce->ce_flags & (CE_UPDATE | CE_REMOVE))
                                total++;
                }
 
-               start_progress_delay(&progress, "Checking %u files out...",
-                                    "", total, 50, 2);
+               progress = start_progress_delay("Checking out files",
+                                               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 (total)
-                       if (!ce->ce_mode || ce->ce_flags & mask)
-                               display_progress(&progress, ++cnt);
-               if (!ce->ce_mode) {
+               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 & mask) {
-                       ce->ce_flags &= ~mask;
+               if (ce->ce_flags & CE_UPDATE) {
+                       ce->ce_flags &= ~CE_UPDATE;
                        if (o->update) {
                                checkout_entry(ce, &state, NULL);
                                *last_symlink = '\0';
                        }
                }
        }
-       if (total)
-               stop_progress(&progress);;
+       stop_progress(&progress);
 }
 
-int unpack_trees(struct object_list *trees, struct unpack_trees_options *o)
+int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options *o)
 {
-       unsigned len = object_list_length(trees);
        struct tree_entry_list **posns;
        int i;
-       struct object_list *posn = trees;
        struct tree_entry_list df_conflict_list;
        static struct cache_entry *dfc;
 
@@ -356,28 +369,38 @@ int unpack_trees(struct object_list *trees, struct unpack_trees_options *o)
 
        if (len) {
                posns = xmalloc(len * sizeof(struct tree_entry_list *));
-               for (i = 0; i < len; i++) {
-                       posns[i] = create_tree_entry_list((struct tree *) posn->item);
-                       posn = posn->next;
-               }
+               for (i = 0; i < len; i++)
+                       posns[i] = create_tree_entry_list(t+i);
+
                if (unpack_trees_rec(posns, len, o->prefix ? o->prefix : "",
-                                    o, &df_conflict_list))
+                                    o, &df_conflict_list)) {
+                       if (o->gently) {
+                               discard_cache();
+                               read_cache();
+                       }
                        return -1;
+               }
        }
 
-       if (o->trivial_merges_only && o->nontrivial_merge)
-               die("Merge requires file-level merging");
+       if (o->trivial_merges_only && o->nontrivial_merge) {
+               if (o->gently) {
+                       discard_cache();
+                       read_cache();
+               }
+               return o->gently ? -1 :
+                       error("Merge requires file-level merging");
+       }
 
-       check_updates(active_cache, active_nr, o);
+       check_updates(o);
        return 0;
 }
 
 /* Here come the merge functions */
 
-static void reject_merge(struct cache_entry *ce)
+static int reject_merge(struct cache_entry *ce)
 {
-       die("Entry '%s' would be overwritten by merge. Cannot merge.",
-           ce->name);
+       return error("Entry '%s' would be overwritten by merge. Cannot merge.",
+                    ce->name);
 }
 
 static int same(struct cache_entry *a, struct cache_entry *b)
@@ -395,23 +418,33 @@ static int same(struct cache_entry *a, struct cache_entry *b)
  * When a CE gets turned into an unmerged entry, we
  * want it to be up-to-date
  */
-static void verify_uptodate(struct cache_entry *ce,
+static int verify_uptodate(struct cache_entry *ce,
                struct unpack_trees_options *o)
 {
        struct stat st;
 
        if (o->index_only || o->reset)
-               return;
+               return 0;
 
        if (!lstat(ce->name, &st)) {
-               unsigned changed = ce_match_stat(ce, &st, 1);
+               unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID);
                if (!changed)
-                       return;
+                       return 0;
+               /*
+                * NEEDSWORK: the current default policy is to allow
+                * submodule to be out of sync wrt the supermodule
+                * index.  This needs to be tightened later for
+                * submodules that are marked to be automatically
+                * checked out.
+                */
+               if (S_ISGITLINK(ce->ce_mode))
+                       return 0;
                errno = 0;
        }
        if (errno == ENOENT)
-               return;
-       die("Entry '%s' not uptodate. Cannot merge.", ce->name);
+               return 0;
+       return o->gently ? -1 :
+               error("Entry '%s' not uptodate. Cannot merge.", ce->name);
 }
 
 static void invalidate_ce_path(struct cache_entry *ce)
@@ -447,7 +480,7 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
        int cnt = 0;
        unsigned char sha1[20];
 
-       if (S_ISGITLINK(ntohl(ce->ce_mode)) &&
+       if (S_ISGITLINK(ce->ce_mode) &&
            resolve_gitlink_ref(ce->name, "HEAD", sha1) == 0) {
                /* If we are not going to update the submodule, then
                 * we don't care.
@@ -477,8 +510,9 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
                 * ce->name is an entry in the subdirectory.
                 */
                if (!ce_stage(ce)) {
-                       verify_uptodate(ce, o);
-                       ce->ce_mode = 0;
+                       if (verify_uptodate(ce, o))
+                               return -1;
+                       ce->ce_flags |= CE_REMOVE;
                }
                cnt++;
        }
@@ -496,8 +530,9 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
                d.exclude_per_dir = o->dir->exclude_per_dir;
        i = read_directory(&d, ce->name, pathbuf, namelen+1, NULL);
        if (i)
-               die("Updating '%s' would lose untracked files in it",
-                   ce->name);
+               return o->gently ? -1 :
+                       error("Updating '%s' would lose untracked files in it",
+                             ce->name);
        free(pathbuf);
        return cnt;
 }
@@ -506,26 +541,27 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
  * We do not want to remove or overwrite a working tree file that
  * is not tracked, unless it is ignored.
  */
-static void verify_absent(struct cache_entry *ce, const char *action,
-               struct unpack_trees_options *o)
+static int verify_absent(struct cache_entry *ce, const char *action,
+                        struct unpack_trees_options *o)
 {
        struct stat st;
 
        if (o->index_only || o->reset || !o->update)
-               return;
+               return 0;
 
        if (has_symlink_leading_path(ce->name, NULL))
-               return;
+               return 0;
 
        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.
                         */
-                       return;
+                       return 0;
                if (S_ISDIR(st.st_mode)) {
                        /*
                         * We are checking out path "foo" and
@@ -554,7 +590,7 @@ static void verify_absent(struct cache_entry *ce, const char *action,
                         * deleted entries here.
                         */
                        o->pos += cnt;
-                       return;
+                       return 0;
                }
 
                /*
@@ -565,19 +601,21 @@ static void verify_absent(struct cache_entry *ce, const char *action,
                cnt = cache_name_pos(ce->name, strlen(ce->name));
                if (0 <= cnt) {
                        struct cache_entry *ce = active_cache[cnt];
-                       if (!ce_stage(ce) && !ce->ce_mode)
-                               return;
+                       if (ce->ce_flags & CE_REMOVE)
+                               return 0;
                }
 
-               die("Untracked working tree file '%s' "
-                   "would be %s by merge.", ce->name, action);
+               return o->gently ? -1 :
+                       error("Untracked working tree file '%s' "
+                             "would be %s by merge.", ce->name, action);
        }
+       return 0;
 }
 
 static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
                struct unpack_trees_options *o)
 {
-       merge->ce_flags |= htons(CE_UPDATE);
+       merge->ce_flags |= CE_UPDATE;
        if (old) {
                /*
                 * See if we can re-use the old CE directly?
@@ -587,18 +625,20 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
                 * a match.
                 */
                if (same(old, merge)) {
-                       *merge = *old;
+                       copy_cache_entry(merge, old);
                } else {
-                       verify_uptodate(old, o);
+                       if (verify_uptodate(old, o))
+                               return -1;
                        invalidate_ce_path(old);
                }
        }
        else {
-               verify_absent(merge, "overwritten", o);
+               if (verify_absent(merge, "overwritten", o))
+                       return -1;
                invalidate_ce_path(merge);
        }
 
-       merge->ce_flags &= ~htons(CE_STAGEMASK);
+       merge->ce_flags &= ~CE_STAGEMASK;
        add_cache_entry(merge, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
        return 1;
 }
@@ -606,11 +646,13 @@ static int merged_entry(struct cache_entry *merge, struct cache_entry *old,
 static int deleted_entry(struct cache_entry *ce, struct cache_entry *old,
                struct unpack_trees_options *o)
 {
-       if (old)
-               verify_uptodate(old, o);
-       else
-               verify_absent(ce, "removed", o);
-       ce->ce_mode = 0;
+       if (old) {
+               if (verify_uptodate(old, o))
+                       return -1;
+       } else
+               if (verify_absent(ce, "removed", o))
+                       return -1;
+       ce->ce_flags |= CE_REMOVE;
        add_cache_entry(ce, ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE);
        invalidate_ce_path(ce);
        return 1;
@@ -631,7 +673,7 @@ static void show_stage_entry(FILE *o,
        else
                fprintf(o, "%s%06o %s %d\t%s\n",
                        label,
-                       ntohl(ce->ce_mode),
+                       ce->ce_mode,
                        sha1_to_hex(ce->sha1),
                        ce_stage(ce),
                        ce->name);
@@ -639,7 +681,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;
@@ -696,16 +739,15 @@ int threeway_merge(struct cache_entry **stages,
        /* #14, #14ALT, #2ALT */
        if (remote && !df_conflict_head && head_match && !remote_match) {
                if (index && !same(index, remote) && !same(index, head))
-                       reject_merge(index);
+                       return o->gently ? -1 : reject_merge(index);
                return merged_entry(remote, index, o);
        }
        /*
         * If we have an entry in the index cache, then we want to
         * make sure that it matches head.
         */
-       if (index && !same(index, head)) {
-               reject_merge(index);
-       }
+       if (index && !same(index, head))
+               return o->gently ? -1 : reject_merge(index);
 
        if (head) {
                /* #5ALT, #15 */
@@ -717,8 +759,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.
@@ -750,10 +794,13 @@ 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)
-                               verify_absent(ce, "removed", o);
+                       else if (ce && !head_deleted) {
+                               if (verify_absent(ce, "removed", o))
+                                       return -1;
+                       }
                        return 0;
                }
                /*
@@ -769,9 +816,11 @@ int threeway_merge(struct cache_entry **stages,
         * conflict resolution files.
         */
        if (index) {
-               verify_uptodate(index, o);
+               if (verify_uptodate(index, o))
+                       return -1;
        }
 
+       remove_entry(remove);
        o->nontrivial_merge = 1;
 
        /* #2, #3, #4, #6, #7, #9, #10, #11. */
@@ -807,7 +856,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];
@@ -835,6 +885,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 &&
@@ -844,19 +895,20 @@ int twoway_merge(struct cache_entry **src,
                }
                else {
                        /* all other failures */
+                       remove_entry(remove);
                        if (oldtree)
-                               reject_merge(oldtree);
+                               return o->gently ? -1 : reject_merge(oldtree);
                        if (current)
-                               reject_merge(current);
+                               return o->gently ? -1 : reject_merge(current);
                        if (newtree)
-                               reject_merge(newtree);
+                               return o->gently ? -1 : reject_merge(newtree);
                        return -1;
                }
        }
        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);
 }
 
 /*
@@ -866,7 +918,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];
@@ -875,7 +928,8 @@ int bind_merge(struct cache_entry **src,
                return error("Cannot do a bind merge of %d trees\n",
                             o->merge_size);
        if (a && old)
-               die("Entry '%s' overlaps.  Cannot bind.", a->name);
+               return o->gently ? -1 :
+                       error("Entry '%s' overlaps.  Cannot bind.", a->name);
        if (!a)
                return keep_entry(old, o);
        else
@@ -889,7 +943,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];
@@ -898,14 +953,16 @@ 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;
                        if (lstat(old->name, &st) ||
-                           ce_match_stat(old, &st, 1))
-                               old->ce_flags |= htons(CE_UPDATE);
+                           ce_match_stat(old, &st, CE_MATCH_IGNORE_VALID))
+                               old->ce_flags |= CE_UPDATE;
                }
                return keep_entry(old, o);
        }