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
}