46
* actions.
47
*/
48
static GIT_PATH_FUNC(rebase_path_done, "rebase-merge/done")
49
+/*
50
+ * The commit message that is planned to be used for any changes that
51
+ * need to be committed following a user interaction.
52
+ */
53
+static GIT_PATH_FUNC(rebase_path_message, "rebase-merge/message")
54
+/*
55
+ * The file into which is accumulated the suggested commit message for
56
+ * squash/fixup commands. When the first of a series of squash/fixups
57
+ * is seen, the file is created and the commit message from the
58
+ * previous commit and from the first squash/fixup commit are written
59
+ * to it. The commit message for each subsequent squash/fixup commit
60
+ * is appended to the file as it is processed.
61
+ *
62
+ * The first line of the file is of the form
63
+ * # This is a combination of $count commits.
64
+ * where $count is the number of commits whose messages have been
65
+ * written to the file so far (including the initial "pick" commit).
66
+ * Each time that a commit message is processed, this line is read and
67
+ * updated. It is deleted just before the combined commit is made.
68
+ */
69
+static GIT_PATH_FUNC(rebase_path_squash_msg, "rebase-merge/message-squash")
70
+/*
71
+ * If the current series of squash/fixups has not yet included a squash
72
+ * command, then this file exists and holds the commit message of the
73
+ * original "pick" commit. (If the series ends without a "squash"
74
+ * command, then this can be used as the commit message of the combined
75
+ * commit without opening the editor.)
76
+ */
77
+static GIT_PATH_FUNC(rebase_path_fixup_msg, "rebase-merge/message-fixup")
78
/*
79
* A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
80
* GIT_AUTHOR_DATE that will be used for the commit that is currently
670
TODO_PICK = 0,
671
TODO_REVERT,
672
TODO_EDIT,
673
+ TODO_FIXUP,
674
+ TODO_SQUASH,
675
/* commands that do something else than handling a single commit */
676
TODO_EXEC,
677
/* commands that do nothing but are counted for reporting progress */
682
"pick",
683
"revert",
684
"edit",
685
+ "fixup",
686
+ "squash",
687
"exec",
688
"noop"
689
};
700
return TODO_NOOP <= (size_t)command;
701
}
702
703
+static int is_fixup(enum todo_command command)
704
+{
705
+ return command == TODO_FIXUP || command == TODO_SQUASH;
706
+}
707
+
708
+static int update_squash_messages(enum todo_command command,
709
+ struct commit *commit, struct replay_opts *opts)
710
+{
711
+ struct strbuf buf = STRBUF_INIT;
712
+ int count, res;
713
+ const char *message, *body;
714
+
715
+ if (file_exists(rebase_path_squash_msg())) {
716
+ struct strbuf header = STRBUF_INIT;
717
+ char *eol, *p;
718
+
719
+ if (strbuf_read_file(&buf, rebase_path_squash_msg(), 2048) <= 0)
720
+ return error(_("could not read '%s'"),
721
+ rebase_path_squash_msg());
722
+
723
+ p = buf.buf + 1;
724
+ eol = strchrnul(buf.buf, '\n');
725
+ if (buf.buf[0] != comment_line_char ||
726
+ (p += strcspn(p, "0123456789\n")) == eol)
727
+ return error(_("unexpected 1st line of squash message:"
728
+ "\n\n\t%.*s"),
729
+ (int)(eol - buf.buf), buf.buf);
730
+ count = strtol(p, NULL, 10);
731
+
732
+ if (count < 1)
733
+ return error(_("invalid 1st line of squash message:\n"
734
+ "\n\t%.*s"),
735
+ (int)(eol - buf.buf), buf.buf);
736
+
737
+ strbuf_addf(&header, "%c ", comment_line_char);
738
+ strbuf_addf(&header,
739
+ _("This is a combination of %d commits."), ++count);
740
+ strbuf_splice(&buf, 0, eol - buf.buf, header.buf, header.len);
741
+ strbuf_release(&header);
742
+ } else {
743
+ unsigned char head[20];
744
+ struct commit *head_commit;
745
+ const char *head_message, *body;
746
+
747
+ if (get_sha1("HEAD", head))
748
+ return error(_("need a HEAD to fixup"));
749
+ if (!(head_commit = lookup_commit_reference(head)))
750
+ return error(_("could not read HEAD"));
751
+ if (!(head_message = get_commit_buffer(head_commit, NULL)))
752
+ return error(_("could not read HEAD's commit message"));
753
+
754
+ find_commit_subject(head_message, &body);
755
+ if (write_message(body, strlen(body),
756
+ rebase_path_fixup_msg(), 0)) {
757
+ unuse_commit_buffer(head_commit, head_message);
758
+ return error(_("cannot write '%s'"),
759
+ rebase_path_fixup_msg());
760
+ }
761
+
762
+ count = 2;
763
+ strbuf_addf(&buf, "%c ", comment_line_char);
764
+ strbuf_addf(&buf, _("This is a combination of %d commits."),
765
+ count);
766
+ strbuf_addf(&buf, "\n%c ", comment_line_char);
767
+ strbuf_addstr(&buf, _("This is the 1st commit message:"));
768
+ strbuf_addstr(&buf, "\n\n");
769
+ strbuf_addstr(&buf, body);
770
+
771
+ unuse_commit_buffer(head_commit, head_message);
772
+ }
773
+
774
+ if (!(message = get_commit_buffer(commit, NULL)))
775
+ return error(_("could not read commit message of %s"),
776
+ oid_to_hex(&commit->object.oid));
777
+ find_commit_subject(message, &body);
778
+
779
+ if (command == TODO_SQUASH) {
780
+ unlink(rebase_path_fixup_msg());
781
+ strbuf_addf(&buf, "\n%c ", comment_line_char);
782
+ strbuf_addf(&buf, _("This is the commit message #%d:"), count);
783
+ strbuf_addstr(&buf, "\n\n");
784
+ strbuf_addstr(&buf, body);
785
+ } else if (command == TODO_FIXUP) {
786
+ strbuf_addf(&buf, "\n%c ", comment_line_char);
787
+ strbuf_addf(&buf, _("The commit message #%d will be skipped:"),
788
+ count);
789
+ strbuf_addstr(&buf, "\n\n");
790
+ strbuf_add_commented_lines(&buf, body, strlen(body));
791
+ } else
792
+ return error(_("unknown command: %d"), command);
793
+ unuse_commit_buffer(commit, message);
794
+
795
+ res = write_message(buf.buf, buf.len, rebase_path_squash_msg(), 0);
796
+ strbuf_release(&buf);
797
+ return res;
798
+}
799
+
800
static int do_pick_commit(enum todo_command command, struct commit *commit,
671
- struct replay_opts *opts)
801
+ struct replay_opts *opts, int final_fixup)
802
{
803
+ int edit = opts->edit, cleanup_commit_message = 0;
804
+ const char *msg_file = edit ? NULL : git_path_merge_msg();
805
unsigned char head[20];
806
struct commit *base, *next, *parent;
807
const char *base_label, *next_label;
808
struct commit_message msg = { NULL, NULL, NULL, NULL };
809
struct strbuf msgbuf = STRBUF_INIT;
678
- int res, unborn = 0, allow;
810
+ int res, unborn = 0, amend = 0, allow;
811
812
if (opts->no_commit) {
813
/*
852
else
853
parent = commit->parents->item;
854
723
- if (opts->allow_ff &&
855
+ if (opts->allow_ff && !is_fixup(command) &&
856
((parent && !hashcmp(parent->object.oid.hash, head)) ||
857
(!parent && unborn)))
858
return fast_forward_to(commit->object.oid.hash, head, unborn, opts);
911
}
912
}
913
914
+ if (is_fixup(command)) {
915
+ if (update_squash_messages(command, commit, opts))
916
+ return -1;
917
+ amend = 1;
918
+ if (!final_fixup)
919
+ msg_file = rebase_path_squash_msg();
920
+ else if (file_exists(rebase_path_fixup_msg())) {
921
+ cleanup_commit_message = 1;
922
+ msg_file = rebase_path_fixup_msg();
923
+ } else {
924
+ const char *dest = git_path("SQUASH_MSG");
925
+ unlink(dest);
926
+ if (copy_file(dest, rebase_path_squash_msg(), 0666))
927
+ return error(_("could not rename '%s' to '%s'"),
928
+ rebase_path_squash_msg(), dest);
929
+ unlink(git_path("MERGE_MSG"));
930
+ msg_file = dest;
931
+ edit = 1;
932
+ }
933
+ }
934
+
935
if (!opts->strategy || !strcmp(opts->strategy, "recursive") || command == TODO_REVERT) {
936
res = do_recursive_merge(base, next, base_label, next_label,
937
head, &msgbuf, opts);
987
goto leave;
988
}
989
if (!opts->no_commit)
837
- res = run_git_commit(opts->edit ? NULL : git_path_merge_msg(),
838
- opts, allow, opts->edit, 0, 0);
990
+ res = run_git_commit(msg_file, opts, allow, edit, amend,
991
+ cleanup_commit_message);
992
+
993
+ if (!res && final_fixup) {
994
+ unlink(rebase_path_fixup_msg());
995
+ unlink(rebase_path_squash_msg());
996
+ }
997
998
leave:
999
free_message(commit, &msg);
1134
{
1135
struct todo_item *item;
1136
char *p = buf, *next_p;
979
- int i, res = 0;
1137
+ int i, res = 0, fixup_okay = file_exists(rebase_path_done());
1138
1139
for (i = 1; *p; i++, p = next_p) {
1140
char *eol = strchrnul(p, '\n');
1149
if (parse_insn_line(item, p, eol)) {
1150
res = error(_("invalid line %d: %.*s"),
1151
i, (int)(eol - p), p);
994
- item->command = -1;
1152
+ item->command = TODO_NOOP;
1153
}
1154
+
1155
+ if (fixup_okay)
1156
+ ; /* do nothing */
1157
+ else if (is_fixup(item->command))
1158
+ return error(_("cannot '%s' without a previous commit"),
1159
+ command_to_string(item->command));
1160
+ else if (!is_noop(item->command))
1161
+ fixup_okay = 1;
1162
}
1163
if (!todo_list->nr)
1164
return error(_("no commits parsed."));
1601
return exit_code;
1602
}
1603
1604
+static int error_failed_squash(struct commit *commit,
1605
+ struct replay_opts *opts, int subject_len, const char *subject)
1606
+{
1607
+ if (rename(rebase_path_squash_msg(), rebase_path_message()))
1608
+ return error(_("could not rename '%s' to '%s'"),
1609
+ rebase_path_squash_msg(), rebase_path_message());
1610
+ unlink(rebase_path_fixup_msg());
1611
+ unlink(git_path("MERGE_MSG"));
1612
+ if (copy_file(git_path("MERGE_MSG"), rebase_path_message(), 0666))
1613
+ return error(_("could not copy '%s' to '%s'"),
1614
+ rebase_path_message(), git_path("MERGE_MSG"));
1615
+ return error_with_patch(commit, subject, subject_len, opts, 1, 0);
1616
+}
1617
+
1618
static int do_exec(const char *command_line)
1619
{
1620
const char *child_argv[] = { NULL, NULL };
1655
return status;
1656
}
1657
1658
+static int is_final_fixup(struct todo_list *todo_list)
1659
+{
1660
+ int i = todo_list->current;
1661
+
1662
+ if (!is_fixup(todo_list->items[i].command))
1663
+ return 0;
1664
+
1665
+ while (++i < todo_list->nr)
1666
+ if (is_fixup(todo_list->items[i].command))
1667
+ return 0;
1668
+ else if (!is_noop(todo_list->items[i].command))
1669
+ break;
1670
+ return 1;
1671
+}
1672
+
1673
static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
1674
{
1675
int res = 0;
1685
struct todo_item *item = todo_list->items + todo_list->current;
1686
if (save_todo(todo_list, opts))
1687
return -1;
1493
- if (item->command <= TODO_EDIT) {
1688
+ if (is_rebase_i(opts)) {
1689
+ unlink(rebase_path_message());
1690
+ unlink(rebase_path_author_script());
1691
+ unlink(rebase_path_stopped_sha());
1692
+ unlink(rebase_path_amend());
1693
+ }
1694
+ if (item->command <= TODO_SQUASH) {
1695
res = do_pick_commit(item->command, item->commit,
1495
- opts);
1696
+ opts, is_final_fixup(todo_list));
1697
if (item->command == TODO_EDIT) {
1698
struct commit *commit = item->commit;
1699
if (!res)
1704
item->arg, item->arg_len, opts, res,
1705
!res);
1706
}
1707
+ if (res && is_fixup(item->command)) {
1708
+ if (res == 1)
1709
+ intend_to_amend();
1710
+ return error_failed_squash(item->commit, opts,
1711
+ item->arg_len, item->arg);
1712
+ }
1713
} else if (item->command == TODO_EXEC) {
1714
char *end_of_arg = (char *)(item->arg + item->arg_len);
1715
int saved = *end_of_arg;
1808
{
1809
setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
1810
return do_pick_commit(opts->action == REPLAY_PICK ?
1604
- TODO_PICK : TODO_REVERT, cmit, opts);
1811
+ TODO_PICK : TODO_REVERT, cmit, opts, 0);
1812
}
1813
1814
int sequencer_pick_revisions(struct replay_opts *opts)