This repo contains scripts to enable a stack-based workflow with git. This is achieved by using the git-stack extension and a few convenience scripts which extend the functionality of git-stack.
- Homebrew must be installed
zshmust be installed
git clone https://github.com/envoy/git-stack.git
cd git-stack
./setup-git-stack.sh
Run the setup-git-stack.sh script. This will
- Install
rustandcargoso that https://github.com/gitext-rs/git-stack can be installed - Install https://github.com/gitext-rs/git-stack
- Install https://github.com/gitext-rs/git-branch-stash which enables quality of life undo operations
- Installs the
ghcli tool which is used to create PRs - Updates the
$PATHin.zshrcto point to thecargobin - Updates the
$PATHin.zshrcto point to~/binand copies the scripts in this repo to~/bin - Runs
git stack aliaswhich sets up aliases forgit stackfor shorter commands. See https://github.com/gitext-rs/git-stack/blob/main/docs/reference.md#git-stack-alias for more information.
git pull && ./upgrade.sh
One configuration which is not automated is to set the protected branch.
git-stack --protect <glob>
In most cases, this will be main, master or develop. Under the hood, this is stored in your local repo's git config. .git/config under stack.protected-branch
Please see https://github.com/gitext-rs/git-stack/blob/main/README.md#configuring-git-stack for more information.
In git-stack a stack is inferred from the current branch and commit ancestry. A stack does not need to be explicitly created.
Regular git commands can be used to create a stack. For example, git checkout -b <branch> && git commit will append a new branch and commit to the current stack. Alternatively, you can use the git bc extension command.
For convenience, this repository contains an extension command git bc which shares the same interface as git commit but will create a branch with a name derived from the commit message and commit on that branch. This will also prompt you to setup a branch prefix for the current stack.
git bc -m "fix: my commit message"
This is just sugar for git checkout -b <branch> && git commit.
Branch prefixes can be setup for all stacks. The branch prefix configuration is used by the git bc command when it generates a branch name.
This repo contains a custom extension command git bc-prefix to configure the prefix
git bc-prefix <prefix>
This will set the branch prefix for the current stack. This is stored in your local repo's git config. .git/config.
You can inspect the current prefix using git config stack.prefix
This prefix supports nested shell commands and is evaluated before each commit. This allows you to set a prefix based on the output of other commands or even environment variables.
For example git bc-prefix 'ahmed/$(date +"%m-%d")' will set the prefix to ahmed/01-01 if the current date is January 1st.
To display the current stack, run git stack. This will display the current stack and the current branch.
git stack next or git next will move HEAD to the next commit in the stack.
git stack prev or git prev will move HEAD to the previous commit in the stack.
This repository contains two convenience scripts git top and git bottom which will navigate to the top-most branch or bottom-most branch in the stack respectively.
git stack amend or git amend will amend the current commit in the stack and will automatically rebase descendents of the current commit.
Let's say you commit to a branch earlier in the stack. This would usually require you to rebase all descendents of that commit. git stack --repair will attempt to automatically repair the stack by rebasing all descendents of the current commit.
Please see https://github.com/gitext-rs/git-stack/blob/main/docs/reference.md#git-stack---push for more information.
If you are on git 2.38 there are additional git rebase options which can be used to alter the history of a stack. Please see the below links for more information.
- https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---update-refs
- https://andrewlock.net/working-with-stacked-branches-in-git-is-easier-with-update-refs/
git stack --push will push the current stack to the remote. Please see https://github.com/gitext-rs/git-stack/blob/main/docs/reference.md#git-stack---push for more information.
Sometimes, git stack --push will not push a branch. It's unclear as to why. You can workaround this by running the follow command:
git spush
This will:
- Use
git stack runto run the command on each commit in the stack - Use
git srun(an internal utility command) to run the command on each branch in the stack and avoid protected branches and detached HEADs - Use
git fpushto push the branch to the remote usinggit push --force-with-lease origin $BRANCH
git stack run <command> will run the command on each commit in the stack. Note, this is not running for each branch, it is running for each commit. This is useful for running tests on each commit in the stack.
The command below will create a PR for each branch in the stack. This command can be run multiple times. If a PR already exists for a branch, it will be updated using git fpush.
git submit
Let's say you've opened a few PRs (manually or otherwise). We can run a script to automatically comment on each PR with the direct parent and immediate descendants of the PR. This is useful for tracking the stack of PRs.
This command can be run multiple times. If a comment already exists, it will be updated.
git submit will do this automatically. The comment template looks like this:
Current dependencies on/for this PR:
* **PR #<parent_PR_number>
* **PR #<current_PR_number> 👈
* **PR #<immediate_descendant_PR_number>
* **PR #<immediate_descendant_PR_number>
* **PR #<immediate_descendant_PR_number>