diff mbox series

[v4,3/8] rebase --merge: fix reflog when continuing

Message ID 2c965f4b97c1773abc6b844b87fa64c5d6d1524c.1666344108.git.gitgitgadget@gmail.com (mailing list archive)
State Accepted
Commit da1d63363f13d4d65c59564c74fd8dd598b39c49
Headers show
Series rebase: make reflog messages independent of the backend | expand

Commit Message

Phillip Wood Oct. 21, 2022, 9:21 a.m. UTC
From: Phillip Wood <phillip.wood@dunelm.org.uk>

The reflog message for a conflict resolution committed by "rebase
--continue" looks like

	rebase (continue): commit subject line

Unfortunately the reflog message each subsequent pick look like

	rebase (continue) (pick): commit subject line

Fix this by setting the reflog message for "rebase --continue" in
sequencer_continue() so it does not affect subsequent commits. This
introduces a memory leak similar to the one leaking GIT_REFLOG_ACTION
in pick_commits(). Both of these will be fixed in a future series that
stops the sequencer calling setenv().

If we fail to commit the staged changes then we error out so
GIT_REFLOG_ACTION does not need to be reset in that case.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
 builtin/rebase.c          | 2 --
 sequencer.c               | 5 +++++
 t/t3406-rebase-message.sh | 9 +++++++--
 3 files changed, 12 insertions(+), 4 deletions(-)

Comments

Junio C Hamano Oct. 21, 2022, 5:37 p.m. UTC | #1
"Phillip Wood via GitGitGadget" <gitgitgadget@gmail.com> writes:

> ... This
> introduces a memory leak similar to the one leaking GIT_REFLOG_ACTION
> in pick_commits().

Is it just the matter of freeing previous_reflog_action after you
call setenv(), or does it take much more involved changes?

> Both of these will be fixed in a future series that
> stops the sequencer calling setenv().

If it gets fixed in a future step in the same series, that is a
different matter, but if it is easy enough not to deliberately
introduce a new leak, we'd prefer to do so.
Phillip Wood Oct. 25, 2022, 10:08 a.m. UTC | #2
Hi Junio

On 21/10/2022 18:37, Junio C Hamano wrote:
> "Phillip Wood via GitGitGadget" <gitgitgadget@gmail.com> writes:
> 
>> ... This
>> introduces a memory leak similar to the one leaking GIT_REFLOG_ACTION
>> in pick_commits().
> 
> Is it just the matter of freeing previous_reflog_action after you
> call setenv(), or does it take much more involved changes?

We should be freeing previous_reflog_action - I had misremembered a 
previous discussion about setenv() but the manual page makes it quite 
clear that it copies the strings passed to it. However we call setenv() 
each time we pick a commit and that leaks the previous value. The 
solution is to avoid calling setenv() at all and instead use the env 
member of struct child_process when we run "git commit".

>> Both of these will be fixed in a future series that
>> stops the sequencer calling setenv().
> 
> If it gets fixed in a future step in the same series, that is a
> different matter, but if it is easy enough not to deliberately
> introduce a new leak, we'd prefer to do so.

It's a couple of patches to fix which are more or less finished, I'm 
planning to send them once this series is in next.

Best Wishes

Phillip
Junio C Hamano Oct. 25, 2022, 4:11 p.m. UTC | #3
Phillip Wood <phillip.wood123@gmail.com> writes:

>>> Both of these will be fixed in a future series that
>>> stops the sequencer calling setenv().
>> If it gets fixed in a future step in the same series, that is a
>> different matter, but if it is easy enough not to deliberately
>> introduce a new leak, we'd prefer to do so.
>
> It's a couple of patches to fix which are more or less finished, I'm
> planning to send them once this series is in next.

So we will do the "add a known breakage of the same kind as there
exists others, and then later fix them all up, including the one
that is added by this series, because fixes are non-trivial and this
topic is easier to finish if we allowed to add a known breakage"
approach?  Just making sure it is what you plan to do.

Thanks.
Phillip Wood Oct. 26, 2022, 3:17 p.m. UTC | #4
Hi Junio

