Git Workflows

Advanced git operations beyond add/commit/push. Use when rebasing, bisecting bugs, using worktrees for parallel development, recovering with reflog, managing subtrees/submodules, r…

gitgoodordietrying

@gitgoodordietrying

What This Skill Does

Command-line tool for advanced Git operations including interactive rebase, bisect, worktree, reflog recovery, subtree/submodule management, merge conflict resolution, cherry-picking, and monorepo patterns.

Replaces manual commit history cleanup and bug hunting with automated rebase, bisect, and recovery workflows.

When to Use It

  • Squash or reorder commits before merging a feature branch
  • Find the exact commit that introduced a bug using binary search
  • Work on multiple branches simultaneously without stashing changes
  • Recover a lost commit or undo a mistaken reset using reflog
  • Resolve complex merge conflicts with structured strategies
  • Manage shared code across repositories using subtrees or submodules

Install

$ openclaw skills install @gitgoodordietrying/git-workflows

Git Workflows

Advanced git operations for real-world development. Covers interactive rebase, bisect, worktree, reflog recovery, subtrees, submodules, sparse checkout, conflict resolution, and monorepo patterns.

When to Use

  • Cleaning up commit history before merging (interactive rebase)
  • Finding which commit introduced a bug (bisect)
  • Working on multiple branches simultaneously (worktree)
  • Recovering lost commits or undoing mistakes (reflog)
  • Managing shared code across repos (subtree/submodule)
  • Resolving complex merge conflicts
  • Cherry-picking commits across branches or forks
  • Working with large monorepos (sparse checkout)

Interactive Rebase

Squash, reorder, edit commits

# Rebase last 5 commits interactively
git rebase -i HEAD~5

# Rebase onto main (all commits since diverging)
git rebase -i main

The editor opens with a pick list:

pick a1b2c3d Add user model
pick e4f5g6h Fix typo in user model
pick i7j8k9l Add user controller
pick m0n1o2p Add user routes
pick q3r4s5t Fix import in controller

Commands available:

pick   = use commit as-is
reword = use commit but edit the message
edit   = stop after this commit to amend it
squash = merge into previous commit (keep both messages)
fixup  = merge into previous commit (discard this message)
drop   = remove the commit entirely

Common patterns

# Squash fix commits into their parent
# Change "pick" to "fixup" for the fix commits:
pick a1b2c3d Add user model
fixup e4f5g6h Fix typo in user model
pick i7j8k9l Add user controller
fixup q3r4s5t Fix import in controller
pick m0n1o2p Add user routes

# Reorder commits (just move lines)
pick i7j8k9l Add user controller
pick m0n1o2p Add user routes
pick a1b2c3d Add user model

# Split a commit into two
# Mark as "edit", then when it stops:
git reset HEAD~
git add src/model.ts
git commit -m "Add user model"
git add src/controller.ts
git commit -m "Add user controller"
git rebase --continue

Autosquash (commit messages that auto-arrange)

# When committing a fix, reference the commit to squash into
git commit --fixup=a1b2c3d -m "Fix typo"
# or
git commit --squash=a1b2c3d -m "Additional changes"

# Later, rebase with autosquash
git rebase -i --autosquash main
# fixup/squash commits are automatically placed after their targets

Abort or continue

git rebase --abort      # Cancel and restore original state
git rebase --continue   # Continue after resolving conflicts or editing
git rebase --skip       # Skip the current commit and continue

Bisect (Find the Bug)

Binary search through commits

# Start bisect
git bisect start

# Mark current commit as bad (has the bug)
git bisect bad

# Mark a known-good commit (before the bug existed)
git bisect good v1.2.0
# or: git bisect good abc123

# Git checks out a middle commit. Test it, then:
git bisect good   # if this commit doesn't have the bug
git bisect bad    # if this commit has the bug

# Repeat until git identifies the exact commit
# "abc123 is the first bad commit"

# Done — return to original branch
git bisect reset

Automated bisect (with a test script)

