aboutsummaryrefslogtreecommitdiff
path: root/replay.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2026-04-08 10:19:18 -0700
committerJunio C Hamano <gitster@pobox.com>2026-04-08 10:19:18 -0700
commit37a4780f2c30de9fe0bef533a266c6bca767a50f (patch)
tree601afbae0030003f3089e95b22dc466d64874d32 /replay.c
parentd8c553bbed21761a8af3fa40a20518e210e78a0d (diff)
parent23d83f8ddbef9adcb87671358b473e55cf90c90b (diff)
downloadgit-37a4780f2c30de9fe0bef533a266c6bca767a50f.tar.xz
Merge branch 'tc/replay-ref'
The experimental `git replay` command learned the `--ref=<ref>` option to allow specifying which ref to update, overriding the default behavior. * tc/replay-ref: replay: allow to specify a ref with option --ref replay: use stuck form in documentation and help message builtin/replay: mark options as not negatable
Diffstat (limited to 'replay.c')
-rw-r--r--replay.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/replay.c b/replay.c
index cf1f0bcba0..f96f1f6551 100644
--- a/replay.c
+++ b/replay.c
@@ -358,13 +358,15 @@ int replay_revisions(struct rev_info *revs,
struct commit *last_commit = NULL;
struct commit *commit;
struct commit *onto = NULL;
- struct merge_options merge_opt;
+ struct merge_options merge_opt = { 0 };
struct merge_result result = {
.clean = 1,
};
bool detached_head;
char *advance;
char *revert;
+ const char *ref;
+ struct object_id old_oid;
enum replay_mode mode = REPLAY_MODE_PICK;
int ret;
@@ -375,6 +377,27 @@ int replay_revisions(struct rev_info *revs,
set_up_replay_mode(revs->repo, &revs->cmdline, opts->onto,
&detached_head, &advance, &revert, &onto, &update_refs);
+ if (opts->ref) {
+ struct object_id oid;
+
+ if (update_refs && strset_get_size(update_refs) > 1) {
+ ret = error(_("'--ref' cannot be used with multiple revision ranges"));
+ goto out;
+ }
+ if (check_refname_format(opts->ref, 0) || !starts_with(opts->ref, "refs/")) {
+ ret = error(_("'%s' is not a valid refname"), opts->ref);
+ goto out;
+ }
+ ref = opts->ref;
+ if (!refs_read_ref(get_main_ref_store(revs->repo), opts->ref, &oid))
+ oidcpy(&old_oid, &oid);
+ else
+ oidclr(&old_oid, revs->repo->hash_algo);
+ } else {
+ ref = advance ? advance : revert;
+ oidcpy(&old_oid, &onto->object.oid);
+ }
+
if (prepare_revision_walk(revs) < 0) {
ret = error(_("error preparing revisions"));
goto out;
@@ -406,7 +429,7 @@ int replay_revisions(struct rev_info *revs,
kh_value(replayed_commits, pos) = last_commit;
/* Update any necessary branches */
- if (advance || revert)
+ if (ref)
continue;
for (decoration = get_name_decoration(&commit->object);
@@ -440,13 +463,9 @@ int replay_revisions(struct rev_info *revs,
goto out;
}
- /* In --advance or --revert mode, update the target ref */
- if (advance || revert) {
- const char *ref = advance ? advance : revert;
- replay_result_queue_update(out, ref,
- &onto->object.oid,
+ if (ref)
+ replay_result_queue_update(out, ref, &old_oid,
&last_commit->object.oid);
- }
ret = 0;