How to buildOctober 12, 202610 min read
Developer ReferenceStep 2 of 8

Git command reference

In short

Below are the most common Git commands grouped by task: setup, commits, history, branches, merging and rebasing, remotes, undoing changes, stash, tags and search. Each one was run in a real repository on Git 2.55 and 2.54. Dangerous commands (reset --hard, clean -f, forced push) are flagged, next to a safe alternative and a way to recover lost work with git reflog.

ReferenceLevel: BeginnerGit Command Reference

After this you will be able to

  • find the Git command for a common task and know what it changes: the working tree, the index or history
  • choose between git restore, git reset and git revert, and recover a commit or branch with git reflog
  • safely overwrite a remote branch with --force-with-lease and --force-if-includes

Verified with

Git 2.55 (Git for Windows, Git Bash)Git 2.54 (Alpine Linux 3.24)

Checked against docs: October 12, 2026

Contents
  1. 01Setup and creating a repository
  2. 02Changes and commits: status, add, diff, commit
  3. 03History and referring to commits
  4. 04Branches, merging and rebasing
  5. 05Remotes: remote, fetch, pull, push
  6. 06Undoing changes: restore, reset, revert
  7. 07Stash and tags
  8. 08Searching code and history, useful aliases

Setup and creating a repository

git config --global user.name "Name"

What it does
Author name for every new commit on this machine

git config --global user.email "email"

What it does
Author email, recorded in every commit

git config --global init.defaultBranch main

What it does
Name of the first branch in new repositories

git config --list --show-origin

What it does
All effective settings and the file each one comes from

git config user.email

What it does
One setting's value, honouring precedence (repository beats user)

git init

What it does
Empty repository in the current folder (creates .git)

git init -b main my-app

What it does
Repository in my-app with main as the first branch

git clone <url>

What it does
Copy of a remote repository with full history; the remote is named origin

git clone --depth 1 <url>

What it does
Shallow clone: only the latest commit — fast for CI, but no history
terminal
$ git config --global user.name "Ivan Petrov"
$ git config --global user.email "ivan@example.com"
$ git config --global init.defaultBranch main
$ git config --global --list
user.name=Ivan Petrov
user.email=ivan@example.com
init.defaultbranch=main
Real Git 2.55 output. Config key names are case-insensitive, so --list prints them in lowercase.

Changes and commits: status, add, diff, commit

git status

What it does
Current branch, staged and unstaged changes, new files

git status -s

What it does
Short form: ?? new file, A added, M modified; left column is the index, right is the working tree

git add <file> / git add .

What it does
Stage one file / all changes in the current folder (put them in the index)

git add -p

What it does
Stage changes hunk by hunk; Git asks about each one

git diff

What it does
Changes in the working tree not yet in the index

git diff --staged

What it does
What is in the index and will go into the next commit

git commit -m "message"

What it does
Record a commit from the index

git commit -am "message"

What it does
Stage modified and deleted tracked files and commit; new files are not included

git commit --amend -m "…"

What it does
Replace the last commit with a new one (new hash); --no-edit keeps the message

git mv old new

What it does
Rename a file and stage the rename

git rm <file>

What it does
Delete a file from disk and the index

git rm --cached <file>

What it does
Stop tracking a file but keep it on disk
terminal
$ git rm --cached .env
rm '.env'
$ echo ".env" >> .gitignore && git add .gitignore && git commit -m "убрать .env из индекса"
[main 5f95985] убрать .env из индекса
 2 files changed, 1 insertion(+), 1 deletion(-)
 delete mode 100644 .env
$ git log --oneline --all -- .env
5f95985 убрать .env из индекса
192b36f oops env
git rm --cached removes the file from the index, but the commit that added it stays in history (Git 2.55, real output).

History and referring to commits

git log --oneline

What it shows
Current branch history: short hash and subject

git log --oneline --graph --all

What it shows
All branches as a graph — where they diverge and merge

git log -n 2 --stat

What it shows
Last 2 commits with the files they changed

git log -p -1 -- README.md

What it shows
The last commit that touched a file, with its diff

git log --since="2 weeks ago" / --author="Ivan"

What it shows
Commits in a period / by one author

git show HEAD

What it shows
Commit metadata and diff

git show HEAD~1:README.md

What it shows
A file's content at a given version

git diff HEAD~2 HEAD --stat

What it shows
Difference between two commits

HEAD

Meaning
The current commit (tip of the branch you are on)

