Loading...
Loading...
Modern Git command best practices for AI agents. Use modern, purposeful commands introduced in Git 2.23+ instead of legacy multi-purpose commands. Teaches when to use `git switch` (branch operations), `git restore` (file operations), and other safer alternatives to improve clarity and reduce errors.
npx skill4agent add daleseo/git-skills modern-gitgit checkoutgit switchgit checkoutgit restoregit checkout --git push --force-with-leasegit push --forcegit switch# ✓ CORRECT: Modern commands
git switch main # Switch to existing branch
git switch -c feature-branch # Create and switch to new branch
git switch - # Switch to previous branch
# ✗ AVOID: Legacy commands
git checkout main # Overloaded command, unclear intent
git checkout -b feature-branch # Same operation, less clear
git checkout - # Same, but what does "-" mean?git switchgit restore# ✓ CORRECT: Modern commands
git restore src/app.js # Discard working directory changes
git restore --staged src/app.js # Unstage file
git restore --source=abc123 src/app.js # Restore from specific commit
git restore --staged --worktree src/app.js # Unstage AND discard
# ✗ AVOID: Legacy commands
git checkout -- src/app.js # Requires confusing "--" separator
git reset HEAD src/app.js # "reset" sounds destructive
git checkout abc123 -- src/app.js # Unclear what's happeninggit restore--staged--worktree--source--force-with-lease# ✓ CORRECT: Safe force push
git push --force-with-lease origin feature-branch
# ✗ AVOID: Dangerous force push
git push --force origin feature-branch--force-with-leaseDo you need to create the branch first?
├─ YES → git switch -c <new-branch>
└─ NO → git switch <existing-branch>
Special cases:
├─ Previous branch → git switch -
└─ With uncommitted changes → git stash && git switch <branch> && git stash pop
OR git switch -c <new-branch> (bring changes with you)What do you want to fix?
├─ Discard working directory changes
│ └─> git restore <file>
│
├─ Unstage file (keep changes in working directory)
│ └─> git restore --staged <file>
│
├─ Discard AND unstage
│ └─> git restore --staged --worktree <file>
│
└─ Restore from specific commit
└─> git restore --source=<commit> <file>Why do you need to force push?
├─ After rebase/amend (common, safe scenario)
│ └─> git push --force-with-lease origin <branch>
│
├─ To overwrite remote (rare, potentially dangerous)
│ ├─ Are you SURE no one else has pushed?
│ │ ├─ YES → git push --force-with-lease origin <branch>
│ │ └─ NO → git fetch && git rebase origin/<branch>
│ │
│ └─> Tip: ALWAYS prefer --force-with-lease over --force# ✓ CORRECT
git switch main
git pull
git switch -c feature/new-feature
# ✗ AVOID
git checkout main
git pull
git checkout -b feature/new-feature# ✓ CORRECT
git restore src/broken.js # Single file
git restore . # All files in current directory
# ✗ AVOID
git checkout -- src/broken.js
git checkout -- .# ✓ CORRECT
git restore --staged --worktree src/app.js
# OR two steps for clarity
git restore --staged src/app.js # Unstage
git restore src/app.js # Then discard
# ✗ AVOID
git reset HEAD src/app.js
git checkout -- src/app.js# ✓ CORRECT
git restore --source=abc123 src/legacy.js
git restore --source=HEAD~3 src/config.js
# ✗ AVOID
git checkout abc123 -- src/legacy.js
git checkout HEAD~3 -- src/config.js# ✓ CORRECT
git switch feature-branch
git rebase main
git push --force-with-lease origin feature-branch
# ✗ AVOID
git checkout feature-branch
git rebase main
git push --force origin feature-branch| Operation | Use This | NOT This |
|---|---|---|
| Switch branch | | |
| Create branch | | |
| Discard changes | | |
| Unstage | | |
| Force push | | |
# ✓ GOOD: Intent is obvious
git restore --staged src/app.js # Clearly unstaging
git restore --source=HEAD~1 src/app.js # Clearly restoring from parent commit
# ✗ UNCLEAR: What's happening?
git checkout -- src/app.js # Restoring? From where?
git checkout HEAD~1 -- src/app.js # Is this switching branches or restoring?# ✓ SAFE: --force-with-lease protects against overwrites
git push --force-with-lease origin feature-branch
# ✗ DANGEROUS: Can overwrite others' work
git push --force origin feature-branch
# ✓ SAFE: git switch refuses to switch with uncommitted changes
git switch main # Errors if uncommitted changes
# ✗ RISKY: Need to remember --discard flag
git switch --discard-changes main # Only use when you WANT to lose changes# ✓ SAFE: Can recover if experiment fails
git stash push -m "Before risky operation"
# Try risky operation
git restore --source=old-commit .
# If it fails:
git stash pop # Recover
# ✗ RISKY: No recovery option
git restore --source=old-commit .
# Changes lost forever!# Exploring history (detached HEAD)
git checkout abc123 # Still acceptable
git switch --detach abc123 # More explicit alternative
# Complex remote tracking
git checkout -b local origin/remote # Still commonly usedgit checkout# ✗ BAD: Unclear intent, error-prone
git checkout main
git checkout -b feature
git checkout -- src/app.js
# ✓ GOOD: Clear intent for each operation
git switch main
git switch -c feature
git restore src/app.js--force-with-lease# ✗ BAD: Can overwrite others' commits
git rebase main
git push --force origin feature-branch
# ✓ GOOD: Safe against overwrites
git rebase main
git push --force-with-lease origin feature-branch--staged--worktree# ✗ WRONG: Only unstages, doesn't discard changes
git restore --staged src/app.js
# File still modified in working directory!
# ✓ CORRECT: Specify both if you want both
git restore --staged --worktree src/app.js
# OR
git restore --staged src/app.js # Unstage
git restore src/app.js # Then discard# ✗ RISKY: Blindly discarding without checking
git restore .
# ✓ SAFE: Check what you're losing first
git status
git diff
git restore .# ✓ GOOD: Use modern commands in examples
To discard your changes, run:
\`\`\`bash
git restore src/app.js
\`\`\`
# ✗ AVOID: Don't teach legacy commands
To discard your changes, run:
\`\`\`bash
git checkout -- src/app.js
\`\`\`# ✓ GOOD: Educate users
Use `git switch` instead of `git checkout` for branch operations.
This makes your intent clearer and provides better error messages.
# ✗ INSUFFICIENT: Just showing command without context
Use `git switch main` to switch branches.# ✓ GOOD: Consistent modern commands throughout
git switch develop
git pull
git switch -c feature/new-feature
git restore --staged accidental-file.js
# ✗ INCONSISTENT: Mixing old and new
git checkout develop
git pull
git switch -c feature/new-feature
git checkout -- accidental-file.js| Use Case | Command | Key Flags | Notes |
|---|---|---|---|
| Switch to branch | | | Replaces |
| Discard file changes | | | Replaces |
| Unstage file | | | Replaces |
| Restore from commit | | | Replaces |
| Force push safely | | | Replaces |
git switchgit restore--force-with-lease