# Fully automatic: git runs the script on each commit
# Script must exit 0 for good, 1 for bad
git bisect start HEAD v1.2.0
git bisect run ./test-for-bug.sh

# Example test script
cat > /tmp/test-for-bug.sh << 'EOF'
#!/bin/bash
# Return 0 if bug is NOT present, 1 if it IS
npm test -- --grep "login should redirect" 2>/dev/null
EOF
chmod +x /tmp/test-for-bug.sh
git bisect run /tmp/test-for-bug.sh

Bisect with build failures

# If a commit doesn't compile, skip it
git bisect skip

# Skip a range of known-broken commits
git bisect skip v1.3.0..v1.3.5

Worktree (Parallel Branches)

Work on multiple branches simultaneously

# Add a worktree for a different branch
git worktree add ../myproject-hotfix hotfix/urgent-fix
# Creates a new directory with that branch checked out

# Add a worktree with a new branch
git worktree add ../myproject-feature -b feature/new-thing

# List worktrees
git worktree list

# Remove a worktree when done
git worktree remove ../myproject-hotfix

# Prune stale worktree references
git worktree prune

Use cases

# Review a PR while keeping your current work untouched
git worktree add ../review-pr-123 origin/pr-123

# Run tests on main while developing on feature branch
git worktree add ../main-tests main
cd ../main-tests && npm test

# Compare behavior between branches side by side
git worktree add ../compare-old release/v1.0
git worktree add ../compare-new release/v2.0

Reflog (Recovery)

See everything git remembers

# Show reflog (all HEAD movements)
git reflog
# Output:
# abc123 HEAD@{0}: commit: Add feature
# def456 HEAD@{1}: rebase: moving to main
# ghi789 HEAD@{2}: checkout: moving from feature to main

# Show reflog for a specific branch
git reflog show feature/my-branch

# Show with timestamps
git reflog --date=relative

Recover from mistakes

# Undo a bad rebase (find the commit before rebase in reflog)
git reflog
# Find: "ghi789 HEAD@{5}: checkout: moving from feature to main" (pre-rebase)
git reset --hard ghi789

# Recover a deleted branch
git reflog
# Find the last commit on that branch
git branch recovered-branch abc123

# Recover after reset --hard
git reflog
git reset --hard HEAD@{2}   # Go back 2 reflog entries

# Recover a dropped stash
git fsck --unreachable | grep commit
# or
git stash list  # if it's still there
git log --walk-reflogs --all -- stash  # find dropped stash commits

Cherry-Pick

Copy specific commits to another branch

# Pick a single commit
git cherry-pick abc123

# Pick multiple commits
git cherry-pick abc123 def456 ghi789

# Pick a range (exclusive start, inclusive end)
git cherry-pick abc123..ghi789

# Pick without committing (stage changes only)
git cherry-pick --no-commit abc123

# Cherry-pick from another remote/fork
git remote add upstream https://github.com/other/repo.git
git fetch upstream
git cherry-pick upstream/main~3   # 3rd commit from upstream's main

Handle conflicts during cherry-pick

# If conflicts arise:
# 1. Resolve conflicts in the files
# 2. Stage resolved files
git add resolved-file.ts
# 3. Continue
git cherry-pick --continue

# Or abort
git cherry-pick --abort

Subtree and Submodule

Subtree (simpler — copies code into your repo)

# Add a subtree
git subtree add --prefix=lib/shared https://github.com/org/shared-lib.git main --squash

# Pull updates from upstream
git subtree pull --prefix=lib/shared https://github.com/org/shared-lib.git main --squash

# Push local changes back to upstream
git subtree push --prefix=lib/shared https://github.com/org/shared-lib.git main

# Split subtree into its own branch (for extraction)
git subtree split --prefix=lib/shared -b shared-lib-standalone

Submodule (pointer to another repo at a specific commit)

# Add a submodule
git submodule add https://github.com/org/shared-lib.git lib/shared

# Clone a repo with submodules
git clone --recurse-submodules https://github.com/org/main-repo.git

# Initialize submodules after clone (if forgot --recurse)
git submodule update --init --recursive

