sequencer: rewrite update-refs as user edits todo list

An interactive rebase provides opportunities for the user to edit the
todo list. The --update-refs option initializes the list with some
'update-ref <ref>' steps, but the user could add these manually.
Further, the user could add or remove these steps during pauses in the
interactive rebase.

Add a new method, todo_list_filter_update_refs(), that scans a todo_list
and compares it to the stored update-refs file. There are two actions
that can happen at this point:

1. If a '<ref>/<before>/<after>' triple in the update-refs file does not
   have a matching 'update-ref <ref>' command in the todo-list _and_ the
   <after> value is the null OID, then remove that triple. Here, the
   user removed the 'update-ref <ref>' command before it was executed,
   since if it was executed then the <after> value would store the
   commit at that position.

2. If a 'update-ref <ref>' command in the todo-list does not have a
   matching '<ref>/<before>/<after>' triple in the update-refs file,
   then insert a new one. Store the <before> value to be the current
   OID pointed at by <ref>. This is handled inside of the
   init_update_ref_record() helper method.

We can test that this works by rewriting the todo-list several times in
the course of a rebase. Check that each ref is locked or unlocked for
updates after each todo-list update. We can also verify that the ref
update fails if a concurrent process updates one of the refs after the
rebase process records the "locked" ref location.

To help these tests, add a new 'set_replace_editor' helper that will
replace the todo-list with an exact file.

Reported-by: Phillip Wood <phillip.wood123@gmail.com>
Signed-off-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Derrick Stolee
2022-07-19 18:33:41 +00:00
committed by Junio C Hamano
parent 89fc0b53fd
commit b3b1a21d1a
5 changed files with 268 additions and 0 deletions

View File

@ -207,3 +207,18 @@ check_reworded_commits () {
>reword-log &&
test_cmp reword-expected reword-log
}
# usage: set_replace_editor <file>
#
# Replace the todo file with the exact contents of the given file.
set_replace_editor () {
cat >script <<-\EOF &&
cat FILENAME >"$1"
echo 'rebase -i script after editing:'
cat "$1"
EOF
sed -e "s/FILENAME/$1/g" <script | write_script fake-editor.sh &&
test_set_editor "$(pwd)/fake-editor.sh"
}