Ниже — частые команды Git, сгруппированные по задачам: настройка, коммиты, история, ветки, слияние и rebase, удалённые репозитории, отмена изменений, stash, теги и поиск. Каждая выполнена в реальном репозитории на Git 2.55 и 2.54. Опасные команды (reset --hard, clean -f, принудительный push) помечены, рядом — безопасная альтернатива и способ вернуть потерянное через git reflog.
После материала вы сможете
- найти команду Git для типовой задачи и понять, что она меняет: рабочую папку, индекс или историю
- выбрать между
git restore,git resetиgit revertи вернуть коммит или ветку черезgit reflog - безопасно перезаписать ветку на сервере через
--force-with-leaseи--force-if-includes
Что знать заранее
Проверено на
Git 2.55 (Git for Windows, Git Bash)Git 2.54 (Alpine Linux 3.24)
Сверено с документацией: 12 октября 2026 г.
Содержание
Настройка и создание репозитория
git config --global user.name "Имя"
- Что делает
- Имя автора для всех новых коммитов на этом компьютере
git config --global user.email "почта"
- Что делает
- Почта автора — попадает в каждый коммит
git config --global init.defaultBranch main
- Что делает
- Имя первой ветки в новых репозиториях
git config --list --show-origin
- Что делает
- Все действующие настройки и файл, из которого взята каждая
git config user.email
- Что делает
- Значение одной настройки с учётом приоритета (репозиторий важнее пользователя)
git init
- Что делает
- Пустой репозиторий в текущей папке (создаётся папка
.git)
git init -b main my-app
- Что делает
- Репозиторий в папке
my-appс первой веткойmain
git clone <url>
- Что делает
- Копия удалённого репозитория со всей историей; remote называется
origin
git clone --depth 1 <url>
- Что делает
- Поверхностный клон: только последний коммит — быстро для CI, но без истории
$ 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 печатает их строчными.Изменения и коммиты: status, add, diff, commit
git status
- Что делает
- Ветка, подготовленные и неподготовленные изменения, новые файлы
git status -s
- Что делает
- Коротко:
??— новый файл,A— добавлен,M— изменён; левая колонка — индекс, правая — рабочая папка
git add <файл> / git add .
- Что делает
- Подготовить файл / все изменения в текущей папке к коммиту (положить в индекс)
git add -p
- Что делает
- Подготовить изменения по кускам (hunk): Git спрашивает про каждый
git diff
- Что делает
- Что изменено в рабочей папке и ещё не добавлено в индекс
git diff --staged
- Что делает
- Что уже в индексе и войдёт в следующий коммит
git commit -m "сообщение"
- Что делает
- Записать коммит из индекса
git commit -am "сообщение"
- Что делает
- Добавить изменённые и удалённые отслеживаемые файлы и закоммитить; новые файлы не попадут
git commit --amend -m "…"
- Что делает
- Заменить последний коммит новым (другой хеш);
--no-edit— оставить сообщение
git mv old new
- Что делает
- Переименовать файл и сразу подготовить переименование
git rm <файл>
- Что делает
- Удалить файл с диска и из индекса
git rm --cached <файл>
- Что делает
- Перестать отслеживать файл, оставив его на диске
$ 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 убирает файл из индекса, но коммит с ним остаётся в истории (Git 2.55, реальный вывод).История и ссылки на коммиты
git log --oneline
- Что показывает
- История текущей ветки: короткий хеш и заголовок
git log --oneline --graph --all
- Что показывает
- Все ветки графом — видно, где они расходятся и сливаются
git log -n 2 --stat
- Что показывает
- Последние 2 коммита со списком изменённых файлов
git log -p -1 -- README.md
- Что показывает
- Последний коммит, который менял файл, с diff
git log --since="2 weeks ago" / --author="Ivan"
- Что показывает
- Коммиты за период / конкретного автора
git show HEAD
- Что показывает
- Метаданные и diff коммита
git show HEAD~1:README.md
- Что показывает
- Содержимое файла в указанной версии
git diff HEAD~2 HEAD --stat
- Что показывает
- Разница между двумя коммитами
HEAD
- Что означает
- Текущий коммит (вершина ветки, на которой вы стоите)
HEAD~1, HEAD~3
- Что означает
- Предок на 1 или 3 коммита назад
a1b2c3d
- Что означает
- Коммит по началу хеша
main, origin/main, v1.0.0
- Что означает
- Вершина ветки, удалённой ветки или тег
HEAD@{1}
- Что означает
- Где был
HEADодно перемещение назад — запись reflog
- в git switch -
- Что означает
- Предыдущая ветка, то же что
@{-1}
Ветки, слияние и перебазирование
git branch / -v / -vv
- Что делает
- Список веток / с последним коммитом / с отслеживаемой удалённой веткой
git branch -a
- Что делает
- Локальные и удалённые ветки
git branch --merged / --no-merged
- Что делает
- Ветки, уже влитые / ещё не влитые в текущую
git switch -c feature/login
- Что делает
- Создать ветку и переключиться на неё
git switch main / git switch -
- Что делает
- Переключиться на ветку / на предыдущую
git switch --detach v1.0.0
- Что делает
- Посмотреть старую версию без ветки (detached HEAD)
git branch -m old new
- Что делает
- Переименовать ветку
git branch -d name
- Что делает
- Удалить ветку, только если она слита; иначе ошибка
not fully merged
git branch -D name
- Что делает
- Удалить ветку принудительно — неслитые коммиты останутся только в reflog
git merge feature
- Что делает
- Влить ветку в текущую: fast-forward, если история не разошлась, иначе коммит слияния
git merge --no-ff feature
- Что делает
- Всегда создавать коммит слияния
git merge --squash feature
- Что делает
- Собрать изменения ветки в индекс одним набором, коммит — вручную
git merge --abort
- Что делает
- Прервать слияние с конфликтом и вернуться к исходному состоянию
git rebase main
- Что делает
- Переложить коммиты текущей ветки поверх
main
git rebase --continue / --skip / --abort
- Что делает
- Продолжить после разрешения конфликта / пропустить коммит / отменить rebase
git cherry-pick <хеш>
- Что делает
- Применить изменения одного коммита к текущей ветке
git merge-base main feature
- Что делает
- Общий предок двух веток
$ 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 — файл с конфликтом; после git merge --abort рабочая папка снова чистая (Git 2.55).Удалённые репозитории: remote, fetch, pull, push
git remote -v
- Что делает
- Список удалённых репозиториев с адресами
git remote add origin <url>
- Что делает
- Подключить удалённый репозиторий под именем
origin
git remote set-url origin <url>
- Что делает
- Сменить адрес (например, HTTPS на SSH)
git remote rename / git remote remove
- Что делает
- Переименовать / отключить remote
git remote show origin
- Что делает
- Адреса, ветка по умолчанию и связи веток
git fetch
- Что делает
- Скачать новые коммиты и обновить
origin/*, не трогая ваши ветки
git fetch --prune
- Что делает
- То же и удалить
origin/*для веток, которых больше нет на сервере
git pull
- Что делает
fetch+ слияние удалённой ветки в текущую
git pull --rebase
- Что делает
fetch+ перенос ваших коммитов поверх удалённых
git push -u origin feature
- Что делает
- Отправить ветку и запомнить её как отслеживаемую — дальше хватает
git push
git push origin --delete feature
- Что делает
- Удалить ветку на сервере
git push --force-with-lease
- Что делает
- Перезаписать удалённую ветку, только если она совпадает с вашей
origin/ветка
git push --force-with-lease --force-if-includes
- Что делает
- Дополнительно проверить, что вершина удалённой ветки уже есть в вашей локальной истории
$ 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 отклонён после --amend; --force-with-lease проходит. Затем коллега отправил коммит: аренда устарела (stale info); после git fetch защиту даёт только --force-if-includes. git pull --rebase переносит ваши коммиты поверх чужих — здесь коммит с тем же содержимым пропущен как уже применённый. Git 2.55, реальный вывод.Отмена изменений: restore, reset, revert
Документация Git разводит три похожие команды так: git restore возвращает файлы в рабочей папке или индексе и не трогает ветку; git reset двигает вершину ветки, добавляя или убирая коммиты, то есть меняет историю; git revert создаёт новый коммит, отменяющий изменения прежних.
Испортили файл, ещё не делали add
- Команда
git restore файл- Что можно потерять
- Правки в файле — безвозвратно
Лишнее попало в индекс
- Команда
git restore --staged файл- Что можно потерять
- Ничего: правки остаются на диске
Нужна версия файла из прошлого коммита
- Команда
git restore --source=HEAD~1 файл- Что можно потерять
- Текущие несохранённые правки этого файла
Последний коммит лишний, изменения нужны в индексе
- Команда
git reset --soft HEAD~1- Что можно потерять
- Ничего
То же, но изменения нужны вне индекса
- Команда
git reset HEAD~1(режим--mixed)- Что можно потерять
- Ничего
Выбросить коммит вместе с изменениями
- Команда
git reset --hard HEAD~1- Что можно потерять
- Незакоммиченные правки — безвозвратно; коммит — восстановим через reflog
Отменить коммит, который уже в общей ветке
- Команда
git revert <хеш>- Что можно потерять
- Ничего: появляется новый коммит
Удалить неотслеживаемые файлы и папки
- Команда
git clean -n, затемgit clean -fd- Что можно потерять
- Файлы, которых нет в Git, — безвозвратно
Вернуть коммит после reset или удаления ветки
- Команда
git reflog, затемgit reset --hard HEAD@{1}илиgit branch имя HEAD@{1}- Что можно потерять
- —
$ 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 и вернулся через 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 и теги
git stash / git stash push -m "описание"
- Что делает
- Спрятать изменения рабочей папки и индекса и вернуть папку к
HEAD
git stash push -u
- Что делает
- Спрятать и неотслеживаемые файлы (без
-uони остаются на месте)
git stash list
- Что делает
- Список спрятанного:
stash@{0}— самое свежее
git stash show -p stash@{1}
- Что делает
- Diff конкретной записи
git stash pop
- Что делает
- Применить последнюю запись и удалить её из списка
git stash apply stash@{0}
- Что делает
- Применить запись, оставив её в списке
git stash drop / git stash clear
- Что делает
- Удалить одну запись / все — после
clearих может быть уже не вернуть
git stash branch имя
- Что делает
- Создать ветку от коммита, где делали stash, и применить запись туда
$ 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 без -u не трогает неотслеживаемый new.txt; с -u прячет и его (Git 2.55).git tag -a v1.0.0 -m "Релиз 1.0.0"
- Что делает
- Аннотированный тег: отдельный объект с автором, датой и сообщением
git tag v1.0.0-light
- Что делает
- Лёгкий тег: просто имя для коммита, без метаданных
git tag / git tag -l "v1.*"
- Что делает
- Список тегов / по шаблону
git tag -a v0.9.0 <хеш> -m "…"
- Что делает
- Поставить тег на старый коммит
git show v1.0.0
- Что делает
- Тег и коммит, на который он указывает
git describe --tags
- Что делает
- Ближайший тег к текущему коммиту
git push origin v1.0.0
- Что делает
- Отправить один тег — обычный
pushтеги не отправляет
git push --tags
- Что делает
- Отправить все теги, включая лёгкие
git tag -d v1.0.0 + git push origin --delete v1.0.0
- Что делает
- Удалить тег локально и на сервере
Поиск по коду и истории, полезные алиасы
git grep -n "login"
- Что находит
- Строки в отслеживаемых файлах с номерами
git grep -n "TODO" -- "*.js"
- Что находит
- Поиск только в JS-файлах
git grep -n "hello" HEAD~10
- Что находит
- Поиск в старой версии проекта
git log -S "TODO"
- Что находит
- Коммиты, где изменилось число вхождений строки (добавили или удалили)
git log -G "log[a-z]+"
- Что находит
- Коммиты, в diff которых есть добавленные или удалённые строки по регулярному выражению
git log --grep="login"
- Что находит
- Коммиты по тексту сообщения
git log --follow -- NOTES.md
- Что находит
- История одного файла с учётом переименований
git blame -L 1,2 app.js
- Что находит
- Кто и в каком коммите последним менял строки 1–2
git bisect start / good / bad / reset
- Что находит
- Двоичный поиск коммита, который внёс ошибку
git bisect run <команда>
- Что находит
- Тот же поиск автоматически по коду выхода проверки
$ 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: код выхода 0 — коммит хороший, 1–127 (кроме 125) — плохой. Git 2.55, реальный вывод.Алиасы сокращают длинные команды. Pro Git предлагает их через git config --global alias.<имя>; ниже — проверенный набор, который не меняет поведение Git, а только даёт короткие имена.
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 убирает файл из индекса, undo снимает последний коммит (Git 2.55).Как Git устроен изнутри и почему команды работают именно так, разобрано в уроке «Git с нуля: коммиты, ветки, слияние»; форки, ревью и слияние на GitHub — в руководстве «GitHub: форк, pull request и код-ревью».
Как проверено4 · пройденосверено 12 октября 2026 г.
- запущено, работает
Все команды из таблиц справочника (206 проверенных вызовов: настройка, init/clone, status/add/diff/commit, log/show, branch/switch, merge/rebase/cherry-pick, remote/fetch/pull/push, restore/reset/revert/clean/reflog, stash, tag, grep/log -S/-G/blame/bisect, алиасы)
скрипт verify.sh во временной папке scratchpad: изолированный конфиг (GIT_CONFIG_NOSYSTEM=1, GIT_CONFIG_GLOBAL во временный файл), bare-репозиторий как origin и второй клон как «коллега»; Git 2.55.0.windows.1 (Git Bash) — 0 непредусмотренных ошибок; ожидаемые отказы (branch -d неслитой ветки, конфликт merge/rebase, отклонённые push) проверены как отказы
- запущено, работает
Тот же сценарий на Linux
docker run --rm alpine:3.24 + apk git 2.54.0, bash: хеши коммитов совпали (фиксированные GIT_AUTHOR_DATE/GIT_COMMITTER_DATE), отличия только в версии, путях и кавычках в сообщениях bisect
- запущено, работает
10 блоков shellsession/bash в статье
вырезаны скриптом build.mjs из транскрипта Git Bash без ручного набора; строки [exit N] служебные и удалены
- запущено, работает
Утверждение: голый --force-with-lease после git fetch перезаписывает чужой коммит; --force-if-includes отклоняет push
сценарий FORCE в verify.sh: push отклонён «remote ref updated since checkout»; в отдельном шаге --force-with-lease после fetch дал forced update, коммит коллеги исчез из origin
«Запущено» — код выполнен во временном проекте или контейнере, вывод в статье взят из прогона. «Частично» — проверено с заглушками вместо внешних сервисов. «Не запускалось» — нужны устройство, аккаунт или ключ; шаги сверены с официальной документацией. Файлы проверочного проекта и логи запусков сохранены в архиве InterLAB.