PHPFlowPHP, MySQL, Laravel и JavaScript

Команды Git для начинающих: от git init до отмены изменений

Обновлено:

Коротко

Основные команды Git для каждого дня укладываются в короткий цикл: git clone или git init, затем git status, git add, git commit, git push и git pull. Ниже все команды Git, которые нужны начинающему: с примерами, пояснением, что делает каждая, и способами отменить изменения, если что-то пошло не так. В конце есть шпаргалка одной таблицей.

Содержание
  1. Установка Git и первая настройка
  2. Создать репозиторий: git init и git clone
  3. Базовый цикл: git status, git add, git commit
  4. Работа с удалённым репозиторием: push, pull, fetch
  5. Ветки: branch, switch, merge
  6. История и сравнение: git log и git diff
  7. Как отменить изменения в Git
  8. Файл .gitignore: что не хранить в репозитории
  9. Шпаргалка: список команд Git
  10. Типовой рабочий день с Git

Установка Git и первая настройка

Прежде чем вводить команды Git, проверьте, что он установлен: выполните git --version. В Windows Git ставится с git-scm.com (в комплекте идёт терминал Git Bash) или командой winget install Git.Git, в Ubuntu командой sudo apt install git, в macOS Git появится после xcode-select --install или brew install git.

Команды git --version и git config в Git Bash
Проверка версии Git и первая настройка автора коммитов в Git Bash

Сразу после установки один раз задайте имя и почту: они записываются в каждый коммит. Ключ --global сохраняет настройки для всех репозиториев пользователя в файле ~/.gitconfig.

# Кто автор коммитов
git config --global user.name "Иван Петров"
git config --global user.email "ivan@example.com"

# Основная ветка в новых репозиториях будет называться main
git config --global init.defaultBranch main

# Windows: хранить в репозитории переносы строк LF, а в рабочих файлах CRLF
git config --global core.autocrlf true

# Посмотреть все настройки и откуда они взяты
git config --list --show-origin

На Linux и macOS вместо core.autocrlf true ставят input, чтобы в репозиторий не попадали переносы Windows.

Ошибка "git не является внутренней или внешней командой"

Так Windows сообщает, что не находит git.exe в PATH. Обычно Git просто не установлен или терминал открыт раньше, чем закончилась установка. Откройте новое окно; если не помогло, переустановите Git и на шаге "Adjusting your PATH environment" выберите вариант "Git from the command line and also from 3rd-party software". В Git Bash похожая ошибка "bash: git: command not found" встречается редко и почти всегда означает повреждённую установку.

Создать репозиторий: git init и git clone

Репозиторий можно начать с нуля в своей папке или скачать существующий с GitHub, GitLab или своего сервера.

# Новый репозиторий в текущей папке: появится скрытая папка .git
cd ~/projects/shop
git init

# Скачать готовый репозиторий (создаст папку shop)
git clone https://github.com/user/shop.git

# Скачать в папку с другим именем
git clone https://github.com/user/shop.git my-shop

# Скачать только последнее состояние, без всей истории (быстро для больших проектов)
git clone --depth 1 https://github.com/user/shop.git

Что делает команда git init: создаёт папку .git, где Git хранит историю, ветки и настройки. Удалите эту папку, и папка снова станет обычной, без истории. git clone делает три действия сразу: создаёт папку, скачивает всю историю и настраивает удалённый репозиторий с именем origin.

Базовый цикл: git status, git add, git commit

В Git у файла три состояния: изменён в рабочей папке, добавлен в индекс (staging area, подготовлен к коммиту) и сохранён в коммите. Команды переводят файлы между этими состояниями.

Схема git add, git commit, git push
Путь изменения в Git: от правки файла до отправки на GitHub или GitLab

git status: что изменилось

git status показывает текущую ветку, изменённые, новые и подготовленные файлы и подсказывает следующую команду. Запускайте её перед каждым коммитом. Короткий вид выводит git status -s: буква M значит изменён, A добавлен, ?? не отслеживается.

git add: подготовить файлы к коммиту

git add index.php            # один файл
git add src/                 # папка целиком
git add .                    # все изменения в текущей папке и ниже
git add -p                   # по кускам: Git спросит про каждый фрагмент

Команда git add не сохраняет историю, она лишь отмечает, какие изменения войдут в следующий коммит. Это позволяет разбить большую правку на несколько понятных коммитов. Режим -p особенно полезен, когда в одном файле вы исправили ошибку и заодно поменяли форматирование: их можно закоммитить отдельно.

git commit: сохранить снимок

git commit -m "Добавлена форма обратной связи"

# Добавить в коммит все изменённые (уже отслеживаемые) файлы без git add
git commit -am "Исправлена валидация email"

# Исправить последний коммит: сообщение или забытый файл
git add forgotten.php
git commit --amend --no-edit

Что делает git commit -m: сохраняет всё, что лежит в индексе, как новую точку истории с сообщением из кавычек. Без -m Git откроет редактор для сообщения. Сообщение пишите в повелительном или прошедшем времени и по сути: "Исправлен расчёт скидки", а не "правки". Многие команды используют формат Conventional Commits: feat: ..., fix: ..., docs: ....

