[PATCH v8 06/11] reset: introduce ability to skip updating HEAD
From: Patrick Steinhardt <hidden>
Date: 2026-07-01 11:35:55
Subsystem:
the rest · Maintainer:
Linus Torvalds
In a subsequent commit we'll introduce a new caller to `reset_working_tree()` that really only wants to update the index and working tree, without updating any references. Introduce a new flag that makes the caller opt in to updating HEAD and adapt all callers to set that flag. Note that in a previous iteration we instead introduced a flag that made callers opt out of updating any references. This was somewhat awkward though because we already have the `UPDATE_ORIG_HEAD` flag, so the result was somewhat inconsistent. Suggested-by: Phillip Wood <redacted> Signed-off-by: Patrick Steinhardt <redacted> --- builtin/rebase.c | 14 ++++++++++---- reset.c | 9 +++++++-- reset.h | 9 ++++++--- sequencer.c | 4 +++- 4 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/builtin/rebase.c b/builtin/rebase.c
index 06dcbaf5e8..10a306310c 100644
--- a/builtin/rebase.c
+++ b/builtin/rebase.c@@ -607,7 +607,8 @@ static int move_to_original_branch(struct rebase_options *opts) strbuf_addf(&head_reflog, "%s (finish): returning to %s", opts->reflog_action, opts->head_name); ropts.branch = opts->head_name; - ropts.flags = RESET_WORKING_TREE_REFS_ONLY; + ropts.flags = RESET_WORKING_TREE_REFS_ONLY | + RESET_WORKING_TREE_UPDATE_HEAD; ropts.branch_msg = branch_reflog.buf; ropts.head_msg = head_reflog.buf; ret = reset_working_tree(the_repository, &ropts);
@@ -693,6 +694,7 @@ static int run_am(struct rebase_options *opts) ropts.oid = &opts->orig_head->object.oid; ropts.branch = opts->head_name; ropts.default_reflog_action = opts->reflog_action; + ropts.flags = RESET_WORKING_TREE_UPDATE_HEAD; reset_working_tree(the_repository, &ropts); error(_("\ngit encountered an error while preparing the " "patches to replay\n"
@@ -862,7 +864,8 @@ static int checkout_up_to_date(struct rebase_options *options) options->reflog_action, options->switch_to); ropts.oid = &options->orig_head->object.oid; ropts.branch = options->head_name; - ropts.flags = RESET_WORKING_TREE_RUN_POST_CHECKOUT_HOOK; + ropts.flags = RESET_WORKING_TREE_RUN_POST_CHECKOUT_HOOK | + RESET_WORKING_TREE_UPDATE_HEAD; if (!ropts.branch) ropts.flags |= RESET_WORKING_TREE_DETACH; ropts.head_msg = buf.buf;
@@ -1384,7 +1387,8 @@ int cmd_rebase(int argc, rerere_clear(the_repository, &merge_rr); string_list_clear(&merge_rr, 1); - ropts.flags = RESET_WORKING_TREE_HARD; + ropts.flags = RESET_WORKING_TREE_HARD | + RESET_WORKING_TREE_UPDATE_HEAD; if (reset_working_tree(the_repository, &ropts) < 0) die(_("could not discard worktree changes")); remove_branch_state(the_repository, 0);
@@ -1409,7 +1413,8 @@ int cmd_rebase(int argc, ropts.oid = &options.orig_head->object.oid; ropts.head_msg = head_msg.buf; ropts.branch = options.head_name; - ropts.flags = RESET_WORKING_TREE_HARD; + ropts.flags = RESET_WORKING_TREE_HARD | + RESET_WORKING_TREE_UPDATE_HEAD; if (reset_working_tree(the_repository, &ropts) < 0) die(_("could not move back to %s"), oid_to_hex(&options.orig_head->object.oid));
@@ -1877,6 +1882,7 @@ int cmd_rebase(int argc, ropts.oid = &options.onto->object.oid; ropts.orig_head = &options.orig_head->object.oid; ropts.flags = RESET_WORKING_TREE_DETACH | + RESET_WORKING_TREE_UPDATE_HEAD | RESET_WORKING_TREE_UPDATE_ORIG_HEAD | RESET_WORKING_TREE_RUN_POST_CHECKOUT_HOOK; ropts.head_msg = msg.buf;
diff --git a/reset.c b/reset.c
index 99f2c1b012..4bde5d8dc6 100644
--- a/reset.c
+++ b/reset.c@@ -92,6 +92,7 @@ int reset_working_tree(struct repository *r, const char *switch_to_branch = opts->branch; unsigned reset_hard = opts->flags & RESET_WORKING_TREE_HARD; unsigned refs_only = opts->flags & RESET_WORKING_TREE_REFS_ONLY; + unsigned update_head = opts->flags & RESET_WORKING_TREE_UPDATE_HEAD; unsigned update_orig_head = opts->flags & RESET_WORKING_TREE_UPDATE_ORIG_HEAD; unsigned dry_run = opts->flags & RESET_WORKING_TREE_DRY_RUN; struct object_id *head = NULL, head_oid;
@@ -113,6 +114,9 @@ int reset_working_tree(struct repository *r, if (opts->branch_msg && !opts->branch) BUG("branch reflog message given without a branch"); + if (update_orig_head && !update_head) + BUG("cannot update ORIG_HEAD without updating HEAD" ); + if (!refs_only && !dry_run && repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0) { ret = -1; goto leave_reset_head;
@@ -129,7 +133,7 @@ int reset_working_tree(struct repository *r, oid = &head_oid; if (refs_only) { - if (!dry_run) + if (!dry_run && update_head) return update_refs(r, opts, oid, head); return 0; }
@@ -197,7 +201,8 @@ int reset_working_tree(struct repository *r, goto leave_reset_head; } - if (oid != &head_oid || update_orig_head || switch_to_branch) + if (update_head && + (oid != &head_oid || update_orig_head || switch_to_branch)) ret = update_refs(r, opts, oid, head); leave_reset_head:
diff --git a/reset.h b/reset.h
index 898e4a1e95..38b2891b53 100644
--- a/reset.h
+++ b/reset.h@@ -19,14 +19,17 @@ enum reset_working_tree_flags { /* Only update refs, do not touch the worktree */ RESET_WORKING_TREE_REFS_ONLY = (1 << 3), - /* Update ORIG_HEAD as well as HEAD */ - RESET_WORKING_TREE_UPDATE_ORIG_HEAD = (1 << 4), + /* Update HEAD */ + RESET_WORKING_TREE_UPDATE_HEAD = (1 << 4), + + /* Update ORIG_HEAD */ + RESET_WORKING_TREE_UPDATE_ORIG_HEAD = (1 << 5), /* * Perform a dry-run by performing the operation without updating * any user-visible state. */ - RESET_WORKING_TREE_DRY_RUN = (1 << 5), + RESET_WORKING_TREE_DRY_RUN = (1 << 6), }; struct reset_working_tree_options {
diff --git a/sequencer.c b/sequencer.c
index 4efe831178..e905b1b2d9 100644
--- a/sequencer.c
+++ b/sequencer.c@@ -4678,7 +4678,8 @@ static void create_autostash_internal(struct repository *r, has_uncommitted_changes(r, 1)) { struct child_process stash = CHILD_PROCESS_INIT; struct reset_working_tree_options ropts = { - .flags = RESET_WORKING_TREE_HARD, + .flags = RESET_WORKING_TREE_HARD | + RESET_WORKING_TREE_UPDATE_HEAD, }; struct object_id oid;
@@ -4873,6 +4874,7 @@ static int checkout_onto(struct repository *r, struct replay_opts *opts, .oid = onto, .orig_head = orig_head, .flags = RESET_WORKING_TREE_DETACH | + RESET_WORKING_TREE_UPDATE_HEAD | RESET_WORKING_TREE_UPDATE_ORIG_HEAD | RESET_WORKING_TREE_RUN_POST_CHECKOUT_HOOK, .head_msg = reflog_message(opts, "start", "checkout %s",
--
2.55.0.795.g602f6c329a.dirty