Starting at the trunk branch, any number of branches may be stacked on top.
git-spice learns about the relationships between branches by 'tracking' them
in an internal data store.
Branches may be tracked manually or automatically:
This will create a new branch stacked on top of the current branch,
commit the staged files to it, and track it with the current branch as base.
An editor will open to let you write a commit message
if one was not provided with the -m/--message flag.
But I use git commit -a
If you prefer to use git commit -a to automatically stage files
before committing, use gs branch create -a to do the same with git-spice.
If you prefer a workflow where you create branches first
and then work on them,
you can configure git-spice to never commit by default.
See Create branches without committing.
git-spice does not require to change your workflow too drastically.
If you prefer to use your usual workflow to create branches and commit changes,
use gs branch track to inform git-spice of the branch after creating it.
$ git checkout -b feat1# make your changes$ git commit$ gs branch trackINF feat1: tracking with base main
We advise picking descriptive names for branches.
You don't need to remember the exact names as git-spice provides
a number of utilities to help navigate and manipulate the stack.
Most places where a branch name is required provide
shell completion and fuzzy-searchable lists.
Can't think of a branch name?
If you can't think of a name for a branch,
run gs branch create without any arguments.
git-spice will use the commit message to generate a branch name for you.
These commands allow for relative movement within the stack,
so that you don't have to remember exact branch names
or their positions in the stack.
What's the value of gs branch checkout?
$ gs branch checkout my-feature
You may be wondering about gs branch checkout
when git checkout exists.
The command behaves not much differently than git checkout
when provided with a branch name as an argument.
$ gs branch checkout # or gs bcoSelect a branch to checkout:┏━■ docs ◀┃ ┏━□ github-optimization┣━┻□ github-supportmain
Its real value lies in the interactive mode.
Invoke it without arguments to get a fuzzy-searchable list of branches,
visualized as a tree-like structure to help you navigate the stack.
With a stacked branch checked out,
you can commit to it as usual with git commit, git commit --amend, etc.
However, after committing, the branches upstack from the current branch
need to be restacked to maintain a linear history.
Use gs upstack restack to do this.
git-spice also offers
gs branch restack to restack just the current branch onto its base,
and gs stack restack to restack all branches in the current stack.
gs commit split (or gs csp)
interactively splits the last commit into two and restacks upstack branches
gs branch edit (or gs be)
opens an interactive rebase of the commits in the current branch
and restacks upstack branches after the rebase completes successfully
For example, the interaction above can be shortened to:
$ gs branch checkout feat1$ $EDITOR file.txt# prepare your changes$ gs commit create # or gs cc
Use gs branch split to split a branch with one or more commits
into two or more branches.
The command presents a prompt allowing you to select one or more
split points in the branch's history.
After selecting the split points,
it will prompt you for a name for each new branch.
$ gs branch splitSelect commits:▶ c4fb996 Add an aardvark (12 minutes ago) f1d2d2f Refactor the pangolin (5 minutes ago) ■ 4186a53 Invent penguins (1 second ago) [penguin] Done
Tip
You can use gs commit split and gs branch edit
to safely and easily manipulate the commits in the branch
before splitting it into multiple branches.
v0.8.0
If you split a branch after submitting it for review,
git-spice will prompt you to assign the submitted CR
to one of the branches.
Assign CR #123 to branch: aardvark pangolin▶ penguinBranch being split has an open CR assigned to it.Select which branch should take over the CR.
If the interactive prompt is not suitable for your workflow,
you can also split a branch non-interactively
by specifying the split points with the --at option
one or more times.
The option takes the form:
--at COMMIT:NAME
Where COMMIT is a reference to a commit in the branch's history,
and NAME is the name of the new branch.
If running in non-interactive mode
and the branch has already been submitted for review,
it will be left assigned to the original branch.
Use the gs upstack onto command to move a branch onto another base branch,
and bring its upstack branches along with it.
$ gs branch checkout feat2$ gs upstack onto main
mainfeat1feat2feat3mainfeat1feat2feat3
Tip
Omit the target branch name
to get a list of branches to choose from.
This is useful when you realize that a branch
does not actually depend on the base branch it is stacked on.
With this command, you can move an entire section of the stack
down to a different base branch, or even to the trunk branch,
reducing the number of changes that need to merge before the target branch.
In rarer cases, you want to extract the current branch from the stack
and move it to a different base branch,
while leaving the upstack branches where they are.
Use gs branch delete to remove a branch from the stack
and delete it from the repository.
Branches that are upstack from the deleted branch
will be restacked on top of the deleted branch's original base branch.