git-machete

repository·develop·Indexed 22 days ago

https://github.com/virtuslab/git-machete

A tool designed to simplify complex Git workflows, particularly when managing multiple interconnected topic branches. It provides a bird's eye view of branch relationships to streamline rebasing, merging, pushing, and pulling. Features include branch layout discovery, interactive navigation with `git machete go`, semi-automatic synchronization via `git machete traverse`, and integration with GitHub Pull Requests and GitLab Merge Requests.

Tokens
40K
Snippets
170
Records
209
Agent score
76%

What's inside git-machete

  1. Overview of git-machete features

    develop

    git-machete is a tool designed to simplify complex Git workflows, specifically when managing multiple branches and stacked pull requests (e.g., feature-3feature-2feature-1develop).

    Key capabilities include:

    • Bird's eye view: Visualize branch relationships and hierarchies.
    • Automatic status: Instantly identify which branches are in sync, which require a rebase, and which are already merged.
    • Simplified syncing: Perform rebase, push, and pull operations across multiple branches simultaneously with single commands.
    • GitHub and GitLab integration: Synchronize local branch states with remote PR structures and descriptions.
  2. Overview of git-machete

    develop

    git-machete is a tool designed to simplify Git workflows by providing a high-level view of branch relationships. It helps manage merges, rebases, pushes, and pulls, especially in repositories with multiple active branches (e.g., master/develop, topic branches, and teammate branches).

    Key workflows include:

    • git machete status: Provides an instant overview of branches in the repository and identifies what is slated to be merged, rebased, pushed, or pulled.
    • git machete traverse: Semi-automatically traverses branches to help you rebase, merge, push, and pull effortlessly.

    Once installed, it integrates directly with the Git CLI as a subcommand: git machete <command> <options>.

  3. Overview of git-machete commands

    develop

    git-machete provides a suite of commands to manage complex branch dependency trees, automate rebasing/merging through the tree, and integrate with GitHub/GitLab.

    Key functional areas include:

    • Tree Management: add (add branches to the tree), discover (auto-discover dependencies), edit (edit layout file), rename (rename in git and layout), and status (view the dependency tree).
    • Branch Synchronization: update (sync with parent), reapply (rebase onto fork point), slide-out (sync downstream children with upstream parent), advance (fast-forward merge and slide out), and traverse (walk the tree to sync multiple branches).
    • Cleanup: clean (delete untracked/unmanaged branches) and delete-unmanaged (delete branches not in the layout file).
    • Git/Platform Integration: github and gitlab (manage PRs/MRs), and diff (diff against computed fork point).
    • History Manipulation: squash (squash unique history into one commit) and log (view branch-specific history).
  4. Reduce Docker image size by combining RUN commands

    develop

    To keep Docker images small, avoid creating multiple RUN layers that add and then remove the same files. Because Docker layers are additive, files removed in a subsequent RUN instruction still occupy space in the previous layer.

    Instead, combine installation and cleanup into a single RUN command using &&. This ensures that build-time dependencies (like compilers or SDKs) and temporary files are removed within the same layer they were created, preventing them from bloating the final image.

    Example pattern:

    1. Install build dependencies.
    2. Download and compile the software.
    3. Install the software.
    4. Remove build dependencies and temporary archives.
    5. Remove unnecessary sub-components of the software.
    ARG git_version
    RUN set -x \
        && apk add --no-cache --virtual=git-build-deps alpine-sdk autoconf gettext wget zlib-dev \
        && wget -q https://github.com/git/git/archive/v$git_version.tar.gz \
        && tar xzf v$git_version.tar.gz \
        && rm v$git_version.tar.gz \
        && cd git-$git_version/ \
        && make configure \
        && ./configure \
        && make \
        && make install \
        && cd .. \
        && rm -r git-$git_version/ \
        && git --version \
        && apk del git-build-deps \
        && rm -rfv /usr/local/bin/git-shell /usr/local/share/git-gui/ \
        && cd /usr/local/libexec/git-core/ \
        && rm -fv git-credential-* git-daemon git-fast-import git-http-backend git-imap-send git-remote-testsvn git-shell
  5. Control `traverse` start and end points

    develop

    You can customize where the traverse walk begins and where it ends using the following options:

    • --start-from=WHERE:
      • here (default): Starts from the current branch.
      • root: Starts from the root branch of the current branch.
      • first-root: Starts from the first listed managed branch.
      • <branch-name>: Starts from a specific branch.
    • --stop-after=BRANCH: Stops the traversal immediately after processing the specified branch.
    • --return-to=WHERE: Defines where you end up after traversal completes:
      • here: Returns to the branch you were on when traversal started.
      • nearest-remaining: Returns to the nearest branch that wasn't 'slid out' (removed).
      • stay (default): Stays on whichever branch the traversal finished on.
  6. Interpret color-coded branch edges in `status`

    develop

    When running git machete status, the lines (edges) connecting branches indicate their relationship to their parent:

    • Green: The branch is in sync with its parent.
    • Red: The branch is out of sync with its parent (the parent has commits not yet in this branch). This branch is a candidate for rebasing onto its parent.
    • Gray: The branch is merged into its parent and can be safely "slid out".
    • Yellow: The branch is in sync with its parent, but its fork point is off (the unique history starts at a later commit than the parent's tip).
  7. Understand the concept of a fork point in git-machete

    develop

    In git-machete, the fork point of a branch is the commit where that branch's history diverges from the history of any other branch. This commit marks the beginning of the branch's unique history.

    Many git-machete commands rely on this range (from the fork point to the branch tip) to perform operations:

    • git machete status --list-commits: Lists these commits.
    • reapply, slide-out, traverse, update: Pass this range to git rebase.
    • diff, log: Provide this range to git diff and git log.

    git-machete determines the fork point by scanning the reflogs of all local branches and their remote tracking branches. This makes it more resilient than git merge-base --fork-point, which only looks at a single upstream branch.

    Note on Accuracy: Because fork point detection can sometimes be incorrect (e.g., when local branches have been deleted), rebase-involving operations run git rebase in interactive mode by default. This allows you to inspect the suggested commit range before proceeding. You can bypass this with the --no-interactive-rebase flag.

  8. Understand the branch layout file format

    develop

    The branch layout file represents the tree of branch dependencies using indentation.

    • Roots: Branches at the leftmost indentation level (e.g., develop, master) are the roots of the dependency tree.
    • Downstream Branches: Branches indented under another branch are its downstream dependencies. For example, if adjust-reads-prec is indented under develop, it is a direct downstream branch of develop.
    • Indentation: You can use tabs or any number of spaces for indentation, but you must use the same indentation method consistently throughout the file.
    • Annotations: Every branch name can be followed by a single space and then custom annotations (e.g., PR #234 rebase=no push=no).
    • Branch Qualifiers: Annotations can include qualifiers like push=no, rebase=no, or slide-out=no, which control the behavior of the traverse command.
    develop
        adjust-reads-prec PR #234 rebase=no push=no
            block-cancel-order PR #235 rebase=no
                change-table
                    drop-location-type
        edit-margin-not-allowed
            full-load-gatling push=no
        grep-errors-script
    master
        hotfix/receipt-trigger PR #236
  9. How fork points are determined in git-machete

    develop

    Git-machete calculates a fork point—the commit where a branch's history diverges from all other branches—using a heuristic based on git reflog.

    It compares the commit-wise history (git log) of a branch against the operation-wise history (git reflog) of all other local branches. The most recent commit in branch x's log that also appears in the reflog of any other branch y is considered the fork point.

    Handling inaccuracies: If the heuristic fails (e.g., due to deleted branches), you can:

    1. Manually specify the fork point for update or reapply using the -f or --fork-point flag.
    2. Manually specify the down-fork-point for slide-out using the -d or --down-fork-point flag.
    3. Use git machete fork-point <branch> to inspect the calculated point.
  10. Sync stacked branches using rebase vs merge

    develop

    There are two ways to sync a branch with its base:

    1. Rebase the branch onto its base branch (Recommended for stacked branches).
    2. Merge the base branch into the branch.

    While git machete traverse --merge is available, using merge with stacked branches can lead to a tangled history and may require complex git cherry-pick operations to fix. Use rebase for stacked branches and reserve merge for specific cases like backporting hotfixes.