Git для начинающих: полное руководство по системе контроля версий
Полное руководство по Git для начинающих: от установки и настройки до работы с ветками и удаленными репозиториями
- Создание репозитория
 - Работа с удалённым репозиторием
 - Управление индексацией файлов
 - Получение информации об изменённых файлах
 - Совершение коммита
 - Возврат к определенному коммиту, откат изменений
 - Отмена коммитов
 - Логи коммитов
 - Показать изменения, внесенные отдельным коммитом
 - Работа с ветками
 - Тэги
 - .gitignore
 - Troubleshooting
 - Дополнительно
 - Полезные ссылки
 
- Создание репозитория
 - Работа с удалённым репозиторием
 - Управление индексацией файлов
 - Получение информации об изменённых файлах
 - Совершение коммита
 - Возврат к определенному коммиту, откат изменений
 - Отмена коммитов
 - Логи коммитов
 - Показать изменения, внесенные отдельным коммитом
 - Работа с ветками
 - Тэги
 - .gitignore
 - Troubleshooting
 - Дополнительно
 - Полезные ссылки
 
Общие возможности Git
Git — это распределенная система контроля версий, которая позволяет отслеживать изменения в файлах и координировать работу нескольких разработчиков над одним проектом. Созданная Линусом Торвальдсом в 2005 году, Git стала стандартом индустрии для управления исходным кодом и версиями файлов.
Система контроля версий (VCS) — это инструмент, который записывает изменения в наборе файлов и позволяет вернуться к определенной версии в будущем. Git относится к распределенным системам контроля версий, что означает, что каждый разработчик имеет полную копию проекта и его истории на своем компьютере.
Создание репозитория
Для начала нужно отметить, что репозиторий может быть удалённым (например, на GitHub/GitLab) и локальным на сервере (директория). Предположим, что у нас уже создан удаленный репозиторий в GitLab и мы знаем его адрес.
Переходим в директорию на сервере, которую нужно превратить в Git репозиторий, выполняем инициализацию:
git init
Это создаст в директории пустой Git репозиторий, информация о нем будет храниться в директории .git, включая конфиг для подключения к удаленному репозиторию.
Указываем какие файлы необходимо индексировать для добавления изменений:
git add .
Команда внесет в индекс все файлы, включая новые. Подробнее по индексации ниже в статье.
Работа с удалённым репозиторием
Добавление удаленного репозитория
Добавить удаленный репозиторий и присвоить ему имя origin:
git remote add origin ssh://user@gitserver:project/myrepo.git
Получение изменений
Забрать изменения из удаленного репозитория:
git fetch origin
Коммит слияния с основной веткой:
git merge origin/main
Команда git pull сразу забирает изменения и проводит слияние с активной веткой. Забрать из репозитория, для которого были созданы удаленные ветки по умолчанию:
git pull
Отправка изменений
Отправить свои изменения в удаленную ветку, созданную при клонировании по умолчанию:
git push
Управление индексацией файлов
Добавление файлов в индекс
Индексация измененного файла, либо оповещение о создании нового:
git add EDITEDFILE
Удаление файлов из индекса
Удаление отдельных файлов из индекса:
git rm FILE1 FILE2
Файлы будут удалены, в том числе и из текущей директории. Можно также удалять файлы по маске:
git rm Documentation/\*.txt
Сброс изменений
Сбросить изменения в индексе или удалить из него изменения определенного файла:
git reset
git reset -- EDITEDFILE
Получение информации об изменённых файлах
С помощью команды git status можно получить информацию обо всех изменениях, внесённых в дерево директорий проекта по сравнению с последним коммитом рабочей ветки:
git status
Кроме того, в вывод попадут файлы с неразрешенными конфликтами слияния и файлы, игнорируемые git.
Совершение коммита
Коммит — базовое понятие во всех системах контроля версий, поэтому совершаться он должен легко и по возможности быстро.
Базовый коммит
В простейшем случае достаточно после индексации набрать:
git commit
Если индекс не пустой, то на его основе будет совершён коммит, после чего пользователя попросят прокомментировать вносимые изменения вызовом команды edit.
Автоматическая индексация изменений при коммите
Новые файлы при этом не будут учитываться:
git commit -a
Коммит конкретного файла
Выполняется через указание нужного файла при коммите:
git commit FILENAME
Возврат к определенному коммиту, откат изменений
Помимо работы с индексом, git reset позволяет сбросить состояние проекта до какого-либо коммита в истории. В git данное действие может быть двух видов: «мягкого» (soft reset) и «жесткого» (hard reset).
Мягкий reset
«Мягкий» (с ключом --soft, либо без указания ключа) reset оставит нетронутыми ваши индекс и все дерево файлов и директорий проекта, вернется к работе с указанным коммитом.
git commit                    # некорректный коммит
git reset --soft HEAD^        # переходим к работе над уже совершенным коммитом,
                             # сохраняя все состояние проекта и проиндексированные файлы
# Корректируем нужные файлы
git add .
git commit -c ORIG_HEAD      # вернуться к последнему коммиту,
                             # будет предложено редактировать его сообщение
Если сообщение оставить прежним, то достаточно изменить регистр ключа:
git commit -C ORIG_HEAD
Жесткий reset
⚠️ «Жесткий» reset (ключ --hard) — команда, которую следует использовать с осторожностью. git reset --hard вернет дерево проекта и индекс в состояние, соответствующее указанному коммиту, удалив изменения последующих коммитов:
git add .
git commit -m "comment"
git reset --hard HEAD~1      # навсегда откатить 1 коммит
git reset --hard HEAD~3      # навсегда откатить 3 коммита
Отмена коммитов
Отменяем коммит, помеченный тегом:
git revert config-modify-tag
Отменяем коммит, используя его хэш:
git revert aabbcc1
Логи коммитов
Иногда требуется получить информацию об:
- истории коммитов
 - коммитах, изменивших отдельный файл
 - коммитах за определенный отрезок времени
 