# Update submodules to latest
git submodule update --remote

# Remove a submodule
git rm lib/shared
rm -rf .git/modules/lib/shared
# Remove entry from .gitmodules if it persists

When to use which

Subtree: Simpler, no special commands for cloners, code lives in your repo.
         Use when: shared library, vendor code, infrequent upstream changes.

Submodule: Pointer to exact commit, smaller repo, clear separation.
           Use when: large dependency, independent release cycle, many contributors.

Sparse Checkout (Monorepo)

Check out only the directories you need

# Enable sparse checkout
git sparse-checkout init --cone

# Select directories
git sparse-checkout set packages/my-app packages/shared-lib

# Add another directory
git sparse-checkout add packages/another-lib

# List what's checked out
git sparse-checkout list

# Disable (check out everything again)
git sparse-checkout disable

Clone with sparse checkout (large monorepos)

# Partial clone + sparse checkout (fastest for huge repos)
git clone --filter=blob:none --sparse https://github.com/org/monorepo.git
cd monorepo
git sparse-checkout set packages/my-service

# No-checkout clone (just metadata)
git clone --no-checkout https://github.com/org/monorepo.git
cd monorepo
git sparse-checkout set packages/my-service
git checkout main

Conflict Resolution

Understand the conflict markers

<<<<<<< HEAD (or "ours")
Your changes on the current branch
=======
Their changes from the incoming branch
>>>>>>> feature-branch (or "theirs")

Resolution strategies

# Accept all of ours (current branch wins)
git checkout --ours path/to/file.ts
git add path/to/file.ts

# Accept all of theirs (incoming branch wins)
git checkout --theirs path/to/file.ts
git add path/to/file.ts

# Accept ours for ALL files
git checkout --ours .
git add .

# Use a merge tool
git mergetool

# See the three-way diff (base, ours, theirs)
git diff --cc path/to/file.ts

# Show common ancestor version
git show :1:path/to/file.ts   # base (common ancestor)
git show :2:path/to/file.ts   # ours
git show :3:path/to/file.ts   # theirs

Rebase conflict workflow

# During rebase, conflicts appear one commit at a time
# 1. Fix the conflict in the file
# 2. Stage the fix
git add fixed-file.ts
# 3. Continue to next commit
git rebase --continue
# 4. Repeat until done

# If a commit is now empty after resolution
git rebase --skip

Rerere (reuse recorded resolutions)

# Enable rerere globally
git config --global rerere.enabled true

# Git remembers how you resolved conflicts
# Next time the same conflict appears, it auto-resolves

# See recorded resolutions
ls .git/rr-cache/

# Forget a bad resolution
git rerere forget path/to/file.ts

Stash Patterns

# Stash with a message
git stash push -m "WIP: refactoring auth flow"

# Stash specific files
git stash push -m "partial stash" -- src/auth.ts src/login.ts

# Stash including untracked files
git stash push -u -m "with untracked"

# List stashes
git stash list

# Apply most recent stash (keep in stash list)
git stash apply

# Apply and remove from stash list
git stash pop

# Apply a specific stash
git stash apply stash@{2}

# Show what's in a stash
git stash show -p stash@{0}

# Create a branch from a stash
git stash branch new-feature stash@{0}

# Drop a specific stash
git stash drop stash@{1}

# Clear all stashes
git stash clear

Blame and Log Archaeology

# Who changed each line (with date)
git blame src/auth.ts

# Blame a specific line range
git blame -L 50,70 src/auth.ts

# Ignore whitespace changes in blame
git blame -w src/auth.ts

# Find when a line was deleted (search all history)
git log -S "function oldName" --oneline

# Find when a regex pattern was added/removed
git log -G "TODO.*hack" --oneline

# Follow a file through renames
git log --follow --oneline -- src/new-name.ts

# Show the commit that last touched each line, ignoring moves
git blame -M src/auth.ts

# Show log with file changes
git log --stat --oneline -20

# Show all commits affecting a specific file
git log --oneline -- src/auth.ts

# Show diff of a specific commit
git show abc123

Tags and Releases

