@ -95,6 +95,15 @@ static GIT_PATH_FUNC(rebase_path_amend, "rebase-merge/amend")
@@ -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,
@@ -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)
@@ -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)
@@ -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)
@@ -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 @@ cleanup_head_ref:
@@ -1891,6 +1953,20 @@ cleanup_head_ref:
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);
}