Important
This project is not actively maintained. That doesn't mean it's going to go stale — Git is stable software, and what works now should continue to work. If you open a support ticket (GitHub issue) I'll respond.
Important
Not to be confused with Git's replay
command, which was introduced years after I first published this project. The danger of coming up with an extension name that fits perfectly in the main product's naming idiom!
Automate the rebasing of Git branches and creation of "stage" branches (ie branches into which one or more feature branches are merged with a merge commit).
Handy if you have several features in progress at once, and find yourself rebasing feature branches and/or recreating stage branches every time there's a significant change in the trunk.
- Requirements
- Installation
- Usage
- Action configuration
- Option configuration
- Related
- Contributing
- License
- Git
- yq (installed for you if you install
git-replay
with Homebrew, as detailed below) - zsh (does not need to be your default interactive shell, just needs to be installed)
Homebrew is the recommended installation method.
Recommended. Download and install git-replay
and its dependency yq with one command:
brew install olets/tap/git-replay
-
Install yq
-
Install git-replay with a zsh plugin manager. Each has their own way of doing things. See your package manager's documentation or the zsh plugin manager plugin installation procedures gist.
zinit users will need to use the
ice
sas"program" pick"git-replay"
zplug users will need to use the tag
as:command
After adding the plugin to the manager, restart zsh:
exec zsh
- Install yq
- Download the latest
git-replay
binary - Put the file
git-replay
in a directory in yourPATH
git-replay
"replays" configured rebases and stage branch creation. Configuration lives in the git-replay.yaml
config file (customizable with --file
and --rev
). The file is YAML and can have any of the top-level objects rebase
, rebase-onto
, and stage
. (See Configuration.)
git replay [--file <config file path>] [--rev <revision>]
[--back-up] [--dry-run]
[(--quiet | -q) | (--quieter | -qq)] [--no-color]
[((--continue | --skip | --continue) | <subcommand>)]
git replay (--help | help)
git replay (--version | -v)
The basics:
Run the actions specified in the configuration file, saving a backup.
git replay --back-up
Change your mind? Restore the backup.
git replay restore-backup
Recommended:
In most cases it will be desirable to replay the same actions regardless of what branch is checked out when git replay
is run. Either
-
gitignore the configuration file. Now regardless of what commit is checked out you can manage the configuration file and/or run
git replay [...]
For this to work, there must be no revision configured (see Options). If you have configured a default revision globally (e.g. with
git config --global replay.rev <revision>
) you will need to nullify it locally (e.g. withgit config replay.rev ''
). -
or always read the configuration from the same revision. In this approach it is possible for collaborators to share a
git-replay
configuration.For example to keep the canonical configuration file in
main
:git checkout main # then add, fill out, and commit the configuration file
and when updating the configuration file first check out
main
.When running
git-replay
,-
either run
git replay --rev main [...]
-
or configure Git once
git config replay.rev main
and then run
git replay [...]
-
Option | Effect |
---|---|
--back-up |
Create git-replay/ -prefixed backup branches for every manipulated branch |
--rev <revision> |
The revision from which to read the configuration file (defaults to the checked out commit). You can also configure this as a git-config option (see Option configuration). |
--dry-run |
Log commands but do not run them |
--file <config file path> |
The configuration file to use (defaults to git-replay.yaml ).You can also configure this as a git-config option (see Option configuration). |
--no-color |
Do not colorize output |
--quiet or -q |
Quiet standard Git output |
--quieter or -qq |
Quiet standard Git output and git-replay output |
Aborts the in-progress replay. Unlike git rebase --abort
, completed actions are not undone. Use git replay restore-backup
to go back.
Continues the in-progress replay.
Run git replay dediverge
after completing the replay.
Largely equivalent to following the replay with git replay dediverge
but with less repetition in the logs.
Add --force
to skip the prompt.
Skips the current action and continues the in-progress replay.
Create git-replay/
-prefixed backup branches for every branch that would be manipulated, and do nothing else.
git replay dediverge [--force]
Identifies all manipulated branches (i.e. <branch>
es in rebase
s, and <branch>
es and <commit>
s in stage
s) that have diverged from their push destinations (aka @{push}
), and offers to git push --force-with-lease
each.
Add --force
to not prompt before force pushing.
git replay delete-backup
Delete all backup branches. Backup branches are defined as those with the prefix git-replay/
. If the backed up branch is not found —for example if there is no branch x
to go with the backup branch git-replay/x
— a warning will be printed and the backup branch will not be deleted.
git replay (help | --help)
Show the manpage.
git replay rebase
Replay only the configured git rebase
s. Does not include configured git rebase --onto
s.
git replay rebase-onto
Replay only the configured git rebase --onto
s. Does not include configured non---onto
git rebase
s.
git replay restore-backup
Reset every configured branch to its git-replay/
-prefixed backup, and then delete all backups.
For every backup branch, reset the current branch to the backup and then delete the backup branch. Backup branches are defined as those with the prefix git-replay/
. If the backed up branch is not found —for example if there is no branch x
to go with the backup branch git-replay/x
— a warning will be printed and the backup branch will not be deleted.
git replay stage
Replay only the configured "stages".
git replay (--version | -v)
Print the git-replay
version.
git-replay
works best with git-rerere
enabled.
git-rerere
has the potential to resolve conflicts in ways you don’t want. Familiarity with rerere is recommended.
To enable git-rerere
, run git config rerere.enabled true
.
If you hit a conflict while replaying, resolve it and then run git replay --continue
. git-replay
will have git-rerere
record the resolution and then will continue the replay.
git-replay
's configuration is a human-readable YAML file, and a handy reference document for keeping track of WIP and how branches relate.
The configuration file takes top-level objects with keys rebase
, rebase-onto
, and stage
.
Actions will always be run in the following order:
- All
rebase
s, in the order they appear in the configuration file- Then all
rebase-onto
s, in the order they appear in the configuration file- Then all
stage
s, in the order they appear in the configuration file
To automate rebase
git rebase <upstream> <branch>
use
rebase:
<upstream>: <branch>
To automate rebase --onto
git rebase --onto <newbase> <upstream> <branch>
use
rebase-onto:
<newbase>:
<upstream>: <branch>
Configure any number of rebases. List notation and square bracket array notations are supported.
rebase:
main:
- feature-1
- feature-2
rebase:
main: [feature-1, feature-2]
rebase:
main: feature-1
mybase:
- myfeature
- another
Tip: leverage gitrevisions and
rebase-onto
to manage stacked branches.rebase: main: - feature-1 rebase-onto: feature-1: feature-1@{u}: - feature-2
To automate
git switch -C <branch> <start-point>
# aka `git checkout -B <branch> <start-point>`
# aka `git checkout <branch> && git reset --hard <start-point>
git commit --no-ff <commit-1>
use the form
<start-point>:
<branch>: <commit-1>
Configure any number of stages. List and square bracket array notations are supported.
stage:
main:
development:
- feature-1
- feature-3
staging: [feature-1, feature-2]
stage:
main:
development: feature-1
staging: feature-2
mybranch:
mystage: myfeature
git-replay
supports git-config
.
Set git config [--global] replay.file
to use a custom file
without passing the --file
parameter.
For example
git config --global replay.file ./config/git-replay.yaml`
will let you run git replay
in place of git replay --file ./config/git-replay.yaml
.
Set git config [--global] replay.rev
to specify a revision without passing the --rev
parameter.
For example
git config --global replay.rev main
will let you run git replay
instead of git replay --rev main
.
Inspired by git-assembler, which is “Like ‘make’, for branches.”
Thanks for your interest. Contributions are welcome!
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.
Check the Issues to see if your topic has been discussed before or if it is being worked on.
Please read CONTRIBUTING.md before opening a pull request.
git-replay by Henry Bley-Vroman is licensed under CC BY-NC-SA 4.0 with a human rights condition from Hippocratic License 2.1. Persons interested in using or adapting this work for commercial purposes should contact the author.
For the full text of the license, see the LICENSE file.