Make the replay_opts_release() function added in the preceding commit
non-static, and use it for freeing the "struct replay_opts"
constructed for "rebase" and "revert".
To safely call our new replay_opts_release() we'll need to stop
calling it in sequencer_remove_state(), and instead call it where we
allocate the "struct replay_opts" itself.
This is because in e.g. do_interactive_rebase() we construct a "struct
replay_opts" with "get_replay_opts()", and then call
"complete_action()". If we get far enough in that function without
encountering errors we'll call "pick_commits()" which (indirectly)
calls sequencer_remove_state() at the end.
But if we encounter errors anywhere along the way we'd punt out early,
and not free() the memory we allocated. Remembering whether we
previously called sequencer_remove_state() would be a hassle.
Using a FREE_AND_NULL() pattern would also work, as it would be safe
to call replay_opts_release() repeatedly. But let's fix this properly
instead, by having the owner of the data free() it.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Ævar Arnfjörð Bjarmason committedFeb 6, 2023 at 20:08 UTC9ff2f0606915cf76fc4865bddf639fd5fd2cba29
19 files changed+23-5
builtin/rebase.c
+4
index c97ce642cf..2ec3ae0b42 100644--- a/builtin/rebase.c+++ b/builtin/rebase.c@@ -297,6 +297,7 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags) } cleanup:+ replay_opts_release(&replay); free(revisions); free(shortrevisions); todo_list_release(&todo_list);@@ -338,6 +339,7 @@ static int run_sequencer_rebase(struct rebase_options *opts) struct replay_opts replay_opts = get_replay_opts(opts); ret = sequencer_continue(the_repository, &replay_opts);+ replay_opts_release(&replay_opts); break; } case ACTION_EDIT_TODO:@@ -553,6 +555,7 @@ static int finish_rebase(struct rebase_options *opts) replay.action = REPLAY_INTERACTIVE_REBASE; ret = sequencer_remove_state(&replay);+ replay_opts_release(&replay); } else { strbuf_addstr(&dir, opts->state_dir); if (remove_dir_recursively(&dir, 0))@@ -1324,6 +1327,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) replay.action = REPLAY_INTERACTIVE_REBASE; ret = sequencer_remove_state(&replay);+ replay_opts_release(&replay); } else { strbuf_reset(&buf); strbuf_addstr(&buf, options.state_dir);
builtin/revert.c
+2
index f2d86d2a8f..1cab16bf3e 100644--- a/builtin/revert.c+++ b/builtin/revert.c@@ -251,6 +251,7 @@ int cmd_revert(int argc, const char **argv, const char *prefix) if (opts.revs) release_revisions(opts.revs); free(opts.revs);+ replay_opts_release(&opts); return res; }@@ -267,5 +268,6 @@ int cmd_cherry_pick(int argc, const char **argv, const char *prefix) free(opts.revs); if (res < 0) die(_("cherry-pick failed"));+ replay_opts_release(&opts); return res; }
index 58371d8a54..e75b3d0e07 100755--- a/t/t3412-rebase-root.sh+++ b/t/t3412-rebase-root.sh@@ -7,6 +7,7 @@ Tests if git rebase --root --onto <newparent> can rebase the root commit. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME+TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh log_with_names () {
t/t3419-rebase-patch-id.sh
+1
index 7181f176b8..6c61f240cf 100755--- a/t/t3419-rebase-patch-id.sh+++ b/t/t3419-rebase-patch-id.sh@@ -5,6 +5,7 @@ test_description='git rebase - test patch id computation' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME+TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh scramble () {
t/t3423-rebase-reword.sh
+1
index 4859bb8f72..2fab703d61 100755--- a/t/t3423-rebase-reword.sh+++ b/t/t3423-rebase-reword.sh@@ -2,6 +2,7 @@ test_description='git rebase interactive with rewording'+TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh
t/t3425-rebase-topology-merges.sh
+2
index 63acc1ea4d..a16428bdf5 100755--- a/t/t3425-rebase-topology-merges.sh+++ b/t/t3425-rebase-topology-merges.sh@@ -1,6 +1,8 @@ #!/bin/sh test_description='rebase topology tests with merges'++TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh
t/t3437-rebase-fixup-options.sh
+1
index c023fefd68..274699dadb 100755--- a/t/t3437-rebase-fixup-options.sh+++ b/t/t3437-rebase-fixup-options.sh@@ -14,6 +14,7 @@ to the "fixup" command that works with "fixup!", "fixup -C" works with "amend!" upon --autosquash. '+TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh
t/t3438-rebase-broken-files.sh
+2
index b92a3ce46b..c614c4f2e4 100755--- a/t/t3438-rebase-broken-files.sh+++ b/t/t3438-rebase-broken-files.sh@@ -1,6 +1,8 @@ #!/bin/sh test_description='rebase behavior when on-disk files are broken'++TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up conflicting branches' '
t/t3501-revert-cherry-pick.sh
+1
index 1f4cfc3744..2f3e3e2416 100755--- a/t/t3501-revert-cherry-pick.sh+++ b/t/t3501-revert-cherry-pick.sh@@ -13,6 +13,7 @@ test_description='test cherry-pick and revert with renames GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME+TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup '
t/t3502-cherry-pick-merge.sh
+1
index 5495eacfec..1b2c0d6aca 100755--- a/t/t3502-cherry-pick-merge.sh+++ b/t/t3502-cherry-pick-merge.sh@@ -11,6 +11,7 @@ test_description='cherry picking and reverting a merge GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME+TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup '