]> git.ipfire.org Git - thirdparty/git.git/commitdiff
replay: add replay.refAction config option
authorSiddharth Asthana <siddharthasthana31@gmail.com>
Wed, 5 Nov 2025 19:16:01 +0000 (00:46 +0530)
committerJunio C Hamano <gitster@pobox.com>
Wed, 5 Nov 2025 21:34:55 +0000 (13:34 -0800)
Add a configuration variable to control the default behavior of git replay
for updating references. This allows users who prefer the traditional
pipeline output to set it once in their config instead of passing
--ref-action=print with every command.

The config variable uses string values that mirror the behavior modes:
  * replay.refAction = update (default): atomic ref updates
  * replay.refAction = print: output commands for pipeline

Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Elijah Newren <newren@gmail.com>
Helped-by: Christian Couder <christian.couder@gmail.com>
Helped-by: Phillip Wood <phillip.wood123@gmail.com>
Signed-off-by: Siddharth Asthana <siddharthasthana31@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config/replay.adoc [new file with mode: 0644]
Documentation/git-replay.adoc
builtin/replay.c
t/t3650-replay-basics.sh

diff --git a/Documentation/config/replay.adoc b/Documentation/config/replay.adoc
new file mode 100644 (file)
index 0000000..7d549d2
--- /dev/null
@@ -0,0 +1,11 @@
+replay.refAction::
+       Specifies the default mode for handling reference updates in
+       `git replay`. The value can be:
++
+--
+       * `update`: Update refs directly using an atomic transaction (default behavior).
+       * `print`: Output update-ref commands for pipeline use.
+--
++
+This setting can be overridden with the `--ref-action` command-line option.
+When not configured, `git replay` defaults to `update` mode.
index 2ef74ddb127b0cf7bb397c98abeab803d8ab4932..dcb26e8a8e88cac30fb04293c8b941b80ef2acc2 100644 (file)
@@ -51,6 +51,8 @@ which uses the target only as a starting point without updating it.
        * `print`: Output update-ref commands for pipeline use. This is the
          traditional behavior where output can be piped to `git update-ref --stdin`.
 --
++
+The default mode can be configured via the `replay.refAction` configuration variable.
 
 <revision-range>::
        Range of commits to replay. More than one <revision-range> can
index 94e60b5b107516d3da7be5957619bec0c38d40aa..6606a2c94bc67168c2b43e86f24717eb408e6f38 100644 (file)
@@ -8,6 +8,7 @@
 #include "git-compat-util.h"
 
 #include "builtin.h"
+#include "config.h"
 #include "environment.h"
 #include "hex.h"
 #include "lockfile.h"
@@ -298,6 +299,22 @@ static enum ref_action_mode parse_ref_action_mode(const char *ref_action, const
        die(_("invalid %s value: '%s'"), source, ref_action);
 }
 
+static enum ref_action_mode get_ref_action_mode(struct repository *repo, const char *ref_action)
+{
+       const char *config_value = NULL;
+
+       /* Command line option takes precedence */
+       if (ref_action)
+               return parse_ref_action_mode(ref_action, "--ref-action");
+
+       /* Check config value */
+       if (!repo_config_get_string_tmp(repo, "replay.refAction", &config_value))
+               return parse_ref_action_mode(config_value, "replay.refAction");
+
+       /* Default to update mode */
+       return REF_ACTION_UPDATE;
+}
+
 static int handle_ref_update(enum ref_action_mode mode,
                             struct ref_transaction *transaction,
                             const char *refname,
@@ -332,7 +349,7 @@ int cmd_replay(int argc,
        const char *onto_name = NULL;
        int contained = 0;
        const char *ref_action = NULL;
-       enum ref_action_mode ref_mode = REF_ACTION_UPDATE;
+       enum ref_action_mode ref_mode;
 
        struct rev_info revs;
        struct commit *last_commit = NULL;
@@ -378,9 +395,8 @@ int cmd_replay(int argc,
        die_for_incompatible_opt2(!!advance_name_opt, "--advance",
                                  contained, "--contained");
 
-       /* Parse ref action mode */
-       if (ref_action)
-               ref_mode = parse_ref_action_mode(ref_action, "--ref-action");
+       /* Parse ref action mode from command line or config */
+       ref_mode = get_ref_action_mode(repo, ref_action);
 
        advance_name = xstrdup_or_null(advance_name_opt);
 
index ec79234c8044c7ec0288b8b687d787610e769e5b..cf3aacf3551f8ee16803ae2a1ddbb7d9d6935980 100755 (executable)
@@ -268,4 +268,50 @@ test_expect_success 'reflog message for --advance mode' '
        test_cmp expect-reflog reflog-msg
 '
 
+test_expect_success 'replay.refAction=print config option' '
+       # Store original state
+       START=$(git rev-parse topic2) &&
+       test_when_finished "git branch -f topic2 $START" &&
+
+       # Test with config set to print
+       test_config replay.refAction print &&
+       git replay --onto main topic1..topic2 >output &&
+       test_line_count = 1 output &&
+       test_grep "^update refs/heads/topic2 " output
+'
+
+test_expect_success 'replay.refAction=update config option' '
+       # Store original state
+       START=$(git rev-parse topic2) &&
+       test_when_finished "git branch -f topic2 $START" &&
+
+       # Test with config set to update
+       test_config replay.refAction update &&
+       git replay --onto main topic1..topic2 >output &&
+       test_must_be_empty output &&
+
+       # Verify ref was updated
+       git log --format=%s topic2 >actual &&
+       test_write_lines E D M L B A >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success 'command-line --ref-action overrides config' '
+       # Store original state
+       START=$(git rev-parse topic2) &&
+       test_when_finished "git branch -f topic2 $START" &&
+
+       # Set config to update but use --ref-action=print
+       test_config replay.refAction update &&
+       git replay --ref-action=print --onto main topic1..topic2 >output &&
+       test_line_count = 1 output &&
+       test_grep "^update refs/heads/topic2 " output
+'
+
+test_expect_success 'invalid replay.refAction value' '
+       test_config replay.refAction invalid &&
+       test_must_fail git replay --onto main topic1..topic2 2>error &&
+       test_grep "invalid.*replay.refAction.*value" error
+'
+
 test_done