1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-29 14:26:11 +02:00

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>
This commit is contained in:
Johannes Schindelin 2017-01-02 16:28:16 +01:00 committed by Junio C Hamano
parent 8ab37ef21f
commit 25cb8df97c

View File

@ -95,6 +95,15 @@ static GIT_PATH_FUNC(rebase_path_amend, "rebase-merge/amend")
* the abbreviated commit name of the corresponding patch.
*/
static GIT_PATH_FUNC(rebase_path_stopped_sha, "rebase-merge/stopped-sha")
/*
* For the post-rewrite hook, we make a list of rewritten commits and
* their new sha1s. The rewritten-pending list keeps the sha1s of
* commits that have been processed, but not committed yet,
* e.g. because they are waiting for a 'squash' command.
*/
static GIT_PATH_FUNC(rebase_path_rewritten_list, "rebase-merge/rewritten-list")
static GIT_PATH_FUNC(rebase_path_rewritten_pending,
"rebase-merge/rewritten-pending")
/*
* The following files are written by git-rebase just after parsing the
* command-line (and are only consumed, not modified, by the sequencer).
@ -850,6 +859,44 @@ static int update_squash_messages(enum todo_command command,
return res;
}
static void flush_rewritten_pending(void) {
struct strbuf buf = STRBUF_INIT;
unsigned char newsha1[20];
FILE *out;
if (strbuf_read_file(&buf, rebase_path_rewritten_pending(), 82) > 0 &&
!get_sha1("HEAD", newsha1) &&
(out = fopen(rebase_path_rewritten_list(), "a"))) {
char *bol = buf.buf, *eol;
while (*bol) {
eol = strchrnul(bol, '\n');
fprintf(out, "%.*s %s\n", (int)(eol - bol),
bol, sha1_to_hex(newsha1));
if (!*eol)
break;
bol = eol + 1;
}
fclose(out);
unlink(rebase_path_rewritten_pending());
}
strbuf_release(&buf);
}
static void record_in_rewritten(struct object_id *oid,
enum todo_command next_command) {
FILE *out = fopen(rebase_path_rewritten_pending(), "a");
if (!out)
return;
fprintf(out, "%s\n", oid_to_hex(oid));
fclose(out);
if (!is_fixup(next_command))
flush_rewritten_pending();
}
static int do_pick_commit(enum todo_command command, struct commit *commit,
struct replay_opts *opts, int final_fixup)
{
@ -1743,6 +1790,17 @@ static int is_final_fixup(struct todo_list *todo_list)
return 1;
}
static enum todo_command peek_command(struct todo_list *todo_list, int offset)
{
int i;
for (i = todo_list->current + offset; i < todo_list->nr; i++)
if (!is_noop(todo_list->items[i].command))
return todo_list->items[i].command;
return -1;
}
static const char *reflog_message(struct replay_opts *opts,
const char *sub_action, const char *fmt, ...)
{
@ -1801,6 +1859,9 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
item->arg, item->arg_len, opts, res,
!res);
}
if (is_rebase_i(opts) && !res)
record_in_rewritten(&item->commit->object.oid,
peek_command(todo_list, 1));
if (res && is_fixup(item->command)) {
if (res == 1)
intend_to_amend();
@ -1827,6 +1888,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
if (is_rebase_i(opts)) {
struct strbuf head_ref = STRBUF_INIT, buf = STRBUF_INIT;
struct stat st;
/* Stopped in the middle, as planned? */
if (todo_list->current < todo_list->nr)
@ -1891,6 +1953,20 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
log_tree_diff_flush(&log_tree_opt);
}
}
flush_rewritten_pending();
if (!stat(rebase_path_rewritten_list(), &st) &&
st.st_size > 0) {
struct child_process child = CHILD_PROCESS_INIT;
child.in = open(rebase_path_rewritten_list(), O_RDONLY);
child.git_cmd = 1;
argv_array_push(&child.args, "notes");
argv_array_push(&child.args, "copy");
argv_array_push(&child.args, "--for-rewrite=rebase");
/* we don't care if this copying failed */
run_command(&child);
}
strbuf_release(&buf);
strbuf_release(&head_ref);
}