New to Rust? Grab our free Rust for Beginners eBook Get it free →
Git Commands: The complete list every developer needs (with examples)

Git commands are the interface between you and every version control operation you run, from staging a single file to rewriting years of commit history. This guide covers every git command you will realistically use, grouped by what you are trying to do, with the exact syntax and a short explanation for each one. No fluff, no filler, just the commands.
Setting up and configuring git
Before you track a single file, git needs to know who you are and where your project lives. These commands run once per machine or once per project, not daily.
git config
git config sets configuration values at the system, global or local (per-repository) level. At minimum, set your name and email since git attaches both to every commit.
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
git config --global core.editor "code --wait"
git config --list
Global settings apply to every repository under your user account. Drop --global and run the same command inside a repo to override it for that project only, which is useful for a work identity that should not leak into personal projects.
git init
git init turns the current folder into a git repository by creating a hidden .git directory that stores all history, refs and configuration.
git init
git init -b main
The -b flag sets the initial branch name at creation time, which matters since git no longer defaults to master on most fresh installs.
git clone
git clone copies an entire remote repository, including its full commit history, to your local machine in one command.
git clone https://github.com/user/project.git
git clone https://github.com/user/project.git -b develop
Passing -b checks out a named branch immediately instead of the default branch, which saves a separate git switch call right after cloning.
git version
git version prints the installed Git release, which is worth checking before you rely on a flag that only exists in newer builds.
git version
Some flags used later in this guide, like git switch and git restore, only exist from Git 2.23 onward, so an outdated install is a common source of “command not found” confusion.
git help
git help opens the manual page for any git command directly in your terminal or browser, which beats searching the web for basic flag syntax.
git help commit
git help -a
The -a flag lists every git command available on your system, including plumbing commands most developers never touch directly.
Staging and committing changes
This is the loop you repeat dozens of times a day. Modify a file, stage it, commit it. These git commands manage that cycle.
git status
git status shows which files are modified, staged or untracked in your working directory, and it is the command you should run before every commit.
git status
git status -s
The -s flag switches to a short, single-letter format per file that scans faster once you know the codes (M for modified, A for added, ?? for untracked).
git add
git add moves changes from your working directory into the staging area, which is the snapshot git uses for your next commit.
git add filename.txt
git add .
git add -p
git add . stages everything in the current directory. The -p flag, short for patch mode, lets you review and stage individual hunks inside a file instead of the whole thing, which keeps unrelated changes out of the same commit.
git rm
git rm deletes a file from both your working directory and the staging area in one step, which is different from manually deleting the file and then running git add.
git rm old-file.js
git rm --cached config.env
The --cached flag removes a file from git tracking while leaving it on disk, which is exactly what you want after accidentally committing a file that belongs in .gitignore.
git mv
git mv renames or moves a tracked file and stages the change in a single command instead of a manual rename followed by two separate add and rm steps.
git mv old-name.js new-name.js
git detects renames automatically even without this command, but using it keeps the operation explicit in your next commit.
git commit
git commit takes everything in the staging area and records it as a permanent snapshot in your project history, along with a message explaining the change.
git commit -m "Fix null pointer in payment validation"
git commit -am "Update login form styles"
The -a flag automatically stages all tracked, modified files before committing, skipping a separate git add step. It will not pick up new untracked files, so you still need git add for those.
git commit –amend
git commit –amend rewrites the most recent commit instead of creating a new one, which is useful for fixing a typo in the message or adding a file you forgot to stage.
git commit --amend -m "Corrected commit message"
git commit --amend --no-edit
--no-edit keeps the original message and only updates the file contents. Avoid amending a commit that has already been pushed to a shared branch, since it rewrites history other people may have already pulled.
Branching, switching and merging
Branches let you isolate work without touching the main line of development. These git commands create, move between and combine them.
git branch
git branch lists, creates, renames or deletes branches, and it is your general-purpose branch administration tool.
git branch
git branch feature-login
git branch -d old-feature
git branch -D broken-experiment
git branch -m new-name
-d is a safe delete that refuses to remove a branch with unmerged commits. -D forces the deletion regardless, which throws away any work that only exists on that branch.
git checkout
git checkout switches between branches and can also restore individual files to a previous state, which is exactly the dual purpose that led git to split its responsibilities into git switch and git restore in newer versions.
git checkout main
git checkout -b new-feature
git checkout -- file.js
-b creates a new branch and switches to it in one step. The -- file.js form discards local changes to that single file, which is one of two jobs this command still quietly handles.
git switch
git switch is the modern, narrower replacement for the branch-switching half of git checkout, introduced specifically to remove the ambiguity of a command that did two unrelated things.
git switch main
git switch -c new-branch
-c creates and switches to a new branch, mirroring checkout -b. Reach for switch over checkout going forward since it cannot accidentally discard file changes the way checkout can.
git merge
git merge combines the commit history of one branch into another, either as a fast-forward when no divergence exists or as a three-way merge with a dedicated merge commit when both branches have new work.
git switch main
git merge feature-login
git merge --abort
If the merge produces conflicting changes in the same lines, git pauses and asks you to resolve them manually before committing the result. --abort cancels the whole operation and returns you to the state before the merge started.
git rebase
git rebase replays the commits from your current branch on top of another branch’s tip instead of creating a merge commit, which produces a linear, easier-to-read history.
git rebase main
git rebase -i HEAD~5
The -i flag starts an interactive rebase where you can squash, reorder, edit or drop individual commits before they become part of shared history. Never rebase commits that have already been pushed to a branch other people are using, since it rewrites their SHA hashes.
git tag
git tag marks one exact commit, almost always a release, with a fixed, memorable name instead of a long commit hash.
git tag v2.1.0
git tag -a v2.1.0 -m "Release 2.1.0"
git push origin v2.1.0
Lightweight tags, the plain form above, are just a pointer to a commit. Annotated tags, created with -a, also store the tagger’s name, date and message, and most release workflows use the annotated form.
Working with remote repositories
Collaboration means syncing your local history with a server. These git commands handle that connection.
git remote
git remote manages the named connections between your local repository and remote servers like GitHub or GitLab.
git remote -v
git remote add origin https://github.com/user/repo.git
git remote remove old-origin
-v shows the fetch and push URLs for every configured remote. origin is the conventional alias for the primary remote, but you can name it anything.
git fetch
git fetch downloads new commits, branches and tags from a remote without touching your current working files, giving you a chance to inspect changes before merging them.
git fetch origin
git fetch --all
This is the non-destructive sibling of git pull. Run it whenever you want to see what changed upstream without committing to integrating it yet.
git pull
git pull is git fetch and git merge combined into one step, downloading remote changes and immediately merging them into your current branch.
git pull origin main
git pull --rebase
The --rebase flag replays your local commits on top of the fetched changes instead of creating a merge commit, which keeps history linear on branches multiple people push to regularly.
git push
git push uploads your local commits to a remote repository so your team can see and build on them.
git push origin main
git push -u origin feature-branch
git push --force-with-lease
-u sets the upstream tracking relationship for a new branch, after which plain git push works without specifying the remote or branch name. --force-with-lease is a safer alternative to a raw force push, since it refuses to overwrite the remote branch if someone else has pushed commits since your last fetch.
Inspecting history and comparing changes
When something breaks, these git commands help you figure out what changed, when and by whom.
git log
git log shows the commit history of your current branch, including the author, date, message and commit hash for every entry.
git log
git log --oneline
git log --oneline --graph --all
git log -p -- src/api/handler.js
--oneline compresses each commit to a single line. Adding --graph --all renders an ASCII visualization of how branches diverged and merged, which is the fastest way to understand a tangled history without a GUI. The -p flag with a file path shows the full patch history for that one file.
git show
git show displays the full detail of a single commit, including its metadata and the actual diff it introduced.
git show abc1234
git show HEAD~3
Use it when git log tells you a commit exists but you need to see exactly what changed inside it.
git diff
git diff shows line-by-line differences between different states of your repository, and which states depends entirely on the flags you pass.
git diff
git diff --staged
git diff main..feature-branch
git diff commit1 commit2
Without arguments, it compares your working directory against the staging area. --staged compares the staging area against your last commit. Passing two branch or commit names compares those directly.
git blame
git blame annotates every line of a file with the commit and author who last modified it, which is the fastest way to find out who wrote a given line and why.
git blame src/utils/validate.js
Combine this with git show on the commit hash it reveals to read the full context behind that change.
git shortlog
git shortlog summarizes commit history by author instead of listing every commit individually, which is useful for a quick contribution overview.
git shortlog -s -n
-s shows commit counts only, and -n sorts the output by that count instead of alphabetically by author.
Undoing and recovering changes
Mistakes are part of daily development. These git commands give you several ways to fix them, ranging from gentle to destructive.
git reset
git reset moves your branch pointer to a different commit and optionally changes what happens to your staging area and working directory, depending on which mode you use.
git reset HEAD~1
git reset --soft HEAD~1
git reset --hard HEAD~1
--soft undoes the commit but keeps everything staged, ready to recommit. The default, mixed mode, unstages the changes but leaves them in your working directory. --hard throws away the commit and all its changes completely, so use it only when you are certain you do not need that work.
git revert
git revert creates a brand new commit that undoes the changes from a specified earlier commit, without touching or removing that original commit from history.
git revert abc1234
This is the safe way to undo something that has already been pushed to a shared branch, since it never rewrites existing history the way git reset can.
git restore
git restore is the modern, narrower replacement for the file-restoring half of git checkout, handling working directory and staging area changes without any risk of accidentally switching branches.
git restore file.js
git restore --staged file.js
Plain git restore discards unstaged changes in your working directory. Adding --staged unstages a file without touching its actual contents on disk.
git clean
git clean removes untracked files from your working directory, which is the logical counterpart to git reset since reset only ever touches tracked files.
git clean -n
git clean -fd
Always run -n first for a dry run that shows exactly what would be deleted. The -f flag is required to actually delete anything, since git deliberately forces you to be explicit about destructive action, and -d extends the cleanup to untracked directories as well as files.
git reflog
git reflog shows a log of every place your HEAD pointer has been, including commits, checkouts, resets and rebases, which makes it your safety net when something above goes wrong.
git reflog
git reset --hard abc1234
If a bad rebase or a hard reset makes a commit look lost, git reflog almost always still has a reference to it. Find the commit hash in the reflog output and reset back to it to recover the work.
Temporarily storing changes with git stash
Sometimes you need to switch context without committing half-finished work. git stash shelves your changes so you can come back to them later.
git stash
git stash saves all your modified and staged changes onto a stack and resets your working directory to match the last commit, giving you a clean slate to switch branches or pull updates.
git stash
git stash save "wip: login form validation"
Adding a message with save makes an individual stash easier to identify later if you end up with more than one on the stack.
git stash list
git stash list shows every stash you currently have saved, indexed from most recent to oldest.
git stash list
Entries appear as stash@{0}, stash@{1} and so on, with stash@{0} always being the most recently created one.
git stash pop
git stash pop reapplies the most recent stash to your working directory and removes it from the stash stack in the same step.
git stash pop
git stash pop stash@{2}
Pass a named stash reference if you want to restore something other than the top of the stack, which is common once you have stashed changes from more than one branch.
git stash drop
git stash drop deletes a stash entry without applying it, which is useful for cleaning up stashes you decided you no longer need.
git stash drop stash@{1}
Unlike pop, drop never touches your working directory, it only removes the entry from the stack.
Advanced and power-user commands
You will not use these git commands daily, but each one solves a problem nothing else handles as well.
git cherry-pick
git cherry-pick applies a single commit from one branch onto your current branch without merging the entire branch history, which is exactly what you want for backporting one fix to a release branch.
git cherry-pick abc1234
Git creates a new commit on your current branch with the same changes and message as the original, but with a different commit hash.
git bisect
git bisect performs a binary search through your commit history to find the exact commit that introduced a bug, which is dramatically faster than checking commits one at a time.
git bisect start
git bisect bad HEAD
git bisect good v2.0.0
git bisect reset
After marking one known-bad and one known-good commit, git checks out the midpoint for you to test. You report good or bad after each check, and git narrows the range until it lands on the exact commit responsible. bisect reset returns you to your original branch once you are done.
git worktree
git worktree creates an additional working directory linked to the same repository, letting you have two branches checked out simultaneously in separate folders instead of stashing and switching.
git worktree add ../hotfix-branch hotfix/critical-fix
git worktree list
git worktree remove ../hotfix-branch
This is a genuine time saver during an urgent hotfix, since you can keep your feature branch’s half-finished work untouched in one folder while you fix and test the hotfix in another.
git grep
git grep searches the contents of tracked files, and it runs faster than a system-level grep since it operates directly on git’s internal object data instead of the filesystem.
git grep "TODO" -- "*.js"
git grep -n "deprecated" HEAD~10
You can search across chosen commits or historical states, not just your current working directory, which regular grep cannot do at all.
git rerere
git rerere, short for reuse recorded resolution, remembers how you resolved a merge conflict and automatically reapplies that same resolution if the identical conflict shows up again.
git config --global rerere.enabled true
This is genuinely useful on long-lived branches that get rebased or merged repeatedly against the same target, since it stops you from resolving the same conflict by hand every single time.
Ignoring files with .gitignore
Not every file in a project belongs in version control. Build output, dependency folders like node_modules and local environment files should stay out of git entirely, and a .gitignore file handles that automatically.
logs/
*.env
node_modules/
Save patterns like these as a plain text file named .gitignore in your project root, using direct string matches or wildcard globs. Any file matching a pattern gets skipped by git status and git add automatically, so it never shows up as untracked clutter. If you manage a large dependency tree in a JavaScript project, it is worth checking exactly what npm packages are currently installed before deciding what belongs in the ignore list versus what should actually be uninstalled from the project entirely.
For a repository-wide pattern that applies across every project on your machine, set a global ignore file instead of repeating the same entries in every .gitignore:
git config --global core.excludesfile ~/.gitignore_global
Git commands cheat sheet
A quick reference table for the commands covered above, grouped the same way.
| Category | Command | What it does |
|---|---|---|
| Setup | git init | Create a new repository |
| Setup | git clone | Copy a remote repository locally |
| Setup | git config | Set user identity and preferences |
| Staging | git status | Show working directory state |
| Staging | git add | Stage changes for commit |
| Staging | git commit | Record staged snapshot |
| Branching | git branch | List, create or delete branches |
| Branching | git switch / checkout | Change branches |
| Branching | git merge | Combine branch histories |
| Branching | git rebase | Replay commits on a new base |
| Remote | git remote | Manage remote connections |
| Remote | git fetch | Download without merging |
| Remote | git pull | Fetch and merge in one step |
| Remote | git push | Upload local commits |
| Inspecting | git log | View commit history |
| Inspecting | git diff | Show line-by-line changes |
| Inspecting | git blame | See who changed each line |
| Undoing | git reset | Move HEAD, optionally discard changes |
| Undoing | git revert | Undo a commit with a new commit |
| Undoing | git restore | Discard working directory changes |
| Undoing | git reflog | Recover lost commits |
| Advanced | git stash | Temporarily shelve changes |
| Advanced | git cherry-pick | Apply one commit to another branch |
| Advanced | git bisect | Binary search for a bug |
| Advanced | git worktree | Multiple working directories at once |
If you work across Windows, macOS and Linux machines, note that the terminal you run these commands in differs by platform even though git itself behaves the same way everywhere. It is worth knowing the equivalent native command line tools on Windows if you regularly switch between a Windows dev box and a Unix-based server or CI environment. And if you rely on AI-assisted coding tools alongside git, setting up GitHub Copilot in VS Code pairs naturally with the commit and branch workflow covered here, since Copilot can draft commit messages and explain diffs directly inside the same editor you run these commands from. Before you start a new project, it is also worth confirming which Node.js version is active on your machine, since a mismatched runtime is a common source of confusing errors that have nothing to do with git itself.
Frequently asked questions
What is the difference between git pull and git fetch?
git fetch downloads remote changes without touching your local branches. git pull does the same download and then immediately merges or rebases those changes into your current branch.
When should I use git rebase instead of git merge?
Use rebase for a clean, linear history on a private feature branch. Use merge when you want an explicit record of when two branches were integrated, especially on shared branches.
How do I undo my last commit without losing the changes?
Run git reset –soft HEAD~1 to undo the commit while keeping everything staged, ready to commit again with a corrected message or content.
What is the difference between git reset and git revert?
git reset moves your branch pointer and can rewrite history, which is unsafe once pushed. git revert creates a new commit that undoes changes safely, without touching existing history.
How do I recover a commit I think I lost?
Run git reflog to see every place HEAD has pointed recently, find the commit hash you need, then run git reset –hard on that hash to return to it.
What is the difference between git checkout and git switch?
git checkout historically handled both branch switching and file restoration, which caused confusion. git switch only switches branches, splitting checkout’s old dual role into one clearer command.
How do I stop tracking a file without deleting it?
Run git rm –cached filename to remove it from git tracking while leaving the actual file untouched on your disk, then add it to .gitignore so it does not get re-added later.