# Create annotated tag (preferred for releases)
git tag -a v1.2.0 -m "Release 1.2.0: Added auth module"

# Create lightweight tag
git tag v1.2.0

# Tag a past commit
git tag -a v1.1.0 abc123 -m "Retroactive tag for release 1.1.0"

# List tags
git tag -l
git tag -l "v1.*"

# Push tags
git push origin v1.2.0      # Single tag
git push origin --tags       # All tags

# Delete a tag
git tag -d v1.2.0            # Local
git push origin --delete v1.2.0  # Remote

Tips

  • git rebase -i is the single most useful advanced git command. Learn it first.
  • Never rebase commits that have been pushed to a shared branch. Rebase your local/feature work only.
  • git reflog is your safety net. If you lose commits, they're almost always recoverable within 90 days.
  • git bisect run with an automated test is faster than manual binary search and eliminates human error.
  • Worktrees are cheaper than multiple clones — they share .git storage.
  • Prefer git subtree over git submodule unless you have a specific reason. Subtrees are simpler for collaborators.
  • Enable rerere globally. It remembers conflict resolutions so you never solve the same conflict twice.
  • git stash push -m "description" is much better than bare git stash. You'll thank yourself when you have 5 stashes.
  • git log -S "string" (pickaxe) is the fastest way to find when a function or variable was added or removed.

Top skills in this category

Free Ride - Unlimited free AI

@shaivpidadi

Manages free AI models from OpenRouter for OpenClaw. Automatically ranks models by quality, configures fallbacks for rate-limit handling, and updates opencla...

49172k

Playwright (Automation + MCP + Scraper)

@ivangdavila

Automates, tests, and debugs browsers with Playwright: locators, auto-waiting, traces, CI runs, and MCP browser control. Use when a test is flaky, times out, or fails only in CI or headless; when a locator matches multiple elements or the wrong one (strict mode violation); when clicks need force, waits become sleeps, or networkidle never settles; for storageState and login setup, request mocking and HAR replay, uploads and downloads, iframes and shadow DOM, popups and dialogs, screenshot diffs that change per machine, trace and report artifacts, sharding a slow suite, device and permission emulation, accessibility checks, driving a real browser through Playwright MCP, extracting data from JS-rendered pages, or porting a Cypress, Puppeteer, or Selenium suite to Playwright. Not for maintaining an existing Cypress or Puppeteer suite (cypress, puppeteer) or for work a plain HTTP request answers (http).

13043k

n8n

@thomasansems

Manage n8n workflows and automations via API. Use when working with n8n workflows, executions, or automation tasks - listing workflows, activating/deactivating, checking execution status, manually triggering workflows, or debugging automation issues.

6121k

google-slides

@byungkyu

Google Slides API integration with managed OAuth. Create presentations, add slides, insert content, and manage slide formatting. Use this skill when users want to interact with Google Slides. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Calls run through the `maton` CLI with OAuth login, or over raw HTTP with a Maton API key where the CLI cannot be installed. Every call is authenticated as the user's connection and reaches only what that connection's authorization allows, which the provider enforces on every request; the endpoints documented here are the ones this skill uses, and any other endpoint of this app needs the user to ask for it by name. Default to read and list calls, and confirm every write or new connection with the user. This file also documents the three constructs that turn a Google Slides connection into automation, in the order they are used: the connection (the first step), a hosted function that runs a Google Slides action through the Maton SDK, and a trigger that calls that function on a schedule or on an event. Those sections are the platform's own reference text, shared with the api-gateway skill, with Google Slides examples; they add no Google Slides capability - Google Slides is not an event source, a trigger cannot read Google Slides data, and the files under `references/<source>/triggers.md` are the platform's event catalogues for the sources Maton offers (time, Calendly, GitHub, Gmail, HubSpot, Linear, Notion, Slack, Stripe).

3420k

Superpowers Dev Workflow

@wlshlad85

Spec-first, TDD, subagent-driven software development workflow. Use when: (1) building any new feature or app — triggers brainstorm → plan → subagent executi...

2129k