Localsetup localsetup-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, resolving merge conflicts, cherry-picking across branches, or working with monorepos.
install
source · Clone the upstream repo
git clone https://github.com/CruxExperts/localsetup
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/CruxExperts/localsetup "$T" && mkdir -p ~/.claude/skills && cp -r "$T/_localsetup/skills/localsetup-git-workflows" ~/.claude/skills/cruxexperts-localsetup-localsetup-git-workflows && rm -rf "$T"
manifest:
_localsetup/skills/localsetup-git-workflows/SKILL.mdsource content
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
is the single most useful advanced git command. Learn it first.git rebase -i- Never rebase commits that have been pushed to a shared branch. Rebase your local/feature work only.
is your safety net. If you lose commits, they're almost always recoverable within 90 days.git reflog
with an automated test is faster than manual binary search and eliminates human error.git bisect run- Worktrees are cheaper than multiple clones — they share
storage..git - Prefer
overgit subtree
unless you have a specific reason. Subtrees are simpler for collaborators.git submodule - Enable
globally. It remembers conflict resolutions so you never solve the same conflict twice.rerere
is much better than baregit stash push -m "description"
. You'll thank yourself when you have 5 stashes.git stash
(pickaxe) is the fastest way to find when a function or variable was added or removed.git log -S "string"