Table of Contents
Open Table of Contents
Advices
Modern Git workflows should be explicit and boring. Prefer git switch for branches, git restore for files, and avoid surprising pulls.
pull.ff only gives you a cleaner workflow. See “Merging” below.
Git new machine configuration
Set the correct identity first:
git config --global user.name "Alexander Holbreich" # Replace with Yours
git config --global user.email "[email protected]" # Replace with Yours
Useful defaults:
git config --global init.defaultBranch main # Use "main" as the default branch name for new repositories
git config --global fetch.prune true # Automatically remove stale remote-tracking branches during fetch
git config --global pull.ff only # Allow git pull only when it can fast-forward, preventing automatic merge commits
git config --global merge.conflictStyle zdiff3 # Show clearer merge conflicts with base context to make resolution easier
git config --global diff.algorithm histogram # Use the histogram diff algorithm, which often produces more readable diffs
git config --global tag.sort version:refname # Sort tags like versions
Optional editor setup:
git config --global core.editor "code --wait" # Use VS Code as Git's editor and wait until you close it
Normally, .gitignore lives inside a repository and applies only to that repo. core.excludesfile adds another ignore file that applies to all your Git repos on your machine.
git config --global core.excludesfile ~/.gitignore_global
Handy aliases
# short commands: git st, git sw, git br, git ci
git config --global alias.st status
git config --global alias.sw switch
git config --global alias.br branch
git config --global alias.ci commit
# amend
git config --global alias.amend "commit --amend"
# useful logs: git lg -10, git last
git config --global alias.lg "log --oneline --graph --decorate --all"
git config --global alias.last "log -1 HEAD --stat"
# show changed files in last commit
git config --global alias.last-files "show --name-status --oneline HEAD"
Branching and switching correctly
Modern Git has better commands than using checkout for everything.
Use switch for branches:
git branch # local branches
git branch -a # local and remote branches
git switch main # switch to existing branch
git switch -c my-feature # create and switch to new branch
git switch - # switch back to previous branch
Create a local branch tracking a remote branch:
git fetch origin
git switch --track origin/my-feature
Push a new branch and set upstream:
git push -u origin my-feature
Rename current branch:
git branch -m new-name
Delete branches:
git branch -d my-feature # delete merged local branch
git branch -D my-feature # force delete local branch
git push origin --delete my-feature
Restoring files
Use restore for files. It is clearer than old checkout usage.
Discard local changes in one file:
git restore file.txt
Unstage a file:
git restore --staged file.txt
Restore a file from another branch:
git restore --source main path/to/file.txt
Restore a file from a specific commit:
git restore --source <commit> path/to/file.txt
Commit history
Basic history:
git log
git log --oneline
git log --oneline --graph --decorate --all
Limit output:
git log --oneline --max-count=20
git log -5
git log --since="2 weeks ago"
git log --oneline v1.0.0..HEAD #Since v1.0.0 till HEAD
git log --after 2023-10-20
git log --after 2.days.ago
git log --after "2014-02-01" --before "2014-02-02"
Show diffs and stats:
git log -p
git log --stat
git log --shortstat
git log --name-only
git log --name-status
Filter by author or message:
git log --author "Alexander"
git log --grep "fix"
History for one file:
git log -- path/to/file.txt
git log -p -- path/to/file.txt
git log --follow -- path/to/file.txt
Find commits that changed a string:
git log -S "someFunction"
git log -G "some.*regex"
-Sfinds commits that added or removed a string-Gsearches changed lines by regex
Show one commit:
git show <commit>
git show --stat <commit>
git show --name-status <commit>
Shortlog
Shortlog can be useful for release notes.
git shortlog # Group commits by author and list commit subjects
git shortlog -s # Show only commit counts per author
git shortlog -sn # Show only commit counts, sorted by highest count first
git shortlog -se # Show counts plus email addresses
More examples with short log
git shortlog v1.0.0..HEAD
git shortlog v1.2.0..v1.3.0 # Release-to-release summary
git shortlog --since="1 month ago" # Human-readable summary for a period
Merging
Update main safely
git switch main
git fetch origin
git pull --ff-only
--ff-only means Git will only move your branch forward if no merge commit is needed. If this fails, stop and inspect instead of blindly merging.
Bring main into your feature branch
For your own local feature branch, rebase is usually cleanest:
git switch feature/my-change
git fetch origin
git rebase origin/main
If conflicts happen:
git status
# edit files
git add fixed-file.txt
git rebase --continue
Abort if needed:
git rebase --abort
Merge feature branch back to main
If the branch is already up to date and you want a linear history:
git switch main
git pull --ff-only
git merge --ff-only feature/my-change
If you intentionally want a merge commit:
git switch main
git pull --ff-only
git merge --no-ff feature/my-change
Merge conflict commands
git status
git diff
# edit conflicted files
git add fixed-file.txt
git merge --continue
Abort a merge:
git merge --abort
Rule of thumb
- Use
rebasefor cleaning up your own local branch. - Do not rebase shared branches unless the team agrees.
- Use
merge --ff-onlywhen you want clean linear history. - Use
merge --no-ffwhen you want to preserve a feature branch as a visible unit. - Never run random
git pullon important branches without knowing your pull strategy.
Stash
Temporarily store local changes:
git stash # Temporarily save your tracked local changes and clean the working directory
git stash push -m "work in progress" # Stash local changes and add a message so you can recognize this stash later
List and inspect stashes:
git stash list # Show all saved stashes, newest first, e.g. stash@{0}, stash@{1}
git stash show # Show a short summary of what changed in the most recent stash
git stash show -p stash@{0} # Show the full patch of stash@{0}, including exact line changes
Apply or remove:
git stash apply # Re-apply the most recent stash, but keep it in the stash list
git stash pop # Re-apply the most recent stash and remove it from the stash list if successful
git stash drop stash@{0} # Delete stash@{0} from the stash list without applying it
Undoing mistakes
Change the last commit message:
git commit --amend
#wuth aliaces
git amend
Add forgotten files to last commit:
git add forgotten-file.txt
git commit --amend --no-edit
Revert a published commit safely:
git revert <commit>
Reset local branch to remote state. Dangerous, but sometimes useful:
git fetch origin
git reset --hard origin/main
Remote cleanup
Fetch and prune deleted remote branches:
git fetch --prune
Show remote branches already merged into main:
git branch -r --merged origin/main
Show local branches already merged into current branch:
git branch --merged
Feedback
Please let me know you find an error.