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.
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 resetandgit revert, and recover a commit or branch withgit reflog - safely overwrite a remote branch with
--force-with-leaseand--force-if-includes
Know beforehand
Verified with
Git 2.55 (Git for Windows, Git Bash)Git 2.54 (Alpine Linux 3.24)
Checked against docs: October 12, 2026
Contents
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-appwithmainas 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
$ 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--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,Aadded,Mmodified; 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-editkeeps 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
$ 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 envgit 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
HEADwas one move ago — a reflog entry
- in git switch -
- Meaning
- The previous branch, same as
@{-1}
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
$ 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 -sUU 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 pushworks 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
$ 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)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(--mixedmode)- 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, thengit clean -fd- What you can lose
- Files Git never tracked — permanently
Get a commit back after reset or branch deletion
- Command
git reflog, thengit reset --hard HEAD@{1}orgit branch name HEAD@{1}- What you can lose
- —
$ 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 sreset --hard and comes back via HEAD@{1} (Git 2.55).$ 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 важный коммит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
-uthey 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
clearthey 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
$ 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
+wipstash 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
pushdoes 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
$ 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.
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'~/.gitconfig).$ 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.txtunstage 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.