sequencer (rebase -i): copy commit notes at end

When rebasing commits that have commit notes attached, the interactive rebase rewrites those notes faithfully at the end. The sequencer must do this, too, if it wishes to do interactive rebase's job. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Jan 2, 2017 at 16:28 UTC 25cb8df97c9be26d7638e79595d361fbc40b65a0
1 file changed +76
sequencer.c
+76
@@ -95,6 +95,15 @@ static GIT_PATH_FUNC(rebase_path_amend, "rebase-merge/amend")
95 * the abbreviated commit name of the corresponding patch.
96 */
97 static GIT_PATH_FUNC(rebase_path_stopped_sha, "rebase-merge/stopped-sha")
98 +/*
99 + * For the post-rewrite hook, we make a list of rewritten commits and
100 + * their new sha1s. The rewritten-pending list keeps the sha1s of
101 + * commits that have been processed, but not committed yet,
102 + * e.g. because they are waiting for a 'squash' command.
103 + */
104 +static GIT_PATH_FUNC(rebase_path_rewritten_list, "rebase-merge/rewritten-list")
105 +static GIT_PATH_FUNC(rebase_path_rewritten_pending,
106 + "rebase-merge/rewritten-pending")
107 /*
108 * The following files are written by git-rebase just after parsing the
109 * command-line (and are only consumed, not modified, by the sequencer).
@@ -850,6 +859,44 @@ static int update_squash_messages(enum todo_command command,
859 return res;
860 }
861
862 +static void flush_rewritten_pending(void) {
863 + struct strbuf buf = STRBUF_INIT;
864 + unsigned char newsha1[20];
865 + FILE *out;
866 +
867 + if (strbuf_read_file(&buf, rebase_path_rewritten_pending(), 82) > 0 &&
868 + !get_sha1("HEAD", newsha1) &&
869 + (out = fopen(rebase_path_rewritten_list(), "a"))) {
870 + char *bol = buf.buf, *eol;
871 +
872 + while (*bol) {
873 + eol = strchrnul(bol, '\n');
874 + fprintf(out, "%.*s %s\n", (int)(eol - bol),
875 + bol, sha1_to_hex(newsha1));
876 + if (!*eol)
877 + break;
878 + bol = eol + 1;
879 + }
880 + fclose(out);
881 + unlink(rebase_path_rewritten_pending());
882 + }
883 + strbuf_release(&buf);
884 +}
885 +
886 +static void record_in_rewritten(struct object_id *oid,
887 + enum todo_command next_command) {
888 + FILE *out = fopen(rebase_path_rewritten_pending(), "a");
889 +
890 + if (!out)
891 + return;
892 +
893 + fprintf(out, "%s\n", oid_to_hex(oid));
894 + fclose(out);
895 +
896 + if (!is_fixup(next_command))
897 + flush_rewritten_pending();
898 +}
899 +
900 static int do_pick_commit(enum todo_command command, struct commit *commit,
901 struct replay_opts *opts, int final_fixup)
902 {
@@ -1743,6 +1790,17 @@ static int is_final_fixup(struct todo_list *todo_list)
1790 return 1;
1791 }
1792
1793 +static enum todo_command peek_command(struct todo_list *todo_list, int offset)
1794 +{
1795 + int i;
1796 +
1797 + for (i = todo_list->current + offset; i < todo_list->nr; i++)
1798 + if (!is_noop(todo_list->items[i].command))
1799 + return todo_list->items[i].command;
1800 +
1801 + return -1;
1802 +}
1803 +
1804 static const char *reflog_message(struct replay_opts *opts,
1805 const char *sub_action, const char *fmt, ...)
1806 {
@@ -1801,6 +1859,9 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
1859 item->arg, item->arg_len, opts, res,
1860 !res);
1861 }
1862 + if (is_rebase_i(opts) && !res)
1863 + record_in_rewritten(&item->commit->object.oid,
1864 + peek_command(todo_list, 1));
1865 if (res && is_fixup(item->command)) {
1866 if (res == 1)
1867 intend_to_amend();
@@ -1827,6 +1888,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
1888
1889 if (is_rebase_i(opts)) {
1890 struct strbuf head_ref = STRBUF_INIT, buf = STRBUF_INIT;
1891 + struct stat st;
1892
1893 /* Stopped in the middle, as planned? */
1894 if (todo_list->current < todo_list->nr)
@@ -1891,6 +1953,20 @@ cleanup_head_ref:
1953 log_tree_diff_flush(&log_tree_opt);
1954 }
1955 }
1956 + flush_rewritten_pending();
1957 + if (!stat(rebase_path_rewritten_list(), &st) &&
1958 + st.st_size > 0) {
1959 + struct child_process child = CHILD_PROCESS_INIT;
1960 +
1961 + child.in = open(rebase_path_rewritten_list(), O_RDONLY);
1962 + child.git_cmd = 1;
1963 + argv_array_push(&child.args, "notes");
1964 + argv_array_push(&child.args, "copy");
1965 + argv_array_push(&child.args, "--for-rewrite=rebase");
1966 + /* we don't care if this copying failed */
1967 + run_command(&child);
1968 + }
1969 +
1970 strbuf_release(&buf);
1971 strbuf_release(&head_ref);
1972 }