Skip to content

Commit 88f95e4

Browse files
committed
Merge branch 'pw/rebase-abort-clean-rewritten'
"git rebase --abort" used to leave refs/rewritten/ when concluding "git rebase -r", which has been corrected. * pw/rebase-abort-clean-rewritten: rebase --abort/--quit: cleanup refs/rewritten sequencer: return errors from sequencer_remove_state() rebase: warn if state directory cannot be removed rebase: fix a memory leak
2 parents 44275f5 + d559f50 commit 88f95e4

File tree

3 files changed

+53
-15
lines changed

3 files changed

+53
-15
lines changed

builtin/rebase.c

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ static int finish_rebase(struct rebase_options *opts)
738738
{
739739
struct strbuf dir = STRBUF_INIT;
740740
const char *argv_gc_auto[] = { "gc", "--auto", NULL };
741+
int ret = 0;
741742

742743
delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
743744
apply_autostash(opts);
@@ -747,11 +748,20 @@ static int finish_rebase(struct rebase_options *opts)
747748
* user should see them.
748749
*/
749750
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
750-
strbuf_addstr(&dir, opts->state_dir);
751-
remove_dir_recursively(&dir, 0);
752-
strbuf_release(&dir);
751+
if (opts->type == REBASE_INTERACTIVE) {
752+
struct replay_opts replay = REPLAY_OPTS_INIT;
753753

754-
return 0;
754+
replay.action = REPLAY_INTERACTIVE_REBASE;
755+
ret = sequencer_remove_state(&replay);
756+
} else {
757+
strbuf_addstr(&dir, opts->state_dir);
758+
if (remove_dir_recursively(&dir, 0))
759+
ret = error(_("could not remove '%s'"),
760+
opts->state_dir);
761+
strbuf_release(&dir);
762+
}
763+
764+
return ret;
755765
}
756766

757767
static struct commit *peel_committish(const char *name)
@@ -1621,15 +1631,23 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
16211631
die(_("could not move back to %s"),
16221632
oid_to_hex(&options.orig_head));
16231633
remove_branch_state(the_repository);
1624-
ret = finish_rebase(&options);
1634+
ret = !!finish_rebase(&options);
16251635
goto cleanup;
16261636
}
16271637
case ACTION_QUIT: {
1628-
strbuf_reset(&buf);
1629-
strbuf_addstr(&buf, options.state_dir);
1630-
ret = !!remove_dir_recursively(&buf, 0);
1631-
if (ret)
1632-
die(_("could not remove '%s'"), options.state_dir);
1638+
if (options.type == REBASE_INTERACTIVE) {
1639+
struct replay_opts replay = REPLAY_OPTS_INIT;
1640+
1641+
replay.action = REPLAY_INTERACTIVE_REBASE;
1642+
ret = !!sequencer_remove_state(&replay);
1643+
} else {
1644+
strbuf_reset(&buf);
1645+
strbuf_addstr(&buf, options.state_dir);
1646+
ret = !!remove_dir_recursively(&buf, 0);
1647+
if (ret)
1648+
error(_("could not remove '%s'"),
1649+
options.state_dir);
1650+
}
16331651
goto cleanup;
16341652
}
16351653
case ACTION_EDIT_TODO:
@@ -2141,6 +2159,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
21412159
ret = !!run_specific_rebase(&options, action);
21422160

21432161
cleanup:
2162+
strbuf_release(&buf);
21442163
strbuf_release(&revisions);
21452164
free(options.head_name);
21462165
free(options.gpg_sign_opt);

sequencer.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ static const char *gpg_sign_opt_quoted(struct replay_opts *opts)
279279
int sequencer_remove_state(struct replay_opts *opts)
280280
{
281281
struct strbuf buf = STRBUF_INIT;
282-
int i;
282+
int i, ret = 0;
283283

284284
if (is_rebase_i(opts) &&
285285
strbuf_read_file(&buf, rebase_path_refs_to_delete(), 0) > 0) {
@@ -288,8 +288,10 @@ int sequencer_remove_state(struct replay_opts *opts)
288288
char *eol = strchr(p, '\n');
289289
if (eol)
290290
*eol = '\0';
291-
if (delete_ref("(rebase -i) cleanup", p, NULL, 0) < 0)
291+
if (delete_ref("(rebase -i) cleanup", p, NULL, 0) < 0) {
292292
warning(_("could not delete '%s'"), p);
293+
ret = -1;
294+
}
293295
if (!eol)
294296
break;
295297
p = eol + 1;
@@ -305,10 +307,11 @@ int sequencer_remove_state(struct replay_opts *opts)
305307

306308
strbuf_reset(&buf);
307309
strbuf_addstr(&buf, get_dir(opts));
308-
remove_dir_recursively(&buf, 0);
310+
if (remove_dir_recursively(&buf, 0))
311+
ret = error(_("could not remove '%s'"), buf.buf);
309312
strbuf_release(&buf);
310313

311-
return 0;
314+
return ret;
312315
}
313316

314317
static const char *action_name(const struct replay_opts *opts)

t/t3430-rebase-merges.sh

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,24 @@ test_expect_success 'refs/rewritten/* is worktree-local' '
237237
test_cmp_rev HEAD "$(cat wt/b)"
238238
'
239239

240+
test_expect_success '--abort cleans up refs/rewritten' '
241+
git checkout -b abort-cleans-refs-rewritten H &&
242+
GIT_SEQUENCE_EDITOR="echo break >>" git rebase -ir @^ &&
243+
git rev-parse --verify refs/rewritten/onto &&
244+
git rebase --abort &&
245+
test_must_fail git rev-parse --verify refs/rewritten/onto
246+
'
247+
248+
test_expect_success '--quit cleans up refs/rewritten' '
249+
git checkout -b quit-cleans-refs-rewritten H &&
250+
GIT_SEQUENCE_EDITOR="echo break >>" git rebase -ir @^ &&
251+
git rev-parse --verify refs/rewritten/onto &&
252+
git rebase --quit &&
253+
test_must_fail git rev-parse --verify refs/rewritten/onto
254+
'
255+
240256
test_expect_success 'post-rewrite hook and fixups work for merges' '
241-
git checkout -b post-rewrite &&
257+
git checkout -b post-rewrite H &&
242258
test_commit same1 &&
243259
git reset --hard HEAD^ &&
244260
test_commit same2 &&

0 commit comments

Comments
 (0)