Back to skills
SkillHub ClubShip Full StackFull Stack

git-rebase

Performs git rebases with intelligent conflict resolution through commit message analysis. This skill should be used when rebasing branches, updating feature branches with latest main/master, resolving rebase conflicts, cleaning up commit history with interactive rebase, or when the user mentions "rebase", "squash commits", "update my branch", or has merge/rebase conflicts to resolve.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
9
Hot score
84
Updated
March 20, 2026
Overall rating
C1.3
Composite score
1.3
Best-practice grade
C67.9

Install command

npx @skill-hub/cli install stirlingmarketinggroup-marlin-git-rebase

Repository

StirlingMarketingGroup/marlin

Skill path: .claude/skills/git-rebase

Performs git rebases with intelligent conflict resolution through commit message analysis. This skill should be used when rebasing branches, updating feature branches with latest main/master, resolving rebase conflicts, cleaning up commit history with interactive rebase, or when the user mentions "rebase", "squash commits", "update my branch", or has merge/rebase conflicts to resolve.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: StirlingMarketingGroup.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install git-rebase into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/StirlingMarketingGroup/marlin before adding git-rebase to shared team environments
  • Use git-rebase for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: git-rebase
description: Performs git rebases with intelligent conflict resolution through commit message analysis. This skill should be used when rebasing branches, updating feature branches with latest main/master, resolving rebase conflicts, cleaning up commit history with interactive rebase, or when the user mentions "rebase", "squash commits", "update my branch", or has merge/rebase conflicts to resolve.
---

# Git Rebase Assistant

Performs safe, effective rebases with intelligent conflict detection and resolution. The key differentiator is **understanding the intent of both sides** through commit message analysis before resolving any conflicts.

## Core Principle: Intent Before Resolution

**Never resolve a conflict mechanically.** Before touching any conflict:

1. Understand what master/main changed and WHY
2. Understand what the feature branch changed and WHY
3. Only then decide how to combine the changes

## Workflow Decision Tree

```
User request
    │
    ├─► "rebase", "update branch", "get latest main"
    │       └─► Full Rebase Workflow (below)
    │
    ├─► Conflict during rebase
    │       └─► Conflict Resolution Workflow (below)
    │
    └─► "squash", "clean up commits", "interactive rebase"
            └─► Interactive Rebase Workflow (below)
```

## Full Rebase Workflow

### Step 1: Validate Prerequisites

```bash
git status                    # MUST be clean
git fetch origin              # Get latest
git branch --show-current     # Confirm correct branch
```

**Stop if**: uncommitted changes exist, wrong branch, or detached HEAD.

### Step 2: Create Safety Backup

```bash
git branch backup/$(git branch --show-current)-$(date +%Y%m%d-%H%M%S)
```

### Step 3: Gather Full Context (MANDATORY)

Run `scripts/rebase-context.sh` or manually gather:

```bash
# What's NEW in main since we branched?
git log --oneline HEAD..origin/main

# What are OUR commits?
git log --oneline origin/main..HEAD

# Files likely to conflict
git diff --name-only origin/main...HEAD

# Preview specific file changes on BOTH sides
git log -p origin/main..HEAD -- <file>   # Our changes to file
git log -p HEAD..origin/main -- <file>   # Their changes to file
```

**Read the commit messages.** Understand:
- What problems were solved in main?
- What new patterns/APIs were introduced?
- What assumptions might have changed?

### Step 4: Execute Rebase

```bash
git rebase origin/main           # Standard
git rebase -i origin/main        # Interactive (for squashing/reordering)
```

### Step 5: Handle Conflicts

See **Conflict Resolution Workflow** below.

### Step 6: Verify and Push

```bash
# Run tests/build
npm test        # or go test ./... or appropriate test command

# Verify log looks correct
git log --oneline -10

# Safe force push
git push --force-with-lease
```

### Step 7: Clean Up

```bash
git branch -d backup/<branch-name>-*
```

## Conflict Resolution Workflow

### Before Resolving ANY Conflict

**Read `references/conflict-analysis.md` for detailed guidance.**

For each conflicted file:

```bash
# 1. See the conflict
git diff --name-only --diff-filter=U    # List conflicted files

# 2. Understand THEIR side (what main added)
git log -p ORIG_HEAD..origin/main -- <conflicted-file>

# 3. Understand OUR side (what we're replaying)
git log -p origin/main..ORIG_HEAD -- <conflicted-file>
```

### Resolution Strategies

| Situation | Action |
|-----------|--------|
| Main refactored shared code | Adapt our changes to new structure |
| Main added new feature | Integrate with our changes |
| Main fixed bug we also fixed | Evaluate which fix is better |
| Main changed API signature | Update our code to use new API |
| Both added similar code | Combine, avoiding duplication |

