Last Updated: 2026-02-16 by Keming He
Important
This guide is for macOS / Linux users with POSIX-compatible shell (sh, bash, zsh).
For Windows users: See Git for Windows - commands work cross-platform, shell syntax may differ.
Essential git workflows for trunk-based development. Organized by development lifecycle.
- Use Cases - Git
Configure git identity (required before committing):
git config --global user.name "Your Name"
git config --global user.email "your-email@example.com"Tip
Use the email associated with your GitHub account. For privacy, use your GitHub-provided noreply email: username@users.noreply.github.com
Verify configuration:
git config --global --listNote
Advanced topic. Skip if you only use one Git identity.
Use includeIf to auto-switch identity based on directory, for example:
# ~/.gitconfig
[user]
name = Your Name
email = personal@email.com
[includeIf "gitdir:~/work/"]
path = ~/.gitconfig-work# ~/.gitconfig-work
[user]
name = Your Name
email = work@company.com
signingkey = WORK_GPG_KEY_IDRepos under ~/work/ automatically use work identity. No manual switching needed.
# Clone repository
git clone https://github.com/username/repo-name.git
cd repo-name
# Verify remotes
git remote -v
# Check current state
git status
git branch -aImportant
Always branch from up-to-date main. One branch = one issue.
# Update main first
git switch main
git pull origin main
# Create feature branch
git switch -c [type]/[description]/[username]
git push -u origin [type]/[description]/[username]Branch naming: type/description/username
| Type | Use For |
|---|---|
feat |
New features |
fix |
Bug fixes |
docs |
Documentation |
refactor |
Code restructuring |
git status # Full status
git status -s # Short format
git diff # Unstaged changes
git diff --staged # Staged changesgit add . # Stage all
git add [file] # Stage specific file
git commit -m "type(scope): description"git log --oneline -10 # Recent commits
git log main..HEAD --oneline # Commits on this branch only
git log --oneline --graph # Visual branch structure
git show [commit-sha] # Full details of a commitImportant
Rebase regularly to avoid conflicts. Always rebase before submitting PR.
# Update main and rebase
git fetch origin main
git rebase origin/main
# If conflicts occur
git add . # Stage resolved files
git rebase --continue # Continue rebase
# Push updated branch
git push --force-with-lease origin [branch-name]Use when your branch contains commits from a previously squash-merged PR.
# Find where to cut
git log main..HEAD --oneline
# Rebase excluding already-merged commits
git rebase --onto origin/main [last-merged-commit-sha]
# Push updated branch
git push --force-with-lease origin [branch-name]Tip
[last-merged-commit-sha] is the SHA of the last commit that was already merged to main via squash-merge.
git rebase --abort # Cancel and restore previous state# Verify branch is ready
git log main..HEAD --oneline # Review your commits
git diff main..HEAD --stat # Summary of changes
# Push final changes
git push origin [branch-name]Then create PR on GitHub linking to the approved issue.
After PR is merged:
# Update local main
git switch main
git pull origin main
# Delete local feature branch
git branch -D [branch-name]
# Delete remote feature branch (if not auto-deleted)
git push origin --delete [branch-name]
# Clean stale references
git fetch origin --pruneTemporarily save changes when switching context.
# Save current work, add -u flag to include unstaged files
git stash -m "WIP: description"
# Switch to other branch, do work, return
# Restore stashed work
git stash pop # Apply and remove from stash
git stash apply # Apply but keep in stashgit stash list # View all stashes
git stash show -p # View stash contents
git stash drop # Delete latest stash
git stash clear # Delete ALL stashes| Mode | Effect |
|---|---|
--soft |
Undo commit, keep staged changes |
--mixed |
Undo commit, unstage changes (default) |
--hard |
Undo commit, discard all changes |
git reset HEAD~1 # Undo last commit (mixed)
git reset --soft HEAD~1 # Undo commit, keep staged
git reset --hard HEAD~1 # Undo and discard (DESTRUCTIVE)git reflog # View recent branch states
git reset --hard [commit-sha] # Reset to specific stateCase-only renames aren't detected on case-insensitive filesystems (macOS, Windows):
# Wrong - won't be tracked
mv readme.md README.md
git status # Shows "nothing to commit"
# Correct - use git mv
git mv readme.md README.md
git commit -m "refactor: correct filename casing"Tip
Always use git mv for case changes. Avoid git config core.ignorecase false as it breaks compatibility.
Symptom: You clone a repo using an HTTPS URL, but get an SSH error:
git clone https://github.com/username/repo.git
# Cloning into 'repo'...
# git@github.com: Permission denied (publickey).Cause: A url.<base>.insteadOf rule in your Git config is silently rewriting HTTPS URLs to SSH. This is often set intentionally (see SSH guide - URL Rewriting) but can cause confusion if forgotten.
Diagnose:
# Check for any URL rewriting rules
git config --global --list | grep insteadofIf you see output like url.git@github.com:.insteadof=https://github.com/, that rule is converting your HTTPS clone URLs to SSH.
Fix:
# Remove all rewriting rules for git@github.com:
git config --global --unset-all url."git@github.com:".insteadOfAfter removing the rule, HTTPS clone commands will work as expected without requiring SSH key setup.
Tip
If an SSH connection was attempted before you found this issue, your SSH client (such as the ssh command or Git over SSH) may have added a host key to ~/.ssh/known_hosts. See SSH guide - Managing Known Hosts for cleanup instructions.
use-cases-gpg-commit-signing.md- GPG signing setup and troubleshootinguse-cases-ssh-authentication.md- SSH authentication and known hosts management