On 25/10/2022 17:11, Junio C Hamano wrote:
> Phillip Wood <phillip.wood123@gmail.com> writes:
> 
>>>> Both of these will be fixed in a future series that
>>>> stops the sequencer calling setenv().
>>> If it gets fixed in a future step in the same series, that is a
>>> different matter, but if it is easy enough not to deliberately
>>> introduce a new leak, we'd prefer to do so.
>>
>> It's a couple of patches to fix which are more or less finished, I'm
>> planning to send them once this series is in next.
> 
> So we will do the "add a known breakage of the same kind as there
> exists others, and then later fix them all up, including the one
> that is added by this series, because fixes are non-trivial and this
> topic is easier to finish if we allowed to add a known breakage"
> approach?  Just making sure it is what you plan to do.

Yes, that's right

Thanks

Phillip

> Thanks.
Junio C Hamano Oct. 26, 2022, 4:55 p.m. UTC | #5
Phillip Wood <phillip.wood123@gmail.com> writes:

> Hi Junio
>
> On 25/10/2022 17:11, Junio C Hamano wrote:
>> Phillip Wood <phillip.wood123@gmail.com> writes:
>> 
>>>>> Both of these will be fixed in a future series that
>>>>> stops the sequencer calling setenv().
>>>> If it gets fixed in a future step in the same series, that is a
>>>> different matter, but if it is easy enough not to deliberately
>>>> introduce a new leak, we'd prefer to do so.
>>>
>>> It's a couple of patches to fix which are more or less finished, I'm
>>> planning to send them once this series is in next.
>> So we will do the "add a known breakage of the same kind as there
>> exists others, and then later fix them all up, including the one
>> that is added by this series, because fixes are non-trivial and this
>> topic is easier to finish if we allowed to add a known breakage"
>> approach?  Just making sure it is what you plan to do.
>
> Yes, that's right

OK, I do not mind as long as we leave a NEEDSWORK note to tell
others that we know the leak and promise to fix it soon (so they do
not waste their effort to fix it independently).

Thanks.
diff mbox series

Patch

diff --git a/builtin/rebase.c b/builtin/rebase.c
index e67020b3586..414526f83a8 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -1271,8 +1271,6 @@  int cmd_rebase(int argc, const char **argv, const char *prefix)
 		int fd;
 
 		options.action = "continue";
-		set_reflog_action(&options);
-
 		/* Sanity check */
 		if (get_oid("HEAD", &head))
 			die(_("Cannot read HEAD"));
diff --git a/sequencer.c b/sequencer.c
index 61a8e0020d5..5790b35d763 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -4785,6 +4785,8 @@  int sequencer_continue(struct repository *r, struct replay_opts *opts)
 	if (read_populate_opts(opts))
 		return -1;
 	if (is_rebase_i(opts)) {
+		char *previous_reflog_action;
+
 		if ((res = read_populate_todo(r, &todo_list, opts)))
 			goto release_todo_list;
 
@@ -4795,10 +4797,13 @@  int sequencer_continue(struct repository *r, struct replay_opts *opts)
 			unlink(rebase_path_dropped());
 		}
 
+		previous_reflog_action = xstrdup(getenv(GIT_REFLOG_ACTION));
+		setenv(GIT_REFLOG_ACTION, reflog_message(opts, "continue", NULL), 1);
 		if (commit_staged_changes(r, opts, &todo_list)) {
 			res = -1;
 			goto release_todo_list;
 		}
+		setenv(GIT_REFLOG_ACTION, previous_reflog_action, 1);
 	} else if (!file_exists(get_todo_path(opts)))
 		return continue_single_pick(r, opts);
 	else if ((res = read_populate_todo(r, &todo_list, opts)))
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index 5253dd1551d..3ca2fbb0d59 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -17,6 +17,7 @@  test_expect_success 'setup' '
 
 	git checkout -b conflicts O &&
 	test_commit P &&
+	test_commit conflict-X fileX &&
 	test_commit Q &&
 
 	git checkout -b topic O &&
@@ -107,13 +108,17 @@  test_reflog () {
 			GIT_REFLOG_ACTION="$reflog_action" &&
 			export GIT_REFLOG_ACTION
 		fi &&
-		git rebase $mode main
+		test_must_fail git rebase $mode main &&
+		echo resolved >fileX &&
+		git add fileX &&
+		git rebase --continue
 	) &&
 
-	git log -g --format=%gs -4 >actual &&
+	git log -g --format=%gs -5 >actual &&
 	write_reflog_expect <<-EOF &&
 	${reflog_action:-rebase} (finish): returning to refs/heads/conflicts
 	${reflog_action:-rebase} (pick): Q
+	${reflog_action:-rebase} (continue): conflict-X
 	${reflog_action:-rebase} (pick): P
 	${reflog_action:-rebase} (start): checkout main
 	EOF