HEAD~1, HEAD~3

Meaning
The ancestor 1 or 3 commits back

a1b2c3d

Meaning
A commit by hash prefix

main, origin/main, v1.0.0

Meaning
Tip of a branch, a remote-tracking branch or a tag

HEAD@{1}

Meaning
Where HEAD was one move ago — a reflog entry

- in git switch -

Meaning
The previous branch, same as @{-1}
How to refer to a commit in any command

Branches, merging and rebasing

git branch / -v / -vv

What it does
List branches / with last commit / with the upstream branch

git branch -a

What it does
Local and remote-tracking branches

git branch --merged / --no-merged

What it does
Branches already / not yet merged into the current one

git switch -c feature/login

What it does
Create a branch and switch to it

git switch main / git switch -

What it does
Switch to a branch / to the previous one

git switch --detach v1.0.0

What it does
Inspect an old version without a branch (detached HEAD)

git branch -m old new

What it does
Rename a branch

git branch -d name

What it does
Delete a branch only if it is merged; otherwise fails with not fully merged

git branch -D name

What it does
Force-delete a branch — unmerged commits survive only in the reflog

git merge feature

What it does
Merge a branch into the current one: fast-forward if history has not diverged, otherwise a merge commit

git merge --no-ff feature

What it does
Always create a merge commit

git merge --squash feature

What it does
Stage the branch's changes as one set; you commit manually

git merge --abort

What it does
Abort a conflicted merge and return to the previous state

git rebase main

What it does
Replay the current branch's commits on top of main

git rebase --continue / --skip / --abort

What it does
Continue after resolving a conflict / skip the commit / cancel the rebase

git cherry-pick <hash>

What it does
Apply one commit's changes to the current branch

git merge-base main feature

What it does
The common ancestor of two branches
terminal
$ git merge feature/b
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
$ git status -s
UU README.md
$ git merge --abort
$ git status -s
UU marks a conflicted file; after git merge --abort the working tree is clean again (Git 2.55).

Remotes: remote, fetch, pull, push

git remote -v

What it does
List remotes with their URLs

git remote add origin <url>

What it does
Add a remote named origin

git remote set-url origin <url>

What it does
Change the URL (for example, HTTPS to SSH)

git remote rename / git remote remove

What it does
Rename / remove a remote

git remote show origin

What it does
URLs, default branch and branch tracking

git fetch

