Merge Main
Fetch and merge the repository's base branch into the current feature branch.
Options
The user may provide these options inline:
- --base
<branch>: Override the auto-detected base branch (e.g.,--base develop)
Workflow
1. Pre-Flight Checks
Run these commands in parallel to understand the current state:
# Check for uncommitted changes
git status
# Detect the repository's default branch
gh repo view --json defaultBranchRef -q '.defaultBranchRef.name'
# Confirm which branch we are on
git branch --show-current
If --base <branch> was specified, use that value instead of the detected default branch.
If gh is not available, fall back to detecting the default branch with:
git remote show origin | grep 'HEAD branch' | sed 's/.*: //'
If the current branch is the default branch itself, warn the user that merging the base branch into itself is a no-op and stop.
2. Handle Uncommitted Changes
If git status shows uncommitted changes (staged or unstaged):
- Warn the user that there are uncommitted changes.
- Ask whether to:
- Stash: Run
git stashbefore proceeding, thengit stash popafter the merge completes. - Commit first: Invoke the
/commitskill, then continue with the merge. - Abort: Stop without doing anything.
- Stash: Run
3. Fetch and Merge
git fetch origin <default-branch>
git merge origin/<default-branch>
Where <default-branch> is the detected or overridden base branch name.
4. Handle Merge Result
Clean Merge
If the merge completes without conflicts:
- Report success.
- Show a summary of what was merged:
git log HEAD@{1}..HEAD --oneline
Already Up to Date
If git reports "Already up to date.", report that the branch is already current with the base branch and stop.
Conflicts
If the merge produces conflicts, proceed to the conflict resolution workflow below.
5. Conflict Resolution
When merge conflicts occur:
- List conflicted files:
git diff --name-only --diff-filter=U
Resolve each conflicted file:
- Read the file and examine the conflict markers (
<<<<<<<,=======,>>>>>>>). - Use the surrounding code context, the intent of both sides, and the project's conventions to determine the correct resolution.
- For trivial conflicts (whitespace, import ordering, adjacent non-overlapping changes), resolve automatically.
- For non-trivial conflicts where the correct resolution is ambiguous, show the user both sides and ask which to keep or how to combine them.
- Read the file and examine the conflict markers (
Stage resolved files:
git add <resolved-file>
- Complete the merge commit (GPG signed):
git commit -S --no-edit
This uses the default merge commit message generated by git. If the user wants a custom message, they can specify it.
6. Post-Merge Steps
After a successful merge (with or without conflict resolution):
Lockfile changes: If any lockfiles changed during the merge (e.g.,
package-lock.json,yarn.lock,pnpm-lock.yaml,go.sum,Gemfile.lock,poetry.lock,Cargo.lock,composer.lock), suggest running the appropriate install command:package-lock.json->npm installyarn.lock->yarn installpnpm-lock.yaml->pnpm installgo.sum->go mod tidyGemfile.lock->bundle installpoetry.lock->poetry installCargo.lock->cargo buildcomposer.lock->composer install
Push:
git push
If the branch has no upstream, use:
git push -u origin HEAD
7. Stash Recovery
If changes were stashed in step 2, pop the stash after the merge completes:
git stash pop
If the stash pop produces conflicts, warn the user and list the conflicted files.
Error Handling
- On the default branch: Warn that merging the base branch into itself is a no-op and stop.
- No remote configured: Report the error and stop.
- Merge aborted by user: Clean up with
git merge --abort. - Fetch failure (network issues, authentication): Report the error clearly and stop.
- Stash pop conflicts: Warn the user and list conflicted files so they can resolve manually.