### The Ours/Theirs Trap

**Read `references/ours-vs-theirs.md` - this is critical.**

During rebase, the meaning is REVERSED from merge:
- `--ours` = the base branch (main)
- `--theirs` = your commits being replayed

```bash
# Accept main's version (during rebase)
git checkout --ours <file>

# Accept our feature branch version (during rebase)
git checkout --theirs <file>
```

### After Each Resolution

```bash
git add <resolved-files>
git rebase --continue

# Run tests after EACH commit if possible
git rebase -i --exec "npm test" origin/main
```

## Interactive Rebase Workflow

For squashing, reordering, or editing commits:

```bash
git rebase -i origin/main     # Rebase onto main
git rebase -i HEAD~5          # Edit last 5 commits
```

### Interactive Commands

| Command | Use When |
|---------|----------|
| `pick` | Keep commit as-is |
| `reword` | Change commit message only |
| `edit` | Stop to amend commit |
| `squash` | Combine with previous, edit combined message |
| `fixup` | Combine with previous, discard this message |
| `drop` | Remove commit entirely |

### Squashing Best Practice

When squashing multiple commits:
1. Read ALL commit messages being combined
2. Craft a new message that captures the full intent
3. Don't just keep the first message if others add context

## Recovery

```bash
# Abort current rebase
git rebase --abort

# Restore from backup
git reset --hard backup/<branch-name>-*

# Find lost commits via reflog
git reflog
git reset --hard HEAD@{n}
```

## Advanced Techniques

### Autosquash Workflow

```bash
# During development, create fixup commits
git commit --fixup=<commit-hash>

# Later, autosquash during rebase
git rebase -i --autosquash origin/main
```

### Run Tests After Each Commit

```bash
git rebase -i --exec "npm test" origin/main
```

### Preserve Merge Commits

```bash
git rebase --rebase-merges origin/main
```

### Enable Rerere (Reuse Recorded Resolution)

```bash
git config --global rerere.enabled true
```

Git remembers conflict resolutions and auto-applies them next time.

## Resources

### scripts/

- `rebase-context.sh` - Gathers context from both sides before rebase

### references/

- `conflict-analysis.md` - Deep dive on understanding conflict intent
- `ours-vs-theirs.md` - Explains the confusing reversal during rebase


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### scripts/rebase-context.sh

```bash
#!/bin/bash
# rebase-context.sh - Gather full context before rebasing
# Usage: ./rebase-context.sh [base-branch]
# Default base-branch: origin/main

set -e

BASE_BRANCH="${1:-origin/main}"
CURRENT_BRANCH=$(git branch --show-current)

echo "=============================================="
echo "REBASE CONTEXT ANALYSIS"
echo "=============================================="
echo "Current branch: $CURRENT_BRANCH"
echo "Target base:    $BASE_BRANCH"
echo ""

# Ensure we have latest
echo ">>> Fetching latest..."
git fetch origin --quiet

echo ""
echo "=============================================="
echo "COMMITS IN $BASE_BRANCH (not in $CURRENT_BRANCH)"
echo "These are the changes you'll be rebasing onto:"
echo "=============================================="
git log --oneline HEAD..$BASE_BRANCH

echo ""
echo "=============================================="
echo "YOUR COMMITS (will be replayed)"
echo "=============================================="
git log --oneline $BASE_BRANCH..HEAD

echo ""
echo "=============================================="
echo "FILES CHANGED IN BOTH (potential conflicts)"
echo "=============================================="
# Files changed in base branch
BASE_FILES=$(git diff --name-only HEAD...$BASE_BRANCH 2>/dev/null || echo "")
# Files changed in our branch
OUR_FILES=$(git diff --name-only $BASE_BRANCH...HEAD 2>/dev/null || echo "")

# Find intersection
if [ -n "$BASE_FILES" ] && [ -n "$OUR_FILES" ]; then
    OVERLAP=$(comm -12 <(echo "$BASE_FILES" | sort) <(echo "$OUR_FILES" | sort))
    if [ -n "$OVERLAP" ]; then
        echo "$OVERLAP"
        echo ""
        echo ">>> These files were modified in BOTH branches!"
        echo ">>> Review changes carefully before rebasing."
    else
        echo "(No overlapping files - conflicts unlikely)"
    fi
else
    echo "(Could not determine file overlap)"
fi

echo ""
echo "=============================================="
echo "COMMIT MESSAGE SUMMARY"
echo "=============================================="
echo ""
echo "--- Base branch commits (read these to understand new context) ---"
git log --format="  %h %s" HEAD..$BASE_BRANCH | head -20

echo ""
echo "--- Your commits (understand what you're trying to achieve) ---"
git log --format="  %h %s" $BASE_BRANCH..HEAD

echo ""
echo "=============================================="
echo "NEXT STEPS"
echo "=============================================="
echo "1. Review the commit messages above"
echo "2. For potential conflict files, examine both sides:"
echo "   git log -p $BASE_BRANCH..HEAD -- <file>"
echo "   git log -p HEAD..$BASE_BRANCH -- <file>"
echo "3. When ready: git rebase $BASE_BRANCH"
echo ""

```