What it does
Download new commits and update origin/* without touching your branches

git fetch --prune

What it does
Same, and delete origin/* refs for branches gone from the server

git pull

What it does
fetch + merge the remote branch into the current one

git pull --rebase

What it does
fetch + replay your commits on top of the remote ones

git push -u origin feature

What it does
Push a branch and set its upstream — plain git push works afterwards

git push origin --delete feature

What it does
Delete a branch on the server

git push --force-with-lease

What it does
Overwrite the remote branch only if it still matches your origin/branch

git push --force-with-lease --force-if-includes

What it does
Also check that the remote tip is already in your local history
terminal
$ git push
To ../origin.git
 ! [rejected]        feature/push -> feature/push (non-fast-forward)
error: failed to push some refs to '../origin.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. If you want to integrate the remote changes,
hint: use 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
$ git push --force-with-lease
To ../origin.git
 + 1aa6dea...296c1c4 feature/push -> feature/push (forced update)
$ git push --force-with-lease
To ../origin.git
 ! [rejected]        feature/push -> feature/push (stale info)
error: failed to push some refs to '../origin.git'
$ git fetch
From ../origin
   296c1c4..1930d7f  feature/push -> origin/feature/push
$ git push --force-with-lease --force-if-includes
To ../origin.git
 ! [rejected]        feature/push -> feature/push (remote ref updated since checkout)
error: failed to push some refs to '../origin.git'
hint: Updates were rejected because the tip of the remote-tracking branch has
hint: been updated since the last checkout. If you want to integrate the
hint: remote changes, use 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
$ git pull --rebase
warning: skipped previously applied commit 1163d36
hint: use --reapply-cherry-picks to include skipped commits
hint: Disable this message with "git config set advice.skippedCherryPicks false"
Successfully rebased and updated refs/heads/feature/push.
$ git log --oneline -3
1930d7f коммит коллеги
296c1c4 p1 amended
2491c3e feature c (squash)
A plain push is rejected after --amend; --force-with-lease goes through. Then a teammate pushes: the lease is stale (stale info); after git fetch only --force-if-includes still protects their work. git pull --rebase replays your commits on top of theirs — here a commit with identical changes is skipped as already applied. Git 2.55, real output.

Undoing changes: restore, reset, revert

The Git docs separate the three similar commands like this: git restore restores files in the working tree or index and does not touch your branch; git reset moves the branch tip, adding or removing commits, so it changes history; git revert makes a new commit that reverses earlier ones.

Broke a file, not yet added

Command
git restore file
What you can lose
The edits in that file — permanently

Staged something by mistake

Command
git restore --staged file
What you can lose
Nothing: the edits stay on disk

Need a file as it was one commit ago

Command
git restore --source=HEAD~1 file
What you can lose
Current uncommitted edits to that file

Last commit is wrong, keep changes staged

Command
git reset --soft HEAD~1
What you can lose
Nothing

Same, but keep changes unstaged

Command
git reset HEAD~1 (--mixed mode)
What you can lose
Nothing

Throw away a commit and its changes

Command
git reset --hard HEAD~1
What you can lose
Uncommitted edits — permanently; the commit — recoverable via reflog

Undo a commit already on a shared branch

Command
git revert <hash>
What you can lose
Nothing: a new commit is added

Delete untracked files and folders

Command
git clean -n, then git clean -fd
What you can lose
Files Git never tracked — permanently

Get a commit back after reset or branch deletion

Command
git reflog, then git reset --hard HEAD@{1} or git branch name HEAD@{1}
What you can lose
—
terminal
$ git reset --hard HEAD~1
HEAD is now at f325994 README v2
$ git log --oneline -1
f325994 README v2
$ git reflog -3
f325994 HEAD@{0}: reset: moving to HEAD~1
51ed613 HEAD@{1}: commit: s
f325994 HEAD@{2}: reset: moving to HEAD~1
$ git reset --hard HEAD@{1}
HEAD is now at 51ed613 s
$ git log --oneline -1
51ed613 s
Commit “s” disappears after reset --hard and comes back via HEAD@{1} (Git 2.55).
terminal
$ git branch -D experiment
Deleted branch experiment (was 8683c92).
$ git reflog -3
4d41069 HEAD@{0}: checkout: moving from experiment to main
8683c92 HEAD@{1}: commit: важный коммит
4d41069 HEAD@{2}: checkout: moving from main to experiment
$ git branch experiment HEAD@{1}
$ git log --oneline -1 experiment
8683c92 важный коммит
A deleted unmerged branch restored from the reflog (Git 2.55).

Stash and tags

git stash / git stash push -m "note"

What it does
Save working tree and index changes and reset the folder to HEAD

git stash push -u

What it does
Stash untracked files too (without -u they stay put)

git stash list

What it does
List entries: stash@{0} is the newest

git stash show -p stash@{1}

What it does
Diff of one entry

git stash pop

What it does
Apply the latest entry and remove it from the list

git stash apply stash@{0}

What it does
Apply an entry and keep it in the list

git stash drop / git stash clear

What it does
Remove one entry / all — after clear they may be impossible to recover

git stash branch name

What it does
Create a branch from the commit where you stashed and apply the entry there
terminal
$ git status -s
 M README.md
?? new.txt
$ git stash push -m "README в работе"
Saved working directory and index state On main: README в работе
$ git status -s
?? new.txt
$ git stash push -u -m "с новым файлом"
Saved working directory and index state On main: с новым файлом
$ git status -s
$ git stash list
stash@{0}: On main: с новым файлом
stash@{1}: On main: README в работе
$ git stash show -p stash@{1}
diff --git a/README.md b/README.md
index 8c1384d..960c312 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
 v2
+wip
stash push without -u leaves the untracked new.txt alone; with -u it stashes it too (Git 2.55).

git tag -a v1.0.0 -m "Release 1.0.0"

What it does
Annotated tag: a separate object with tagger, date and message

git tag v1.0.0-light

What it does
Lightweight tag: just a name for a commit, no metadata

git tag / git tag -l "v1.*"

What it does
List tags / by pattern

git tag -a v0.9.0 <hash> -m "…"

What it does
Tag an older commit

git show v1.0.0

What it does
The tag and the commit it points to

git describe --tags

What it does
The nearest tag to the current commit

git push origin v1.0.0

What it does
Push one tag — a plain push does not send tags

git push --tags

What it does
Push all tags, lightweight ones included

git tag -d v1.0.0 + git push origin --delete v1.0.0

What it does
Delete a tag locally and on the server

Searching code and history, useful aliases

git grep -n "login"

What it finds
Matching lines in tracked files, with line numbers

git grep -n "TODO" -- "*.js"

What it finds
Search only JS files

git grep -n "hello" HEAD~10

What it finds
Search an old version of the project

git log -S "TODO"

What it finds
Commits that changed the number of occurrences of a string (added or removed it)

git log -G "log[a-z]+"

What it finds
Commits whose diff adds or removes lines matching a regex

git log --grep="login"

What it finds
Commits by message text

git log --follow -- NOTES.md

What it finds
One file's history across renames

git blame -L 1,2 app.js

What it finds
Who last changed lines 1–2, and in which commit

git bisect start / good / bad / reset

What it finds
Binary search for the commit that introduced a bug

git bisect run <command>

What it finds
The same search, driven by a check's exit code
terminal
$ git bisect start
status: waiting for both 'good' and 'bad' commits
$ git bisect bad
status: waiting for 'good' commit(s), 'bad' commit known
$ git bisect good 30123dd
Bisecting: 2 revisions left to test after this (roughly 2 steps)
[36b20e49ded793693f5c6c67c4d53a53f72b71d3] step 3
$ git bisect run sh -c 'grep -q BUG app.js && exit 1 || exit 0'
running 'sh' '-c' 'grep -q BUG app.js && exit 1 || exit 0'
Bisecting: 0 revisions left to test after this (roughly 1 step)
[223f3766298e0d51da290d36d09dc63a584e3b2c] step 5
running 'sh' '-c' 'grep -q BUG app.js && exit 1 || exit 0'
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[d592b5894f4f1a07a1306c0e68cba1fc3cfe304a] step 4
running 'sh' '-c' 'grep -q BUG app.js && exit 1 || exit 0'
d592b5894f4f1a07a1306c0e68cba1fc3cfe304a is the first 'bad' commit
commit d592b5894f4f1a07a1306c0e68cba1fc3cfe304a
Author: Ivan Petrov <ivan@example.com>
Date:   Sun Oct 11 10:00:00 2026 +0500

    step 4

 app.js | 1 +
 1 file changed, 1 insertion(+)
bisect found first 'bad' commit
$ git bisect reset
Previous HEAD position was d592b58 step 4
Switched to branch 'main'
Your branch is ahead of 'origin/main' by 7 commits.
  (use "git push" to publish your local commits)
git bisect run: exit code 0 means good, 1–127 (except 125) means bad. Git 2.55, real output.

Aliases shorten long commands. Pro Git sets them up with git config --global alias.<name>; below is a tested set that does not change Git's behaviour, only adds short names.

bash
git config --global alias.st 'status -sb'
git config --global alias.lg 'log --oneline --graph --decorate --all'
git config --global alias.last 'log -1 HEAD --stat'
git config --global alias.unstage 'restore --staged --'
git config --global alias.amend 'commit --amend --no-edit'
git config --global alias.undo 'reset --soft HEAD~1'
Aliases are written to your user config (~/.gitconfig).
terminal
$ git st
## main...origin/main [ahead 7]
A  z.txt
$ git unstage z.txt
$ git st
## main...origin/main [ahead 7]
?? z.txt
$ git commit -m "z"
[main 76c953c] z
 1 file changed, 1 insertion(+)
 create mode 100644 z.txt
$ git undo
$ git st
## main...origin/main [ahead 7]
A  z.txt
Aliases at work: unstage removes a file from the index, undo drops the last commit (Git 2.55).

How Git works under the hood and why these commands behave as they do is covered in the lesson “Git from scratch: commits, branches, merging”; forks, review and merging on GitHub are in “GitHub: fork, pull request and code review”.

How this was verified4 · passedchecked 12 October 2026

“Run” means the code was executed in a scratch project or container and the output in the article comes from that run. “Partial” means it was checked against stubs instead of external services. “Not run” means it needs a device, an account or a key; the steps were checked against the official documentation. The verification project files and run logs are kept in the InterLAB archive.

Tell us about your task — we'll review your request and get back to you

Got a project?
We'll scope and estimate it — for free.

Tell us about the product or the problem. After reviewing the task we'll come back with an architecture, a timeline and a price for the first version.

  • Scope and risks estimated before we start
  • NDA — yours or ours
  • Work starts within a week

Please do not send passwords, access keys or source code through this form — we will agree a safe way to share access separately.

By clicking the button you agree to the processing of your personal data.