Git Mastery - Complete Git Expertise
🚨 CRITICAL GUIDELINES
Windows File Path Requirements
MANDATORY: Always Use Backslashes on Windows for File Paths
When using Edit or Write tools on Windows, you MUST use backslashes (\) in file paths, NOT forward slashes (/).
Examples:
- •❌ WRONG:
D:/repos/project/file.tsx - •✅ CORRECT:
D:\repos\project\file.tsx
This applies to:
- •Edit tool file_path parameter
- •Write tool file_path parameter
- •All file operations on Windows systems
Documentation Guidelines
NEVER create new documentation files unless explicitly requested by the user.
- •Priority: Update existing README.md files rather than creating new documentation
- •Repository cleanliness: Keep repository root clean - only README.md unless user requests otherwise
- •Style: Documentation should be concise, direct, and professional - avoid AI-generated tone
- •User preference: Only create additional .md files when user specifically asks for documentation
Comprehensive guide for ALL Git operations from basic to advanced, including dangerous operations with safety guardrails.
TL;DR QUICK REFERENCE
Safety First - Before ANY Destructive Operation:
# ALWAYS check status first git status git log --oneline -10 # For risky operations, create a safety branch git branch backup-$(date +%Y%m%d-%H%M%S) # Remember: git reflog is your safety net (90 days default) git reflog
User Preference Check:
- •ALWAYS ASK: "Would you like me to create commits automatically, or would you prefer to handle commits manually?"
- •Respect user's choice throughout the session
Overview
This skill provides COMPLETE Git expertise for ANY Git operation, no matter how advanced, niche, or risky. It covers:
MUST use this skill for:
- •✅ ANY Git command or operation
- •✅ Repository initialization, cloning, configuration
- •✅ Branch management and strategies
- •✅ Commit workflows and best practices
- •✅ Merge strategies and conflict resolution
- •✅ Rebase operations (interactive and non-interactive)
- •✅ History rewriting (filter-repo, reset, revert)
- •✅ Recovery operations (reflog, fsck)
- •✅ Dangerous operations (force push, hard reset)
- •✅ Platform-specific workflows (GitHub, Azure DevOps, Bitbucket)
- •✅ Advanced features (submodules, worktrees, hooks)
- •✅ Performance optimization
- •✅ Cross-platform compatibility (Windows/Linux/macOS)
Core Principles
1. Safety Guardrails for Destructive Operations
CRITICAL: Before ANY destructive operation (reset --hard, force push, filter-repo, etc.):
- •Always warn the user explicitly
- •Explain the risks clearly
- •Ask for confirmation
- •Suggest creating a backup branch first
- •Provide recovery instructions
# Example safety pattern for dangerous operations
echo "⚠️ WARNING: This operation is DESTRUCTIVE and will:"
echo " - Permanently delete uncommitted changes"
echo " - Rewrite Git history"
echo " - [specific risks for the operation]"
echo ""
echo "Safety recommendation: Creating backup branch first..."
git branch backup-before-reset-$(date +%Y%m%d-%H%M%S)
echo ""
echo "To recover if needed: git reset --hard backup-before-reset-XXXXXXXX"
echo ""
read -p "Are you SURE you want to proceed? (yes/NO): " confirm
if [[ "$confirm" != "yes" ]]; then
echo "Operation cancelled."
exit 1
fi
2. Commit Creation Policy
ALWAYS ASK at the start of ANY Git task: "Would you like me to:
- •Create commits automatically with appropriate messages
- •Stage changes only (you handle commits manually)
- •Just provide guidance (no automatic operations)"
Respect this choice throughout the session.
3. Platform Awareness
Git behavior and workflows differ across platforms and hosting providers:
Windows (Git Bash/PowerShell):
- •Line ending handling (core.autocrlf)
- •Path separators and case sensitivity
- •Credential management (Windows Credential Manager)
Linux/macOS:
- •Case-sensitive filesystems
- •SSH key management
- •Permission handling
Hosting Platforms:
- •GitHub: Pull requests, GitHub Actions, GitHub CLI
- •Azure DevOps: Pull requests, Azure Pipelines, policies
- •Bitbucket: Pull requests, Bitbucket Pipelines, Jira integration
- •GitLab: Merge requests, GitLab CI/CD
Basic Git Operations
Repository Initialization and Cloning
# Initialize new repository git init git init --initial-branch=main # Specify default branch name # Clone repository git clone <url> git clone <url> <directory> git clone --depth 1 <url> # Shallow clone (faster, less history) git clone --branch <branch> <url> # Clone specific branch git clone --recurse-submodules <url> # Include submodules
Configuration
# User identity (required for commits) git config --global user.name "Your Name" git config --global user.email "your.email@example.com" # Default branch name git config --global init.defaultBranch main # Line ending handling (Windows) git config --global core.autocrlf true # Windows git config --global core.autocrlf input # macOS/Linux # Editor git config --global core.editor "code --wait" # VS Code git config --global core.editor "vim" # Diff tool git config --global diff.tool vscode git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE' # Merge tool git config --global merge.tool vscode git config --global mergetool.vscode.cmd 'code --wait $MERGED' # Aliases git config --global alias.st status git config --global alias.co checkout git config --global alias.br branch git config --global alias.ci commit git config --global alias.unstage 'reset HEAD --' git config --global alias.last 'log -1 HEAD' git config --global alias.visual '!gitk' # View configuration git config --list git config --global --list git config --local --list git config user.name # Get specific value
Basic Workflow
# Check status git status git status -s # Short format git status -sb # Short with branch info # Add files git add <file> git add . # Add all changes in current directory git add -A # Add all changes in repository git add -p # Interactive staging (patch mode) # Remove files git rm <file> git rm --cached <file> # Remove from index, keep in working directory git rm -r <directory> # Move/rename files git mv <old> <new> # Commit git commit -m "message" git commit -am "message" # Add and commit tracked files git commit --amend # Amend last commit git commit --amend --no-edit # Amend without changing message git commit --allow-empty -m "message" # Empty commit (useful for triggers) # View history git log git log --oneline git log --graph --oneline --all --decorate git log --stat # Show file statistics git log --patch # Show diffs git log -p -2 # Show last 2 commits with diffs git log --since="2 weeks ago" git log --until="2025-01-01" git log --author="Name" git log --grep="pattern" git log -- <file> # History of specific file git log --follow <file> # Follow renames # Show changes git diff # Unstaged changes git diff --staged # Staged changes git diff HEAD # All changes since last commit git diff <branch> # Compare with another branch git diff <commit1> <commit2> git diff <commit> # Changes since specific commit git diff <branch1>...<branch2> # Changes between branches # Show commit details git show <commit> git show <commit>:<file> # Show file at specific commit
Branch Management
Creating and Switching Branches
# List branches git branch # Local branches git branch -r # Remote branches git branch -a # All branches git branch -v # With last commit info git branch -vv # With tracking info # Create branch git branch <branch-name> git branch <branch-name> <start-point> # From specific commit/tag # Switch branch git switch <branch-name> git checkout <branch-name> # Old syntax, still works # Create and switch git switch -c <branch-name> git checkout -b <branch-name> git switch -c <branch-name> <start-point> # Delete branch git branch -d <branch-name> # Safe delete (only if merged) git branch -D <branch-name> # Force delete (even if not merged) # Rename branch git branch -m <old-name> <new-name> git branch -m <new-name> # Rename current branch # Set upstream tracking git branch --set-upstream-to=origin/<branch> git branch -u origin/<branch>
Branch Strategies
Git Flow:
- •
main/master: Production-ready code - •
develop: Integration branch for features - •
feature/*: New features - •
release/*: Release preparation - •
hotfix/*: Production fixes
GitHub Flow:
- •
main: Always deployable - •
feature/*: Short-lived feature branches - •Create PR, review, merge
Trunk-Based Development:
- •
main: Single branch - •Short-lived feature branches (< 1 day)
- •Feature flags for incomplete features
GitLab Flow:
- •Environment branches:
production,staging,main - •Feature branches merge to
main - •Deploy from environment branches
Merging and Rebasing
Merge Strategies
# Fast-forward merge (default if possible) git merge <branch> # Force merge commit (even if fast-forward possible) git merge --no-ff <branch> # Squash merge (combine all commits into one) git merge --squash <branch> # Then commit manually: git commit -m "Merged feature X" # Merge with specific strategy git merge -s recursive <branch> # Default strategy git merge -s ours <branch> # Always use "our" version git merge -s theirs <branch> # Always use "their" version (requires merge-theirs) git merge -s octopus <branch1> <branch2> <branch3> # Merge multiple branches # Merge with strategy options git merge -X ours <branch> # Prefer "our" changes in conflicts git merge -X theirs <branch> # Prefer "their" changes in conflicts git merge -X ignore-all-space <branch> git merge -X ignore-space-change <branch> # Abort merge git merge --abort # Continue after resolving conflicts git merge --continue
Conflict Resolution
# When merge conflicts occur git status # See conflicted files # Conflict markers in files: # <<<<<<< HEAD # Your changes # ======= # Their changes # >>>>>>> branch-name # Resolve conflicts manually, then: git add <resolved-file> git commit # Complete the merge # Use mergetool git mergetool # Accept one side completely git checkout --ours <file> # Keep our version git checkout --theirs <file> # Keep their version git add <file> # View conflict diff git diff # Show conflicts git diff --ours # Compare with our version git diff --theirs # Compare with their version git diff --base # Compare with base version # List conflicts git diff --name-only --diff-filter=U
Rebase Operations
⚠️ WARNING: Rebase rewrites history. Never rebase commits that have been pushed to shared branches!
# Basic rebase git rebase <base-branch> git rebase origin/main # Interactive rebase (POWERFUL) git rebase -i <base-commit> git rebase -i HEAD~5 # Last 5 commits # Interactive rebase commands: # p, pick = use commit # r, reword = use commit, but edit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like squash, but discard commit message # x, exec = run command (rest of line) using shell # b, break = stop here (continue rebase later with 'git rebase --continue') # d, drop = remove commit # l, label = label current HEAD with a name # t, reset = reset HEAD to a label # Rebase onto different base git rebase --onto <new-base> <old-base> <branch> # Continue after resolving conflicts git rebase --continue # Skip current commit git rebase --skip # Abort rebase git rebase --abort # Preserve merge commits git rebase --preserve-merges <base> # Deprecated git rebase --rebase-merges <base> # Modern approach # Autosquash (with fixup commits) git commit --fixup <commit> git rebase -i --autosquash <base>
Cherry-Pick
# Apply specific commit to current branch git cherry-pick <commit> # Cherry-pick multiple commits git cherry-pick <commit1> <commit2> git cherry-pick <commit1>..<commit5> # Cherry-pick without committing git cherry-pick -n <commit> git cherry-pick --no-commit <commit> # Continue after resolving conflicts git cherry-pick --continue # Abort cherry-pick git cherry-pick --abort
Remote Operations
Remote Management
# List remotes git remote git remote -v # With URLs # Add remote git remote add <name> <url> git remote add origin https://github.com/user/repo.git # Change remote URL git remote set-url <name> <new-url> # Remove remote git remote remove <name> git remote rm <name> # Rename remote git remote rename <old> <new> # Show remote info git remote show <name> git remote show origin # Prune stale remote branches git remote prune origin git fetch --prune
Fetch and Pull
# Fetch from remote (doesn't merge) git fetch git fetch origin git fetch --all # All remotes git fetch --prune # Remove stale remote-tracking branches # Pull (fetch + merge) git pull git pull origin <branch> git pull --rebase # Fetch + rebase instead of merge git pull --no-ff # Always create merge commit git pull --ff-only # Only if fast-forward possible # Set default pull behavior git config --global pull.rebase true # Always rebase git config --global pull.ff only # Only fast-forward
Push
# Push to remote git push git push origin <branch> git push origin <local-branch>:<remote-branch> # Push new branch and set upstream git push -u origin <branch> git push --set-upstream origin <branch> # Push all branches git push --all # Push tags git push --tags git push origin <tag-name> # Delete remote branch git push origin --delete <branch> git push origin :<branch> # Old syntax # Delete remote tag git push origin --delete <tag> git push origin :refs/tags/<tag> # ⚠️ DANGEROUS: Force push (overwrites remote history) # ALWAYS ASK USER FOR CONFIRMATION FIRST git push --force git push -f # ⚠️ SAFER: Force push with lease (fails if remote updated) git push --force-with-lease git push --force-with-lease=<ref>:<expected-value>
Force Push Safety Protocol:
Before ANY force push, execute this safety check:
echo "⚠️ DANGER: Force push will overwrite remote history!"
echo ""
echo "Remote branch status:"
git fetch origin
git log --oneline origin/<branch> ^<branch> --decorate
if [ -z "$(git log --oneline origin/<branch> ^<branch>)" ]; then
echo "✓ No commits will be lost (remote is behind local)"
else
echo "❌ WARNING: Remote has commits that will be LOST:"
git log --oneline --decorate origin/<branch> ^<branch>
echo ""
echo "These commits from other developers will be destroyed!"
fi
echo ""
echo "Consider using --force-with-lease instead of --force"
echo ""
read -p "Type 'force push' to confirm: " confirm
if [[ "$confirm" != "force push" ]]; then
echo "Cancelled."
exit 1
fi
Advanced Commands
Stash
# Stash changes
git stash
git stash save "message"
git stash push -m "message"
# Stash including untracked files
git stash -u
git stash --include-untracked
# Stash including ignored files
git stash -a
git stash --all
# List stashes
git stash list
# Show stash contents
git stash show
git stash show -p # With diff
git stash show stash@{2}
# Apply stash (keep in stash list)
git stash apply
git stash apply stash@{2}
# Pop stash (apply and remove)
git stash pop
git stash pop stash@{2}
# Drop stash
git stash drop
git stash drop stash@{2}
# Clear all stashes
git stash clear
# Create branch from stash
git stash branch <branch-name>
git stash branch <branch-name> stash@{1}
# Git 2.51+ : Import/Export stashes (share stashes between machines)
# Export stash to a file
git stash store --file=stash.patch stash@{0}
# Import stash from a file
git stash import --file=stash.patch
# Share stashes like branches/tags
git stash export > my-stash.patch
git stash import < my-stash.patch
Reset
⚠️ WARNING: reset can permanently delete changes!
# Soft reset (keep changes staged) git reset --soft <commit> git reset --soft HEAD~1 # Undo last commit, keep changes staged # Mixed reset (default - keep changes unstaged) git reset <commit> git reset HEAD~1 # Undo last commit, keep changes unstaged # ⚠️ HARD reset (DELETE all changes - DANGEROUS!) # ALWAYS create backup branch first! git branch backup-$(date +%Y%m%d-%H%M%S) git reset --hard <commit> git reset --hard HEAD~1 # Undo last commit and DELETE all changes git reset --hard origin/<branch> # Reset to remote state # Unstage files git reset HEAD <file> git reset -- <file> # Reset specific file to commit git checkout <commit> -- <file>
Revert
# Revert commit (creates new commit that undoes changes) # Safer than reset for shared branches git revert <commit> # Revert without creating commit git revert -n <commit> git revert --no-commit <commit> # Revert merge commit git revert -m 1 <merge-commit> # Keep first parent git revert -m 2 <merge-commit> # Keep second parent # Revert multiple commits git revert <commit1> <commit2> git revert <commit1>..<commit5> # Continue after resolving conflicts git revert --continue # Abort revert git revert --abort
Reflog (Recovery)
reflog is your safety net - it tracks all HEAD movements for 90 days (default)
# View reflog git reflog git reflog show git reflog show <branch> # More detailed reflog git log -g # Reflog as log git log -g --all # Find lost commits git reflog --all git fsck --lost-found # Recover deleted branch git reflog # Find commit where branch existed git branch <branch-name> <commit-hash> # Recover from hard reset git reflog # Find commit before reset git reset --hard <commit-hash> # Recover deleted commits git cherry-pick <commit-hash> # Reflog expiration (change retention) git config gc.reflogExpire "90 days" git config gc.reflogExpireUnreachable "30 days"
Bisect (Find Bad Commits)
# Start bisect git bisect start # Mark current commit as bad git bisect bad # Mark known good commit git bisect good <commit> # Test each commit, then mark as good or bad git bisect good # Current commit is good git bisect bad # Current commit is bad # Automate with test script git bisect run <test-script> # Bisect shows the first bad commit # Finish bisect git bisect reset # Skip commit if unable to test git bisect skip
Clean
⚠️ WARNING: clean permanently deletes untracked files!
# Show what would be deleted (dry run - ALWAYS do this first!) git clean -n git clean --dry-run # Delete untracked files git clean -f # Delete untracked files and directories git clean -fd # Delete untracked and ignored files git clean -fdx # Interactive clean git clean -i
Worktrees
# List worktrees git worktree list # Add new worktree git worktree add <path> <branch> git worktree add ../project-feature feature-branch # Add worktree for new branch git worktree add -b <new-branch> <path> # Remove worktree git worktree remove <path> # Prune stale worktrees git worktree prune
Submodules
# Add submodule git submodule add <url> <path> # Initialize submodules (after clone) git submodule init git submodule update # Clone with submodules git clone --recurse-submodules <url> # Update submodules git submodule update --remote git submodule update --init --recursive # Execute command in all submodules git submodule foreach <command> git submodule foreach git pull origin main # Remove submodule git submodule deinit <path> git rm <path> rm -rf .git/modules/<path>
Dangerous Operations (High Risk)
Filter-Repo (History Rewriting)
⚠️ EXTREMELY DANGEROUS: Rewrites entire repository history!
# Install git-filter-repo (not built-in) # pip install git-filter-repo # Remove file from all history git filter-repo --path <file> --invert-paths # Remove directory from all history git filter-repo --path <directory> --invert-paths # Change author info git filter-repo --name-callback 'return name.replace(b"Old Name", b"New Name")' git filter-repo --email-callback 'return email.replace(b"old@email.com", b"new@email.com")' # Remove large files git filter-repo --strip-blobs-bigger-than 10M # ⚠️ After filter-repo, force push required git push --force --all git push --force --tags
Safety protocol for filter-repo:
echo "⚠️⚠️⚠️ EXTREME DANGER ⚠️⚠️⚠️"
echo "This operation will:"
echo " - Rewrite ENTIRE repository history"
echo " - Change ALL commit hashes"
echo " - Break all existing clones"
echo " - Require all team members to re-clone"
echo " - Cannot be undone after force push"
echo ""
echo "MANDATORY: Create full backup:"
git clone --mirror <repo-url> backup-$(date +%Y%m%d-%H%M%S)
echo ""
echo "Notify ALL team members before proceeding!"
echo ""
read -p "Type 'I UNDERSTAND THE RISKS' to continue: " confirm
if [[ "$confirm" != "I UNDERSTAND THE RISKS" ]]; then
echo "Cancelled."
exit 1
fi
Amend Pushed Commits
⚠️ DANGER: Changing pushed commits requires force push!
# Amend last commit git commit --amend # Amend without changing message git commit --amend --no-edit # Change author of last commit git commit --amend --author="Name <email>" # ⚠️ Force push required if already pushed git push --force-with-lease
Rewrite Multiple Commits
⚠️ DANGER: Interactive rebase on pushed commits!
# Interactive rebase git rebase -i HEAD~5 # Change author of older commits git rebase -i <commit>^ # Mark commit as "edit" # When stopped: git commit --amend --author="Name <email>" --no-edit git rebase --continue # ⚠️ Force push required git push --force-with-lease
Platform-Specific Workflows
GitHub
Pull Requests:
# Install GitHub CLI # https://cli.github.com/ # Create PR gh pr create gh pr create --title "Title" --body "Description" gh pr create --base main --head feature-branch # List PRs gh pr list # View PR gh pr view gh pr view <number> # Check out PR locally gh pr checkout <number> # Review PR gh pr review gh pr review --approve gh pr review --request-changes gh pr review --comment # Merge PR gh pr merge gh pr merge --squash gh pr merge --rebase gh pr merge --merge # Close PR gh pr close <number>
GitHub Actions:
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: npm test
Azure DevOps
Pull Requests:
# Install Azure DevOps CLI # https://docs.microsoft.com/en-us/cli/azure/install-azure-cli # Create PR az repos pr create --title "Title" --description "Description" az repos pr create --source-branch feature --target-branch main # List PRs az repos pr list # View PR az repos pr show --id <id> # Complete PR az repos pr update --id <id> --status completed # Branch policies az repos policy list az repos policy create --config policy.json
Azure Pipelines:
# azure-pipelines.yml
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- script: npm test
displayName: 'Run tests'
Bitbucket
Pull Requests:
# Create PR (via web or Bitbucket CLI) bb pr create # Review PR bb pr list bb pr view <id> # Merge PR bb pr merge <id>
Bitbucket Pipelines:
# bitbucket-pipelines.yml
pipelines:
default:
- step:
script:
- npm test
GitLab
Merge Requests:
# Install GitLab CLI (glab) # https://gitlab.com/gitlab-org/cli # Create MR glab mr create glab mr create --title "Title" --description "Description" # List MRs glab mr list # View MR glab mr view <id> # Merge MR glab mr merge <id> # Close MR glab mr close <id>
GitLab CI:
# .gitlab-ci.yml
stages:
- test
test:
stage: test
script:
- npm test
Performance Optimization
Repository Maintenance
# Garbage collection git gc git gc --aggressive # More thorough, slower # Prune unreachable objects git prune # Verify repository git fsck git fsck --full # Optimize repository git repack -a -d --depth=250 --window=250 # Git 2.51+: Path-walk repacking (generates smaller packs) # More efficient delta compression by walking paths git repack --path-walk -a -d # Count objects git count-objects -v # Repository size du -sh .git
Large Files
# Find large files in history git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sed -n 's/^blob //p' | sort --numeric-sort --key=2 | tail -n 10 # Git LFS (Large File Storage) git lfs install git lfs track "*.psd" git lfs track "*.zip" git add .gitattributes git add file.psd git commit -m "Add large file" # List LFS files git lfs ls-files # Fetch LFS files git lfs fetch git lfs pull
Shallow Clones
# Shallow clone (faster, less disk space) git clone --depth 1 <url> # Unshallow (convert to full clone) git fetch --unshallow # Fetch more history git fetch --depth=100
Tags and Releases
Creating Tags
# Lightweight tag git tag <tag-name> git tag v1.0.0 # Annotated tag (recommended - includes metadata) git tag -a <tag-name> -m "message" git tag -a v1.0.0 -m "Release version 1.0.0" # Tag specific commit git tag -a <tag-name> <commit> # Signed tag (GPG signature) git tag -s <tag-name> -m "message"
Managing Tags
# List tags git tag git tag -l "v1.*" # Pattern matching # Show tag info git show <tag-name> # Delete local tag git tag -d <tag-name> # Delete remote tag git push origin --delete <tag-name> git push origin :refs/tags/<tag-name> # Push tags git push origin <tag-name> git push --tags # All tags git push --follow-tags # Only annotated tags
Git Hooks
Client-Side Hooks
# Hooks location: .git/hooks/
# pre-commit: Run before commit
# Example: .git/hooks/pre-commit
#!/bin/bash
npm run lint || exit 1
# prepare-commit-msg: Edit commit message before editor opens
# commit-msg: Validate commit message
#!/bin/bash
msg=$(cat "$1")
if ! echo "$msg" | grep -qE "^(feat|fix|docs|style|refactor|test|chore):"; then
echo "Error: Commit message must start with type (feat|fix|docs|...):"
exit 1
fi
# post-commit: Run after commit
# pre-push: Run before push
# post-checkout: Run after checkout
# post-merge: Run after merge
# Make hook executable
chmod +x .git/hooks/pre-commit
Server-Side Hooks
# pre-receive: Run before refs are updated
# update: Run for each branch being updated
# post-receive: Run after refs are updated
# Example: Reject force pushes
#!/bin/bash
while read oldrev newrev refname; do
if [ "$oldrev" != "0000000000000000000000000000000000000000" ]; then
if ! git merge-base --is-ancestor "$oldrev" "$newrev"; then
echo "Error: Force push rejected"
exit 1
fi
fi
done
Troubleshooting and Recovery
Common Problems
Detached HEAD:
# You're in detached HEAD state git branch temp # Create branch at current commit git switch main git merge temp git branch -d temp
Merge conflicts:
# During merge/rebase git status # See conflicted files # Edit files to resolve conflicts git add <resolved-files> git merge --continue # or git rebase --continue # Abort and start over git merge --abort git rebase --abort
Accidentally deleted branch:
# Find branch in reflog git reflog # Create branch at commit git branch <branch-name> <commit-hash>
Committed to wrong branch:
# Move commit to correct branch git switch correct-branch git cherry-pick <commit> git switch wrong-branch git reset --hard HEAD~1 # Remove from wrong branch
Pushed sensitive data:
# ⚠️ URGENT: Remove from history immediately git filter-repo --path <sensitive-file> --invert-paths git push --force --all # Then: Rotate compromised credentials immediately!
Large commit by mistake:
# Before pushing git reset --soft HEAD~1 git reset HEAD <large-file> git commit -m "message" # After pushing - use filter-repo or BFG
Recovery Scenarios
Recover after hard reset:
git reflog git reset --hard <commit-before-reset>
Recover deleted file:
git log --all --full-history -- <file> git checkout <commit>^ -- <file>
Recover deleted commits:
git reflog # Find commit hash git cherry-pick <commit> # or git merge <commit> # or git reset --hard <commit>
Recover from corrupted repository:
# Verify corruption git fsck --full # Attempt repair git gc --aggressive # Last resort: clone from remote
Best Practices
Commit Messages
Conventional Commits format:
<type>(<scope>): <subject> <body> <footer>
Types:
- •
feat: New feature - •
fix: Bug fix - •
docs: Documentation - •
style: Formatting (no code change) - •
refactor: Code restructuring - •
test: Adding tests - •
chore: Maintenance
Example:
feat(auth): add OAuth2 authentication Implement OAuth2 flow for Google and GitHub providers. Includes token refresh and revocation. Closes #123
Branching Best Practices
- •Keep branches short-lived (< 2 days ideal)
- •Use descriptive names:
feature/user-auth,fix/header-crash - •One purpose per branch
- •Rebase before merge to keep history clean
- •Delete merged branches
Workflow Best Practices
- •Commit often (small, logical chunks)
- •Pull before push (stay up to date)
- •Review before commit (
git diff --staged) - •Write meaningful messages
- •Test before commit
- •Never commit secrets (use
.gitignore, environment variables)
.gitignore Best Practices
# Environment files .env .env.local *.env # Dependencies node_modules/ vendor/ venv/ # Build outputs dist/ build/ *.exe *.dll *.so # IDE .vscode/ .idea/ *.swp *.swo # OS files .DS_Store Thumbs.db # Logs *.log logs/ # Temporary files tmp/ temp/ *.tmp
Security Best Practices
Credential Management
# Store credentials (cache for 1 hour) git config --global credential.helper cache git config --global credential.helper 'cache --timeout=3600' # Store credentials (permanent - use with caution) git config --global credential.helper store # Windows: Use Credential Manager git config --global credential.helper wincred # macOS: Use Keychain git config --global credential.helper osxkeychain # Linux: Use libsecret git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret
SSH Keys
# Generate SSH key ssh-keygen -t ed25519 -C "your_email@example.com" ssh-keygen -t rsa -b 4096 -C "your_email@example.com" # If ed25519 not supported # Start ssh-agent eval "$(ssh-agent -s)" # Add key to ssh-agent ssh-add ~/.ssh/id_ed25519 # Test connection ssh -T git@github.com ssh -T git@ssh.dev.azure.com
GPG Signing
# Generate GPG key gpg --full-generate-key # List keys gpg --list-secret-keys --keyid-format LONG # Configure Git to sign commits git config --global user.signingkey <key-id> git config --global commit.gpgsign true # Sign commits git commit -S -m "message" # Verify signatures git log --show-signature
Preventing Secrets
# Git-secrets (AWS tool)
git secrets --install
git secrets --register-aws
# Gitleaks
gitleaks detect
# Pre-commit hook
#!/bin/bash
if git diff --cached | grep -E "(password|secret|api_key)" ; then
echo "Potential secret detected!"
exit 1
fi
Cross-Platform Considerations
Line Endings
# Windows (CRLF in working directory, LF in repository) git config --global core.autocrlf true # macOS/Linux (LF everywhere) git config --global core.autocrlf input # No conversion (not recommended) git config --global core.autocrlf false # Use .gitattributes for consistency # .gitattributes: * text=auto *.sh text eol=lf *.bat text eol=crlf
Case Sensitivity
# macOS/Windows: Case-insensitive filesystems # Linux: Case-sensitive filesystem # Enable case sensitivity in Git git config --global core.ignorecase false # Rename file (case-only change) git mv --force myfile.txt MyFile.txt
Path Handling
# Git always uses forward slashes internally # Works on all platforms: git add src/components/Header.jsx # Windows-specific tools may need backslashes in some contexts
Git Bash / MINGW Path Conversion (Windows)
CRITICAL: Git Bash is the primary Git environment on Windows!
Git Bash (MINGW/MSYS2) automatically converts Unix-style paths to Windows paths for native executables, which can cause issues with Git operations.
Path Conversion Behavior:
# Automatic conversions that occur: /foo → C:/Program Files/Git/usr/foo /foo:/bar → C:\msys64\foo;C:\msys64\bar --dir=/foo → --dir=C:/msys64/foo # What triggers conversion: # ✓ Leading forward slash (/) in arguments # ✓ Colon-separated path lists # ✓ Arguments after - or , with path components # What's exempt from conversion: # ✓ Arguments containing = (variable assignments) # ✓ Drive specifiers (C:) # ✓ Arguments with ; (already Windows format) # ✓ Arguments starting with // (Windows switches)
Controlling Path Conversion:
# Method 1: MSYS_NO_PATHCONV (Git for Windows only) # Disable ALL path conversion for a command MSYS_NO_PATHCONV=1 git command --option=/path # Permanently disable (use with caution - can break scripts) export MSYS_NO_PATHCONV=1 # Method 2: MSYS2_ARG_CONV_EXCL (MSYS2) # Exclude specific argument patterns export MSYS2_ARG_CONV_EXCL="*" # Exclude everything export MSYS2_ARG_CONV_EXCL="--dir=;/test" # Specific prefixes # Method 3: Manual conversion with cygpath cygpath -u "C:\path" # → Unix format: /c/path cygpath -w "/c/path" # → Windows format: C:\path cygpath -m "/c/path" # → Mixed format: C:/path # Method 4: Workarounds # Use double slashes: //e //s instead of /e /s # Use dash notation: -e -s instead of /e /s # Quote paths with spaces: "/c/Program Files/file.txt"
Shell Detection in Git Workflows:
# Method 1: $MSYSTEM (Most Reliable for Git Bash) case "$MSYSTEM" in MINGW64) echo "Git Bash 64-bit" ;; MINGW32) echo "Git Bash 32-bit" ;; MSYS) echo "MSYS environment" ;; esac # Method 2: uname -s (Portable) case "$(uname -s)" in MINGW64_NT*) echo "Git Bash 64-bit" ;; MINGW32_NT*) echo "Git Bash 32-bit" ;; MSYS_NT*) echo "MSYS" ;; CYGWIN*) echo "Cygwin" ;; Darwin*) echo "macOS" ;; Linux*) echo "Linux" ;; esac # Method 3: $OSTYPE (Bash-only, fast) case "$OSTYPE" in msys*) echo "Git Bash/MSYS" ;; cygwin*) echo "Cygwin" ;; darwin*) echo "macOS" ;; linux-gnu*) echo "Linux" ;; esac
Git Bash Path Issues & Solutions:
# Issue: Git commands with paths fail in Git Bash # Example: git log --follow /path/to/file fails # Solution 1: Use relative paths git log --follow ./path/to/file # Solution 2: Disable path conversion MSYS_NO_PATHCONV=1 git log --follow /path/to/file # Solution 3: Use Windows-style paths git log --follow C:/path/to/file # Issue: Spaces in paths (Program Files) # Solution: Always quote paths git add "/c/Program Files/project/file.txt" # Issue: Drive letter duplication (D:\dev → D:\d\dev) # Solution: Use cygpath for conversion file=$(cygpath -u "D:\dev\file.txt") git add "$file"
Git Bash Best Practices:
- •Always use forward slashes in Git commands - Git handles them on all platforms
- •Quote paths with spaces - Essential in Git Bash
- •Use relative paths when possible - Avoids conversion issues
- •Detect shell environment - Use $MSYSTEM for Git Bash detection
- •Test scripts on Git Bash - Primary Windows Git environment
- •Use MSYS_NO_PATHCONV selectively - Only when needed, not globally
Success Criteria
A Git workflow using this skill should:
- •✓ ALWAYS ask user preference for automatic commits vs manual
- •✓ ALWAYS warn before destructive operations
- •✓ ALWAYS create backup branches before risky operations
- •✓ ALWAYS explain recovery procedures
- •✓ Use appropriate branch strategy for the project
- •✓ Write meaningful commit messages
- •✓ Keep commit history clean and linear
- •✓ Never commit secrets or large binary files
- •✓ Test code before committing
- •✓ Know how to recover from any mistake
Emergency Recovery Reference
Quick recovery commands:
# Undo last commit (keep changes) git reset --soft HEAD~1 # Undo changes to file git checkout -- <file> # Recover deleted branch git reflog git branch <name> <commit> # Undo force push (if recent) git reflog git reset --hard <commit-before-push> git push --force-with-lease # Recover from hard reset git reflog git reset --hard <commit-before-reset> # Find lost commits git fsck --lost-found git reflog --all # Recover deleted file git log --all --full-history -- <file> git checkout <commit>^ -- <file>
When to Use This Skill
Always activate for:
- •Any Git command or operation
- •Repository management questions
- •Branch strategy decisions
- •Merge conflict resolution
- •History rewriting needs
- •Recovery from Git mistakes
- •Platform-specific Git questions
- •Dangerous operations (with appropriate warnings)
Key indicators:
- •User mentions Git, GitHub, GitLab, Bitbucket, Azure DevOps
- •Version control questions
- •Commit, push, pull, merge, rebase operations
- •Branch management
- •History modification
- •Recovery scenarios
This skill provides COMPLETE Git expertise. Combined with the reference files and safety guardrails, you have the knowledge to handle ANY Git operation safely and effectively.