X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=builtin%2Fmerge.c;h=dffd5ec1245865259fd4e72cc304286a1a5b4633;hb=82bc9f515c93cdb66f87092c7e270b8de112919f;hp=7d593097dea987e580d1e79f010faf23c1f98fb0;hpb=288396994f077eec7e7db0017838a5afbfbf81e3;p=git.git diff --git a/builtin/merge.c b/builtin/merge.c index 7d593097d..dffd5ec12 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -46,7 +46,7 @@ static const char * const builtin_merge_usage[] = { static int show_diffstat = 1, shortlog_len, squash; static int option_commit = 1, allow_fast_forward = 1; -static int fast_forward_only; +static int fast_forward_only, option_edit; static int allow_trivial = 1, have_message; static struct strbuf merge_msg; static struct commit_list *remoteheads; @@ -189,6 +189,8 @@ static struct option builtin_merge_options[] = { "create a single commit instead of doing a merge"), OPT_BOOLEAN(0, "commit", &option_commit, "perform a commit if the merge succeeds (default)"), + OPT_BOOLEAN('e', "edit", &option_edit, + "edit message before committing"), OPT_BOOLEAN(0, "ff", &allow_fast_forward, "allow fast-forward (default)"), OPT_BOOLEAN(0, "ff-only", &fast_forward_only, @@ -843,30 +845,54 @@ static void add_strategies(const char *string, unsigned attr) } -static void write_merge_msg(void) +static void write_merge_msg(struct strbuf *msg) { int fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666); if (fd < 0) die_errno(_("Could not open '%s' for writing"), git_path("MERGE_MSG")); - if (write_in_full(fd, merge_msg.buf, merge_msg.len) != merge_msg.len) + if (write_in_full(fd, msg->buf, msg->len) != msg->len) die_errno(_("Could not write to '%s'"), git_path("MERGE_MSG")); close(fd); } -static void read_merge_msg(void) +static void read_merge_msg(struct strbuf *msg) { - strbuf_reset(&merge_msg); - if (strbuf_read_file(&merge_msg, git_path("MERGE_MSG"), 0) < 0) + strbuf_reset(msg); + if (strbuf_read_file(msg, git_path("MERGE_MSG"), 0) < 0) die_errno(_("Could not read from '%s'"), git_path("MERGE_MSG")); } -static void run_prepare_commit_msg(void) +static void write_merge_state(void); +static void abort_commit(const char *err_msg) { - write_merge_msg(); + if (err_msg) + error("%s", err_msg); + fprintf(stderr, + _("Not committing merge; use 'git commit' to complete the merge.\n")); + write_merge_state(); + exit(1); +} + +static void prepare_to_commit(void) +{ + struct strbuf msg = STRBUF_INIT; + strbuf_addbuf(&msg, &merge_msg); + strbuf_addch(&msg, '\n'); + write_merge_msg(&msg); run_hook(get_index_file(), "prepare-commit-msg", git_path("MERGE_MSG"), "merge", NULL, NULL); - read_merge_msg(); + if (option_edit) { + if (launch_editor(git_path("MERGE_MSG"), NULL, NULL)) + abort_commit(NULL); + } + read_merge_msg(&msg); + stripspace(&msg, option_edit); + if (!msg.len) + abort_commit(_("Empty commit message.")); + strbuf_release(&merge_msg); + strbuf_addbuf(&merge_msg, &msg); + strbuf_release(&msg); } static int merge_trivial(struct commit *head) @@ -880,7 +906,7 @@ static int merge_trivial(struct commit *head) parent->next = xmalloc(sizeof(*parent->next)); parent->next->item = remoteheads->item; parent->next->next = NULL; - run_prepare_commit_msg(); + prepare_to_commit(); commit_tree(merge_msg.buf, result_tree, parent, result_commit, NULL); finish(head, result_commit, "In-index merge"); drop_save(); @@ -909,9 +935,9 @@ static int finish_automerge(struct commit *head, for (j = remoteheads; j; j = j->next) pptr = &commit_list_insert(j->item, pptr)->next; } - free_commit_list(remoteheads); strbuf_addch(&merge_msg, '\n'); - run_prepare_commit_msg(); + prepare_to_commit(); + free_commit_list(remoteheads); commit_tree(merge_msg.buf, result_tree, parents, result_commit, NULL); strbuf_addf(&buf, "Merge made by the '%s' strategy.", wt_strategy); finish(head, result_commit, buf.buf); @@ -1018,6 +1044,36 @@ static int setup_with_upstream(const char ***argv) return i; } +static void write_merge_state(void) +{ + int fd; + struct commit_list *j; + struct strbuf buf = STRBUF_INIT; + + for (j = remoteheads; j; j = j->next) + strbuf_addf(&buf, "%s\n", + sha1_to_hex(j->item->object.sha1)); + fd = open(git_path("MERGE_HEAD"), O_WRONLY | O_CREAT, 0666); + if (fd < 0) + die_errno(_("Could not open '%s' for writing"), + git_path("MERGE_HEAD")); + if (write_in_full(fd, buf.buf, buf.len) != buf.len) + die_errno(_("Could not write to '%s'"), git_path("MERGE_HEAD")); + close(fd); + strbuf_addch(&merge_msg, '\n'); + write_merge_msg(&merge_msg); + fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fd < 0) + die_errno(_("Could not open '%s' for writing"), + git_path("MERGE_MODE")); + strbuf_reset(&buf); + if (!allow_fast_forward) + strbuf_addf(&buf, "no-ff"); + if (write_in_full(fd, buf.buf, buf.len) != buf.len) + die_errno(_("Could not write to '%s'"), git_path("MERGE_MODE")); + close(fd); +} + int cmd_merge(int argc, const char **argv, const char *prefix) { unsigned char result_tree[20]; @@ -1423,33 +1479,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix) if (squash) finish(head_commit, NULL, NULL); - else { - int fd; - struct commit_list *j; - - for (j = remoteheads; j; j = j->next) - strbuf_addf(&buf, "%s\n", - sha1_to_hex(j->item->object.sha1)); - fd = open(git_path("MERGE_HEAD"), O_WRONLY | O_CREAT, 0666); - if (fd < 0) - die_errno(_("Could not open '%s' for writing"), - git_path("MERGE_HEAD")); - if (write_in_full(fd, buf.buf, buf.len) != buf.len) - die_errno(_("Could not write to '%s'"), git_path("MERGE_HEAD")); - close(fd); - strbuf_addch(&merge_msg, '\n'); - write_merge_msg(); - fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666); - if (fd < 0) - die_errno(_("Could not open '%s' for writing"), - git_path("MERGE_MODE")); - strbuf_reset(&buf); - if (!allow_fast_forward) - strbuf_addf(&buf, "no-ff"); - if (write_in_full(fd, buf.buf, buf.len) != buf.len) - die_errno(_("Could not write to '%s'"), git_path("MERGE_MODE")); - close(fd); - } + else + write_merge_state(); if (merge_was_ok) { fprintf(stderr, _("Automatic merge went well; "