Merge branch 'maint'
authorShawn O. Pearce <spearce@spearce.org>
Thu, 9 Oct 2008 17:18:32 +0000 (10:18 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Thu, 9 Oct 2008 17:18:32 +0000 (10:18 -0700)
* maint:
builtin-apply: fix typo leading to stack corruption
git-stash.sh: fix flawed fix of invalid ref handling (commit da65e7c1)
builtin-merge.c: allocate correct amount of memory
Makefile: do not set NEEDS_LIBICONV for Solaris 8
rebase -i: remove leftover debugging
rebase -i: proper prepare-commit-msg hook argument when squashing

1  2 
Makefile
builtin-apply.c
builtin-merge.c
diff --combined Makefile
index 15ca6599a7b665d5d4888c00b0fecd7bbde28879,0d40f0ecca30a6c86f2f7016be02d8e936bc1dab..dd31e339fb8d28baaaba78ea09518de0171d35a5
+++ b/Makefile
@@@ -124,9 -124,6 +124,9 @@@ all:
  # Define USE_STDEV below if you want git to care about the underlying device
  # change being considered an inode change from the update-index perspective.
  #
 +# Define NO_ST_BLOCKS_IN_STRUCT_STAT if your platform does not have st_blocks
 +# field that counts the on-disk footprint in 512-byte blocks.
 +#
  # Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
  #
  # Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72.
@@@ -294,8 -291,8 +294,8 @@@ PROGRAMS += git-mktag$
  PROGRAMS += git-mktree$X
  PROGRAMS += git-pack-redundant$X
  PROGRAMS += git-patch-id$X
 -PROGRAMS += git-receive-pack$X
  PROGRAMS += git-send-pack$X
 +PROGRAMS += git-shell$X
  PROGRAMS += git-show-index$X
  PROGRAMS += git-unpack-file$X
  PROGRAMS += git-update-server-info$X
@@@ -357,8 -354,6 +357,8 @@@ LIB_H += git-compat-util.
  LIB_H += graph.h
  LIB_H += grep.h
  LIB_H += hash.h
 +LIB_H += help.h
 +LIB_H += levenshtein.h
  LIB_H += list-objects.h
  LIB_H += ll-merge.h
  LIB_H += log-tree.h
@@@ -435,7 -430,6 +435,7 @@@ LIB_OBJS += hash.
  LIB_OBJS += help.o
  LIB_OBJS += ident.o
  LIB_OBJS += interpolate.o
 +LIB_OBJS += levenshtein.o
  LIB_OBJS += list-objects.o
  LIB_OBJS += ll-merge.o
  LIB_OBJS += lockfile.o
@@@ -443,7 -437,6 +443,7 @@@ LIB_OBJS += log-tree.
  LIB_OBJS += mailmap.o
  LIB_OBJS += match-trees.o
  LIB_OBJS += merge-file.o
 +LIB_OBJS += merge-recursive.o
  LIB_OBJS += name-hash.o
  LIB_OBJS += object.o
  LIB_OBJS += pack-check.o
@@@ -525,7 -518,6 +525,7 @@@ BUILTIN_OBJS += builtin-for-each-ref.
  BUILTIN_OBJS += builtin-fsck.o
  BUILTIN_OBJS += builtin-gc.o
  BUILTIN_OBJS += builtin-grep.o
 +BUILTIN_OBJS += builtin-help.o
  BUILTIN_OBJS += builtin-init-db.o
  BUILTIN_OBJS += builtin-log.o
  BUILTIN_OBJS += builtin-ls-files.o
@@@ -546,7 -538,6 +546,7 @@@ BUILTIN_OBJS += builtin-prune-packed.
  BUILTIN_OBJS += builtin-prune.o
  BUILTIN_OBJS += builtin-push.o
  BUILTIN_OBJS += builtin-read-tree.o
 +BUILTIN_OBJS += builtin-receive-pack.o
  BUILTIN_OBJS += builtin-reflog.o
  BUILTIN_OBJS += builtin-remote.o
  BUILTIN_OBJS += builtin-rerere.o
@@@ -584,11 -575,9 +584,11 @@@ EXTLIBS 
  
  ifeq ($(uname_S),Linux)
        NO_STRLCPY = YesPlease
 +      THREADED_DELTA_SEARCH = YesPlease
  endif
  ifeq ($(uname_S),GNU/kFreeBSD)
        NO_STRLCPY = YesPlease
 +      THREADED_DELTA_SEARCH = YesPlease
  endif
  ifeq ($(uname_S),UnixWare)
        CC = cc
@@@ -650,7 -639,6 +650,6 @@@ ifeq ($(uname_S),SunOS
        NO_MKDTEMP = YesPlease
        OLD_ICONV = UnfortunatelyYes
        ifeq ($(uname_R),5.8)
-               NEEDS_LIBICONV = YesPlease
                NO_UNSETENV = YesPlease
                NO_SETENV = YesPlease
                NO_C99_FORMAT = YesPlease
@@@ -689,7 -677,6 +688,7 @@@ ifeq ($(uname_S),FreeBSD
        BASIC_CFLAGS += -I/usr/local/include
        BASIC_LDFLAGS += -L/usr/local/lib
        DIR_HAS_BSD_GROUP_SEMANTICS = YesPlease
 +      THREADED_DELTA_SEARCH = YesPlease
        COMPAT_CFLAGS += -Icompat/regex
        COMPAT_OBJS += compat/regex/regex.o
  endif
@@@ -699,15 -686,14 +698,15 @@@ ifeq ($(uname_S),OpenBSD
        NEEDS_LIBICONV = YesPlease
        BASIC_CFLAGS += -I/usr/local/include
        BASIC_LDFLAGS += -L/usr/local/lib
 +      THREADED_DELTA_SEARCH = YesPlease
  endif
  ifeq ($(uname_S),NetBSD)
        ifeq ($(shell expr "$(uname_R)" : '[01]\.'),2)
                NEEDS_LIBICONV = YesPlease
        endif
        BASIC_CFLAGS += -I/usr/pkg/include
 -      BASIC_LDFLAGS += -L/usr/pkg/lib
 -      ALL_LDFLAGS += -Wl,-rpath,/usr/pkg/lib
 +      BASIC_LDFLAGS += -L/usr/pkg/lib $(CC_LD_DYNPATH)/usr/pkg/lib
 +      THREADED_DELTA_SEARCH = YesPlease
  endif
  ifeq ($(uname_S),AIX)
        NO_STRCASESTR=YesPlease
@@@ -770,7 -756,6 +769,7 @@@ ifneq (,$(findstring MINGW,$(uname_S))
        NO_SVN_TESTS = YesPlease
        NO_PERL_MAKEMAKER = YesPlease
        NO_POSIX_ONLY_PROGRAMS = YesPlease
 +      NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
        COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/regex -Icompat/fnmatch
        COMPAT_CFLAGS += -DSNPRINTF_SIZE_CORR=1
        COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
@@@ -803,14 -788,12 +802,14 @@@ ifeq ($(uname_S),Darwin
        endif
  endif
  
 -ifdef NO_R_TO_GCC_LINKER
 -      # Some gcc does not accept and pass -R to the linker to specify
 -      # the runtime dynamic library path.
 -      CC_LD_DYNPATH = -Wl,-rpath=
 -else
 -      CC_LD_DYNPATH = -R
 +ifndef CC_LD_DYNPATH
 +      ifdef NO_R_TO_GCC_LINKER
 +              # Some gcc does not accept and pass -R to the linker to specify
 +              # the runtime dynamic library path.
 +              CC_LD_DYNPATH = -Wl,-rpath,
 +      else
 +              CC_LD_DYNPATH = -R
 +      endif
  endif
  
  ifdef NO_CURL
@@@ -846,6 -829,7 +845,6 @@@ EXTLIBS += -l
  ifndef NO_POSIX_ONLY_PROGRAMS
        PROGRAMS += git-daemon$X
        PROGRAMS += git-imap-send$X
 -      PROGRAMS += git-shell$X
  endif
  ifndef NO_OPENSSL
        OPENSSL_LIBSSL = -lssl
@@@ -886,9 -870,6 +885,9 @@@ endi
  ifdef NO_D_INO_IN_DIRENT
        BASIC_CFLAGS += -DNO_D_INO_IN_DIRENT
  endif
 +ifdef NO_ST_BLOCKS_IN_STRUCT_STAT
 +      BASIC_CFLAGS += -DNO_ST_BLOCKS_IN_STRUCT_STAT
 +endif
  ifdef NO_C99_FORMAT
        BASIC_CFLAGS += -DNO_C99_FORMAT
  endif
@@@ -1117,7 -1098,7 +1116,7 @@@ git$X: git.o $(BUILTIN_OBJS) $(GITLIBS
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \
                $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS)
  
 -help.o: help.c common-cmds.h GIT-CFLAGS
 +builtin-help.o: builtin-help.c common-cmds.h GIT-CFLAGS
        $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) \
                '-DGIT_HTML_PATH="$(htmldir_SQ)"' \
                '-DGIT_MAN_PATH="$(mandir_SQ)"' \
@@@ -1244,9 -1225,7 +1243,9 @@@ endi
  git-%$X: %.o $(GITLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
  
 -git-imap-send$X: imap-send.o $(LIB_FILE)
 +git-imap-send$X: imap-send.o $(GITLIBS)
 +      $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
 +              $(LIBS) $(OPENSSL_LINK) $(OPENSSL_LIBSSL)
  
  http.o http-walker.o http-push.o transport.o: http.h
  
@@@ -1273,12 -1252,6 +1272,12 @@@ $(XDIFF_LIB): $(XDIFF_OBJS
  doc:
        $(MAKE) -C Documentation all
  
 +man:
 +      $(MAKE) -C Documentation man
 +
 +html:
 +      $(MAKE) -C Documentation html
 +
  info:
        $(MAKE) -C Documentation info
  
@@@ -1382,7 -1355,7 +1381,7 @@@ install: al
        $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
        $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
        $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
 -      $(INSTALL) git$X git-upload-pack$X git-receive-pack$X git-upload-archive$X '$(DESTDIR_SQ)$(bindir_SQ)'
 +      $(INSTALL) git$X git-upload-pack$X git-receive-pack$X git-upload-archive$X git-shell$X git-cvsserver '$(DESTDIR_SQ)$(bindir_SQ)'
        $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
        $(MAKE) -C perl prefix='$(prefix_SQ)' DESTDIR='$(DESTDIR_SQ)' install
  ifndef NO_TCLTK
@@@ -1415,9 -1388,6 +1414,9 @@@ install-info
  quick-install-doc:
        $(MAKE) -C Documentation quick-install
  
 +quick-install-html:
 +      $(MAKE) -C Documentation quick-install-html
 +
  
  
  ### Maintainer's dist rules
diff --combined builtin-apply.c
index 342f2fe5e6476db7cb7b4647aea45a42d7ac7642,74f7e79241b1f8192ad00af39571ef59a796b8af..bf806105062caa47ca168720e0e987ac8957c8af
@@@ -1697,7 -1697,7 +1697,7 @@@ static int match_fragment(struct image 
                fixlen = ws_fix_copy(buf, orig, oldlen, ws_rule, NULL);
  
                /* Try fixing the line in the target */
-               if (sizeof(tgtfixbuf) < tgtlen)
+               if (sizeof(tgtfixbuf) > tgtlen)
                        tgtfix = tgtfixbuf;
                else
                        tgtfix = xmalloc(tgtlen);
@@@ -2989,45 -2989,29 +2989,45 @@@ static int write_out_results(struct pat
  
  static struct lock_file lock_file;
  
 -static struct excludes {
 -      struct excludes *next;
 -      const char *path;
 -} *excludes;
 +static struct string_list limit_by_name;
 +static int has_include;
 +static void add_name_limit(const char *name, int exclude)
 +{
 +      struct string_list_item *it;
 +
 +      it = string_list_append(name, &limit_by_name);
 +      it->util = exclude ? NULL : (void *) 1;
 +}
  
  static int use_patch(struct patch *p)
  {
        const char *pathname = p->new_name ? p->new_name : p->old_name;
 -      struct excludes *x = excludes;
 -      while (x) {
 -              if (fnmatch(x->path, pathname, 0) == 0)
 -                      return 0;
 -              x = x->next;
 -      }
 +      int i;
 +
 +      /* Paths outside are not touched regardless of "--include" */
        if (0 < prefix_length) {
                int pathlen = strlen(pathname);
                if (pathlen <= prefix_length ||
                    memcmp(prefix, pathname, prefix_length))
                        return 0;
        }
 -      return 1;
 +
 +      /* See if it matches any of exclude/include rule */
 +      for (i = 0; i < limit_by_name.nr; i++) {
 +              struct string_list_item *it = &limit_by_name.items[i];
 +              if (!fnmatch(it->string, pathname, 0))
 +                      return (it->util != NULL);
 +      }
 +
 +      /*
 +       * If we had any include, a path that does not match any rule is
 +       * not used.  Otherwise, we saw bunch of exclude rules (or none)
 +       * and such a path is used.
 +       */
 +      return !has_include;
  }
  
 +
  static void prefix_one(char **name)
  {
        char *old_name = *name;
@@@ -3168,12 -3152,10 +3168,12 @@@ int cmd_apply(int argc, const char **ar
                        continue;
                }
                if (!prefixcmp(arg, "--exclude=")) {
 -                      struct excludes *x = xmalloc(sizeof(*x));
 -                      x->path = arg + 10;
 -                      x->next = excludes;
 -                      excludes = x;
 +                      add_name_limit(arg + 10, 1);
 +                      continue;
 +              }
 +              if (!prefixcmp(arg, "--include=")) {
 +                      add_name_limit(arg + 10, 0);
 +                      has_include = 1;
                        continue;
                }
                if (!prefixcmp(arg, "-p")) {
diff --combined builtin-merge.c
index dcf898778202c3e4cfb249c1013a2bb59d8f7645,d0bf1fc1edb5fc7783669e4086210a521a3ab6e3..fa7c95472c984b0a8325aa61a75137c0a8c1e36e
@@@ -22,8 -22,6 +22,8 @@@
  #include "log-tree.h"
  #include "color.h"
  #include "rerere.h"
 +#include "help.h"
 +#include "merge-recursive.h"
  
  #define DEFAULT_TWOHEAD (1<<0)
  #define DEFAULT_OCTOPUS (1<<1)
@@@ -79,9 -77,7 +79,9 @@@ static int option_parse_message(const s
  static struct strategy *get_strategy(const char *name)
  {
        int i;
 -      struct strbuf err;
 +      struct strategy *ret;
 +      static struct cmdnames main_cmds, other_cmds;
 +      static int loaded;
  
        if (!name)
                return NULL;
                if (!strcmp(name, all_strategy[i].name))
                        return &all_strategy[i];
  
 -      strbuf_init(&err, 0);
 -      for (i = 0; i < ARRAY_SIZE(all_strategy); i++)
 -              strbuf_addf(&err, " %s", all_strategy[i].name);
 -      fprintf(stderr, "Could not find merge strategy '%s'.\n", name);
 -      fprintf(stderr, "Available strategies are:%s.\n", err.buf);
 -      exit(1);
 +      if (!loaded) {
 +              struct cmdnames not_strategies;
 +              loaded = 1;
 +
 +              memset(&not_strategies, 0, sizeof(struct cmdnames));
 +              load_command_list("git-merge-", &main_cmds, &other_cmds);
 +              for (i = 0; i < main_cmds.cnt; i++) {
 +                      int j, found = 0;
 +                      struct cmdname *ent = main_cmds.names[i];
 +                      for (j = 0; j < ARRAY_SIZE(all_strategy); j++)
 +                              if (!strncmp(ent->name, all_strategy[j].name, ent->len)
 +                                              && !all_strategy[j].name[ent->len])
 +                                      found = 1;
 +                      if (!found)
 +                              add_cmdname(&not_strategies, ent->name, ent->len);
 +                      exclude_cmds(&main_cmds, &not_strategies);
 +              }
 +      }
 +      if (!is_in_cmdlist(&main_cmds, name) && !is_in_cmdlist(&other_cmds, name)) {
 +              fprintf(stderr, "Could not find merge strategy '%s'.\n", name);
 +              fprintf(stderr, "Available strategies are:");
 +              for (i = 0; i < main_cmds.cnt; i++)
 +                      fprintf(stderr, " %s", main_cmds.names[i]->name);
 +              fprintf(stderr, ".\n");
 +              if (other_cmds.cnt) {
 +                      fprintf(stderr, "Available custom strategies are:");
 +                      for (i = 0; i < other_cmds.cnt; i++)
 +                              fprintf(stderr, " %s", other_cmds.names[i]->name);
 +                      fprintf(stderr, ".\n");
 +              }
 +              exit(1);
 +      }
 +
 +      ret = xcalloc(1, sizeof(struct strategy));
 +      ret->name = xstrdup(name);
 +      return ret;
  }
  
  static void append_strategy(struct strategy *s)
@@@ -547,65 -513,28 +547,65 @@@ static int try_merge_strategy(const cha
        struct commit_list *j;
        struct strbuf buf;
  
 -      args = xmalloc((4 + commit_list_count(common) +
 -                      commit_list_count(remoteheads)) * sizeof(char *));
 -      strbuf_init(&buf, 0);
 -      strbuf_addf(&buf, "merge-%s", strategy);
 -      args[i++] = buf.buf;
 -      for (j = common; j; j = j->next)
 -              args[i++] = xstrdup(sha1_to_hex(j->item->object.sha1));
 -      args[i++] = "--";
 -      args[i++] = head_arg;
 -      for (j = remoteheads; j; j = j->next)
 -              args[i++] = xstrdup(sha1_to_hex(j->item->object.sha1));
 -      args[i] = NULL;
 -      ret = run_command_v_opt(args, RUN_GIT_CMD);
 -      strbuf_release(&buf);
 -      i = 1;
 -      for (j = common; j; j = j->next)
 -              free((void *)args[i++]);
 -      i += 2;
 -      for (j = remoteheads; j; j = j->next)
 -              free((void *)args[i++]);
 -      free(args);
 -      return -ret;
 +      if (!strcmp(strategy, "recursive") || !strcmp(strategy, "subtree")) {
 +              int clean;
 +              struct commit *result;
 +              struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
 +              int index_fd;
 +              struct commit_list *reversed = NULL;
 +              struct merge_options o;
 +
 +              if (remoteheads->next) {
 +                      error("Not handling anything other than two heads merge.");
 +                      return 2;
 +              }
 +
 +              init_merge_options(&o);
 +              if (!strcmp(strategy, "subtree"))
 +                      o.subtree_merge = 1;
 +
 +              o.branch1 = head_arg;
 +              o.branch2 = remoteheads->item->util;
 +
 +              for (j = common; j; j = j->next)
 +                      commit_list_insert(j->item, &reversed);
 +
 +              index_fd = hold_locked_index(lock, 1);
 +              clean = merge_recursive(&o, lookup_commit(head),
 +                              remoteheads->item, reversed, &result);
 +              if (active_cache_changed &&
 +                              (write_cache(index_fd, active_cache, active_nr) ||
 +                               commit_locked_index(lock)))
 +                      die ("unable to write %s", get_index_file());
 +              rollback_lock_file(lock);
 +              return clean ? 0 : 1;
 +      } else {
 +              args = xmalloc((4 + commit_list_count(common) +
 +                                      commit_list_count(remoteheads)) * sizeof(char *));
 +              strbuf_init(&buf, 0);
 +              strbuf_addf(&buf, "merge-%s", strategy);
 +              args[i++] = buf.buf;
 +              for (j = common; j; j = j->next)
 +                      args[i++] = xstrdup(sha1_to_hex(j->item->object.sha1));
 +              args[i++] = "--";
 +              args[i++] = head_arg;
 +              for (j = remoteheads; j; j = j->next)
 +                      args[i++] = xstrdup(sha1_to_hex(j->item->object.sha1));
 +              args[i] = NULL;
 +              ret = run_command_v_opt(args, RUN_GIT_CMD);
 +              strbuf_release(&buf);
 +              i = 1;
 +              for (j = common; j; j = j->next)
 +                      free((void *)args[i++]);
 +              i += 2;
 +              for (j = remoteheads; j; j = j->next)
 +                      free((void *)args[i++]);
 +              free(args);
 +              discard_cache();
 +              if (read_cache() < 0)
 +                      die("failed to read the cache");
 +              return -ret;
 +      }
  }
  
  static void count_diff_files(struct diff_queue_struct *q,
@@@ -722,15 -651,15 +722,15 @@@ static void add_strategies(const char *
  static int merge_trivial(void)
  {
        unsigned char result_tree[20], result_commit[20];
-       struct commit_list *parent = xmalloc(sizeof(struct commit_list *));
+       struct commit_list *parent = xmalloc(sizeof(*parent));
  
        write_tree_trivial(result_tree);
        printf("Wonderful.\n");
        parent->item = lookup_commit(head);
-       parent->next = xmalloc(sizeof(struct commit_list *));
+       parent->next = xmalloc(sizeof(*parent->next));
        parent->next->item = remoteheads->item;
        parent->next->next = NULL;
 -      commit_tree(merge_msg.buf, result_tree, parent, result_commit);
 +      commit_tree(merge_msg.buf, result_tree, parent, result_commit, NULL);
        finish(result_commit, "In-index merge");
        drop_save();
        return 0;
@@@ -759,7 -688,7 +759,7 @@@ static int finish_automerge(struct comm
        }
        free_commit_list(remoteheads);
        strbuf_addch(&merge_msg, '\n');
 -      commit_tree(merge_msg.buf, result_tree, parents, result_commit);
 +      commit_tree(merge_msg.buf, result_tree, parents, result_commit, NULL);
        strbuf_addf(&buf, "Merge made by %s.", wt_strategy);
        finish(result_commit, buf.buf);
        strbuf_release(&buf);
@@@ -816,6 -745,10 +816,6 @@@ static int evaluate_result(void
        int cnt = 0;
        struct rev_info rev;
  
 -      discard_cache();
 -      if (read_cache() < 0)
 -              die("failed to read the cache");
 -
        /* Check how many files differ. */
        init_revisions(&rev, "");
        setup_revisions(0, NULL, &rev, NULL);
@@@ -903,11 -836,6 +903,11 @@@ int cmd_merge(int argc, const char **ar
                if (argc != 1)
                        die("Can merge only exactly one commit into "
                                "empty head");
 +              if (squash)
 +                      die("Squash commit into empty head not supported yet");
 +              if (!allow_fast_forward)
 +                      die("Non-fast-forward commit does not make sense into "
 +                          "an empty head");
                remote_head = peel_to_type(argv[0], 0, NULL, OBJ_COMMIT);
                if (!remote_head)
                        die("%s - not something we can merge", argv[0]);
  
        for (i = 0; i < argc; i++) {
                struct object *o;
 +              struct commit *commit;
  
                o = peel_to_type(argv[i], 0, NULL, OBJ_COMMIT);
                if (!o)
                        die("%s - not something we can merge", argv[i]);
 -              remotes = &commit_list_insert(lookup_commit(o->sha1),
 -                      remotes)->next;
 +              commit = lookup_commit(o->sha1);
 +              commit->util = (void *)argv[i];
 +              remotes = &commit_list_insert(commit, remotes)->next;
  
                strbuf_addf(&buf, "GITHEAD_%s", sha1_to_hex(o->sha1));
                setenv(buf.buf, argv[i], 1);
                }
  
                /* Automerge succeeded. */
 -              discard_cache();
                write_tree_trivial(result_tree);
                automerge_was_ok = 1;
                break;