[PATCH v6 0/3] replay: make atomic ref updates the default
- From
Siddharth Asthana <siddharthasthana31@gmail.com>
- Date
- Oct 30, 2025, 19:19 UTC
- Message-ID
- <20251030191931.30837-1-siddharthasthana31@gmail.com>
- In-Reply-To
- <20251028214609.10041-1-siddharthasthana31@gmail.com>
This is v6 of the git-replay atomic updates series.
This version addresses Christian's feedback from v5 regarding code consistency and test patterns. Thanks to Christian, Junio, Phillip, Elijah, Patrick, and Karthik for the thorough reviews.
## Changes in v6
**Fixed parameter naming inconsistency**
Christian pointed out that parse_ref_action_mode() used `mode_str` as the parameter name while the rest of the code used `ref_action`. Changed to use `ref_action` consistently throughout for better code readability.
**Improved test cleanup pattern**
Replaced manual `git config --unset` with `test_when_finished` pattern with `test_config` helper in the replay.refAction config test. The test_config helper automatically handles cleanup via test_when_finished, providing better test isolation and following Git test suite best practices.
These are code quality improvements that don't change functionality but make the code more consistent with Git's established patterns.
## Technical Implementation
Same as v5, using Git's ref transaction API:
- ref_store_transaction_begin() with default atomic behavior - ref_transaction_update() to stage each update - ref_transaction_commit() for atomic application
The helper functions provide clean separation:
- parse_ref_action_mode(): Validates strings and converts to enum - get_ref_action_mode(): Implements command-line > config > default precedence - handle_ref_update(): Uses type-safe enum with switch statement
Config reading uses repo_config_get_string_tmp() for simplicity while maintaining proper precedence behavior.
## Testing
All tests pass:
- t3650-replay-basics.sh (20 tests pass) - Config tests now use test_config for automatic cleanup - Atomic behavior tests verify direct ref updates - Backward compatibility maintained for pipeline workflow
CI results: https://gitlab.com/gitlab-org/git/-/pipelines/2130504045
Siddharth Asthana (3): replay: use die_for_incompatible_opt2() for option validation replay: make atomic ref updates the default behavior replay: add replay.refAction config option
Documentation/config/replay.adoc | 11 +++ Documentation/git-replay.adoc | 65 +++++++++++------ builtin/replay.c | 121 +++++++++++++++++++++++++++---- t/t3650-replay-basics.sh | 90 +++++++++++++++++++++-- 4 files changed, 244 insertions(+), 43 deletions(-) create mode 100644 Documentation/config/replay.adoc
Range-diff against v5:
1: 3e27d07d3b = 1: 1f0fad0cac replay: use die_for_incompatible_opt2() for option validation
2: 643d9ca86a = 2: bfc6188234 replay: make atomic ref updates the default behavior
3: 334da71911 ! 3: 6b2a44c72c replay: add replay.refAction config option
@@ Metadata
Author: Siddharth Asthana <siddharthasthana31@gmail.com>
## Commit message ##
replay: add replay.refAction config option
[Commit message unchanged]
## builtin/replay.c ##
@@ builtin/replay.c: static struct commit *pick_regular_commit
return create_commit(repo, result->tree, pickme, replayed_base);
}
-+static enum ref_action_mode parse_ref_action_mode(const char *mode_str, const char *source)
++static enum ref_action_mode parse_ref_action_mode(const char *ref_action, const char *source)
+{
-+ if (!mode_str || !strcmp(mode_str, "update"))
++ if (!ref_action || !strcmp(ref_action, "update"))
+ return REF_ACTION_UPDATE;
-+ if (!strcmp(mode_str, "print"))
++ if (!strcmp(ref_action, "print"))
+ return REF_ACTION_PRINT;
-+ die(_("invalid %s value: '%s'"), source, mode_str);
++ die(_("invalid %s value: '%s'"), source, ref_action);
+}
+
+static enum ref_action_mode get_ref_action_mode(struct repository *repo, const char *ref_action_str)
## t/t3650-replay-basics.sh ##
@@ t/t3650-replay-basics.sh
+test_expect_success 'replay.refAction config option' '
+ START=$(git rev-parse topic2) &&
+ test_when_finished "git branch -f topic2 $START" &&
-+ test_when_finished "git config --unset replay.refAction || true" &&
+
-+ git config replay.refAction 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 &&
+
+ git branch -f topic2 $START &&
-+ git config replay.refAction update &&
++ test_config replay.refAction update &&
+ git replay --onto main topic1..topic2 >output &&
+test_expect_success 'command-line --ref-action overrides config' '-- 2.51.0 base-commit: 57da342c78d8bf00259d2b720292e5b3035dadcc Thanks - Siddharth