Лаборатория кодера

Справочник · Код и сборка

Git: шпаргалка на каждый день

Команды, которые нужны в обычной работе: ветки, коммиты, слияние и перебазирование, отмена изменений и поиск по истории.

Обновлено · 7 мин чтения

Git хранит историю как цепочку снимков проекта. Каждый коммит знает своего родителя, ветка — это просто подвижный указатель на коммит, а HEAD показывает, где вы сейчас. Если держать эту картину в голове, большинство команд перестают пугать.

Первая настройка

Имя и почта попадают в каждый коммит. Ключ --global пишет настройку в ~/.gitconfig, без него — в .git/config текущего репозитория.

bash
git config --global user.name "Иван Петров"
git config --global user.email ivan@example.com
git config --global init.defaultBranch main
git config --global pull.ff only        # pull не создаёт случайных коммитов слияния
git config --global core.editor vim
git config --list --show-origin         # что и откуда настроено

Три состояния файла

Изменение проходит путь: рабочая папка → индекс (staging) → коммит. Индекс — черновик следующего коммита, в него можно положить не весь файл, а только часть правок.

КомандаЧто делает
git status -sbкороткий статус и текущая ветка
git add файлположить файл в индекс
git add -pвыбрать куски изменений по одному
git diffчто изменено, но ещё не в индексе
git diff --stagedчто попадёт в коммит
git commit -m "текст"записать коммит
git commit --amendпереписать последний коммит
git restore файлвернуть файл к состоянию индекса
git restore --staged файлубрать файл из индекса, правки остаются

Ветки

bash
git branch                  # список локальных веток
git branch -a               # вместе с удалёнными
git switch -c feature/login # создать ветку и перейти в неё
git switch main             # перейти в существующую
git switch -                # вернуться в предыдущую ветку
git branch -d feature/login # удалить влитую ветку
git branch -D feature/login # удалить, даже если не влита
git branch -m старое новое  # переименовать

Команда git checkout умеет всё то же самое и ещё восстанавливать файлы, поэтому её разделили на switch (ветки) и restore (файлы). Старые руководства используют checkout -b, это то же, что switch -c.

Работа с удалённым репозиторием

bash
git clone git@example.com:team/app.git
git remote -v                     # куда смотрят remote
git fetch --all --prune           # забрать новое и убрать удалённые ветки
git pull                          # fetch + слияние текущей ветки
git push -u origin HEAD           # первый push ветки с привязкой
git push                          # дальше без аргументов
git push origin --delete old-branch

fetch ничего не меняет в ваших файлах, он только обновляет указатели вида origin/main. Поэтому git fetch безопасно запускать когда угодно, а потом смотреть, что пришло: git log HEAD..origin/main.

Слияние и перебазирование

Обе команды переносят изменения из одной ветки в другую, но по-разному пишут историю.

git merge maingit rebase main
Историясохраняется как была, появляется коммит слиянияваши коммиты переписываются поверх main
Хеши коммитовне меняютсяменяются
Когда удобнообщие ветки, итоговое слияниесвоя ветка до публикации
Конфликтырешаются один размогут встретиться на каждом коммите
bash
git rebase main               # переписать свою ветку поверх main
git rebase -i HEAD~4          # склеить, переставить, переименовать 4 последних коммита
git rebase --continue         # после решения конфликта
git rebase --abort            # вернуть всё как было
git merge --no-ff feature     # всегда создавать коммит слияния
git merge --abort

Конфликты

Git помечает спорное место в файле:

text
<<<<<<< HEAD
timeout = 30
=======
timeout = 60
>>>>>>> feature

Оставьте нужный вариант, удалите маркеры, затем git add файл и git commit (или git rebase --continue). Полезная настройка git config --global merge.conflictstyle zdiff3 показывает ещё и исходную версию, из которой разошлись ветки.

Отмена изменений

Самая частая паника — «я всё сломал». Почти всегда это поправимо.

СитуацияКоманда
Испортил файл, ещё не добавил в индексgit restore файл
Добавил в индекс лишнееgit restore --staged файл
Опечатка в сообщении последнего коммитаgit commit --amend
Забыл файл в последнем коммитеgit add файл && git commit --amend --no-edit
Отменить опубликованный коммитgit revert хеш
Убрать последний локальный коммит, правки оставитьgit reset --soft HEAD~1
Убрать коммит и правки полностьюgit reset --hard HEAD~1
Отложить незаконченную работуgit stash push -m "заметка"
Вернуть отложенноеgit stash pop

revert создаёт новый коммит с обратными изменениями и безопасен для общих веток. reset двигает указатель ветки назад и подходит только для того, что ещё не ушло на сервер.

История и поиск

bash
git log --oneline --graph --all     # дерево всех веток
git log -p файл                     # история файла с изменениями
git log --author="Иван" --since="2 weeks ago"
git log -S "parseConfig"            # коммиты, где строка появилась или пропала
git log --grep="fix"                # поиск по сообщению
git show хеш                        # один коммит целиком
git blame -L 10,30 файл             # кто менял строки 10–30
git diff main...feature             # что изменилось в feature с момента ответвления

Чтобы найти коммит, который сломал поведение, есть двоичный поиск:

bash
git bisect start
git bisect bad                 # текущий коммит плохой
git bisect good v1.4.0         # этот был хорошим
# git переключает коммиты, вы проверяете и говорите good или bad
git bisect reset               # закончить

Если проверку можно автоматизировать, git bisect run ./test.sh найдёт виновника сам: скрипт должен вернуть 0 для хорошего коммита и не 0 для плохого.

Метки и версии

bash
git tag -a v1.2.0 -m "Выпуск 1.2.0"   # аннотированная метка
git push origin v1.2.0
git tag --list "v1.*"
git describe --tags                     # v1.2.0-5-g3f2a1bc: 5 коммитов после метки

Номера версий удобно вести по правилам семантического версионирования.

Файл .gitignore

text
# всё в папке build
build/
# все логи, кроме важного
*.log
!important.log
# только в корне репозитория
/config.local.yml

Если файл уже отслеживается, .gitignore на него не действует. Уберите его из индекса, оставив на диске: git rm --cached файл. Проверить, какое правило сработало: git check-ignore -v путь.

Сообщения коммитов

Первая строка — до 50–70 символов, в повелительном или описательном виде: что меняет коммит. Пустая строка, затем подробности: почему так. Многие команды используют префиксы feat:, fix:, docs:, refactor:, из них потом собирают список изменений и подбирают номер версии.