Back to Blog
GitVersion ControlCLI

Git Commands Every Developer Must Know

April 18, 2026 · 9 min read

Git is the version control system that underpins nearly all modern software development. Yet many developers only know a handful of commands and reach for a GUI when things get complicated. This guide covers the commands you will use every day — and the ones you wish you had known earlier.

Repository Setup

git init

Create a new Git repository in the current directory. This adds a hidden .git folder that tracks all changes.

git init                    # initialise in current dir
git init my-project         # create new dir and initialise

git clone

Copy a remote repository to your local machine. You get the full history, all branches, and a configured remote called origin.

git clone https://github.com/user/repo.git
git clone git@github.com:user/repo.git  # SSH
git clone <url> my-folder               # clone into custom folder

Staging and Committing

Git has a two-step save process: you first stage changes (add them to the index), then commit them to history. This lets you bundle related changes into one logical commit even when you have edits across many files.

git add

git add file.txt          # stage a specific file
git add src/              # stage a directory
git add .                 # stage everything in current dir
git add -p                # interactively pick hunks to stage

git add -p is one of the most underused commands. It walks you through each changed chunk so you can split a messy working directory into clean, focused commits.

git commit

git commit -m "Add login endpoint"
git commit                        # opens editor for longer message
git commit --amend                # edit the last commit (before pushing)
git commit -am "Fix typo"         # stage tracked files and commit in one step

Branching

Branches are lightweight pointers to commits. Creating a branch is instant and costs almost nothing — use them freely.

git branch                        # list local branches
git branch -a                     # list all branches including remote
git branch feature/login          # create a branch
git switch feature/login          # switch to it (modern syntax)
git switch -c feature/signup      # create and switch in one step
git branch -d feature/login       # delete (safe — warns if unmerged)
git branch -D feature/login       # force delete

Merging and Rebasing

git merge

Merging joins two branches by creating a new merge commit. It preserves the full history of both lines of work.

git switch main
git merge feature/login           # merge feature into main
git merge --no-ff feature/login   # always create a merge commit
git merge --abort                 # abort a conflicted merge

git rebase

Rebasing replays your commits on top of another branch, producing a linear history. Never rebase commits that have already been pushed to a shared remote — it rewrites history and will cause problems for your teammates.

git rebase main               # replay current branch on top of main
git rebase -i HEAD~3          # interactive rebase: squash, reorder, edit last 3 commits
git rebase --abort            # abort an in-progress rebase

Stashing

Stash saves your uncommitted changes to a temporary stack so you can switch branches without losing work.

git stash                     # stash tracked changes
git stash push -u             # also stash untracked files
git stash list                # view all stashes
git stash pop                 # apply most recent stash and remove it
git stash apply stash@{2}     # apply a specific stash without removing
git stash drop stash@{0}      # delete a specific stash

Viewing History

git log                       # full log
git log --oneline --graph     # compact graph view
git log -p                    # show diff for each commit
git log --author="Alice"      # filter by author
git log --since="2 weeks ago"
git log -- path/to/file       # commits that changed a specific file
git show abc1234              # show a specific commit

Undoing Things

git restore

Discard changes in the working tree without touching the staging area.

git restore file.txt          # discard working tree changes
git restore --staged file.txt # unstage a file

git reset

git reset HEAD~1              # undo last commit, keep changes staged
git reset --soft HEAD~1       # undo commit, keep changes staged
git reset --hard HEAD~1       # undo commit and discard all changes (destructive)

git revert

The safe way to undo a pushed commit. It creates a new commit that reverses the changes, leaving history intact.

git revert abc1234            # create a revert commit for a specific commit

Working with Remotes

git remote -v                 # list remotes
git remote add origin <url>   # add a remote
git fetch origin              # download remote changes without merging
git pull                      # fetch + merge
git pull --rebase             # fetch + rebase (cleaner history)
git push origin feature/x     # push a branch
git push -u origin main       # set upstream and push

Useful Everyday Commands

git status                    # see what has changed
git diff                      # diff of unstaged changes
git diff --staged             # diff of staged changes
git blame file.txt            # who changed each line
git bisect start              # binary search for the commit that introduced a bug
git cherry-pick abc1234       # apply a commit from another branch

Git Config Essentials

git config --global user.name "Alice"
git config --global user.email "alice@example.com"
git config --global core.editor "vim"
git config --global alias.lg "log --oneline --graph --all"
git config --list             # show all config values

Mastering Git is less about memorising every flag and more about understanding the underlying model: commits form a directed acyclic graph, branches are moveable pointers, and the staging area is your friend. Use the Compare tool on io9.me to diff any two files before committing.