Git для начинающих: полное руководство по системе контроля версий - docs.devboxops.com

Git для начинающих: полное руководство по системе контроля версий

Полное руководство по Git для начинающих: от установки и настройки до работы с ветками и удаленными репозиториями

Общие возможности 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

Полезные ссылки

Top