| git-replay(1) | |
| ============= | |
| NAME | |
| ---- | |
| git-replay - EXPERIMENTAL: Replay commits on a new base, works with bare repos too | |
| SYNOPSIS | |
| -------- | |
| [verse] | |
| (EXPERIMENTAL!) 'git replay' ([--contained] --onto=<newbase> | --advance=<branch> | --revert=<branch>) | |
| [--ref=<ref>] [--ref-action=<mode>] <revision-range> | |
| DESCRIPTION | |
| ----------- | |
| Takes a range of commits and replays them onto a new location. Leaves | |
| the working tree and the index untouched. By default, updates the | |
| relevant references using an atomic transaction (all refs update or | |
| none). Use `--ref-action=print` to avoid automatic ref updates and | |
| instead get update commands that can be piped to `git update-ref --stdin` | |
| (see the <<output,OUTPUT>> section below). | |
| THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. | |
| OPTIONS | |
| ------- | |
| --onto=<newbase>:: | |
| Starting point at which to create the new commits. May be any | |
| valid commit, and not just an existing branch name. | |
| + | |
| When `--onto` is specified, the branch(es) in the revision range will be | |
| updated to point at the new commits, similar to the way `git rebase --update-refs` | |
| updates multiple branches in the affected range. | |
| --advance=<branch>:: | |
| Starting point at which to create the new commits; must be a | |
| branch name. | |
| + | |
| The history is replayed on top of the <branch> and <branch> is updated to | |
| point at the tip of the resulting history. This is different from `--onto`, | |
| which uses the target only as a starting point without updating it. | |
| --revert=<branch>:: | |
| Starting point at which to create the reverted commits; must be a | |
| branch name. | |
| + | |
| When `--revert` is specified, the commits in the revision range are reverted | |
| (their changes are undone) and the reverted commits are created on top of | |
| <branch>. The <branch> is then updated to point at the new commits. This is | |
| the same as running `git revert <revision-range>` but does not update the | |
| working tree. | |
| + | |
| The commit messages follow `git revert` conventions: they are prefixed with | |
| "Revert" and include "This reverts commit <hash>." When reverting a commit | |
| whose message starts with "Revert", the new message uses "Reapply" instead. | |
| Unlike cherry-pick which preserves the original author, revert commits use | |
| the current user as the author, matching the behavior of `git revert`. | |
| + | |
| This option is mutually exclusive with `--onto` and `--advance`. It is also | |
| incompatible with `--contained` (which is a modifier for `--onto` only). | |
| --contained:: | |
| Update all branches that point at commits in | |
| <revision-range>. Requires `--onto`. | |
| --ref=<ref>:: | |
| Override which reference is updated with the result of the replay. | |
| The ref must be fully qualified. | |
| When used with `--onto`, the `<revision-range>` should have a | |
| single tip and only the specified reference is updated instead of | |
| inferring refs from the revision range. | |
| When used with `--advance` or `--revert`, the specified reference is | |
| updated instead of the branch given to those options. | |
| This option is incompatible with `--contained`. | |
| --ref-action[=<mode>]:: | |
| Control how references are updated. The mode can be: | |
| + | |
| -- | |
| * `update` (default): Update refs directly using an atomic transaction. | |
| All refs are updated or none are (all-or-nothing behavior). | |
| * `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; see "Specifying Ranges" in | |
| linkgit:git-rev-parse[1]. In `--advance=<branch>` or | |
| `--revert=<branch>` mode, the range should have a single tip, | |
| so that it's clear to which tip the advanced or reverted | |
| <branch> should point. Any commits in the range whose changes | |
| are already present in the branch the commits are being | |
| replayed onto will be dropped. | |
| :git-replay: 1 | |
| include::rev-list-options.adoc[] | |
| [[output]] | |
| OUTPUT | |
| ------ | |
| By default, or with `--ref-action=update`, this command produces no output on | |
| success, as refs are updated directly using an atomic transaction. | |
| When using `--ref-action=print`, the output is usable as input to | |
| `git update-ref --stdin`. It is of the form: | |
| update refs/heads/branch1 ${NEW_branch1_HASH} ${OLD_branch1_HASH} | |
| update refs/heads/branch2 ${NEW_branch2_HASH} ${OLD_branch2_HASH} | |
| update refs/heads/branch3 ${NEW_branch3_HASH} ${OLD_branch3_HASH} | |
| where the number of refs updated depends on the arguments passed and | |
| the shape of the history being replayed. When using `--advance` or | |
| `--revert`, the number of refs updated is always one, but for `--onto`, | |
| it can be one or more (rebasing multiple branches simultaneously is | |
| supported). | |
| There is no stderr output on conflicts; see the <<exit-status,EXIT | |
| STATUS>> section below. | |
| [[exit-status]] | |
| EXIT STATUS | |
| ----------- | |
| For a successful, non-conflicted replay, the exit status is 0. When | |
| the replay has conflicts, the exit status is 1. If the replay is not | |
| able to complete (or start) due to some kind of error, the exit status | |
| is something other than 0 or 1. | |
| EXAMPLES | |
| -------- | |
| To simply rebase `mybranch` onto `target`: | |
| ------------ | |
| $ git replay --onto=target origin/main..mybranch | |
| ------------ | |
| The refs are updated atomically and no output is produced on success. | |
| To see what would be updated without actually updating: | |
| ------------ | |
| $ git replay --ref-action=print --onto=target origin/main..mybranch | |
| update refs/heads/mybranch ${NEW_mybranch_HASH} ${OLD_mybranch_HASH} | |
| ------------ | |
| To cherry-pick the commits from mybranch onto target: | |
| ------------ | |
| $ git replay --advance=target origin/main..mybranch | |
| ------------ | |
| Note that the first two examples replay the exact same commits and on | |
| top of the exact same new base, they only differ in that the first | |
| updates mybranch to point at the new commits and the second updates | |
| target to point at them. | |
| What if you have a stack of branches, one depending upon another, and | |
| you'd really like to rebase the whole set? | |
| ------------ | |
| $ git replay --contained --onto=origin/main origin/main..tipbranch | |
| ------------ | |
| All three branches (`branch1`, `branch2`, and `tipbranch`) are updated | |
| atomically. | |
| When calling `git replay`, one does not need to specify a range of | |
| commits to replay using the syntax `A..B`; any range expression will | |
| do: | |
| ------------ | |
| $ git replay --onto=origin/main ^base branch1 branch2 branch3 | |
| ------------ | |
| This will simultaneously rebase `branch1`, `branch2`, and `branch3`, | |
| all commits they have since `base`, playing them on top of | |
| `origin/main`. These three branches may have commits on top of `base` | |
| that they have in common, but that does not need to be the case. | |
| To revert commits on a branch: | |
| ------------ | |
| $ git replay --revert=main topic~2..topic | |
| ------------ | |
| This reverts the last two commits from `topic`, creating revert commits on | |
| top of `main`, and updates `main` to point at the result. This is useful when | |
| commits from `topic` were previously merged or cherry-picked into `main` and | |
| need to be undone. | |
| NOTE: For reverting an entire merge request as a single commit (rather than | |
| commit-by-commit), consider using `git merge-tree --merge-base $TIP HEAD $BASE` | |
| which can avoid unnecessary merge conflicts. | |
| To replay onto a specific commit while updating a different reference: | |
| ------------ | |
| $ git replay --onto=112233 --ref=refs/heads/mybranch aabbcc..ddeeff | |
| ------------ | |
| This replays the range `aabbcc..ddeeff` onto commit `112233` and updates | |
| `refs/heads/mybranch` to point at the result. This can be useful when you want | |
| to use bare commit IDs instead of branch names. | |
| GIT | |
| --- | |
| Part of the linkgit:git[1] suite |