Skip to content

Commit d188a60

Browse files
phillipwoodttaylorr
authored andcommitted
sequencer: stop exporting GIT_REFLOG_ACTION
Each time it picks a commit the sequencer copies the GIT_REFLOG_ACITON environment variable so it can temporarily change it and then restore the previous value. This results in code that is hard to follow and also leaks memory because (i) we fail to free the copy when we've finished with it and (ii) each call to setenv() leaks the previous value. Instead pass the reflog action around in a variable and use it to set GIT_REFLOG_ACTION in the child environment when running "git commit". Within the sequencer GIT_REFLOG_ACTION is no longer set and is only read by sequencer_reflog_action(). It is still set by rebase before calling the sequencer, that will be addressed in the next commit. cherry-pick and revert are unaffected as they do not set GIT_REFLOG_ACTION before calling the sequencer. Signed-off-by: Phillip Wood <[email protected]> Reviewed-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Taylor Blau <[email protected]>
1 parent 3b08839 commit d188a60

File tree

2 files changed

+31
-20
lines changed

2 files changed

+31
-20
lines changed

sequencer.c

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ int sequencer_remove_state(struct replay_opts *opts)
375375
}
376376

377377
free(opts->gpg_sign);
378+
free(opts->reflog_action);
378379
free(opts->default_strategy);
379380
free(opts->strategy);
380381
for (i = 0; i < opts->xopts_nr; i++)
@@ -1050,6 +1051,8 @@ static int run_git_commit(const char *defmsg,
10501051
gpg_opt, gpg_opt);
10511052
}
10521053

