git config --global user.name "Your Name"
git config --global user.email "[email protected]"
Sets the name and email attached to every commit. Use --global for all repos or omit it for per-repo config.
git config --global init.defaultBranch main
Sets the default branch name for new repositories to "main" instead of "master".
git config --global core.editor "code --wait"
Sets VS Code as the default editor for commit messages and interactive operations. Replace with vim, nano, or your preferred editor.
git config --global color.ui auto
Enables colored output in all git commands for better readability.
git config --list --show-origin
Shows all git config settings and which file each setting comes from.
git init
Creates a new git repository in the current directory. Run this once at the start of every new project.
git clone https://github.com/user/repo.git
git clone [email protected]:user/repo.git # SSH
Downloads a repository and its full history. Creates a directory with the repo name.
git status
git status -s # short format
Shows which files are modified, staged, or untracked. Run this constantly -- it is your compass.
git add filename.js
git add src/
git add .
Moves changes to the staging area. git add . stages everything. Prefer adding specific files to avoid committing sensitive files.
git commit -m "Add user authentication"
git commit # opens editor for longer message
Records the staged snapshot permanently. Write clear, descriptive messages in imperative mood ("Add feature" not "Added feature").
git commit -am "Fix login validation bug"
Stages all modified tracked files and commits them. Does not include new untracked files -- use git add for those first.
git branch
git branch -a # include remote branches
git branch -v # show last commit on each
Lists all local branches. The current branch is marked with an asterisk.
git branch feature/user-auth
git checkout -b feature/user-auth # create and switch
git switch -c feature/user-auth # modern syntax
Creates a new branch from the current HEAD. Use -b or -c to create and switch in one command.
git checkout main
git switch main # modern syntax
Switches your working directory to another branch. Use git switch (Git 2.23+) for clearer intent.
git branch -d feature/user-auth # safe delete (merged only)
git branch -D feature/user-auth # force delete
git push origin --delete feature/user-auth # delete remote branch
The -d flag only deletes branches that have been merged. Use -D to force-delete unmerged branches.
git branch -m old-name new-name
git branch -m new-name # rename current branch
Renames a branch locally. Push the new name and delete the old remote branch to rename on the remote.
git merge feature/user-auth
git merge --no-ff feature/user-auth # force merge commit
Merges the specified branch into the current branch. --no-ff creates a merge commit even for fast-forward merges, preserving branch history.
git merge --abort
Cancels a merge in progress and restores the pre-merge state. Use this when you encounter conflicts you are not ready to resolve.
git rebase main
Replays your branch's commits on top of the target branch. Creates a linear history. Never rebase commits that have been pushed to a shared branch.
git rebase -i HEAD~3 # rebase last 3 commits
Opens an editor where you can reorder, squash, edit, or drop commits. Essential for cleaning up commit history before creating a pull request.
git remote add origin https://github.com/user/repo.git
Connects your local repo to a remote repository. "origin" is the conventional name for the primary remote.
git remote -v
Lists all configured remotes with their URLs for fetch and push operations.
git push origin main
git push -u origin feature/new # set upstream and push
git push # after upstream is set
Uploads commits to the remote. -u sets the upstream tracking relationship so future pushes only need git push.
git pull
git pull --rebase # rebase instead of merge
Fetches and merges remote changes. --rebase puts your local commits on top of the remote changes for a cleaner history.
git fetch origin
git fetch --all # fetch from all remotes
Downloads remote changes without modifying your working directory. Use this to see what has changed before deciding to merge or rebase.
git stash
git stash -m "WIP: user validation"
git stash -u # include untracked files
Saves uncommitted changes to a stack so you can switch branches cleanly. Add -m for a descriptive message and -u to include new files.
git stash pop # apply and remove from stack
git stash apply # apply but keep in stack
git stash apply stash@{2} # apply specific stash
Restores stashed changes. pop removes the stash after applying; apply keeps it for later.
git stash list
git stash show -p stash@{0} # show diff
git stash drop stash@{0} # delete specific stash
git stash clear # delete all stashes
View, inspect, and clean up your stash stack.
git restore --staged filename.js
git reset HEAD filename.js # older syntax
Removes a file from the staging area without discarding changes. The file remains modified in your working directory.
git restore filename.js
git checkout -- filename.js # older syntax
Discards all uncommitted changes to a file, reverting it to the last committed state. This is irreversible.
git reset --soft HEAD~1 # keep staged
git reset HEAD~1 # keep unstaged (mixed)
Moves HEAD back one commit. --soft keeps changes staged. Default (mixed) keeps changes but unstages them. Both are safe for unpushed commits.
git reset --hard HEAD~1
Moves HEAD back one commit and discards all changes. This is destructive and irreversible. Only use for unpushed commits.
git revert abc1234
git revert HEAD # revert the latest commit
Creates a new commit that undoes the specified commit's changes. Safe for pushed commits because it does not rewrite history.
git commit --amend -m "Updated commit message"
git commit --amend --no-edit # add staged changes to last commit
Modifies the most recent commit. Use for fixing typos in commit messages or adding forgotten files. Do not amend pushed commits.
git log
git log --oneline # compact format
git log --oneline --graph --all # visual branch graph
git log --author="Name" # filter by author
git log -5 # last 5 commits
The --oneline --graph --all combination is the most useful for understanding branch structure.
git diff # unstaged changes
git diff --staged # staged changes
git diff main..feature # between branches
git diff HEAD~3 # last 3 commits
Shows line-by-line differences. Install delta for syntax-highlighted diffs.
git show abc1234
git show HEAD # latest commit
Displays the commit message and diff for a specific commit.
git blame filename.js
git blame -L 10,20 filename.js # lines 10-20
Shows the author and commit for each line of a file. Essential for understanding why code was written a certain way.
git log --grep="fix login"
Searches commit messages for a string. Case-insensitive with --grep="pattern" -i.
git cherry-pick abc1234
Applies a specific commit from another branch to your current branch. Useful for backporting bug fixes.
git bisect start
git bisect bad # current commit is bad
git bisect good abc1234 # this commit was good
Binary searches through commit history to find which commit introduced a bug. Git checks out commits for you to test, narrowing down the culprit in O(log n) steps.
git clean -n # dry run (show what would be deleted)
git clean -fd # delete untracked files and directories
Removes untracked files. Always run with -n first to preview. Add -x to also remove files in .gitignore.
git worktree add ../hotfix hotfix-branch
Creates a separate working directory for another branch without switching branches. Work on a hotfix in one directory while your feature branch stays untouched in another.
git rebase -i HEAD~3
Opens interactive rebase. Change "pick" to "squash" (or "s") on commits you want to combine. Write a new commit message for the squashed result. Clean up messy commit history before merging.
Add these to your ~/.gitconfig under [alias] to save keystrokes:
[alias] s = status -s co = checkout br = branch ci = commit lg = log --oneline --graph --all --decorate last = log -1 HEAD --stat unstage = restore --staged undo = reset HEAD~1 amend = commit --amend --no-edit wip = !git add -A && git commit -m "WIP" branches = branch -a -v stashes = stash list contributors = shortlog -sn
With these aliases, git s shows status, git lg shows a visual branch graph, and git undo reverts the last commit while keeping changes.
git switch -c feature/new-feature # create feature branch # ... make changes ... git add . git commit -m "Add new feature" git push -u origin feature/new-feature # Create Pull Request on GitHub # After review and merge, clean up: git switch main git pull git branch -d feature/new-feature
git switch main git pull git switch -c hotfix/critical-bug # ... fix the bug ... git commit -am "Fix critical login bug" git push -u origin hotfix/critical-bug # Create PR, merge, then: git switch main git pull git branch -d hotfix/critical-bug
git remote add upstream https://github.com/original/repo.git git fetch upstream git switch main git merge upstream/main git push origin main
Check out our Best Terminal Apps and Best VS Code Extensions guides.
Browse All Free ToolsGit merge creates a new merge commit that combines two branches, preserving the complete history. Git rebase replays your commits on top of another branch, creating a linear history. Use merge for shared branches to preserve context. Use rebase for feature branches before merging to keep history clean. Never rebase commits that have been pushed to a shared branch.
To undo the last commit but keep changes staged: git reset --soft HEAD~1. To undo and unstage: git reset HEAD~1. To completely discard: git reset --hard HEAD~1. If already pushed, use git revert HEAD to create a new commit that safely undoes the changes.
Git stash temporarily saves uncommitted changes so you can switch branches without committing work in progress. Use git stash to save, git stash pop to restore, and git stash list to see all stashes. It is useful when you need to quickly switch context.
Open conflicted files and look for markers (<<<<<<, =======, >>>>>>). Edit to keep the code you want, remove the markers, then git add the resolved file and git commit. VS Code and lazygit have visual conflict resolvers that simplify this process.
SSH is recommended for frequent pushers -- set up a key once and never enter credentials again. HTTPS is simpler initially and works behind restrictive firewalls. For most developers, SSH with an ed25519 key is the best long-term choice.
Follow @SpunkArt13 for daily developer tips, free tools, and build-in-public updates.