aboutsummaryrefslogtreecommitdiff
path: root/builtin/replay.c
AgeCommit message (Collapse)Author
13 daysreplay: allow to specify a ref with option --refToon Claes
When option '--onto' is passed to git-replay(1), the command will update refs from the <revision-range> passed to the command. When using option '--advance' or '--revert', the argument of that option is a ref that will be updated. To enable users to specify which ref to update, add option '--ref'. When using option '--ref', the refs described above are left untouched and instead the argument of this option is updated instead. Because this introduces code paths in replay.c that jump to `out` before init_basic_merge_options() is called on `merge_opt`, zero-initialize the struct. Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
13 daysreplay: use stuck form in documentation and help messageToon Claes
gitcli(7) suggests to use stuck form. Change the documentation strings to use this form. While at it, reorder them to match the order in the docs. Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
13 daysbuiltin/replay: mark options as not negatableToon Claes
The options '--onto', '--advance', '--revert', and '--ref-action' of git-replay(1) are not negatable. Mark them as such using PARSE_OPT_NONEG. Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-25replay: add --revert mode to reverse commit changesSiddharth Asthana
Add a `--revert <branch>` mode to git replay that undoes the changes introduced by the specified commits. Like --onto and --advance, --revert is a standalone mode: it takes a branch argument and updates that branch with the newly created revert commits. At GitLab, we need this in Gitaly for reverting commits directly on bare repositories without requiring a working tree checkout. The approach is the same as sequencer.c's do_pick_commit() -- cherry-pick and revert are just the same three-way merge with swapped arguments: - Cherry-pick: merge(ancestor=parent, ours=current, theirs=commit) - Revert: merge(ancestor=commit, ours=current, theirs=parent) We swap the base and pickme trees passed to merge_incore_nonrecursive() to reverse the diff direction. Reverts are processed newest-first (matching git revert behavior) to reduce conflicts by peeling off changes from the top. Each revert builds on the result of the previous one via the last_commit fallback in the main replay loop, rather than relying on the parent-mapping used for cherry-pick. Revert commit messages follow the usual git revert conventions: prefixed with "Revert" (or "Reapply" when reverting a revert), and including "This reverts commit <hash>.". The author is set to the current user rather than preserving the original author, matching git revert behavior. Helped-by: Christian Couder <christian.couder@gmail.com> Helped-by: Patrick Steinhardt <ps@pks.im> Helped-by: Elijah Newren <newren@gmail.com> Helped-by: Phillip Wood <phillip.wood123@gmail.com> Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Helped-by: Junio C Hamano <gitster@pobox.com> Helped-by: Toon Claes <toon@iotcl.com> Signed-off-by: Siddharth Asthana <siddharthasthana31@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-13builtin/replay: move core logic into "libgit.a"Patrick Steinhardt
Move the core logic used to replay commits into "libgit.a" so that it can be easily reused by other commands. It will be used in a subsequent commit where we're about to introduce a new git-history(1) command. Note that with this change we have no sign-comparison warnings anymore, and neither do we depend on `the_repository`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-13builtin/replay: extract core logic to replay revisionsPatrick Steinhardt
We're about to move the core logic used to replay revisions onto a new base into the "libgit.a" library. Prepare for this by pulling out the logic into a new function `replay_revisions()` that: 1. Takes a set of revisions to replay and some options that tell it how it ought to replay the revisions. 2. Replays the commits. 3. Records any reference updates that would be caused by replaying the commits in a structure that is owned by the caller. The logic itself will be moved into a separate file in the next commit. This change is not expected to cause user-visible change in behaviour. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-06replay: die if we cannot parse objectKristoffer Haugsbakk
`parse_object` can return `NULL`. That will in turn make `repo_peel_to_type` return the same. Let’s die fast and descriptively with the `*_or_die` variant. Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-06replay: improve code comment and die messageKristoffer Haugsbakk
Suggested-by: Elijah Newren <newren@gmail.com> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-06replay: die descriptively when invalid commit-ish is givenKristoffer Haugsbakk
Giving an invalid commit-ish to `--onto` makes git-replay(1) fail with: fatal: Replaying down to root commit is not supported yet! Going backwards from this point: 1. `onto` is `NULL` from `set_up_replay_mode`; 2. that function in turn calls `peel_committish`; and 3. here we return `NULL` if `repo_get_oid` fails. Let’s die immediately with a descriptive error message instead. Doing this also provides us with a descriptive error if we “forget” to provide an argument to `--onto` (but we really do unintentionally):[1] $ git replay --onto ^main topic1 fatal: '^main' is not a valid commit-ish Note that the `--advance` case won’t be triggered in practice because of the “argument to --advance must be a reference” check (see the previous test, and commit). † 1: The argument to `--onto` is mandatory and the option parser accepts both `--onto=<name>` (stuck form) and `--onto name`. The latter form makes it easy to unintentionally pass something to the option when you really meant to pass a positional argument. Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-06replay: find *onto only after testing for ref nameKristoffer Haugsbakk
We are about to make `peel_committish` die when it cannot find a commit-ish instead of returning `NULL`. But that would make e.g. `git replay --advance=refs/non-existent` die with a less descriptive error message; the highest-level error message is that the name does not exist as a ref, not that we cannot find a commit-ish based on the name. Let’s try to find the ref and only after that try to peel to as a commit-ish. Also add a regression test to protect this error order from future modifications. Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-01-06replay: remove dead code and rearrangeKristoffer Haugsbakk
22d99f01 (replay: add --advance or 'cherry-pick' mode, 2023-11-24) both added `--advance` and made one of `--onto` or `--advance` mandatory. But `determine_replay_mode` claims that there is a third alternative; neither of `--onto` or `--advance` were given: if (onto_name) { ... } else if (*advance_name) { ... } else { ... } But this is false—the fallthrough else-block is dead code. Commit 22d99f01 was iterated upon by several people.[1] The initial author wrote code for a sort of *guess mode*, allowing for shorter commands when that was possible. But the next person instead made one of the aforementioned options mandatory. In turn this code was dead on arrival in git.git. [1]: https://lore.kernel.org/git/CABPp-BEcJqjD4ztsZo2FTZgWT5ZOADKYEyiZtda+d0mSd1quPQ@mail.gmail.com/ Let’s remove this code. We can also join the if-block with the condition `!*advance_name` into the `*onto` block since we do not set `*advance_name` in this function. It only looked like we might set it since the dead code has this line: *advance_name = xstrdup_or_null(last_key); Let’s also rename the function since we do not determine the replay mode here. We just set up `*onto` and refs to update. Note that there might be more dead code caused by this *guess mode*. We only concern ourselves with this function for now. Helped-by: Elijah Newren <newren@gmail.com> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-22Merge branch 'rs/replay-wrong-onto-fix'Junio C Hamano
"git replay --onto=<commit> ...", when <commit> is mistyped, started to segfault with recent change, which has been corrected. * rs/replay-wrong-onto-fix: replay: move onto NULL check before first use
2025-12-22Merge branch 'kh/doc-replay-updates'Junio C Hamano
"git replay" documentation updates. * kh/doc-replay-updates: doc: replay: link section using markup replay: improve --contained and add to doc doc: replay: mention no output on conflicts
2025-12-14replay: improve --contained and add to docKristoffer Haugsbakk
There is no documentation for `--contained`. Start by copying the text from `replay_options` in `builtin/ replay.c`. But some people think that the existing text is a bit unclear; what does it mean for a branch to be contained in a revision range? Let’s include the implied commits here: the branches that point at commits in the range. Also use “update” instead of “advance”. “Update” is the verb commonly used in this context. Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk> Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-12replay: move onto NULL check before first useRené Scharfe
cmd_replay() aborts if the pointer "onto" is NULL after argument parsing, e.g. when specifying a non-existing commit with --onto. 15cd4ef1f4 (replay: make atomic ref updates the default behavior, 2025-11-06) added code that dereferences this pointer before the check. Switch their places to avoid a segmentation fault. Reported-by: Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-12-09Merge branch 'en/replay-doc-revision-range'Junio C Hamano
The use of "revision" (a connected set of commits) has been clarified in the "git replay" documentation. * en/replay-doc-revision-range: Documentation/git-replay.adoc: fix errors around revision range
2025-12-09Merge branch 'pw/replay-exclude-gpgsig-fix'Junio C Hamano
"git replay" forgot to omit the "gpgsig-sha256" extended header from the resulting commit the same way it omits "gpgsig", which has been corrected. * pw/replay-exclude-gpgsig-fix: replay: do not copy "gpgsign-sha256" header
2025-11-28Documentation/git-replay.adoc: fix errors around revision rangeElijah Newren
There was significant confusion in the git-replay manual about what constitutes a revision range. As noted in f302c1e4aa09 (revisions(7): clarify that most commands take a single revision range, 2021-05-18): Commands that are specifically designed to take two distinct ranges (e.g. "git range-diff R1 R2" to compare two ranges) do exist, but they are exceptions. Unless otherwise noted, all "git" commands that operate on a set of commits work on a single revision range. `git replay` is not an exception, but a few places in the manual were written as though it were. These appear to have come in revisions to the original series, between v3->v4 (see https://lore.kernel.org/git/CAP8UFD3bpLrVW97DH7j=V9H2GsTSAkksC9L3QujQERFk_kLnZA@mail.gmail.com/ , "More than one <revision-range> can be passed") and between v6->v7 (https://lore.kernel.org/git/20231115143327.2441397-1-christian.couder@gmail.com/, "Takes ranges of commits"), and I missed both of these revisions when reviewing. Fix them now. There was also a reference to the "Commit Limiting options below", but this page has no such section of options; strike the misleading reference. It is worth noting that we are documenting existing behavior, rather than optimal behavior. Junio has multiple times suggested introducing alternative ways to walk revisions and use them in `git replay --advance`, e.g. at * https://lore.kernel.org/git/xmqqy1mqo6kv.fsf@gitster.g/ * https://lore.kernel.org/git/xmqq8rb3is8c.fsf@gitster.g/ * https://lore.kernel.org/git/xmqqtsydj2zk.fsf@gitster.g/ (item (2)) If/when we introduce some new revision walking flag that implements one of these alternate types of revision walks, we can update the --advance option and this manual appropriately. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-26replay: do not copy "gpgsign-sha256" headerPhillip Wood
When "git replay" replays a commit it copies the extended headers across from the original commit. However, if the original commit was signed, we do not want to copy the header associated with the signature is it wont be valid for the new commit. The code already knows to avoid coping the "gpgsig" header but does not know to avoid copying the "gpgsig-sha256" header. Add that header to the list of exclusions to match what "git commit --amend" does. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-11-05replay: add replay.refAction config optionSiddharth Asthana
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>
2025-11-05replay: make atomic ref updates the default behaviorSiddharth Asthana
The git replay command currently outputs update commands that can be piped to update-ref to achieve a rebase, e.g. git replay --onto main topic1..topic2 | git update-ref --stdin This separation had advantages for three special cases: * it made testing easy (when state isn't modified from one step to the next, you don't need to make temporary branches or have undo commands, or try to track the changes) * it provided a natural can-it-rebase-cleanly (and what would it rebase to) capability without automatically updating refs, similar to a --dry-run * it provided a natural low-level tool for the suite of hash-object, mktree, commit-tree, mktag, merge-tree, and update-ref, allowing users to have another building block for experimentation and making new tools However, it should be noted that all three of these are somewhat special cases; users, whether on the client or server side, would almost certainly find it more ergonomic to simply have the updating of refs be the default. For server-side operations in particular, the pipeline architecture creates process coordination overhead. Server implementations that need to perform rebases atomically must maintain additional code to: 1. Spawn and manage a pipeline between git-replay and git-update-ref 2. Coordinate stdout/stderr streams across the pipe boundary 3. Handle partial failure states if the pipeline breaks mid-execution 4. Parse and validate the update-ref command output Change the default behavior to update refs directly, and atomically (at least to the extent supported by the refs backend in use). This eliminates the process coordination overhead for the common case. For users needing the traditional pipeline workflow, add a new --ref-action=<mode> option that preserves the original behavior: git replay --ref-action=print --onto main topic1..topic2 | git update-ref --stdin The mode can be: * update (default): Update refs directly using an atomic transaction * print: Output update-ref commands for pipeline use Test suite changes: All existing tests that expected command output now use --ref-action=print to preserve their original behavior. This keeps the tests valid while allowing them to verify that the pipeline workflow still works correctly. New tests were added to verify: - Default atomic behavior (no output, refs updated directly) - Bare repository support (server-side use case) - Equivalence between traditional pipeline and atomic updates - Real atomicity using a lock file to verify all-or-nothing guarantee - Test isolation using test_when_finished to clean up state - Reflog messages include replay mode and target A following commit will add a replay.refAction configuration option for users who prefer the traditional pipeline output as their default behavior. Helped-by: Elijah Newren <newren@gmail.com> Helped-by: Patrick Steinhardt <ps@pks.im> 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>
2025-11-05replay: use die_for_incompatible_opt2() for option validationSiddharth Asthana
In preparation for adding the --ref-action option, convert option validation to use die_for_incompatible_opt2(). This helper provides standardized error messages for mutually exclusive options. The following commit introduces --ref-action which will be incompatible with certain other options. Using die_for_incompatible_opt2() now means that commit can cleanly add its validation using the same pattern, keeping the validation logic consistent and maintainable. This also aligns git-replay's option handling with how other Git commands manage option conflicts, using the established die_for_incompatible_opt*() helper family. Signed-off-by: Siddharth Asthana <siddharthasthana31@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-06-05repo_logmsg_reencode: fix memory leak when use repo_logmsg_reencode ()Lidong Yan
pretty.c:repo_logmsg_reencode() allocated memory should be freed with repo_unuse_commit_buffer(). Callers sometimes forgot free it at exit point. Add `repo_unuse_commit_buffer()` in insert_records_from_trailers at builtin/shortlog.c and create_commit at builtin/replay.c Signed-off-by: Lidong Yan <502024330056@smail.nju.edu.cn> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-05-14replay: replace the_repository with repo parameter passed to cmd_replay ()Elijah Newren
Replace the_repository everywhere with repo, feed repo from cmd_replay() to all the other functions in the file that need it, and remove the UNUSED annotation on repo. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-02-06parse-options: introduce die_for_incompatible_opt2()Toon Claes
The functions die_for_incompatible_opt3() and die_for_incompatible_opt4() already exist to die whenever a user specifies three or four options respectively that are not compatible. Introduce die_for_incompatible_opt2() which dies when two options that are incompatible are set. Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06global: mark code units that generate warnings with `-Wsign-compare`Patrick Steinhardt
Mark code units that generate warnings with `-Wsign-compare`. This allows for a structured approach to get rid of all such warnings over time in a way that can be easily measured. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-13builtin: remove USE_THE_REPOSITORY_VARIABLE from builtin.hJohn Cai
Instead of including USE_THE_REPOSITORY_VARIABLE by default on every builtin, remove it from builtin.h and add it to all the builtins that include builtin.h (by definition, that means all builtins/*.c). Also, remove the include statement for repository.h since it gets brought in through builtin.h. The next step will be to migrate each builtin from having to use the_repository. Signed-off-by: John Cai <johncai86@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-13builtin: add a repository parameter for builtin functionsJohn Cai
In order to reduce the usage of the global the_repository, add a parameter to builtin functions that will get passed a repository variable. This commit uses UNUSED on most of the builtin functions, as subsequent commits will modify the actual builtins to pass the repository parameter down. Signed-off-by: John Cai <johncai86@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-08-14Merge branch 'ps/leakfixes-part-3'Junio C Hamano
More leakfixes. * ps/leakfixes-part-3: (24 commits) commit-reach: fix trivial memory leak when computing reachability convert: fix leaking config strings entry: fix leaking pathnames during delayed checkout object-name: fix leaking commit list items t/test-repository: fix leaking repository builtin/credential-cache: fix trivial leaks builtin/worktree: fix leaking derived branch names builtin/shortlog: fix various trivial memory leaks builtin/rerere: fix various trivial memory leaks builtin/credential-store: fix leaking credential builtin/show-branch: fix several memory leaks builtin/rev-parse: fix memory leak with `--parseopt` builtin/stash: fix various trivial memory leaks builtin/remote: fix various trivial memory leaks builtin/remote: fix leaking strings in `branch_list` builtin/ls-remote: fix leaking `pattern` strings builtin/submodule--helper: fix leaking buffer in `is_tip_reachable` builtin/submodule--helper: fix leaking clone depth parameter builtin/name-rev: fix various trivial memory leaks builtin/describe: fix trivial memory leak when describing blob ...
2024-08-01builtin/replay: plug leaking `advance_name` variablePatrick Steinhardt
The `advance_name` variable can either contain a static string when parsed via the `--advance` command line option or it may be an allocated string when set via `determine_replay_mode()`. Because we cannot be sure whether it is allocated or not we just didn't free it at all, resulting in a memory leak. Split up the variables such that we can track the static and allocated strings separately and then free the allocated one to fix the memory leak. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-07-13merge-recursive: honor diff.algorithmAntonin Delpeuch
The documentation claims that "recursive defaults to the diff.algorithm config setting", but this is currently not the case. This fixes it, ensuring that diff.algorithm is used when -Xdiff-algorithm is not supplied. This affects the following porcelain commands: "merge", "rebase", "cherry-pick", "pull", "stash", "log", "am" and "checkout". It also affects the "merge-tree" ancillary interrogator. This change refactors the initialization of merge options to introduce two functions, "init_merge_ui_options" and "init_merge_basic_options" instead of just one "init_merge_options". This design follows the approach used in diff.c, providing initialization methods for porcelain and plumbing commands respectively. Thanks to that, the "replay" and "merge-recursive" plumbing commands remain unaffected by diff.algorithm. Signed-off-by: Antonin Delpeuch <antonin@delpeuch.eu> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-06-11commit: fix leaking parents when calling `commit_tree_extended()`Patrick Steinhardt
When creating commits via `commit_tree_extended()`, the caller passes in a string list of parents. This call implicitly transfers ownership of that list to the function, which is quite surprising to begin with. But to make matters worse, `commit_tree_extended()` doesn't even bother to free the list of parents in error cases. The result is a memory leak, and one that the caller cannot fix by themselves because they do not know whether parts of the string list have already been released. Refactor the code such that callers can keep ownership of the list of parents, which is getting indicated by parameter being a constant pointer now. Free the lists at the calling site and add a common exit path to those sites as required. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-04-18builtin: stop using `the_index`Patrick Steinhardt
Convert builtins to use `the_repository->index` instead of `the_index`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-26replay: stop assuming replayed branches do not divergeElijah Newren
The replay command is able to replay multiple branches but when some of them are based on other replayed branches, their commit should be replayed onto already replayed commits. For this purpose, let's store the replayed commit and its original commit in a key value store, so that we can easily find and reuse a replayed commit instead of the original one. Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-26replay: add --contained to rebase contained branchesElijah Newren
Let's add a `--contained` option that can be used along with `--onto` to rebase all the branches contained in the <revision-range> argument. Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-26replay: add --advance or 'cherry-pick' modeElijah Newren
There is already a 'rebase' mode with `--onto`. Let's add an 'advance' or 'cherry-pick' mode with `--advance`. This new mode will make the target branch advance as we replay commits onto it. The replayed commits should have a single tip, so that it's clear where the target branch should be advanced. If they have more than one tip, this new mode will error out. Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-26replay: use standard revision rangesElijah Newren
Instead of the fixed "<oldbase> <branch>" arguments, the replay command now accepts "<revision-range>..." arguments in a similar way as many other Git commands. This makes its interface more standard and more flexible. This also enables many revision related options accepted and eaten by setup_revisions(). If the replay command was a high level one or had a high level mode, it would make sense to restrict some of the possible options, like those generating non-contiguous history, as they could be confusing for most users. Also as the interface of the command is now mostly finalized, we can add more documentation and more testcases to make sure the command will continue to work as designed in the future. We only document the rev-list related options among all the revision related options that are now accepted, as the rev-list related ones are probably the most useful for now. Helped-by: Dragan Simic <dsimic@manjaro.org> Helped-by: Linus Arver <linusa@google.com> Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-26replay: make it a minimal server side commandElijah Newren
We want this command to be a minimal command that just does server side picking of commits, displaying the results on stdout for higher level scripts to consume. So let's simplify it: * remove the worktree and index reading/writing, * remove the ref (and reflog) updating, * remove the assumptions tying us to HEAD, since (a) this is not a rebase and (b) we want to be able to pick commits in a bare repo, i.e. to/from branches that are not checked out and not the main branch, * remove unneeded includes, * handle rebasing multiple branches by printing on stdout the update ref commands that should be performed. The output can be piped into `git update-ref --stdin` for the ref updates to happen. In the future to make it easier for users to use this command directly maybe an option can be added to automatically pipe its output into `git update-ref`. Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-26replay: remove HEAD related sanity checkElijah Newren
We want replay to be a command that can be used on the server side on any branch, not just the current one, so we are going to stop updating HEAD in a future commit. A "sanity check" that makes sure we are replaying the current branch doesn't make sense anymore. Let's remove it. Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-26replay: remove progress and info outputElijah Newren
The replay command will be changed in a follow up commit, so that it will not update refs directly, but instead it will print on stdout a list of commands that can be consumed by `git update-ref --stdin`. We don't want this output to be polluted by its current low value output, so let's just remove the latter. In the future, when the command gets an option to update refs by itself, it will make a lot of sense to display a progress meter, but we are not there yet. Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-26replay: add an important FIXME comment about gpg signingElijah Newren
We want to be able to handle signed commits in some way in the future, but we are not ready to do it now. So for the time being let's just add a FIXME comment to remind us about it. These are different ways we could handle them: - in case of a cli user and if there was an interactive mode, we could perhaps ask if the user wants to sign again - we could add an option to just fail if there are signed commits Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-26replay: change rev walking optionsElijah Newren
Let's force the rev walking options we need after calling setup_revisions() instead of before. This might override some user supplied rev walking command line options though. So let's detect that and warn users by: a) setting the desired values, before setup_revisions(), b) checking after setup_revisions() whether these values differ from the desired values, c) if so throwing a warning and setting the desired values again. We want the command to work from older commits to newer ones by default. Also we don't want history simplification, as we want to deal with all the commits in the affected range. Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-26replay: introduce pick_regular_commit()Elijah Newren
Let's refactor the code to handle a regular commit (a commit that is neither a root commit nor a merge commit) into a single function instead of keeping it inside cmd_replay(). This is good for separation of concerns, and this will help further work in the future to replay merge commits. Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-26replay: die() instead of failing assert()Elijah Newren
It's not a good idea for regular Git commands to use an assert() to check for things that could happen but are not supported. Let's die() with an explanation of the issue instead. Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-26replay: start using parse_options APIElijah Newren
Instead of manually parsing arguments, let's start using the parse_options API. This way this new builtin will look more standard, and in some upcoming commits will more easily be able to handle more command line options. Note that we plan to later use standard revision ranges instead of hardcoded "<oldbase> <branch>" arguments. When we will use standard revision ranges, it will be easier to check if there are no spurious arguments if we keep ARGV[0], so let's call parse_options() with PARSE_OPT_KEEP_ARGV0 even if we don't need ARGV[0] right now to avoid some useless code churn. Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-26replay: introduce new builtinElijah Newren
For now, this is just a rename from `t/helper/test-fast-rebase.c` into `builtin/replay.c` with minimal changes to make it build appropriately. Let's add a stub documentation and a stub test script though. Subsequent commits will flesh out the capabilities of the new command and make it a more standard regular builtin. Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Co-authored-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>