Skip to content

Commit bcd020f

Browse files
committed
Merge branch 'pw/use-in-process-checkout-in-rebase'
Use an internal call to reset_head() helper function instead of spawning "git checkout" in "rebase", and update code paths that are involved in the change. * pw/use-in-process-checkout-in-rebase: rebase -m: don't fork git checkout rebase --apply: set ORIG_HEAD correctly rebase --apply: fix reflog reset_head(): take struct rebase_head_opts rebase: cleanup reset_head() calls create_autostash(): remove unneeded parameter reset_head(): make default_reflog_action optional reset_head(): factor out ref updates reset_head(): remove action parameter rebase --apply: don't run post-checkout hook if there is an error rebase: do not remove untracked files on checkout rebase: pass correct arguments to post-checkout hook t5403: refactor rebase post-checkout hook tests rebase: factor out checkout for up to date branch
2 parents 867b520 + 38c541c commit bcd020f

File tree

9 files changed

+312
-163
lines changed

9 files changed

+312
-163
lines changed

builtin/merge.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,8 +1568,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
15681568

15691569
if (autostash)
15701570
create_autostash(the_repository,
1571-
git_path_merge_autostash(the_repository),
1572-
"merge");
1571+
git_path_merge_autostash(the_repository));
15731572
if (checkout_fast_forward(the_repository,
15741573
&head_commit->object.oid,
15751574
&commit->object.oid,
@@ -1640,8 +1639,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
16401639

16411640
if (autostash)
16421641
create_autostash(the_repository,
1643-
git_path_merge_autostash(the_repository),
1644-
"merge");
1642+
git_path_merge_autostash(the_repository));
16451643

16461644
/* We are going to make a new commit. */
16471645
git_committer_info(IDENT_STRICT);

builtin/rebase.c

Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,8 @@ static int finish_rebase(struct rebase_options *opts)
571571

572572
static int move_to_original_branch(struct rebase_options *opts)
573573
{
574-
struct strbuf orig_head_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;
574+
struct strbuf branch_reflog = STRBUF_INIT, head_reflog = STRBUF_INIT;
575+
struct reset_head_opts ropts = { 0 };
575576
int ret;
576577

577578
if (!opts->head_name)
@@ -580,16 +581,17 @@ static int move_to_original_branch(struct rebase_options *opts)
580581
if (!opts->onto)
581582
BUG("move_to_original_branch without onto");
582583

583-
strbuf_addf(&orig_head_reflog, "rebase finished: %s onto %s",
584+
strbuf_addf(&branch_reflog, "rebase finished: %s onto %s",
584585
opts->head_name, oid_to_hex(&opts->onto->object.oid));
585586
strbuf_addf(&head_reflog, "rebase finished: returning to %s",
586587
opts->head_name);
587-
ret = reset_head(the_repository, NULL, "", opts->head_name,
588-
RESET_HEAD_REFS_ONLY,
589-
orig_head_reflog.buf, head_reflog.buf,
590-
DEFAULT_REFLOG_ACTION);
588+
ropts.branch = opts->head_name;
589+
ropts.flags = RESET_HEAD_REFS_ONLY;
590+
ropts.branch_msg = branch_reflog.buf;
591+
ropts.head_msg = head_reflog.buf;
592+
ret = reset_head(the_repository, &ropts);
591593

592-
strbuf_release(&orig_head_reflog);
594+
strbuf_release(&branch_reflog);
593595
strbuf_release(&head_reflog);
594596
return ret;
595597
}
@@ -671,13 +673,15 @@ static int run_am(struct rebase_options *opts)
671673

672674
status = run_command(&format_patch);
673675
if (status) {
676+
struct reset_head_opts ropts = { 0 };
674677
unlink(rebased_patches);
675678
free(rebased_patches);
676679
strvec_clear(&am.args);
677680

678-
reset_head(the_repository, &opts->orig_head, "checkout",
679-
opts->head_name, 0,
680-
"HEAD", NULL, DEFAULT_REFLOG_ACTION);
681+
ropts.oid = &opts->orig_head;
682+
ropts.branch = opts->head_name;
683+
ropts.default_reflog_action = DEFAULT_REFLOG_ACTION;
684+
reset_head(the_repository, &ropts);
681685
error(_("\ngit encountered an error while preparing the "
682686
"patches to replay\n"
683687
"these revisions:\n"
@@ -813,6 +817,26 @@ static int rebase_config(const char *var, const char *value, void *data)
813817
return git_default_config(var, value, data);
814818
}
815819

820+
static int checkout_up_to_date(struct rebase_options *options)
821+
{
822+
struct strbuf buf = STRBUF_INIT;
823+
struct reset_head_opts ropts = { 0 };
824+
int ret = 0;
825+
826+
strbuf_addf(&buf, "%s: checkout %s",
827+
getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
828+
options->switch_to);
829+
ropts.oid = &options->orig_head;
830+
ropts.branch = options->head_name;
831+
ropts.flags = RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
832+
ropts.head_msg = buf.buf;
833+
if (reset_head(the_repository, &ropts) < 0)
834+
ret = error(_("could not switch to %s"), options->switch_to);
835+
strbuf_release(&buf);
836+
837+
return ret;
838+
}
839+
816840
/*
817841
* Determines whether the commits in from..to are linear, i.e. contain
818842
* no merge commits. This function *expects* `from` to be an ancestor of
@@ -1018,6 +1042,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
10181042
int reschedule_failed_exec = -1;
10191043
int allow_preemptive_ff = 1;
10201044
int preserve_merges_selected = 0;
1045+
struct reset_head_opts ropts = { 0 };
10211046
struct option builtin_rebase_options[] = {
10221047
OPT_STRING(0, "onto", &options.onto_name,
10231048
N_("revision"),
@@ -1255,9 +1280,8 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
12551280

12561281
rerere_clear(the_repository, &merge_rr);
12571282
string_list_clear(&merge_rr, 1);
1258-
1259-
if (reset_head(the_repository, NULL, "reset", NULL, RESET_HEAD_HARD,
1260-
NULL, NULL, DEFAULT_REFLOG_ACTION) < 0)
1283+
ropts.flags = RESET_HEAD_HARD;
1284+
if (reset_head(the_repository, &ropts) < 0)
12611285
die(_("could not discard worktree changes"));
12621286
remove_branch_state(the_repository, 0);
12631287
if (read_basic_state(&options))
@@ -1274,9 +1298,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
12741298

12751299
if (read_basic_state(&options))
12761300
exit(1);
1277-
if (reset_head(the_repository, &options.orig_head, "reset",
1278-
options.head_name, RESET_HEAD_HARD,
1279-
NULL, NULL, DEFAULT_REFLOG_ACTION) < 0)
1301+
ropts.oid = &options.orig_head;
1302+
ropts.branch = options.head_name;
1303+
ropts.flags = RESET_HEAD_HARD;
1304+
ropts.default_reflog_action = DEFAULT_REFLOG_ACTION;
1305+
if (reset_head(the_repository, &ropts) < 0)
12801306
die(_("could not move back to %s"),
12811307
oid_to_hex(&options.orig_head));
12821308
remove_branch_state(the_repository, 0);
@@ -1642,10 +1668,10 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
16421668
if (repo_read_index(the_repository) < 0)
16431669
die(_("could not read index"));
16441670

1645-
if (options.autostash) {
1646-
create_autostash(the_repository, state_dir_path("autostash", &options),
1647-
DEFAULT_REFLOG_ACTION);
1648-
}
1671+
if (options.autostash)
1672+
create_autostash(the_repository,
1673+
state_dir_path("autostash", &options));
1674+
16491675

16501676
if (require_clean_work_tree(the_repository, "rebase",
16511677
_("Please commit or stash them."), 1, 1)) {
@@ -1674,21 +1700,9 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
16741700
if (!(options.flags & REBASE_FORCE)) {
16751701
/* Lazily switch to the target branch if needed... */
16761702
if (options.switch_to) {
1677-
strbuf_reset(&buf);
1678-
strbuf_addf(&buf, "%s: checkout %s",
1679-
getenv(GIT_REFLOG_ACTION_ENVIRONMENT),
1680-
options.switch_to);
1681-
if (reset_head(the_repository,
1682-
&options.orig_head, "checkout",
1683-
options.head_name,
1684-
RESET_HEAD_RUN_POST_CHECKOUT_HOOK,
1685-
NULL, buf.buf,
1686-
DEFAULT_REFLOG_ACTION) < 0) {
1687-
ret = error(_("could not switch to "
1688-
"%s"),
1689-
options.switch_to);
1703+
ret = checkout_up_to_date(&options);
1704+
if (ret)
16901705
goto cleanup;
1691-
}
16921706
}
16931707

16941708
if (!(options.flags & REBASE_NO_QUIET))
@@ -1755,10 +1769,13 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
17551769

17561770
strbuf_addf(&msg, "%s: checkout %s",
17571771
getenv(GIT_REFLOG_ACTION_ENVIRONMENT), options.onto_name);
1758-
if (reset_head(the_repository, &options.onto->object.oid, "checkout", NULL,
1759-
RESET_HEAD_DETACH | RESET_ORIG_HEAD |
1760-
RESET_HEAD_RUN_POST_CHECKOUT_HOOK,
1761-
NULL, msg.buf, DEFAULT_REFLOG_ACTION))
1772+
ropts.oid = &options.onto->object.oid;
1773+
ropts.orig_head = &options.orig_head,
1774+
ropts.flags = RESET_HEAD_DETACH | RESET_ORIG_HEAD |
1775+
RESET_HEAD_RUN_POST_CHECKOUT_HOOK;
1776+
ropts.head_msg = msg.buf;
1777+
ropts.default_reflog_action = DEFAULT_REFLOG_ACTION;
1778+
if (reset_head(the_repository, &ropts))
17621779
die(_("Could not detach HEAD"));
17631780
strbuf_release(&msg);
17641781

@@ -1773,9 +1790,11 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
17731790
strbuf_addf(&msg, "rebase finished: %s onto %s",
17741791
options.head_name ? options.head_name : "detached HEAD",
17751792
oid_to_hex(&options.onto->object.oid));
1776-
reset_head(the_repository, NULL, "Fast-forwarded", options.head_name,
1777-
RESET_HEAD_REFS_ONLY, "HEAD", msg.buf,
1778-
DEFAULT_REFLOG_ACTION);
1793+
memset(&ropts, 0, sizeof(ropts));
1794+
ropts.branch = options.head_name;
1795+
ropts.flags = RESET_HEAD_REFS_ONLY;
1796+
ropts.head_msg = msg.buf;
1797+
reset_head(the_repository, &ropts);
17791798
strbuf_release(&msg);
17801799
ret = finish_rebase(&options);
17811800
goto cleanup;

0 commit comments

Comments
 (0)