git machete traverse: Manage Branch Stacks
git machete traverse walks a defined tree of branches, rebasing and pushing each onto its parent.
git-machete records parent/child branch relationships in a .git/machete file and automates keeping the whole tree rebased. traverse is the batch command that syncs every branch in order.
What it does
git machete reads a branch tree from .git/machete. git machete status shows which branches are in sync, and git machete traverse walks the tree bottom-up, rebasing each branch onto its parent and pushing, stopping to ask (or acting on flags) at each step.
Common usage
# generate the initial branch tree
git machete discover --yes
# show sync status of the tree
git machete status
# rebase and push the whole tree without prompts
git machete traverse --fetch --push --start-from=first-root --return-to=here --yesOptions
| Command / Flag | What it does |
|---|---|
| git machete discover | Infer and write the branch tree |
| git machete status | Show in-sync/out-of-sync branches |
| git machete traverse | Rebase/push each branch onto its parent |
| --fetch | Fetch from the remote before traversing |
| --push / --no-push | Push (or not) after each rebase |
| --yes | Assume yes to all prompts (non-interactive) |
In CI
Pass --yes (or a specific answer mode) so traverse does not prompt. It needs the .git/machete file present, so commit it or run git machete discover --yes first. A rebase can hit conflicts mid-traverse; check the exit code so the job stops rather than pushing a half-rebased tree.
Common errors in CI
"the current directory ... is not a git repository" means it ran outside a checkout. "no branches listed in .git/machete" means the tree file is missing; run discover. A traverse that halts with "There are some uncommitted changes" needs a clean tree. Conflicts leave a rebase in progress that the job must resolve or abort.
Using this in CI
CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.
- uses: actions/checkout@v4
with:
fetch-depth: 0 # history, tags, and git describe all need this
- run: |
git rev-parse --is-shallow-repository # expect false
git rev-parse --abbrev-ref HEAD # prints HEAD when detached