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.
Drag a branch onto another
Section titled “Drag a branch onto another”- 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.
- 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.
- 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.
From the sidebar
Section titled “From the sidebar”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.
From the command palette
Section titled “From the command palette”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.
Merge a branch
Section titled “Merge a branch”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:
git checkout maingit merge --no-ff feat/loginClick Merge or press Enter. yaggui runs:
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 a branch
Section titled “Fast-forward a branch”Fast-forward {target} to {source} (drop menu or sidebar) runs without a dialog: it checks out the target if needed, then runs
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.
Rebase onto a branch
Section titled “Rebase onto a branch”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.
Local changes and conflicts
Section titled “Local changes and conflicts”- 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.