{"thread":{"id":"51435","subject":"[RFC/PATCH v1] merge - make squash a 1-step operation","startedAt":"2019-07-05T16:56:50Z","lastAt":"2019-07-05T17:01:45Z","messageCount":2,"participants":["Edmundo Carmona Antoranz"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"378629","messageId":"20190705165624.22243-1-eantoranz@gmail.com","threadId":"51435","inReplyTo":null,"subject":"[RFC/PATCH v1] merge - make squash a 1-step operation","fromName":"Edmundo Carmona Antoranz","fromEmail":"eantoranz@gmail.com","sentAt":"2019-07-05T16:56:24Z","receivedAt":"2019-07-05T16:56:50Z","isPatch":true,"sender":{"key":"eantoranz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1491018?v=4"},"body":"---\n builtin/merge.c | 63 +++++++++++++++++++++++++------------------------\n 1 file changed, 32 insertions(+), 31 deletions(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 6e99aead46..d5745a7888 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -64,6 +64,7 @@ static int option_edit = -1;\n static int allow_trivial = 1, have_message, verify_signatures;\n static int overwrite_ignore = 1;\n static struct strbuf merge_msg = STRBUF_INIT;\n+static struct strbuf squash_msg = STRBUF_INIT;\n static struct strategy **use_strategies;\n static size_t use_strategies_nr, use_strategies_alloc;\n static const char **xopts;\n@@ -390,12 +391,9 @@ static void finish_up_to_date(const char *msg)\n static void squash_message(struct commit *commit, struct commit_list *remoteheads)\n {\n \tstruct rev_info rev;\n-\tstruct strbuf out = STRBUF_INIT;\n \tstruct commit_list *j;\n \tstruct pretty_print_context ctx = {0};\n \n-\tprintf(_(\"Squash commit -- not updating HEAD\\n\"));\n-\n \trepo_init_revisions(the_repository, &rev, NULL);\n \trev.ignore_merges = 1;\n \trev.commit_format = CMIT_FMT_MEDIUM;\n@@ -414,15 +412,13 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead\n \tctx.date_mode = rev.date_mode;\n \tctx.fmt = rev.commit_format;\n \n-\tstrbuf_addstr(&out, \"Squashed commit of the following:\\n\");\n+\tstrbuf_addstr(&squash_msg, \"Squashed commit of the following:\\n\");\n \twhile ((commit = get_revision(&rev)) != NULL) {\n-\t\tstrbuf_addch(&out, '\\n');\n-\t\tstrbuf_addf(&out, \"commit %s\\n\",\n+\t\tstrbuf_addch(&squash_msg, '\\n');\n+\t\tstrbuf_addf(&squash_msg, \"commit %s\\n\",\n \t\t\toid_to_hex(&commit->object.oid));\n-\t\tpretty_print_commit(&ctx, commit, &out);\n+\t\tpretty_print_commit(&ctx, commit, &squash_msg);\n \t}\n-\twrite_file_buf(git_path_squash_msg(the_repository), out.buf, out.len);\n-\tstrbuf_release(&out);\n }\n \n static void finish(struct commit *head_commit,\n@@ -440,8 +436,12 @@ static void finish(struct commit *head_commit,\n \t\tstrbuf_addf(&reflog_message, \"%s: %s\",\n \t\t\tgetenv(\"GIT_REFLOG_ACTION\"), msg);\n \t}\n-\tif (squash) {\n+\tif (squash && !squash_msg.len) {\n+\t\t// message hasn't been calculated, that means we are stopping the squash process so the user can finish it\n \t\tsquash_message(head_commit, remoteheads);\n+\t\twrite_file_buf(git_path_squash_msg(the_repository), squash_msg.buf, squash_msg.len);\n+\t\tif (option_commit > 0)\n+\t\t\tprintf(_(\"Squash conflicts -- not updating HEAD\\n\"));\n \t} else {\n \t\tif (verbosity >= 0 && !merge_msg.len)\n \t\t\tprintf(_(\"No merge message -- not updating HEAD\\n\"));\n@@ -893,13 +893,21 @@ static int finish_automerge(struct commit *head,\n \tstruct object_id result_commit;\n \n \tfree_commit_list(common);\n-\tparents = remoteheads;\n-\tif (!head_subsumed || fast_forward == FF_NO)\n-\t\tcommit_list_insert(head, &parents);\n-\tprepare_to_commit(remoteheads);\n-\tif (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parents,\n-\t\t\t&result_commit, NULL, sign_commit))\n-\t\tdie(_(\"failed to write commit object\"));\n+\tif (squash) {\n+\t\tsquash_message(head, remoteheads);\n+\t\tparents = commit_list_insert(head, &parents);\n+\t\tif (commit_tree(squash_msg.buf, squash_msg.len, result_tree, parents,\n+\t\t\t\t&result_commit, NULL, sign_commit))\n+\t\t\tdie(_(\"failed to write commit object on squash\"));\n+\t} else {\n+\t\tparents = remoteheads;\n+\t\tif (!head_subsumed || fast_forward == FF_NO)\n+\t\t\tcommit_list_insert(head, &parents);\n+\t\tprepare_to_commit(remoteheads);\n+\t\tif (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parents,\n+\t\t\t\t&result_commit, NULL, sign_commit))\n+\t\t\tdie(_(\"failed to write commit object\"));\n+\t}\n \tstrbuf_addf(&buf, \"Merge made by the '%s' strategy.\", wt_strategy);\n \tfinish(head, remoteheads, &result_commit, buf.buf);\n \tstrbuf_release(&buf);\n@@ -1342,18 +1350,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \tif (verbosity < 0)\n \t\tshow_diffstat = 0;\n \n-\tif (squash) {\n-\t\tif (fast_forward == FF_NO)\n-\t\t\tdie(_(\"You cannot combine --squash with --no-ff.\"));\n-\t\tif (option_commit > 0)\n-\t\t\tdie(_(\"You cannot combine --squash with --commit.\"));\n-\t\t/*\n-\t\t * squash can now silently disable option_commit - this is not\n-\t\t * a problem as it is only overriding the default, not a user\n-\t\t * supplied option.\n-\t\t */\n-\t\toption_commit = 0;\n-\t}\n+\tif (squash && fast_forward == FF_NO)\n+\t\tdie(_(\"You cannot combine --squash with --no-ff.\"));\n \n \tif (option_commit < 0)\n \t\toption_commit = 1;\n@@ -1682,8 +1680,11 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\twrite_merge_state(remoteheads);\n \n \tif (merge_was_ok)\n-\t\tfprintf(stderr, _(\"Automatic merge went well; \"\n-\t\t\t\"stopped before committing as requested\\n\"));\n+\t\tif (!option_commit)\n+\t\t\tfprintf(stderr, _(\"Automatic merge went well; \"\n+\t\t\t\t\"stopped before committing as requested\\n\"));\n+\t\telse\n+\t\t\t;\n \telse\n \t\tret = suggest_conflicts();\n \n-- \n2.22.0.214.g8dca754b1e.dirty\n\n"},{"id":"378630","messageId":"CAOc6etYRSRJm34X1=x7nh6PyhypF3nTvKSqzDhDCzOrNXyZkQw@mail.gmail.com","threadId":"51435","inReplyTo":"20190705165624.22243-1-eantoranz@gmail.com","subject":"Re: [RFC/PATCH v1] merge - make squash a 1-step operation","fromName":"Edmundo Carmona Antoranz","fromEmail":"eantoranz@gmail.com","sentAt":"2019-07-05T17:01:33Z","receivedAt":"2019-07-05T17:01:45Z","isPatch":true,"sender":{"key":"eantoranz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1491018?v=4"},"body":"On Fri, Jul 5, 2019 at 10:56 AM Edmundo Carmona Antoranz\n<eantoranz@gmail.com> wrote:\n>\n> ---\n>  builtin/merge.c | 63 +++++++++++++++++++++++++------------------------\n>  1 file changed, 32 insertions(+), 31 deletions(-)\n>\n\nThis would be a first step in order to achieve the dream of having\nrebase/squash in a single step. Let the flame-fest begin. I'm\nwondering if it makes sense to support -m with squash or if we should\nkeep the default message with all the revisions that are being\nsquashed (perhaps erroring out if the user mixes --squash and -m, just\nlike mixing --squash and --no-ff)\n\nThanks in advance for your feedback.\n"}]}