Welcome to git machete’s documentation!

Probably the sharpest git repository organizer & rebase/merge workflow automation tool you’ve ever seen.

  1. Description

  2. Command Line Interface

  3. Learning Materials

  4. Installing git machete command line completion

Description

git machete is a robust tool that simplifies your git workflows.

The bird’s eye view provided by git machete makes merges/rebases/push/pulls hassle-free even when multiple branches are present in the repository (master/develop, your topic branches, teammate’s branches checked out for review, etc.).

Using this tool, you can maintain small, focused, easy-to-review pull requests with little effort.

A look at a git machete status gives an instant answer to the questions:

  • What branches are in this repository?

  • What is going to be merged (rebased/pushed/pulled) and to what?

git machete traverse semi-automatically traverses the branches, helping you effortlessly rebase, merge, push and pull.

Command Line Interface

When git-machete is installed, it adds machete command to git, so it can be called from command line: git machete <command> <options>. git machete comes with a wide variety of customizable commands and in this site you can find their documentation.

git machete commands and help topics:

  • add – Add a branch to the tree of branch dependencies.

  • advance – Fast-forward merge one of children to the current branch and then slide out this child

  • anno – Manage custom annotations

  • delete-unmanaged – Delete local branches that are not present in the definition file`

  • diff – Diff current working directory or a given branch against its computed fork point

  • discover – Automatically discover tree of branch dependencies

  • edit – Edit the definition file

  • file – Display the location of the definition file

  • fork-point – Display or override fork point for a branch

  • format – Display docs for the format of the definition file

  • github – Create, retarget and manage GitHub PRs while keeping them reflected in git machete

  • go – Check out the branch relative to the position of the current branch, accepts down/first/last/next/root/prev/up <annotation text>

  • help – Display this overview, or detailed help for a specified command

  • hooks – Display docs for the extra hooks added by git machete

  • is-managed – Check if the current branch is managed by git machete (mostly for scripts)

  • list – List all branches that fall into one of pre-defined categories (mostly for internal use)

  • log – Log the part of history specific to the given branch

  • reapply – Rebase the current branch onto its computed fork point

  • show – Show name(s) of the branch(es) relative to the position of a branch, accepts down/first/last/next/root/prev/up <annotation text>

  • slide-out – Slide out the current branch and sync its downstream (child) branches with its upstream (parent) branch via rebase or merge

  • squash – Squash the unique history of the current branch into a single commit

  • status – Display formatted tree of branch dependencies, including info on their sync with upstream branch and with remote

  • traverse – Walk through the tree of branch dependencies and rebase, merge, slide out, push and/or pull each branch one by one

  • update – Sync the current branch with its upstream (parent) branch via rebase or merge

  • version – Display the version and exit

To get help via CLI run:

git machete help
git machete help go
git machete go --help

add

Usage:

git machete add [-o|--onto=<target-upstream-branch>] [-R|--as-root] [-y|--yes] [<branch>]

Adds the provided <branch> (or the current branch, if none specified) to the definition file. If <branch> is provided but no local branch with the given name exists:

  • if a remote branch of the same name exists in exactly one remote, then user is asked whether to check out this branch locally (as in git checkout),

  • otherwise, user is asked whether it should be created as a new local branch.

If the definition file is empty or -R/--as-root is provided, the branch will be added as a root of the tree of branch dependencies. Otherwise, the desired upstream (parent) branch can be specified with -o/--onto. Neither of these options is mandatory, however; if both are skipped, git machete will try to automatically infer the target upstream. If the upstream branch can be inferred, the user will be presented with inferred branch and asked to confirm.

Note: all the effects of add (except git branch creation) can as well be achieved by manually editing the definition file.

Options:

-o, --onto=<target-upstream-branch>

Specifies the target parent branch to add the given branch onto. Cannot be specified together with -R/--as-root.

-R, --as-root

Add the given branch as a new root (and not onto any other branch). Cannot be specified together with -o/--onto.

-y, --yes

Don’t ask for confirmation whether to create the branch or whether to add onto the inferred upstream.

advance

Usage:

git machete advance [-y|--yes]

Fast forwards (as in git merge --ff-only) the current branch C to match its downstream D, and subsequently slides out D. Both steps require manual confirmation unless -y/--yes is provided.

The downstream C is selected according to the following criteria:

  • if C has exactly one downstream (child) branch d connected with a green edge (see status for definition) to C or is overridden, then d is selected as D,

  • if C has no downstream branches connected with a green edge to C, then advance fails,

  • if C has more than one downstream branch connected with a green edge to C, then user is asked to pick the branch to fast-forward merge into (similarly to what happens in git machete go down).

If --yes is specified, then advance fails.

As an example, if git machete status --color=never --list-commits is as follows:

master
|
m-develop *
  |
  | Enable adding remote branch in the manner similar to git checkout
  o-feature/add-from-remote
  | |
  | | Add support and sample for machete-post-slide-out hook
  | o-feature/post-slide-out-hook
  |
  | Remove support for Python 2
  | Remove support for Python 2 --- 1st round of fixes
  ?-chore/v3
  |
  | Apply Python2-compatible static typing
  x-feature/types

then running git machete advance will fast-forward the current branch develop to match feature/add-from-remote, and subsequently slide out the latter. After advance completes, status will show:

master
|
| Enable adding remote branch in the manner similar to git checkout
o-develop *
  |
  | Add support and sample for machete-post-slide-out hook
  o-feature/post-slide-out-hook
  |
  | Remove support for Python 2
  | Remove support for Python 2 --- 1st round of fixes
  ?-chore/v3
  |
  | Apply Python2-compatible static typing
  x-feature/types

Note that the current branch after the operation is still develop, just pointing to feature/add-from-remote’s tip now.

Options:

-y, --yes

Don’t ask for confirmation whether to fast-forward the current branch or whether to slide-out the downstream. Fails if the current branch has more than one green-edge downstream branch.

anno

Usage:

git machete anno [-b|--branch=<branch>] [<annotation text>]
git machete anno -H|--sync-github-prs

If invoked without any <annotation text>, prints out the custom annotation for the given branch (or current branch, if none specified with -b/--branch).

If invoked with a single empty string <annotation text>, like:

$ git machete anno ''

then clears the annotation for the current branch (or a branch specified with -b/--branch).

If invoked with -H or --sync-github-prs, annotates the branches based on their corresponding GitHub PR numbers and authors. Any existing annotations are overwritten for the branches that have an opened PR; annotations for the other branches remain untouched.

To allow GitHub API access for private repositories (and also to perform side-effecting actions like opening a PR, even in case of public repositories), a GitHub API token with repo scope is required, see https://github.com/settings/tokens. This will be resolved from the first of:

  1. GITHUB_TOKEN env var,

  2. current auth token from the gh GitHub CLI,

  3. current auth token from the hub GitHub CLI.

In any other case, sets the annotation for the given/current branch to the given <annotation text>. If multiple <annotation text>’s are passed to the command, they are concatenated with a single space.

Note: all the effects of anno can be always achieved by manually editing the definition file.

Options:

-b, --branch=<branch>

Branch to set the annotation for.

-H, --sync-github-prs

Annotate with GitHub PR numbers and authors where applicable.

delete-unmanaged

Usage:

git machete delete-unmanaged [-y|--yes]

Goes one-by-one through all the local git branches that don’t exist in the definition file, and ask to delete each of them (with git branch -d or git branch -D) if confirmed by user. No branch will be deleted unless explicitly confirmed by the user (or unless -y/--yes option is passed).

Note: this should be used with care since deleting local branches can sometimes make it impossible for git machete to properly figure out fork points. See fork-point for more details.

Options:

-y, --yes

Don’t ask for confirmation.

diff

Usage:

git machete d[iff] [-s|--stat] [<branch>]

Runs git diff of the given branch tip against its fork point or, if none specified, of the current working tree against the fork point of the currently checked out branch. See fork-point for more details on meaning of the fork point.

Note: the branch in question does not need to occur in the definition file.

Options:

-s, --stat

Makes git machete diff pass --stat option to git diff, so that only summary (diffstat) is printed.

discover

Usage:

git machete discover [-C|--checked-out-since=<date>] [-l|--list-commits] [-r|--roots=<branch1>,<branch2>,...] [-y|--yes]

Discovers and displays tree of branch dependencies using a heuristic based on reflogs and asks whether to overwrite the existing definition file with the new discovered tree. If confirmed with a y[es] or e[dit] reply, backs up the current definition file (if it exists) as $GIT_DIR/machete~ and saves the new tree under the usual $GIT_DIR/machete path. If the reply was e[dit], additionally an editor is opened (as in git machete edit) after saving the new definition file.

Options:

-C, --checked-out-since=<date>

Only consider branches checked out at least once since the given date. <date> can be e.g. 2 weeks ago or 2020-06-01, as in git log --since=<date>. If not present, the date is selected automatically so that around 10 branches are included.

-l, --list-commits

When printing the discovered tree, additionally lists the messages of commits introduced on each branch (as for git machete status).

-r, --roots=<branch1,…>

Comma-separated list of branches that should be considered roots of trees of branch dependencies. If not present, master is assumed to be a root. Note that in the process of discovery, certain other branches can also be additionally deemed to be roots as well.

-y, --yes

Don’t ask for confirmation before saving the newly-discovered tree. Mostly useful in scripts; not recommended for manual use.

edit

Usage:

git machete e[dit]

Opens an editor and lets you edit the definition file manually.

The editor is determined by checking up the following locations:

  • $GIT_MACHETE_EDITOR

  • $GIT_EDITOR

  • $(git config core.editor)

  • $VISUAL

  • $EDITOR

  • editor

  • nano

  • vi

and selecting the first one that is defined and points to an executable file accessible on PATH.

Note that the above editor selection only applies for editing the definition file, but not for any other actions that may be indirectly triggered by git machete, including editing of rebase TODO list, commit messages etc.

The definition file can be always accessed and edited directly under the path returned by git machete file (currently fixed to <git-directory>/machete).

file

Usage:

git machete file

Outputs the absolute path of machete definition file. The file is always called machete and is located in the git directory of the project.

Three cases are possible:
  • if git machete is executed from a regular working directory (not a worktree or submodule), the file is located under .git/machete,

  • if git machete is executed from a worktree, this file is located under .git/machete as well (not in the git folder of the worktree under .git/worktrees/.../machete),

  • if git machete is executed from a submodule, this file is located in the git folder of the submodule itself under .git/modules/.../machete.

fork-point

Usage:

git machete fork-point [--inferred] [<branch>]
git machete fork-point --override-to=<revision>|--override-to-inferred|--override-to-parent [<branch>]
git machete fork-point --unset-override [<branch>]

Note: in all three forms, if no <branch> is specified, the currently checked out branch is assumed. The branch in question does not need to occur in the definition file.

Without any option, displays full SHA of the fork point commit for the <branch>. Fork point of the given <branch> is the commit at which the history of the <branch> diverges from history of any other branch.

Fork point is assumed by many git machete commands as the place where the unique history of the <branch> starts. The range of commits between the fork point and the tip of the given branch is, for instance:

  • listed for each branch by git machete status --list-commits

  • passed to git rebase by git machete reapply/slide-out/traverse/update

  • provided to git diff/log by git machete diff/log.

git machete assumes fork point of <branch> is the most recent commit in the log of <branch> that has NOT been introduced on that very branch, but instead occurs on a reflog (see help for git reflog) of some other, usually chronologically earlier, branch. This yields a correct result in typical cases, but there are some situations (esp. when some local branches have been deleted) where the fork point might not be determined correctly. Thus, all rebase-involving operations (reapply, slide-out, traverse and update) run git rebase in the interactive mode by default, unless told explicitly not to do so by --no-interactive-rebase flag, so that the suggested commit range can be inspected before the rebase commences. Also, reapply, slide-out, squash, and update allow to specify the fork point explicitly by a command-line option.

git machete fork-point is different (and more powerful) than git merge-base --fork-point, since the latter takes into account only the reflog of the one provided upstream branch, while the former scans reflogs of all local branches and their remote tracking branches. This makes git machete’s fork-point more resilient to modifications of .git/machete file where certain branches are re-attached under new parents (upstreams).

With --override-to=<revision>, sets up a fork point override for <branch>. Fork point for <branch> will be overridden to the provided <revision> (commit) as long as the <branch> still points to (or is descendant of) the commit X that <branch> pointed to at the moment the override is set up. Even if revision is a symbolic name (e.g. other branch name or HEAD~3) and not explicit commit hash (like a1b2c3ff), it’s still resolved to a specific commit hash at the moment the override is set up (and not later when the override is actually used). The override data is stored under machete.overrideForkPoint.<branch>.to and machete.overrideForkPoint.<branch>.whileDescendantOf git config keys. Note: the provided fork point <revision> must be an ancestor of the current <branch> commit X.

With --override-to-parent, overrides fork point of the <branch> to the commit currently pointed by <branch>’s parent in the branch dependency tree. Note: this will only work if <branch> has a parent at all (i.e. is not a root) and parent of <branch> is an ancestor of current <branch> commit X.

With --inferred, displays the commit that git machete fork-point infers to be the fork point of <branch>. If there is NO fork point override for <branch>, this is identical to the output of git machete fork-point. If there is a fork point override for <branch>, this is identical to the what the output of git machete fork-point would be if the override was NOT present.

With --override-to-inferred option, overrides fork point of the <branch> to the commit that git machete fork-point infers to be the fork point of <branch>. Note: this piece of information is also displayed by git machete status --list-commits in case a yellow edge occurs.

With --unset-override, the fork point override for <branch> is unset. This is simply done by removing the corresponding machete.overrideForkPoint.<branch>.* config entries.

Note: if an overridden fork point applies to a branch B, then it’s considered to be connected with a green edge to its upstream (parent) U, even if the overridden fork point of B is NOT equal to the commit pointed by U.

format

Note: there is no git machete format command as such; format is just a topic of git machete help.

The format of the definition file should be as follows:

develop
    adjust-reads-prec PR #234
        block-cancel-order PR #235
            change-table
                drop-location-type
    edit-margin-not-allowed
        full-load-gatling
    grep-errors-script
master
    hotfix/receipt-trigger PR #236

In the above example develop and master are roots of the tree of branch dependencies. Branches adjust-reads-prec, edit-margin-not-allowed and grep-errors-script are direct downstream branches for develop. block-cancel-order is a downstream branch of adjust-reads-prec, change-table is a downstream branch of block-cancel-order and so on.

Every branch name can be followed (after a single space as a delimiter) by a custom annotation — a PR number in the above example. The annotations don’t influence the way git machete operates other than that they are displayed in the output of the status command. Also see anno command.

Tabs or any number of spaces can be used as indentation. It’s only important to be consistent wrt. the sequence of characters used for indentation between all lines.

github

Usage:

git machete github <subcommand>

where <subcommand> is one of: anno-prs, checkout-prs, create-pr, retarget-pr.

Creates, checks out and manages GitHub PRs while keeping them reflected in branch definition file.

To allow GitHub API access for private repositories (and also to perform side-effecting actions like opening a PR, even in case of public repositories), a GitHub API token with repo scope is required, see https://github.com/settings/tokens. This will be resolved from the first of:

  1. GITHUB_TOKEN env var,

  2. content of the .github-token file in the home directory (~),

  3. current auth token from the gh GitHub CLI,

  4. current auth token from the hub GitHub CLI.

anno-prs:

Annotates the branches based on their corresponding GitHub PR numbers and authors. Any existing annotations are overwritten for the branches that have an opened PR; annotations for the other branches remain untouched. Equivalent to git machete anno --sync-github-prs.

checkout-prs:

Check out the head branch of the given pull request (specified by number), also traverse chain of pull requests upwards, adding branches one by one to git-machete and check them out locally. Once pull request is checked out locally, annotate local branches with corresponding pull request numbers.

Parameters:

<PR-number>

Pull request number to checkout.

create-pr [--draft]:

Creates a PR for the current branch, using the upstream (parent) branch as the PR base. Once the PR is successfully created, annotates the current branch with the new PR’s number.

If .git/info/description file is present, its contents are used as PR description. If .git/info/milestone file is present, its contents (a single number — milestone id) are used as milestone. If .git/info/reviewers file is present, its contents (one GitHub login per line) are used to set reviewers.

Options:

--draft

Creates the new PR as a draft.

retarget-pr:

Sets the base of the current branch’s PR to upstream (parent) branch, as seen by git machete (see git machete show up).

go

Usage:

git machete g[o] <direction>

where <direction> is one of: d[own], f[irst], l[ast], n[ext], p[rev], r[oot], u[p]

Checks out the branch specified by the given direction relative to the current branch:

  • down: the direct children/downstream branch of the current branch.

  • first: the first downstream of the root branch of the current branch (like root followed by next), or the root branch itself if the root has no downstream branches.

  • last: the last branch in the definition file that has the same root as the current branch; can be the root branch itself if the root has no downstream branches.

  • next: the direct successor of the current branch in the definition file.

  • prev: the direct predecessor of the current branch in the definition file.

  • root: the root of the tree where the current branch is located. Note: this will typically be something like develop or master, since all branches are usually meant to be ultimately merged to one of those.

  • up: the direct parent/upstream branch of the current branch.

Roughly equivalent to git checkout $(git machete show <direction>).

help

Usage:

git machete help [<command>]

Prints a summary of this tool, or a detailed info on a command if provided.

hooks

As with the standard git hooks, git machete looks for its own specific hooks in $GIT_DIR/hooks/* (or $(git config core.hooksPath)/*, if set).

Note: hooks is not a command as such, just a help topic (there is no git machete hooks command).

  • machete-post-slide-out <new-upstream> <lowest-slid-out-branch> [<new-downstreams>...]

    The hook that is executed after a branch (or possibly multiple branches, in case of slide-out) is slid out by advance, slide-out or traverse.

    At least two parameters (branch names) are passed to the hook:

    • <new-upstream> is the upstream of the branch that has been slid out, or in case of multiple branches being slid out — the upstream of the highest slid out branch;

    • <lowest-slid-out-branch> is the branch that has been slid out, or in case of multiple branches being slid out — the lowest slid out branch;

    • <new-downstreams> are all the following (possibly zero) parameters, which correspond to all original downstreams of <lowest-slid-out-branch>, now reattached as the downstreams of <new-upstream>.

    Note that this may be zero, one, or multiple branches.

    Note: the hook, if present, is executed:

    • zero or once during a advance execution (depending on whether the slide-out has been confirmed or not),

    • exactly once during a slide-out execution (even if multiple branches are slid out),

    • zero or more times during traverse (every time a slide-out operation is confirmed).

    If the hook returns a non-zero exit code, then an error is raised and the execution of the command is aborted, i.e. slide-out won’t attempt rebase of the new downstream branches and traverse won’t continue the traversal. In case of advance there is no difference (other than exit code of the entire advance command being non-zero), since slide-out is the last operation that happens within advance.

    Note that non-zero exit code of the hook doesn’t cancel the effects of slide-out itself, only the subsequent operations. The hook is executed only once the slide-out is complete and can in fact rely on .git/machete file being updated to the new branch layout.

  • machete-pre-rebase <new-base> <fork-point-hash> <branch-being-rebased>

    The hook that is executed before rebase is run during reapply, slide-out, traverse and update. Note that it is NOT executed by squash (despite its similarity to reapply), since no rebase is involved in squash.

    The parameters are exactly the three revisions that are passed to git rebase --onto:

    1. what is going to be the new base for the rebased commits,

    2. what is the fork point — the place where the rebased history diverges from the upstream history,

    3. what branch is rebased.

    If the hook returns a non-zero exit code, an error is raised and the entire rebase is aborted.

    Note: this hook is independent from git’s standard pre-rebase hook. If machete-pre-rebase returns zero, the execution flow continues to git rebase, which may also run pre-rebase hook if present. machete-pre-rebase is thus always launched before pre-rebase.

  • machete-status-branch <branch-name>

    The hook that is executed for each branch displayed during discover, status and traverse.

    The standard output of this hook is displayed at the end of the line, after branch name, (optionally) custom annotation and (optionally) remote sync-ness status. Standard error is ignored. If the hook returns a non-zero exit code, both stdout and stderr are ignored, and printing the status continues as usual.

    Note: the hook is always invoked with ASCII_ONLY variable passed into the environment. If status runs in ASCII-only mode (i.e. if --color=auto and stdout is not a terminal, or if --color=never), then ASCII_ONLY=true, otherwise ASCII_ONLY=false.

Please see hook_samples for examples. An example of using the standard git post-commit hook to git machete add branches automatically is also included.

is-managed

Usage:

git machete is-managed [<branch>]

Returns with zero exit code if the given branch (or current branch, if none specified) is managed by git machete (i.e. listed in .git/machete).

Returns with a non-zero exit code in case:

  • the <branch> is provided but isn’t managed (or doesn’t exist), or

  • the <branch> isn’t provided and the current branch isn’t managed, or

  • the <branch> isn’t provided and there’s no current branch (detached HEAD).

list

Usage:

git machete list <category>

where <category> is one of: addable, managed, slidable, slidable-after <branch>, unmanaged, with-overridden-fork-point.

Lists all branches that fall into one of the specified categories:

  • addable: all branches (local or remote) than can be added to the definition file,

  • managed: all branches that appear in the definition file,

  • slidable: all managed branches that have an upstream and can be slid out with slide-out command

  • slidable-after <branch>: the downstream branch of the <branch>, if it exists and is the only downstream of <branch> (i.e. the one that can be slid out immediately following <branch>),

  • unmanaged: all local branches that don’t appear in the definition file,

  • with-overridden-fork-point: all local branches that have a fork point override set up (even if this override does not affect the location of their fork point anymore).

This command is generally not meant for a day-to-day use, it’s mostly needed for the sake of branch name completion in shell.

log

Usage:

git machete l[og] [<branch>]

Runs git log for the range of commits from tip of the given branch (or current branch, if none specified) back to its fork point. See fork-point for more details on meaning of the fork point.

Note: the branch in question does not need to occur in the definition file.

reapply

Usage:

git machete reapply [-f|--fork-point=<fork-point-commit>]

Interactively rebase the current branch on the top of its computed fork point. The chunk of the history to be rebased starts at the automatically computed fork point of the current branch by default, but can also be set explicitly by --fork-point. See fork-point for more details on meaning of the fork point.

Note: the current reapplied branch does not need to occur in the definition file.

Tip: reapply can be used for squashing the commits on the current branch to make history more condensed before push to the remote, but there is also dedicated squash command that achieves the same goal without running git rebase.

Options:

-f, --fork-point=<fork-point-commit>

Specifies the alternative fork point commit after which the rebased part of history is meant to start.

show

Usage:

git machete show <direction> [<branch>]

where <direction> is one of: c[urrent], d[own], f[irst], l[ast], n[ext], p[rev], r[oot], u[p] displayed relative to given <branch>, or the current checked out branch if <branch> is unspecified.

Outputs name of the branch (or possibly multiple branches, in case of down) that is:

  • current: the current branch; exits with a non-zero status if none (detached HEAD)

  • down: the direct children/downstream branch of the given branch.

  • first: the first downstream of the root branch of the given branch (like root followed by next), or the root branch itself if the root has no downstream branches.

  • last: the last branch in the definition file that has the same root as the given branch; can be the root branch itself if the root has no downstream branches.

  • next: the direct successor of the given branch in the definition file.

  • prev: the direct predecessor of the given branch in the definition file.

  • root: the root of the tree where the given branch is located. Note: this will typically be something like develop or master, since all branches are usually meant to be ultimately merged to one of those.

  • up: the direct parent/upstream branch of the given branch.

slide-out

Usage:

git machete slide-out [-d|--down-fork-point=<down-fork-point-commit>] [-M|--merge] [-n|--no-edit-merge|--no-interactive-rebase] [<branch> [<branch> [<branch> ...]]]

Removes the given branch (or multiple branches) from the branch tree definition. If no branch has been specified current branch is assumed as the only branch. Then synchronizes the downstream (child) branches of the last specified branch on the top of the upstream (parent) branch of the first specified branch. Sync is performed either by rebase (default) or by merge (if --merge option passed).

The most common use is to slide out a single branch whose upstream was a develop/master branch and that has been recently merged.

Since this tool is designed to perform only one single rebase/merge at the end, provided branches must form a chain, i.e. all of the following conditions must be met:

  • for i=1..N-1, (i+1)-th branch must be the only downstream (child) branch of the i-th branch,

  • all provided branches must have an upstream branch (so, in other words, roots of branch dependency tree cannot be slid out).

For example, let’s assume the following dependency tree:

develop
    adjust-reads-prec
        block-cancel-order
            change-table
                drop-location-type
            add-notification

And now let’s assume that adjust-reads-prec and later block-cancel-order were merged to develop. After running git machete slide-out adjust-reads-prec block-cancel-order the tree will be reduced to:

develop
    change-table
        drop-location-type
    add-notification

and change-table and add-notification will be rebased onto develop (fork point for this rebase is configurable, see -d option below).

Note: This command doesn’t delete any branches from git, just removes them from the tree of branch dependencies.

Options:

-d, --down-fork-point=<down-fork-point-commit>

If updating by rebase, specifies the alternative fork point for downstream branches for the operation. git machete fork-point overrides for downstream branches are recommended over use of this option. See also doc for --fork-point option in git machete help reapply and git machete help update. Not allowed if updating by merge.

-M, --merge

Update the downstream branch by merge rather than by rebase.

-n

If updating by rebase, equivalent to --no-interactive-rebase. If updating by merge, equivalent to --no-edit-merge.

--no-edit-merge

If updating by merge, skip opening the editor for merge commit message while doing git merge (i.e. pass --no-edit flag to underlying git merge). Not allowed if updating by rebase.

--no-interactive-rebase

If updating by rebase, run git rebase in non-interactive mode (without -i/--interactive flag). Not allowed if updating by merge.

squash

Usage:

git machete squash [-f|--fork-point=<fork-point-commit>]

Squashes the commits belonging uniquely to the current branch into a single commit. The chunk of the history to be squashed starts at the automatically computed fork point of the current branch by default, but can also be set explicitly by --fork-point. See fork-point for more details on meaning of the fork point. The message for the squashed is taken from the earliest squashed commit, i.e. the commit directly following the fork point.

Note: the current squashed branch does not need to occur in the definition file.

Tip: squash does NOT run git rebase under the hood. For more complex scenarios that require rewriting the history of current branch, see reapply and update.

Options:

-f, --fork-point=<fork-point-commit>

Specifies the alternative fork point commit after which the squashed part of history is meant to start.

status

Usage:

git machete s[tatus] [--color=WHEN] [-l|--list-commits] [-L|--list-commits-with-hashes] [--no-detect-squash-merges]

Displays a tree-shaped status of the branches listed in the definition file.

Apart from simply ASCII-formatting the definition file, this also:

  • colors the edges between upstream (parent) and downstream (children) branches:

    • red edge means that the downstream branch tip is not a direct descendant of the upstream branch tip,

    • yellow edge means that the downstream branch tip is a direct descendant of the upstream branch tip, but the fork point of the downstream branch is not equal to the upstream branch tip,

    • green edge means that the downstream branch tip is a direct descendant of the upstream branch tip and the fork point of the downstream branch is equal to the upstream branch tip,

    • grey/dimmed edge means that the downstream branch has been merged to the upstream branch, detected by commit equivalency (default), or by strict detection of merge commits (if --no-detect-squash-merges passed).

  • prints (untracked/ahead of <remote>/behind <remote>/diverged from [& older than] <remote>) message if the branch is not in sync with its remote counterpart;

  • displays the custom annotations (see format and anno) next to each branch, if present;

  • displays the output of machete-status-branch hook (see hooks), if present;

  • optionally lists commits introduced on each branch if -l/--list-commits or -L/--list-commits-with-hashes is supplied.

The currently checked-out branch is underlined.

In case of yellow edge, use -l or -L flag to show the exact location of the inferred fork point (which indicates e.g. what range of commits is going to be rebased when the branch is updated). The inferred fork point can be always overridden manually, see fork-point.

Grey/dimmed edge suggests that the downstream branch can be slid out (see slide-out and traverse).

Using colors can be disabled with a --color flag set to never. With --color=always, git machete always emits colors and with --color=auto, it emits colors only when standard output is connected to a terminal. --color=auto is the default. When colors are disabled, relation between branches is represented in the following way:

<branch0>
|
o-<branch1>  # green (in sync with parent)
| |
| x-<branch2> # red (not in sync with parent)
|   |
|   ?-<branch3> # yellow (in sync with parent, but parent is not the fork point)
|
m-<branch4> # grey (merged to parent)

Options:

--color=WHEN

Colorize the output; WHEN can be always, auto (default; i.e. only if stdout is a terminal), or never.

-l, --list-commits

Additionally list the commits introduced on each branch.

-L, --list-commits-with-hashes

Additionally list the short hashes and messages of commits introduced on each branch.

--no-detect-squash-merges

Only consider strict (fast-forward or 2-parent) merges, rather than rebase/squash merges, when detecting if a branch is merged into its upstream (parent).

traverse

Usage:

git machete t[raverse] [-F|--fetch] [-l|--list-commits] [-M|--merge]
                       [-n|--no-edit-merge|--no-interactive-rebase] [--no-detect-squash-merges]
                       [--[no-]push] [--[no-]push-untracked]
                       [--return-to=WHERE] [--start-from=WHERE] [-w|--whole] [-W] [-y|--yes]

Traverses the branch dependency tree in pre-order (i.e. simply in the order as they occur in the definition file). By default traverse starts from current branch, however this behaviour can be customized using options: --start-from=, --whole or -w, -W. For each branch, the command:

  • detects if the branch is merged to its parent/upstream:

    • by commit equivalency (default), or by strict detection of merge commits (if --no-detect-squash-merges passed),

    • if so, asks the user whether to slide out the branch from the dependency tree (typically branches are longer needed after they’re merged);

  • otherwise, if the branch is not in green sync with its parent/upstream (see status):

    • asks the user whether to rebase (default) or merge (if --merge passed) the branch onto into its upstream branch — equivalent to git machete update with no --fork-point option passed;

  • if the branch is not tracked on a remote, is ahead of its remote counterpart, or diverged from the counterpart & has newer head commit than the counterpart:

    • asks the user whether to push the branch (possibly with --force-with-lease if the branches diverged);

  • otherwise, if the branch diverged from the remote counterpart & has older head commit than the counterpart:

    • asks the user whether to git reset --keep the branch to its remote counterpart

  • otherwise, if the branch is behind its remote counterpart:

    • asks the user whether to pull the branch;

  • and finally, if any of the above operations has been successfully completed:

    • prints the updated status.

Note that even if the traverse flow is stopped (typically due to merge/rebase conflicts), running git machete traverse after the merge/rebase is finished will pick up the walk where it stopped. In other words, there is no need to explicitly ask to continue as it is the case with e.g. git rebase.

Options:

-F, --fetch

Fetch the remotes of all managed branches at the beginning of traversal (no git pull involved, only git fetch).

-l, --list-commits

When printing the status, additionally list the messages of commits introduced on each branch.

-M, --merge

Update by merge rather than by rebase.

-n

If updating by rebase, equivalent to --no-interactive-rebase. If updating by merge, equivalent to --no-edit-merge.

--no-detect-squash-merges

Only consider strict (fast-forward or 2-parent) merges, rather than rebase/squash merges, when detecting if a branch is merged into its upstream (parent).

--no-edit-merge

If updating by merge, skip opening the editor for merge commit message while doing git merge (i.e. pass --no-edit flag to underlying git merge). Not allowed if updating by rebase.

--no-interactive-rebase

If updating by rebase, run git rebase in non-interactive mode (without -i/--interactive flag). Not allowed if updating by merge.

--no-push

Do not push any (neither tracked nor untracked) branches to remote, re-enable via --push.

--no-push-untracked

Do not push untracked branches to remote, re-enable via --push-untracked.

--push

Push all (both tracked and untracked) branches to remote — default behavior.

--push-untracked

Push untracked branches to remote — default behavior.

--return-to=WHERE

Specifies the branch to return after traversal is successfully completed; WHERE can be here (the current branch at the moment when traversal starts), nearest-remaining (nearest remaining branch in case the here branch has been slid out by the traversal) or stay (the default — just stay wherever the traversal stops). Note: when user quits by q/yq or when traversal is stopped because one of git actions fails, the behavior is always stay.

--start-from=WHERE

Specifies the branch to start the traversal from; WHERE can be here (the default — current branch, must be managed by git machete), root (root branch of the current branch, as in git machete show root) or first-root (first listed managed branch).

-w, --whole

Equivalent to -n --start-from=first-root –return-to=nearest-remaining; useful for quickly traversing & syncing all branches (rather than doing more fine-grained operations on the local section of the branch tree).

-W

Equivalent to --fetch --whole; useful for even more automated traversal of all branches.

-y, --yes

Don’t ask for any interactive input, including confirmation of rebase/push/pull. Implies -n.

update

Usage:

git machete update [-f|--fork-point=] [-M|--merge] [-n|--no-edit-merge|--no-interactive-rebase]

Synchronizes the current branch with its upstream (parent) branch either by rebase (default) or by merge (if --merge option passed).

If updating by rebase, interactively rebases the current branch on the top of its upstream (parent) branch. The chunk of the history to be rebased starts at the fork point of the current branch, which by default is inferred automatically, but can also be set explicitly by --fork-point. See fork-point for more details on meaning of the fork point.

If updating by merge, merges the upstream (parent) branch into the current branch.

Options:

-f, --fork-point=<fork-point-commit>

If updating by rebase, specifies the alternative fork point commit after which the rebased part of history is meant to start. Not allowed if updating by merge.

-M, --merge

Update by merge rather than by rebase.

-n

If updating by rebase, equivalent to --no-interactive-rebase. If updating by merge, equivalent to --no-edit-merge.

--no-edit-merge

If updating by merge, skip opening the editor for merge commit message while doing git merge (i.e. pass --no-edit flag to underlying git merge). Not allowed if updating by rebase.

--no-interactive-rebase

If updating by rebase, run git rebase in non-interactive mode (without -i/--interactive flag). Not allowed if updating by merge.

version

Usage:

git machete version

Prints the version and exits.

Learning Materials

git machete is a handy tool for managing your git repositories and to make it easier to use, the author of the tool Paweł Lipski has prepared series of articles on various git machete related topics. Check them for more information on how to use git machete or how to manage your own programming project using Docker and CI services:

Installing git machete command line completion

Bash:

  • Mac (via Homebrew)

    Make sure you have bash completion installed (with brew install bash-completion).

    brew install git machete automatically installs bash completion files for git machete.

  • Linux
    1. In a non-minimal installation of Linux, bash completion should be available.

    2. Place the completion script in /etc/bash_completion.d/.

    sudo curl -L https://raw.githubusercontent.com/VirtusLab/git-machete/master/completion/git-machete.completion.bash -o /etc/bash_completion.d/git-machete
    

Zsh:

  • Linux/Mac: with [oh-my-zsh](https://ohmyz.sh/) shell
    $ mkdir -p ~/.oh-my-zsh/custom/plugins/git-machete/
    $ curl -L https://raw.githubusercontent.com/VirtusLab/git-machete/master/completion/git-machete.completion.zsh -o ~/.oh-my-zsh/custom/plugins/git-machete/git-machete.plugin.zsh
    

    Add git machete to the plugins list in ~/.zshrc to run autocompletion within the oh-my-zsh shell. In the following example, ... represents other zsh plugins you may have installed.

    plugins=(... git-machete
    )
    
    • Workarounds for Zsh on Mac

      On Mac, unfortunately there might be a problem that git machete subcommands still don’t complete even when the zsh plugin is active. This issue also affects other non-standard git subcommands like git flow and git lfs. To work the issue around, first establish how git is installed in your system.

      which git
      

      If git resolves to /usr/bin/git, then likely git is the default installation provided in Mac OS. As a workaround, add the following line directly at the end of ~/.zshrc:

      source ~/.oh-my-zsh/custom/plugins/git-machete/git-machete.plugin.zsh
      

      and reload the shell.

      If git resolves to /usr/local/bin/git, then likely git has been installed via brew. Up to our current knowledge, workaround is much harder to provide in such scenario.

      One option is to brew uninstall git and then use the solution for Mac’s default git provided above, but that’s likely undesired since git shipped with Mac OS is almost always an older version than what’s available via brew.

      Another, less intrusive workaround is to make sure that the zsh _git function is NOT taken from brew-git’s /usr/local/share/zsh/site-functions/_git, but instead from /usr/share/zsh/5.7.1/functions/_git (zsh version path fragment can be different from 5.7.1). Add the following at the end of ~/.zshrc:

      source /usr/share/zsh/5.7.1/functions/_git  # or other zsh version instead of 5.7.1, depending on what's available in the system
      

      and reload the shell.

  • Linux/Mac: without oh-my-zsh shell
    1. Place the completion script in your /path/to/zsh/completion (typically ~/.zsh/completion/):

      $ mkdir -p ~/.zsh/completion
      $ curl -L https://raw.githubusercontent.com/VirtusLab/git-machete/master/completion/git-machete.completion.zsh -o ~/.zsh/completion/_git-machete
      
    2. Include the directory in your $fpath by adding in ~/.zshrc:

      fpath=(~/.zsh/completion $fpath)
      
    3. Make sure compinit is loaded or do it by adding in ~/.zshrc:

      autoload -Uz compinit && compinit -i
      
    4. Then reload your shell:

      exec $SHELL -l
      

Fish:

  • Mac (via Homebrew)

    Please look at the section about [installation via Homebrew](https://github.com/VirtusLab/git-machete#using-homebrew-macos). brew install git-machete automatically installs fish completion files for git machete.

  • Linux

    Place the completion script in /path/to/fish/completions/ (typically ~/.config/fish/completions/git-machete.fish).

    mkdir -p ~/.config/fish/completions
    curl -L https://raw.githubusercontent.com/VirtusLab/git-machete/develop/completion/git-machete.fish -o ~/.config/fish/completions/git-machete.fish
    echo "source ~/.config/fish/completions/git-machete.fish >/dev/null" >> ~/.config/fish/config.fish