Skip to content
yaggui docsNext (unreleased)

Merge and rebase

Bring the commits of one branch into another: merge them, fast-forward the branch, or replay them on top of it with a rebase. Each action can start from a drag and drop, from the sidebar menu of a branch, or from the command palette.

  1. Press a branch in the sidebar or a branch label (pill) in the graph, local or remote, and move the pointer. The drag starts after a few pixels and a label with the branch name follows the pointer.
  2. Release it on a local branch, in the sidebar or on a graph pill. The branch under the pointer is highlighted. Remote branches are not drop targets.
  3. A menu titled Dropped on {target} opens at the pointer. Pick an action, or press Esc to cancel.

Press Esc during the drag to cancel it.

When you drag branch X onto branch Y:

Menu item What it does Notes
Merge X into Y… Opens the merge dialog Hint Checks out Y first when Y is not the current branch
Rebase X onto Y Asks for confirmation, then rebases X onto Y Disabled for a remote branch: A remote branch cannot be rebased. Hint Checks out X first when X is not the current branch
Fast-forward Y to X Fast-forwards Y to X, without a dialog Hint Checks out Y first when Y is not the current branch
  • Dropping a branch on itself shows a single disabled item, Nothing to do: same branch.
  • Dragging commits instead of a branch offers a cherry-pick: see Cherry-pick, revert and reset.
  • While a merge, rebase, cherry-pick or revert is in progress, every item is disabled with the hint Finish or abort the operation in progress first.

When the target must be checked out first and you have local changes in the way, yaggui opens the usual dialog for a checkout with local changes and stops there: see Branches.

Right-click a branch other than the checked-out one. The menu has the same three actions, always against the current branch:

Menu item Same as
Merge {name} into {current}… Dragging {name} onto {current}, then Merge
Rebase {name} onto {current} Dragging {name} onto {current}, then Rebase
Fast-forward {current} to {name} Dragging {name} onto {current}, then Fast-forward

These items are hidden when HEAD is detached, and disabled while an operation is in progress. Rebase is disabled on remote branches.

This menu is the keyboard path to the drag: in the sidebar, press Shift+F10 or the context-menu key on the selected branch.

Open the palette with ⌘K (Ctrl+K on Windows and Linux) and run:

Action What it opens
Merge a branch into the current branch… The merge dialog with a Branch to merge picker
Rebase the current branch onto… The rebase dialog with a Rebase onto picker

They have no default shortcut; you can bind one (see Palette and shortcuts). Both are unavailable while an operation is in progress.

The dialog Merge {source} into {target} reads: “Choose how the commits of the branch are brought in. The choice is remembered.”

Field Content
Branch to merge Only when opened from the palette. Local branches except the target, plus remote branches
Merge mode One of the three modes below
Commit message Only for Always create a merge commit and Squash. Leave it empty to use Git’s default message
Mode Help text Git option
Fast-forward when possible Moves {target} forward without a new commit when nothing diverged; otherwise creates a merge commit. --ff
Always create a merge commit Keeps the shape of the history: the branch stays visible in the graph. --no-ff
Squash Combines all the commits of the branch into a single commit on {target}. The branch is not linked to it. --squash

The last mode you used is remembered and preselected next time (stored by the app’s web view, not in the preferences database). The default is Fast-forward when possible.

When the target is not checked out, the dialog says {target} will be checked out first. The bottom of the dialog previews the commands, for example:

Terminal window
git checkout main
git merge --no-ff feat/login

Click Merge or press Enter. yaggui runs:

Terminal window
git merge <--ff|--no-ff|--squash> --no-edit [-m <message>] -- <source>

-m is passed only for Always create a merge commit when you typed a message.

For a squash, yaggui then creates the commit itself with git commit -F - (your hooks run). The message is the one you typed, else the message Git prepared, else Squashed commit of <source>.

Result toasts: {source} merged into {target}, {target} fast-forwarded to {source}, {source} squashed into {target}. If the target already contains every commit of the source, yaggui runs nothing and shows {target} already contains {source}.

If a squash brings nothing new, the toast The squash brings no change explains that there is nothing to commit and offers Abort merge to clean up.

See git-merge for the merge strategies themselves.

Fast-forward {target} to {source} (drop menu or sidebar) runs without a dialog: it checks out the target if needed, then runs

Terminal window
git merge --ff-only --no-edit -- <source>

If the branches have diverged, Git refuses and you see: “The branches have diverged: “{source}” cannot be fast-forwarded. Merge with a merge commit, or rebase.” The toast has a Merge instead… button that opens the merge dialog for the same two branches.

A rebase replays the commits of a branch on top of another branch; they get new SHAs (git-rebase). For reordering, squashing or editing commits, use the interactive rebase.

  • From the palette: the dialog Rebase {branch} onto {onto} rebases the current branch. Pick the branch in Rebase onto (local branches except the current one, and remote branches), check the preview git rebase <onto>, and click Rebase. The dialog is the confirmation.
  • From the drop menu or the sidebar: a confirmation Rebase {branch} onto {onto}? explains: “The commits of {branch} are replayed on top of {onto}: they get new SHAs. If {branch} was already pushed, it will need a force push (with lease).” When the rebased branch is not the current one, it adds “{branch} is checked out for the rebase and stays checked out.” The command shown is git rebase <onto> <branch>. Click Rebase.

yaggui resolves <onto> to a commit and runs git rebase <onto-sha> [<branch>]. The step (Rebasing 3/7) shows in the status bar. On success: {branch} rebased onto {onto}, or {branch} is already based on {onto} when there was nothing to replay.

Errors specific to rebase:

  • “HEAD is detached (no current branch): check out a branch first.” when you rebase the current branch on a detached HEAD.
  • Rebase is disabled for a remote branch, which has nothing to rewrite locally.
  • Rebase refuses as soon as a tracked file has changes, staged or not: “Your local changes would be overwritten by the rebase. Commit or stash them first.” Untracked files do not block it.
  • Merge and fast-forward run with local changes; Git refuses only if they would be overwritten: “Your local changes would be overwritten by the merge. Commit or stash them first.”
  • In both cases the error toast lists up to three paths and offers Show changes. Commit or stash the changes, then retry.
  • Another operation in progress blocks all three: “Another operation (merge, rebase, cherry-pick, revert or bisect) is in progress: continue or abort it first.” So do files still in conflict: “Some files are still in conflict: resolve them (and stage them) first.”

When Git stops on conflicts, the merge or rebase stays in progress. A toast says how many files are in conflict and offers Show conflicts, a banner appears above the graph, and the working copy is selected so the conflicts panel shows. Resolve the files, then Continue, Skip (rebase only) or Abort: see Resolve conflicts.

Every command appears in the command log.

Operation Undoable
Merge, fast-forward or squash that completed in one go Yes, with ⌘Z (Ctrl+Z on Windows and Linux): merge of {source}
Merge that stopped on conflicts and was finished with Continue No
Rebase No. While it is in progress, Abort restores the branch; afterwards, use the reflog

Undoing a merge runs git reset --keep to the previous commit. When yaggui checked out the target first, that checkout is a separate entry: undo it too to get back to the branch you were on. Details and limits: Undo and redo.