diff options
Diffstat (limited to 'builtin-merge.c')
-rw-r--r-- | builtin-merge.c | 71 |
1 files changed, 56 insertions, 15 deletions
diff --git a/builtin-merge.c b/builtin-merge.c index dde0c7e..9ad9791 100644 --- a/builtin-merge.c +++ b/builtin-merge.c @@ -22,6 +22,7 @@ #include "log-tree.h" #include "color.h" #include "rerere.h" +#include "help.h" #define DEFAULT_TWOHEAD (1<<0) #define DEFAULT_OCTOPUS (1<<1) @@ -77,7 +78,9 @@ static int option_parse_message(const struct option *opt, 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; @@ -86,12 +89,43 @@ static struct strategy *get_strategy(const char *name) 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(¬_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(¬_strategies, ent->name, ent->len); + exclude_cmds(&main_cmds, ¬_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 = xmalloc(sizeof(struct strategy)); + memset(ret, 0, sizeof(struct strategy)); + ret->name = xstrdup(name); + return ret; } static void append_strategy(struct strategy *s) @@ -564,8 +598,7 @@ static int checkout_fast_forward(unsigned char *head, unsigned char *remote) struct dir_struct dir; struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file)); - if (read_cache_unmerged()) - die("you need to resolve your current index first"); + refresh_cache(REFRESH_QUIET); fd = hold_locked_index(lock_file, 1); @@ -650,13 +683,15 @@ static void add_strategies(const char *string, unsigned attr) static int merge_trivial(void) { unsigned char result_tree[20], result_commit[20]; - struct commit_list parent; + struct commit_list *parent = xmalloc(sizeof(struct commit_list *)); write_tree_trivial(result_tree); printf("Wonderful.\n"); - parent.item = remoteheads->item; - parent.next = NULL; - commit_tree(merge_msg.buf, result_tree, &parent, result_commit); + parent->item = lookup_commit(head); + parent->next = xmalloc(sizeof(struct commit_list *)); + parent->next->item = remoteheads->item; + parent->next->next = NULL; + commit_tree(merge_msg.buf, result_tree, parent, result_commit); finish(result_commit, "In-index merge"); drop_save(); return 0; @@ -742,6 +777,7 @@ static int evaluate_result(void) int cnt = 0; struct rev_info rev; + discard_cache(); if (read_cache() < 0) die("failed to read the cache"); @@ -775,7 +811,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) struct commit_list **remotes = &remoteheads; setup_work_tree(); - if (unmerged_cache()) + if (read_cache_unmerged()) die("You are in the middle of a conflicted merge."); /* @@ -832,6 +868,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix) 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]); @@ -936,7 +977,6 @@ int cmd_merge(int argc, const char **argv, const char *prefix) hex, find_unique_abbrev(remoteheads->item->object.sha1, DEFAULT_ABBREV)); - refresh_cache(REFRESH_QUIET); strbuf_init(&msg, 0); strbuf_addstr(&msg, "Fast forward"); if (have_message) @@ -1073,6 +1113,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) } /* Automerge succeeded. */ + discard_cache(); write_tree_trivial(result_tree); automerge_was_ok = 1; break; |