Skip to content

rebase -i: fix re-reading the todo list when newly created objects are referenced #2121

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions sequencer.c
Original file line number Diff line number Diff line change
Expand Up @@ -2136,7 +2136,8 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
item->arg_len = (int)(eol - item->arg);

if (status < 0)
return -1;
return error(_("could not parse '%.*s'"),
(int)(end_of_object_name - bol), bol);

item->commit = lookup_commit_reference(r, &commit_oid);
return !item->commit;
Expand Down Expand Up @@ -3639,14 +3640,14 @@ static int pick_commits(struct repository *r,
res = do_exec(r, item->arg);
*end_of_arg = saved;

/* Reread the todo file if it has changed. */
if (res) {
if (opts->reschedule_failed_exec)
reschedule = 1;
} else if (stat(get_todo_path(opts), &st))
res = error_errno(_("could not stat '%s'"),
get_todo_path(opts));
else if (match_stat_data(&todo_list->stat, &st)) {
/* Reread the todo file if it has changed. */
todo_list_release(todo_list);
if (read_populate_todo(r, todo_list, opts))
res = -1; /* message was printed */
Expand Down
12 changes: 12 additions & 0 deletions sha1-name.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,18 @@ static enum get_oid_result get_short_oid(const char *name, int len,
find_short_packed_object(&ds);
status = finish_object_disambiguation(&ds, oid);

/*
* If we didn't find it, do the usual reprepare() slow-path,
* since the object may have recently been added to the repository
* or migrated from loose to packed.
*/
if (status == MISSING_OBJECT) {
reprepare_packed_git(the_repository);
find_short_object_filename(&ds);
find_short_packed_object(&ds);
status = finish_object_disambiguation(&ds, oid);
}

if (!quietly && (status == SHORT_NAME_AMBIGUOUS)) {
struct oid_array collect = OID_ARRAY_INIT;

Expand Down
22 changes: 22 additions & 0 deletions t/t3429-rebase-edit-todo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,26 @@ test_expect_success 'rebase exec modifies rebase-todo' '
test -e F
'

test_expect_success SHA1 'loose object cache vs re-reading todo list' '
GIT_REBASE_TODO=.git/rebase-merge/git-rebase-todo &&
export GIT_REBASE_TODO &&
write_script append-todo.sh <<-\EOS &&
# For values 5 and 6, this yields SHA-1s with the same first two digits
echo "pick $(git rev-parse --short \
$(printf "%s\\n" \
"tree $EMPTY_TREE" \
"author A U Thor <author@example.org> $1 +0000" \
"committer A U Thor <author@example.org> $1 +0000" \
"" \
"$1" |
git hash-object -t commit -w --stdin))" >>$GIT_REBASE_TODO

shift
test -z "$*" ||
echo "exec $0 $*" >>$GIT_REBASE_TODO
EOS

git rebase HEAD -x "./append-todo.sh 5 6"
'

test_done