1054+
strvec_pushf(&cmd.env, GIT_REFLOG_ACTION "=%s", opts->reflog_message);
1055+
10531056
if (opts->committer_date_is_author_date)
10541057
strvec_pushf(&cmd.env, "GIT_COMMITTER_DATE=%s",
10551058
opts->ignore_date ?
@@ -1589,8 +1592,8 @@ static int try_to_commit(struct repository *r,
15891592
goto out;
15901593
}
15911594

1592-
if (update_head_with_reflog(current_head, oid,
1593-
getenv("GIT_REFLOG_ACTION"), msg, &err)) {
1595+
if (update_head_with_reflog(current_head, oid, opts->reflog_message,
1596+
msg, &err)) {
15941597
res = error("%s", err.buf);
15951598
goto out;
15961599
}
@@ -3674,17 +3677,28 @@ static int do_label(struct repository *r, const char *name, int len)
36743677
return ret;
36753678
}
36763679

3680+
static const char *sequencer_reflog_action(struct replay_opts *opts)
3681+
{
3682+
if (!opts->reflog_action) {
3683+
opts->reflog_action = getenv(GIT_REFLOG_ACTION);
3684+
opts->reflog_action =
3685+
xstrdup(opts->reflog_action ? opts->reflog_action
3686+
: action_name(opts));
3687+
}
3688+
3689+
return opts->reflog_action;
3690+
}
3691+
36773692
__attribute__((format (printf, 3, 4)))
36783693
static const char *reflog_message(struct replay_opts *opts,
36793694
const char *sub_action, const char *fmt, ...)
36803695
{
36813696
va_list ap;
36823697
static struct strbuf buf = STRBUF_INIT;
3683-
char *reflog_action = getenv(GIT_REFLOG_ACTION);
36843698

36853699
va_start(ap, fmt);
36863700
strbuf_reset(&buf);
3687-
strbuf_addstr(&buf, reflog_action ? reflog_action : action_name(opts));
3701+
strbuf_addstr(&buf, sequencer_reflog_action(opts));
36883702
if (sub_action)
36893703
strbuf_addf(&buf, " (%s)", sub_action);
36903704
if (fmt) {
@@ -4497,7 +4511,7 @@ static int checkout_onto(struct repository *r, struct replay_opts *opts,
44974511
RESET_HEAD_RUN_POST_CHECKOUT_HOOK,
44984512
.head_msg = reflog_message(opts, "start", "checkout %s",
44994513
onto_name),
4500-
.default_reflog_action = "rebase"
4514+
.default_reflog_action = sequencer_reflog_action(opts)
45014515
};
45024516
if (reset_head(r, &ropts)) {
45034517
apply_autostash(rebase_path_autostash());
@@ -4566,11 +4580,8 @@ static int pick_commits(struct repository *r,
45664580
struct replay_opts *opts)
45674581
{
45684582
int res = 0, reschedule = 0;
4569-
char *prev_reflog_action;
45704583

4571-
/* Note that 0 for 3rd parameter of setenv means set only if not set */
4572-
setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
4573-
prev_reflog_action = xstrdup(getenv(GIT_REFLOG_ACTION));
4584+
opts->reflog_message = sequencer_reflog_action(opts);
45744585
if (opts->allow_ff)
45754586
assert(!(opts->signoff || opts->no_commit ||
45764587
opts->record_origin || should_edit(opts) ||
@@ -4618,14 +4629,12 @@ static int pick_commits(struct repository *r,
46184629
}
46194630
if (item->command <= TODO_SQUASH) {
46204631
if (is_rebase_i(opts))
4621-
setenv(GIT_REFLOG_ACTION, reflog_message(opts,
4622-
command_to_string(item->command), NULL),
4623-
1);
4632+
opts->reflog_message = reflog_message(opts,
4633+
command_to_string(item->command), NULL);
4634+
46244635
res = do_pick_commit(r, item, opts,
46254636
is_final_fixup(todo_list),
46264637
&check_todo);
4627-
if (is_rebase_i(opts))
4628-
setenv(GIT_REFLOG_ACTION, prev_reflog_action, 1);
46294638
if (is_rebase_i(opts) && res < 0) {
46304639
/* Reschedule */
46314640
advise(_(rescheduled_advice),
@@ -5050,8 +5059,6 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)
50505059
if (read_populate_opts(opts))
50515060
return -1;
50525061
if (is_rebase_i(opts)) {
5053-
char *previous_reflog_action;
5054-
50555062
if ((res = read_populate_todo(r, &todo_list, opts)))
50565063
goto release_todo_list;
50575064

@@ -5062,13 +5069,11 @@ int sequencer_continue(struct repository *r, struct replay_opts *opts)
50625069
unlink(rebase_path_dropped());
50635070
}
50645071

5065-
previous_reflog_action = xstrdup(getenv(GIT_REFLOG_ACTION));
5066-
setenv(GIT_REFLOG_ACTION, reflog_message(opts, "continue", NULL), 1);
5072+
opts->reflog_message = reflog_message(opts, "continue", NULL);
50675073
if (commit_staged_changes(r, opts, &todo_list)) {
50685074
res = -1;
50695075
goto release_todo_list;
50705076
}
5071-
setenv(GIT_REFLOG_ACTION, previous_reflog_action, 1);
50725077
} else if (!file_exists(get_todo_path(opts)))
50735078
return continue_single_pick(r, opts);
50745079
else if ((res = read_populate_todo(r, &todo_list, opts)))
@@ -5116,7 +5121,7 @@ static int single_pick(struct repository *r,
51165121
TODO_PICK : TODO_REVERT;
51175122
item.commit = cmit;
51185123

5119-
setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
5124+
opts->reflog_message = sequencer_reflog_action(opts);
51205125
return do_pick_commit(r, &item, opts, 0, &check_todo);
51215126
}
51225127

sequencer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ struct replay_opts {
6363
char **xopts;
6464
size_t xopts_nr, xopts_alloc;
6565

66+
/* Reflog */
67+
char *reflog_action;
68+
6669
/* Used by fixup/squash */
6770
struct strbuf current_fixups;
6871
int current_fixup_count;
@@ -73,6 +76,9 @@ struct replay_opts {
7376

7477
/* Only used by REPLAY_NONE */
7578
struct rev_info *revs;
79+
80+
/* Private use */
81+
const char *reflog_message;
7682
};
7783
#define REPLAY_OPTS_INIT { .edit = -1, .action = -1, .current_fixups = STRBUF_INIT }
7884

0 commit comments

Comments
 (0)