git commit --amend переписывает последний коммит. Делайте это только до git push: если коммит уже на сервере, коллеги получат конфликт истории.

Работа с удалённым репозиторием: push, pull, fetch

Удалённый репозиторий (remote) хранится на GitHub, GitLab или вашем сервере. После git clone он уже настроен под именем origin, а для репозитория из git init его нужно добавить вручную.

# Подключить удалённый репозиторий
git remote add origin git@github.com:user/shop.git
git remote -v                       # проверить адреса

# Первая отправка ветки main и связь её с origin/main
git push -u origin main

# Дальше достаточно
git push
git pull

Что делает git push и ключ -u

git push отправляет ваши коммиты на сервер. Команда git push -u origin main означает "отправь ветку main в репозиторий origin и запомни связь" (-u это --set-upstream). После этого в ветке можно писать просто git push и git pull. Ответ "Everything up-to-date" значит, что новых коммитов для отправки нет: проверьте, не забыли ли вы сделать коммит.

Если сервер отклоняет push с сообщением "rejected ... fetch first", на сервере есть коммиты, которых нет у вас. Сначала выполните git pull, а потом снова git push. Принудительная отправка нужна редко; если без неё не обойтись (например, после rebase своей ветки), используйте безопасный вариант git push --force-with-lease: он не затрёт чужие коммиты, появившиеся на сервере.

Чем git pull отличается от git fetch

КомандаЧто делаетМеняет ваши файлы
git fetchСкачивает новые коммиты и ветки с сервераНет
git pullfetch и сразу слияние с текущей веткойДа
git pull --rebasefetch и перенос ваших коммитов поверх скачанныхДа, история без лишних слияний

Команда git fetch безопасна: после неё можно посмотреть, что пришло (git log main..origin/main), и только потом решить, сливать ли. git pull используется для того, чтобы одной командой получить чужие изменения в свою ветку.

Ветки: branch, switch, merge

Ветка в Git это подвижный указатель на коммит. Новую функцию удобно делать в отдельной ветке, а в main сливать готовый результат.

git branch                    # список локальных веток, текущая отмечена *
git branch -a                 # вместе с ветками на сервере

# Команда для создания ветки и переход в неё
git switch -c feature/cart    # современный вариант
git checkout -b feature/cart  # старый вариант, работает так же

git switch main               # перейти в существующую ветку

# Влить ветку feature/cart в текущую (main)
git merge feature/cart

# Удалить влитую ветку локально и на сервере
git branch -d feature/cart
git push origin --delete feature/cart

Что делает команда git checkout: исторически она и переключает ветки, и восстанавливает файлы, поэтому в новых версиях Git её разделили на две понятные команды git switch (ветки) и git restore (файлы). checkout по-прежнему работает, его можно встретить в старых инструкциях.

Конфликт при слиянии

Если две ветки изменили одни и те же строки, git merge остановится и пометит файл маркерами <<<<<<<, ======= и >>>>>>>. Откройте файл, оставьте нужный вариант и удалите маркеры, затем выполните git add файл и git commit. Передумали сливать: git merge --abort вернёт всё как было до слияния.

Маркеры конфликта слияния в файле config.php
Так выглядит конфликт после git merge: оставьте один вариант и удалите строки-маркеры

Что делает git rebase

git rebase main, выполненная в своей ветке, переносит ваши коммиты так, будто вы начали работу от последнего состояния main. История получается прямой, без коммитов слияния. Правило простое: перебазируйте только свои ветки, которые ещё никто не скачивал. Общую ветку main не перебазируйте.

История и сравнение: git log и git diff

git log                       # полная история текущей ветки
git log --oneline --graph --all   # компактно, с ветками в виде дерева
git log -p index.php          # история одного файла с изменениями
git log --author="Иван" --since="2 weeks ago"

git diff                      # что изменено, но ещё не добавлено в индекс
git diff --staged             # что уже в индексе и уйдёт в коммит
git diff main feature/cart    # разница между ветками
git show a1b2c3d              # содержимое одного коммита

Длинный вывод git log и git diff открывается в просмотрщике. Как выйти из git log: нажмите Q. Листать можно пробелом и стрелками, искать по тексту клавишей /.

История коммитов в виде дерева в терминале
Вывод git log --oneline --graph: каждая строка это коммит, слева видно ветвление и слияние

Как отменить изменения в Git

Самая нужная начинающему часть. Выбирайте команду по тому, где сейчас находится изменение.

СитуацияКомандаЧто произойдёт
Испортили файл, не делали addgit restore файлФайл вернётся к последнему коммиту
Сделали add лишнего файлаgit restore --staged файлФайл уйдёт из индекса, правки останутся
Последний коммит лишний, ещё не отправленgit reset --soft HEAD~1Коммит удалится, изменения останутся в индексе
Выбросить последний коммит вместе с правкамиgit reset --hard HEAD~1Коммит и изменения пропадут
Коммит уже на сервереgit revert a1b2c3dПоявится новый коммит, отменяющий старый

