Files
scopone/.github/skills/merge-branch/SKILL.md
2026-04-10 22:35:01 +02:00

184 lines
4.7 KiB
Markdown

```skill
---
name: merge-branch
description: Git branch merging workflow — merges current feature branch into the default branch (main/master) with conflict detection, working tree validation, and safety checks.
---
# Merge Branch
## Overview
This skill merges the current feature branch into the detected default branch (main or master).
**Prerequisites:**
- Working in a git repository
- On a feature branch (not already on default branch)
- Have commits ready to merge
**Outcome:**
- Feature branch merged into default branch
- Default branch updated with latest changes
- Ready to push merged changes to remote
## Default Branch Detection
Detect the default branch name:
```sh
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@'
```
Fallback: check if `master` exists, else `main`. Store as `{default_branch}`.
## Pre-Merge Validation
Run these checks BEFORE merging:
### 1. Get Current Branch
```sh
CURRENT_BRANCH=$(git branch --show-current)
```
### 2. Verify Not on Default Branch
```sh
if [ "$CURRENT_BRANCH" = "{default_branch}" ]; then
echo "ERROR: Already on default branch. Cannot merge into self."
exit 1
fi
```
### 3. Check Working Tree State
```sh
IS_DIRTY=$(git status --porcelain)
```
If `IS_DIRTY` is not empty, working tree is dirty. Handle before merging.
## Dirty Working Tree Options
When dirty, present these options to the user (use `ask_questions` tool):
- **Commit changes first**: `git add -A && git commit -m "message"` — commits all changes before merging
- **Stash changes**: `git stash push -m "WIP: auto-stash before merge"` — saves changes for later
- **Discard changes**: `git checkout -- . && git clean -fd` — permanently removes uncommitted changes
- **Abort**: Stop the workflow — user handles git state manually
After committing, stashing, or discarding, working tree is clean. Proceed with merge.
## Merge Execution
After working tree is clean:
### 1. Switch to Default Branch
```sh
git checkout {default_branch}
```
### 2. Pull Latest Changes
```sh
git pull
```
### 3. Execute Merge
```sh
git merge $CURRENT_BRANCH
```
### 4. Handle Merge Result
Check exit code:
- **Exit 0** (success): Merge completed successfully
```
✓ Merged $CURRENT_BRANCH into {default_branch}
Next steps:
- Review merged changes: git log
- Push to remote: git push
- Delete feature branch if done: git branch -d $CURRENT_BRANCH
```
- **Non-zero exit** (conflict): Merge conflict detected
```sh
git merge --abort
echo "ERROR: Merge conflict detected. Merge aborted."
echo "Resolve conflicts manually and retry merge."
exit 1
```
## Error Handling
| Scenario | Error Message | Exit Code |
|----------|---------------|-----------|
| Already on default branch | `ERROR: Already on default branch. Cannot merge into self.` | 1 |
| Dirty working tree (user aborts) | `ERROR: Working tree is dirty. Merge aborted.` | 1 |
| Merge conflict | `ERROR: Merge conflict detected. Merge aborted.` | 1 |
| Default branch detection fails | `ERROR: Could not detect default branch.` | 1 |
All errors exit with non-zero status to prevent downstream issues.
## Usage Example
Complete workflow demonstrating all steps:
```sh
#!/bin/bash
set -e
# Step 1: Detect default branch
DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')
if [ -z "$DEFAULT_BRANCH" ]; then
if git show-ref --verify --quiet refs/heads/master; then
DEFAULT_BRANCH="master"
else
DEFAULT_BRANCH="main"
fi
fi
# Step 2: Get current branch
CURRENT_BRANCH=$(git branch --show-current)
# Step 3: Verify not on default branch
if [ "$CURRENT_BRANCH" = "$DEFAULT_BRANCH" ]; then
echo "ERROR: Already on default branch. Cannot merge into self."
exit 1
fi
# Step 4: Check working tree state
IS_DIRTY=$(git status --porcelain)
if [ -n "$IS_DIRTY" ]; then
echo "WARNING: Working tree is dirty."
echo "Options: (c)ommit, (s)tash, (d)iscard, (a)bort"
read -p "Choose: " choice
case $choice in
c) git add -A && git commit -m "Changes before merge" ;;
s) git stash push -m "WIP: auto-stash before merge" ;;
d) git checkout -- . && git clean -fd ;;
a) echo "Merge aborted."; exit 1 ;;
*) echo "Invalid choice. Aborting."; exit 1 ;;
esac
fi
# Step 5: Switch to default branch
git checkout $DEFAULT_BRANCH
# Step 6: Pull latest changes
git pull
# Step 7: Execute merge
if git merge $CURRENT_BRANCH; then
echo "✓ Merged $CURRENT_BRANCH into $DEFAULT_BRANCH"
echo "Next steps:"
echo "- Review merged changes: git log"
echo "- Push to remote: git push"
echo "- Delete feature branch if done: git branch -d $CURRENT_BRANCH"
else
echo "ERROR: Merge conflict detected. Aborting merge."
git merge --abort
exit 1
fi
```