Для этих целей используется команда git log:
git log
Подробная информация о коммитах
Получить подробную информацию о каждом в виде патчей по файлам из коммитов можно, добавив ключ -p (или -u):
git log -p
Статистика изменений
Статистика изменения файлов, вроде числа измененных файлов, внесенных в них строк, удаленных файлов вызывается ключом --stat:
git log --stat
Информация о файловых операциях
За информацию по созданиям, переименованиям и правам доступа файлов отвечает ключ --summary:
git log --summary
Показать изменения, внесенные отдельным коммитом
Посмотреть изменения, внесенные любым коммитом в истории, можно командой git show:
git show COMMIT_TAG
Работа с ветками
git branch
Перечислить существующие ветки, отметив активную:
git branch
Создать новую ветку new-branch:
git branch new-branch
Удалить ветку, если та была залита (merged) с разрешением возможных конфликтов в текущую:
git branch -d new-branch
Удалить ветку в любом случае:
git branch -D new-branch
Переименовать ветку:
git branch -m new-name-branch
Показать те ветки, среди предков которых есть определенный коммит:
git branch --contains v1.0
git checkout
git checkout позволяет переключаться между ветками и извлекать файлы:
git checkout some-other-branch
Создать ветку и переключиться в неё:
git checkout -b fix/something
Если в текущей ветке были какие-то изменения по сравнению с последним коммитом в ветке (HEAD), то команда откажется производить переключение, дабы не потерять произведенную работу.
Проигнорировать изменения (изменения затрутся) позволяет ключ -f:
git checkout -f some-other-branch
Сохранить изменения при переключении следует использовать ключ -m. Тогда команда перед переключением попробует залить изменения в текущую ветку и, после разрешения возможных конфликтов, переключиться в новую:
git checkout -m some-other-branch
Вернуть файл к состоянию последнего коммита:
git checkout somefile
Вернуть файл к состоянию на два коммита назад:
git checkout HEAD~2 somefile
git merge
Объединить несколько веток в одну можно с помощью git merge:
git merge new-branch
Тэги
Тэг (tag) — это объект, связанный с коммитом, хранящий ссылку на сам коммит, имя автора, собственное имя и некоторый комментарий. Кроме того, разработчик может оставлять на таких тегах собственную цифровую подпись.
В Git представлены так называемые «легковесные тэги» (lightweight tags), состоящие только из имени и ссылки на коммит. Такие тэги, как правило, используются для упрощения навигации по дереву истории.
Управление тэгами
Создать «легковесный» тэг, связанный с последним коммитом:
git tag v1.2.3
Пометить определенный коммит:
git tag v1.2.3 aabbcc1
Удалить тег:
git tag -d v1.2.3
Перечислить тэги:
git tag -l
Создать тэг для последнего коммита, заменить существующий, если таковой уже был:
git tag -f v1.2.3
После создания тэга его имя можно использовать вместо хэша в любых командах вроде git diff, git log и так далее:
git diff v1.2.2 v1.2.3
Аннотированные тэги
Обычные тэги имеет смысл использовать для приложения к коммиту какой-либо информации, вроде номера версии и комментария к нему.
Создать обычный тэг для последнего коммита (будет вызван текстовый редактор для составления комментария):
git tag -a v1.2.3
Создать обычный тэг, сразу указав комментарий:
git tag -a v1.2.3 -m "production"
Команды перечисления, удаления, перезаписи для обычных тэгов не отличаются от команд для «легковесных» тэгов.
.gitignore
Заставить git status игнорировать определенные файлы можно, создав в корне или глубже по дереву файл .gitignore. В этих файлах можно описывать шаблоны игнорируемых файлов определенного формата.
Пример содержимого .gitignore
# Зависимости
node_modules/
vendor/
# Файлы сборки
dist/
build/
# Системные файлы
.DS_Store
Thumbs.db
# Конфигурационные файлы
.env
config.local.js
Больше примеров можно найти тут
Существуют и другие способы указания игнорируемых файлов, о которых можно узнать из справки:
git help gitignore
Troubleshooting
Debug SSH-соединения
Переопределяем переменную окружения GIT_SSH_COMMAND перед выполнением команды:
GIT_SSH_COMMAND="ssh -v" git clone git@gitserver:project/repo.git
Verbose вывод любой операции
Для получения более подробного вывода по выполнении операции добавляем ключ -vvv:
git clone -vvv git@gitserver:project/repo.git
Debug операций
Задаём перед выполняемой командой переменную окружения GIT_TRACE:
GIT_TRACE=true git log
Есть и другие отладочные переменные окружения, см. раздел “Debugging” официальной документации.
Дополнительно
Некоторые трюки работы с локальными репозиториями
Суть трюка в том, что можно работать с локальным репозиторием как с удаленным.
Создаем чистый репозиторий в любой удобной директории:
mkdir repo.git
cd repo.git
git init --bare
Далее создаем репозиторий, как обычно, только в качестве remote указываем локальную директорию:
git remote add origin /path/to/repo.git
git push origin main
После этого с созданным локально репозиторием можно работать как с удаленным, например, клонировать:
git clone /path/to/repo.git /new/path/for/cloned/repo
Полезные ссылки
- Официальная документация Git
 - Pro Git book - подробная книга по Git
 - Git Tutorial - интерактивные уроки по Git