Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2019-07-29 22:38:20 +0300
committerJunio C Hamano <gitster@pobox.com>2019-07-29 22:38:20 +0300
commit649cae69bc8cc99fd5a9e72f8a08ae301d0d5e16 (patch)
treedacfd5d2a4738af3ffffd3215f9cb2fd090336e7
parent39521d07bedc4a8f1f8891ff1bc0a5b34213504f (diff)
parentd559f502c59658ea1f360fd28d8909894e40a4fe (diff)
Merge branch 'pw/rebase-abort-clean-rewritten' into maint
"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
-rw-r--r--builtin/rebase.c39
-rw-r--r--sequencer.c11
-rwxr-xr-xt/t3430-rebase-merges.sh18
3 files changed, 53 insertions, 15 deletions
diff --git a/builtin/rebase.c b/builtin/rebase.c
index b6892bc771..3d6219d022 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c
@@ -738,6 +738,7 @@ static int finish_rebase(struct rebase_options *opts)
{
struct strbuf dir = STRBUF_INIT;
const char *argv_gc_auto[] = { "gc", "--auto", NULL };
+ int ret = 0;
delete_ref(NULL, "REBASE_HEAD", NULL, REF_NO_DEREF);
apply_autostash(opts);
@@ -747,11 +748,20 @@ static int finish_rebase(struct rebase_options *opts)
* user should see them.
*/
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
- strbuf_addstr(&dir, opts->state_dir);
- remove_dir_recursively(&dir, 0);
- strbuf_release(&dir);
+ if (opts->type == REBASE_INTERACTIVE) {
+ struct replay_opts replay = REPLAY_OPTS_INIT;
- return 0;
+ replay.action = REPLAY_INTERACTIVE_REBASE;
+ ret = sequencer_remove_state(&replay);
+ } else {
+ strbuf_addstr(&dir, opts->state_dir);
+ if (remove_dir_recursively(&dir, 0))
+ ret = error(_("could not remove '%s'"),
+ opts->state_dir);
+ strbuf_release(&dir);
+ }
+
+ return ret;
}
static struct commit *peel_committish(const char *name)
@@ -1627,15 +1637,23 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
die(_("could not move back to %s"),
oid_to_hex(&options.orig_head));
remove_branch_state(the_repository);
- ret = finish_rebase(&options);
+ ret = !!finish_rebase(&options);
goto cleanup;
}
case ACTION_QUIT: {
- strbuf_reset(&buf);
- strbuf_addstr(&buf, options.state_dir);
- ret = !!remove_dir_recursively(&buf, 0);
- if (ret)
- die(_("could not remove '%s'"), options.state_dir);
+ if (options.type == REBASE_INTERACTIVE) {
+ struct replay_opts replay = REPLAY_OPTS_INIT;
+
+ replay.action = REPLAY_INTERACTIVE_REBASE;
+ ret = !!sequencer_remove_state(&replay);
+ } else {
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, options.state_dir);
+ ret = !!remove_dir_recursively(&buf, 0);
+ if (ret)
+ error(_("could not remove '%s'"),
+ options.state_dir);
+ }
goto cleanup;
}
case ACTION_EDIT_TODO:
@@ -2150,6 +2168,7 @@ run_rebase:
ret = !!run_specific_rebase(&options, action);
cleanup:
+ strbuf_release(&buf);
strbuf_release(&revisions);
free(options.head_name);
free(options.gpg_sign_opt);
diff --git a/sequencer.c b/sequencer.c
index 63b09cfceb..1d206fd224 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -279,7 +279,7 @@ static const char *gpg_sign_opt_quoted(struct replay_opts *opts)
int sequencer_remove_state(struct replay_opts *opts)
{
struct strbuf buf = STRBUF_INIT;
- int i;
+ int i, ret = 0;
if (is_rebase_i(opts) &&
strbuf_read_file(&buf, rebase_path_refs_to_delete(), 0) > 0) {
@@ -288,8 +288,10 @@ int sequencer_remove_state(struct replay_opts *opts)
char *eol = strchr(p, '\n');
if (eol)
*eol = '\0';
- if (delete_ref("(rebase -i) cleanup", p, NULL, 0) < 0)
+ if (delete_ref("(rebase -i) cleanup", p, NULL, 0) < 0) {
warning(_("could not delete '%s'"), p);
+ ret = -1;
+ }
if (!eol)
break;
p = eol + 1;
@@ -305,10 +307,11 @@ int sequencer_remove_state(struct replay_opts *opts)
strbuf_reset(&buf);
strbuf_addstr(&buf, get_dir(opts));
- remove_dir_recursively(&buf, 0);
+ if (remove_dir_recursively(&buf, 0))
+ ret = error(_("could not remove '%s'"), buf.buf);
strbuf_release(&buf);
- return 0;
+ return ret;
}
static const char *action_name(const struct replay_opts *opts)
diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index 42ba5b9f09..f0814d5280 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -224,8 +224,24 @@ test_expect_success 'refs/rewritten/* is worktree-local' '
test_cmp_rev HEAD "$(cat wt/b)"
'
+test_expect_success '--abort cleans up refs/rewritten' '
+ git checkout -b abort-cleans-refs-rewritten H &&
+ GIT_SEQUENCE_EDITOR="echo break >>" git rebase -ir @^ &&
+ git rev-parse --verify refs/rewritten/onto &&
+ git rebase --abort &&
+ test_must_fail git rev-parse --verify refs/rewritten/onto
+'
+
+test_expect_success '--quit cleans up refs/rewritten' '
+ git checkout -b quit-cleans-refs-rewritten H &&
+ GIT_SEQUENCE_EDITOR="echo break >>" git rebase -ir @^ &&
+ git rev-parse --verify refs/rewritten/onto &&
+ git rebase --quit &&
+ test_must_fail git rev-parse --verify refs/rewritten/onto
+'
+
test_expect_success 'post-rewrite hook and fixups work for merges' '
- git checkout -b post-rewrite &&
+ git checkout -b post-rewrite H &&
test_commit same1 &&
git reset --hard HEAD^ &&
test_commit same2 &&