Skip to content

Commit 0998b64

Browse files
committed
Merge branch 'sh/rebase-i-reread-todo-after-exec'
"git rebase -i" failed to re-read the todo list file when the command specified with the `exec` instruction updated it. * sh/rebase-i-reread-todo-after-exec: rebase -i: reread the todo list if `exec` touched it
2 parents 3c0a7b9 + 54fd324 commit 0998b64

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

sequencer.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,7 @@ struct todo_list {
12001200
struct todo_item *items;
12011201
int nr, alloc, current;
12021202
int done_nr, total_nr;
1203+
struct stat_data stat;
12031204
};
12041205

12051206
#define TODO_LIST_INIT { STRBUF_INIT }
@@ -1330,6 +1331,7 @@ static int count_commands(struct todo_list *todo_list)
13301331
static int read_populate_todo(struct todo_list *todo_list,
13311332
struct replay_opts *opts)
13321333
{
1334+
struct stat st;
13331335
const char *todo_file = get_todo_path(opts);
13341336
int fd, res;
13351337

@@ -1343,6 +1345,11 @@ static int read_populate_todo(struct todo_list *todo_list,
13431345
}
13441346
close(fd);
13451347

1348+
res = stat(todo_file, &st);
1349+
if (res)
1350+
return error(_("could not stat '%s'"), todo_file);
1351+
fill_stat_data(&todo_list->stat, &st);
1352+
13461353
res = parse_insn_buffer(todo_list->buf.buf, todo_list);
13471354
if (res) {
13481355
if (is_rebase_i(opts))
@@ -2028,10 +2035,25 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
20282035
} else if (item->command == TODO_EXEC) {
20292036
char *end_of_arg = (char *)(item->arg + item->arg_len);
20302037
int saved = *end_of_arg;
2038+
struct stat st;
20312039

20322040
*end_of_arg = '\0';
20332041
res = do_exec(item->arg);
20342042
*end_of_arg = saved;
2043+
2044+
/* Reread the todo file if it has changed. */
2045+
if (res)
2046+
; /* fall through */
2047+
else if (stat(get_todo_path(opts), &st))
2048+
res = error_errno(_("could not stat '%s'"),
2049+
get_todo_path(opts));
2050+
else if (match_stat_data(&todo_list->stat, &st)) {
2051+
todo_list_release(todo_list);
2052+
if (read_populate_todo(todo_list, opts))
2053+
res = -1; /* message was printed */
2054+
/* `current` will be incremented below */
2055+
todo_list->current = -1;
2056+
}
20352057
} else if (!is_noop(item->command))
20362058
return error(_("unknown command %d"), item->command);
20372059

t/t3429-rebase-edit-todo.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/sh
2+
3+
test_description='rebase should reread the todo file if an exec modifies it'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success 'rebase exec modifies rebase-todo' '
8+
test_commit initial &&
9+
todo=.git/rebase-merge/git-rebase-todo &&
10+
git rebase HEAD -x "echo exec touch F >>$todo" &&
11+
test -e F
12+
'
13+
14+
test_done

0 commit comments

Comments
 (0)