git reset --hard и git restore удаляют несохранённые правки без корзины. Если сомневаетесь, сначала спрячьте изменения через git stash. Даже после неудачного reset коммиты обычно можно найти командой git reflog и вернуть через git reset --hard <хеш>.

git stash: временно спрятать правки

Команда git stash убирает незакоммиченные изменения в отдельное хранилище и очищает рабочую папку. Это удобно, когда нужно срочно переключиться на другую ветку и исправить ошибку.

git stash push -m "недоделанная корзина"   # спрятать с подписью
git stash list                             # список спрятанного
git stash pop                              # вернуть последнее и удалить из списка
git stash apply stash@{1}                  # вернуть конкретное, оставив в списке
git stash push -u                          # спрятать вместе с новыми файлами

git cherry-pick: перенести один коммит

Что делает команда git cherry-pick a1b2c3d: копирует указанный коммит в текущую ветку. Типичный случай: исправление сделали в ветке разработки, а нужно срочно выпустить его в main, не вливая остальную работу.

Файл .gitignore: что не хранить в репозитории

В корне проекта создайте файл .gitignore и перечислите в нём то, что Git не должен отслеживать: зависимости, логи, локальные настройки и секреты.

# Зависимости: восстанавливаются через composer install и npm install
/vendor/
/node_modules/

# Настройки окружения с паролями к базе
.env

# Логи, кеш и сборка
*.log
/storage/*.key
/public/build/

# Файлы редакторов и системы
.idea/
.vscode/
.DS_Store
Thumbs.db

Папки vendor и node_modules в репозитории не нужны: их пересобирают composer install и npm install (про второе подробно в статье об установке Node.js и npm). Если файл уже попал в репозиторий, одного .gitignore мало: уберите его из индекса командой git rm --cached .env и сделайте коммит. Пароль, который когда-либо оказался в истории, считайте раскрытым и смените его.

Если сайт выкладывается на хостинг через git pull, закройте доступ к папке .git из браузера, иначе по адресу /.git/config можно скачать исходники. Готовое правило есть в статье про настройку .htaccess.

Шпаргалка: список команд Git

КомандаНазначение
git initСоздать репозиторий в текущей папке
git clone URLСкачать репозиторий
git statusПоказать изменения
git add .Подготовить все изменения
git commit -m "..."Сохранить коммит
git push / git pullОтправить / получить изменения
git fetchСкачать изменения без слияния
git switch -c имяСоздать ветку и перейти в неё
git merge имяВлить ветку в текущую
git log --onelineКраткая история
git diffРазница с последним коммитом
git restore файлОтменить правки в файле
git revert хешОтменить коммит новым коммитом
git stash / git stash popСпрятать / вернуть правки
git tag v1.0Отметить версию

Все эти команды одинаково работают в терминале Linux и macOS, в Git Bash, PowerShell и во встроенном терминале VS Code. Подробная справка по любой команде открывается через git help commit или git commit -h (короткий вариант прямо в терминале).

Типовой рабочий день с Git

Как команды складываются в работу над задачей в команде:

  1. Обновите main: git switch main, затем git pull.
  2. Создайте ветку под задачу: git switch -c fix/login-error.
  3. Внесите правки и проверьте их через git status и git diff.
  4. Подготовьте и сохраните: git add . и git commit -m "Исправлена ошибка входа".
  5. Отправьте ветку: git push -u origin fix/login-error.
  6. Создайте Pull Request (на GitLab Merge Request) в веб-интерфейсе и дождитесь проверки.
  7. После слияния вернитесь в main, выполните git pull и удалите ветку: git branch -d fix/login-error.
git switch -c, git commit и git push -u в терминале
Работа над задачей в отдельной ветке: создать, закоммитить и отправить на сервер

Если проект запускается в контейнерах, файлы Dockerfile и compose.yaml тоже храните в репозитории: тогда коллега после git clone поднимет окружение одной командой. Пример такой сборки разобран в статье про Docker для PHP.

Частые вопросы

Какие команды Git нужно знать начинающему?

Для старта хватит десятка: git clone, git status, git add, git commit, git push, git pull, git switch, git merge, git log и git restore. Остальные понадобятся по мере работы.

Что делает команда git add?

Добавляет изменения в индекс, то есть отмечает, что именно войдёт в следующий коммит. Сама по себе она историю не сохраняет, для этого нужна git commit.

Как выйти из git log?

Нажмите клавишу Q. Чтобы вывод не открывался в просмотрщике, запустите git --no-pager log -5.

Чем отличаются git pull и git fetch?
git fetch только скачивает новые коммиты с сервера и не трогает ваши файлы, а git pull скачивает и сразу сливает их с текущей веткой.
Как создать ветку в Git?

Командой git switch -c имя-ветки (или старой git checkout -b имя-ветки): ветка создастся от текущего коммита, и вы сразу в неё перейдёте.

Как отменить последний коммит?

Если он ещё не отправлен, выполните git reset --soft HEAD~1: коммит исчезнет, а изменения останутся. Если коммит уже на сервере, используйте git revert с его хешем.