### references/conflict-analysis.md

```markdown
# Conflict Analysis: Understanding Intent Before Resolution

## The Problem with Mechanical Resolution

Most conflict resolution guides focus on the mechanics:
- "Accept theirs"
- "Accept ours"
- "Edit the file and remove markers"

This misses the point. **Conflicts are communication.** They tell you that two people made different decisions about the same code. Understanding those decisions is essential to resolving them correctly.

## The Intent-First Approach

Before touching any conflict, answer these questions:

### 1. What was main trying to accomplish?

```bash
# Find the commit(s) that touched this file in main
git log -p ORIG_HEAD..origin/main -- <conflicted-file>
```

Look for:
- Bug fixes (does this fix something our code depends on?)
- Refactoring (did the structure change?)
- New features (do we need to integrate with this?)
- API changes (did signatures/interfaces change?)

### 2. What was our branch trying to accomplish?

```bash
# Find our commits that touched this file
git log -p origin/main..ORIG_HEAD -- <conflicted-file>
```

Look for:
- What feature were we adding?
- What bug were we fixing?
- What's the minimal change needed?

### 3. Are both changes trying to solve the same problem?

Sometimes two developers fix the same bug independently. In this case:
- Evaluate which fix is more complete/correct
- Consider if they can be combined
- Don't blindly keep both

## Conflict Type Analysis

### Type 1: Infrastructure Change in Main

**Symptoms:**
- Main refactored a function/class you were using
- Main renamed variables/files
- Main changed an API signature

**Resolution principle:** Adapt your changes to the new infrastructure.

Main has already been merged and likely deployed. Your code needs to work with the new reality, not fight it.

```bash
# See what changed in the function/API
git diff ORIG_HEAD..origin/main -- <file>
```

### Type 2: Both Added to Same Location

**Symptoms:**
- Both branches added new code to the same spot (e.g., new function, new import)
- The code doesn't actually conflict logically

**Resolution principle:** Include both additions, maintaining logical order.

```
<<<<<<< HEAD (main's version)
import { newFeatureA } from './features';
=======
import { newFeatureB } from './features';
>>>>>>> your-commit

# Resolution: Include both
import { newFeatureA } from './features';
import { newFeatureB } from './features';
```

### Type 3: Semantic Conflict (Code Merges Clean But Breaks)

**Symptoms:**
- Git doesn't report a conflict
- But tests fail after rebase
- Runtime errors occur

**This is the most dangerous type.**

**Resolution principle:** Always run tests after each commit in the rebase.

```bash
git rebase -i --exec "npm test" origin/main
```

### Type 4: Delete vs Modify Conflict

**Symptoms:**
- One side deleted a file/function
- Other side modified it

**Resolution principle:** Understand why it was deleted.

```bash
# Find the deletion commit
git log --diff-filter=D --summary ORIG_HEAD..origin/main -- <file>
```

If main deleted it intentionally:
- Your changes might need to go elsewhere
- The feature might have been replaced
- Ask the team if unclear

### Type 5: Dependency/Version Conflict

**Symptoms:**
- Different package versions in package.json, go.mod, etc.
- Both sides updated dependencies

**Resolution principle:** Usually take the newer version, but test.

```bash
# After resolving, verify dependencies work
npm install && npm test
# or
go mod tidy && go test ./...
```

## Resolution Workflow

For each conflicted file:

### Step 1: Gather Context

```bash
# List conflicted files
git diff --name-only --diff-filter=U

# For each file, understand both sides
git log -p ORIG_HEAD..origin/main -- <file>    # Main's changes
git log -p origin/main..ORIG_HEAD -- <file>    # Our changes (before rebase started)
```

### Step 2: Categorize the Conflict

Ask: Which type from above does this match?

### Step 3: Apply the Appropriate Principle

- Infrastructure change? Adapt to new structure.
- Both added? Include both.
- Delete vs modify? Understand why deleted.
- Dependency? Take newer, test.

### Step 4: Verify

```bash
# Stage the resolution
git add <file>

# Check for remaining markers
git diff --check

# Run tests if possible
npm test
```

### Step 5: Continue

```bash
git rebase --continue
```

## When to Ask for Help

Escalate to the team when:
- You don't understand why main made a change
- The conflict involves critical business logic
- You're unsure if your feature is still needed
- The original author is available and can clarify

## Anti-Patterns to Avoid

### 1. "Accept Theirs" for Everything

This discards your work. Only appropriate when your changes are truly obsolete.

### 2. "Accept Ours" for Everything

This ignores main's updates. Your code may break when deployed.

### 3. Resolving Without Reading Commit Messages

You're guessing. Read the messages.

### 4. Not Running Tests After Each Resolution

Semantic conflicts won't be caught.

### 5. Resolving Quickly to "Just Get It Done"

Technical debt accumulates. Incorrect resolutions cause bugs.

```

### references/ours-vs-theirs.md

```markdown
# The Ours vs Theirs Confusion During Rebase

## The Problem

During `git rebase`, the meaning of `--ours` and `--theirs` is **reversed** from what you might expect. This trips up even experienced developers.

## Why It's Reversed

During a merge:
- You're on your branch
- You're merging another branch into yours
- "Ours" = your branch (current HEAD)
- "Theirs" = the branch being merged in

During a rebase:
- Git checks out the target branch (main)
- Git replays your commits one by one onto main
- From git's perspective, main is now "current HEAD"
- Your commits being replayed are "incoming"

So during rebase:
- **"Ours" = main** (the base branch you're rebasing onto)
- **"Theirs" = your commits** (being replayed)

## Visual Explanation

```
MERGE (on feature-branch, merging main):
                                    "ours"
                                      │
    main:     A ─── B ─── C          │
                     \               ▼
    feature:          D ─── E ─── [MERGE CONFLICT]
                                      ▲
                                      │
                                   "theirs"

REBASE (on feature-branch, rebasing onto main):
                                      "ours" (surprisingly!)
                                        │
    main:     A ─── B ─── C ◄───────────┘
                           \
    replaying:              D' ─── [CONFLICT]
                                      ▲
                                      │
                                   "theirs" (your commit!)
```

## Command Reference

### During Rebase

| Command | Effect |
|---------|--------|
| `git checkout --ours <file>` | Use main's version |
| `git checkout --theirs <file>` | Use your feature branch version |

### During Merge (for comparison)

| Command | Effect |
|---------|--------|
| `git checkout --ours <file>` | Use your current branch version |
| `git checkout --theirs <file>` | Use the incoming branch version |

## Memory Aid

Think of it this way during rebase:
- **"Ours"** = "the base we're standing on" = main
- **"Theirs"** = "the commits flying in to land" = your commits

Or remember this mnemonic:
> "Rebase Reverses"

## Safe Alternatives

If the ours/theirs confusion is too error-prone, use explicit references:

```bash
# During a rebase conflict, these refs are available:

# The commit being rebased onto (main's version)
git show REBASE_HEAD:<file>

# The original branch tip (your version before rebase)
git show ORIG_HEAD:<file>

# To accept main's version explicitly (stage 2 = ours during rebase):
git show :2:<file> > <file>
git add <file>

# To accept your version explicitly (stage 3 = theirs during rebase):
git show :3:<file> > <file>
git add <file>
```

## Practical Example

You're on `feature/login` and rebasing onto `main`.

Main has:
```javascript
function authenticate(user, password) {
  return validateCredentials(user, password);
}
```

Your branch has:
```javascript
function authenticate(user, password, token) {
  return validateWithMFA(user, password, token);
}
```

Conflict occurs. You want to keep YOUR version with MFA:

```bash
# WRONG (this keeps main's version!)
git checkout --ours src/auth.js

# CORRECT (this keeps your feature branch version)
git checkout --theirs src/auth.js
```

Or use index stages to avoid confusion:

```bash
# See what your version (stage 3 = theirs during rebase) has:
git show :3:src/auth.js

# Copy your version:
git show :3:src/auth.js > src/auth.js
git add src/auth.js
```

## Strategy Flags

The `-X` strategy flags follow the same reversed logic:

```bash
# Accept main's version for ALL conflicts (dangerous)
git rebase -X ours main

# Accept your version for ALL conflicts (dangerous)
git rebase -X theirs main
```

Only use these when you're certain one side should always win.

## Debugging: Which Version Is Which?

When in doubt during a conflict:

```bash
# Show what "ours" would give you
git show :2:<file>    # Stage 2 = ours

# Show what "theirs" would give you
git show :3:<file>    # Stage 3 = theirs

# Compare them
git diff :2:<file> :3:<file>
```

## Key Takeaway

During rebase:
- `--ours` = **main** (counterintuitive)
- `--theirs` = **your commits** (counterintuitive)

When in doubt, use `:2:<file>` (main's version) and `:3:<file>` (your version) for explicit, unambiguous references.

```

git-rebase | SkillHub