Краткий справочник Git
Введение Git
Git — распределённая система контроля версий: система, записывающая изменения в файл или набор файлов в течение времени и позволяющая вернуться позже к определённой версии. Для контроля версий файлов в этой книге в качестве примера будет использоваться исходный код программного обеспечения, хотя на самом деле вы можете использовать контроль версий практически для любых типов файлов.
Если вы графический или web-дизайнер и хотите сохранить каждую версию изображения или макета (скорее всего, захотите), система контроля версий (далее СКВ) — как раз то, что нужно. Она позволяет вернуть файлы к состоянию, в котором они были до изменений, вернуть проект к исходному состоянию, увидеть изменения, увидеть, кто последний менял что-то и вызвал проблему, кто поставил задачу и когда и многое другое. Использование СКВ также значит в целом, что, если вы сломали что-то или потеряли файлы, вы спокойно можете всё исправить. В дополнение ко всему вы получите всё это без каких-либо дополнительных усилий.
Основные команды git
Создание пустого git репозитория в папке <dir>
. Если <dir>
не задана — пустой репозиторий инициализируется в текущей папке (<dir> = .
). Все базы данных для работы git
создаются в «скрытой» папке <dir>/.git
. Такой репозиторий хранит локальную историю версий рабочей директории.
$ git init <dir>
Создание простого пустого git репозитория в папке <dir>
. Если <dir>
не задана — пустой репозиторий инициализируется в текущей папке (<dir> = .
). При таком варианте создания репозитория, папка <dir>
содержит исключительно историю версий. Такой вариант создания репозитория необходимо использовать для совместного использования созданного репозитория. Репозиторий не содержит «рабочей» версии, позволяющей работать с проектом непосредственного в рабочей папке.
$ git init --bare <dir>
Сам по себе git работает полностью локально, без выхода в Интернет.
При этом вокруг git появилась целая экосистема сервисов: облачные хранилища репозиториев (с поддержкой git-команд прямо в браузере), системы автоматической сборки (проекта, документации к нему и т.д.), автоматического поиска уязвимостей в коде (например, Snik.io) и многие другие.
Поскольку git работает полностью локально, работа с ним обычно строится следующим образом: сначала код выгружается из какого-либо облачного хранилища, затем локально (на компьютере) делаются изменения, делается коммит этих изменений (о нем ниже, пока "коммит" стоит понимать как "сохранение") и в отправляется обратно в облачное хранилище.
Выгрузить репозиторий с облака можно командой git clone
.
Она создаёт копию git репозитория <rep>
в папке <dir>
и автоматически настраивать git так, чтобы он был в курсе, откуда был скачан репозиторий. Если имя папки <dir>
не задано — имя папки выбирается автоматически на основании <rep>
.
$ git clone <rep> <dir>
Примеры использования:
Клонирование локального репозитория:
$ git clone /path/to/repository/directoryКлонирование удалённого интернет репозитория:
$ git clone https://github.com/path/to/repositoryКлонирование удалённого репозитория по протоколу
ssh
(не будет просить пароль и соединение будет более безопасным):$ git clone ssh://<username>@<address>/path/to/repository/directory
Почти во всех облачных хранилищах (далее будем их иногда называть "удаленное хранилище", remote) есть разделение прав доступа, и у вас не всегда получится отправить свои изменения в чужой репозиторий. Проблема решается так: вы создаете полную копию кода в своем аккаунте (такой репозиторий называется fork), делаете в нем изменения и потом предлагаете свои изменения оригинальному владельцу.
Есть возможность получить только содержимое папки .git
(обычно используется на серверных машинах):
$ git clone --bare <rep>
Настройка git
После создания (клонирования) репозитория, необходимо настроить информацию, о том, кто будет работать с ним работать. Для этого необходимо сообщить информацию об имени и почте пользователя. Данная информацию может быть сохранена локально — сохраняется только для данного репозитория и глобальной — информация сохраняется для текущего пользователя ОС (Windows, Linux, OS) и её не надо будет заново вводить для последующих репозиториев.
$ git config --global user.name="Тут имя"
$ git config --global user.email="Почта"
или
$ git config --local user.name="Тут имя"
$ git config --local user.email="Почта"
Работа с репозиторием
Отметить изменения в файле <filename>
— изменения, сделанные в файле, подготавливаются для их фиксации как отдельной версии в репозитории.
$ git add <filename>
Отметить изменения во всех доступных файлах репозитория:
$ git add *
Отменить действие команды add
для <filename>
$ git reset -- <filename>
Зафиксировать все подготовленные, с использованием git add
, изменения
$ git commit -m "commit message"
Посмотреть текущее состояние репозитория
$ git status
Откатить все изменения, сделанные после фиксации (commit
)
$ git checkout -- .
Коммит - это "снимок" вашего кода в данный момент времени. Когда вы сделали коммит, вы сможете вернуться к нему в любой момент - и получить свой проект в том состоянии, в котором вы сделали этот коммит.
Взаимодействие с внешним репозиторием
Загрузить из внешнего репозитория все изменения. Возможно потребуется разрешение конфликтов, если файл был изменён различными пользователями
$ git pull
Выгрузить, зафиксированные на вашем компьютере, версии (коммиты) в удалённом репозиторий. При этом git должен знать, откуда вы скачиваете изменения. Если Вы не выполнили операцию pull
, системы выдаст соответствующую ошибку.
$ git push
Ветки git
Под капотом git выстраивает связи между коммитами: когда вы делаете новый коммит, он по факту становится после старого. Это образует граф. Например, если были коммиты A и B в порядке: A -> B, то после очередного коммита состояние станет таким: A -> B -> C. При этом можно в любой момент вернуться на коммит B, "отпочковаться" (т.е. решить от нее пойти в другом направлении, а не в C) и делать новые изменения. Этот процесс называется ветвлением.
Git позволяет создавать ветки и проводить разработку проекта в них. При этом получится писать код независимо от других пользователей. Обычно при этом код из ветки перетекает в master
(сейчас много где переименован в main
), но считается хорошим тоном это делать только после тщательной проверки и доработки всех изменений внутри отдельно созданной ветки.
Чтобы создать ветку <branch_name>
необходимо выполнить команду.
$ git branch <branch_name>
В случае, если <branch_name>
не задан, будет выведен список существующих веток. Создав новую ветку, вы остаётесь в старой.
Переключение на ветку <branch_name>
осуществляется по команде
$ git checkout <branch_name>
Создать и сразу переключиться на новую ветку <branch_name>
можно по команде
$ git checkout -b <branch_name>
Для того, чтобы объединить ветки (например, присоединить <branch_name>
в главную ветку master
). Необходимо переключиться на основную ветку (master
), и присоединить к ней (merge
) другую ветку (<branch_name>
). В примере ниже, создаётся отдельная ветка hotfix_123
. После решения проблемы фиксируются все изменения в данной ветке, после чего происходит присоединение ветки с hotfix-ом в основную ветку (master
)
$ git checkout -b hotfix_123
...
$ git add *
$ git commimt -m "HOTFIX for #ISSUE-123"
$ git checkout master
$ git merge hotfix
.gitignore
Для того, чтобы быстро зафиксировать все сделанные изменения, удобно использовать команду add *
, но такая команда может поместить в репозиторий те файлы, изменение которых Вы не хотите отслеживать (например, служебные файлы питона .pyc
). Информацию о таковых удобно поместить в файл .gitignore
(имя файла начинается с точки), тогда add *
не будет «подхватывать» новые файлы из заданных папок (с заданным именем, расширением, пр.).
Github
Крупнейшим веб-сервисом для хостинга IT-проектов и их совместной разработки на основании технологии git
, является сайт Github. Он целиком построен на git
и поддерживает все перечисленные команды, дополняя их различными возможностями. К дополнительным возможностям относятся: Issues — назначение заданий пользователям с описанием задачи, которую необходимо решить; Pull Request — не являясь владельцем репозитория и не имея возможности напрямую отправлять изменения в репозиторий (или же просто в основную master
ветку), у пользователя github есть возможность запросить осуществление команды merge <ваша_репозиторий/ваша_ветка> <целевая_ветка_репозитория>
у привилегированного пользователя, имеющего полный доступ к репозиторию. В случае положительного ответа, предложенные Вами изменения «вольются» в основной проект.
А теперь подробнее.
Issues - это способ общения между пользователями кода и разработчиками. Очень похож на форум: люди создают топики (они и называются issue), оставляют комментариями, могут закрывать и открывать обратно issue. Основная цель - репортить ошибки в коде (собственно, из-за этого issues и получили свое называние), обсуждать пути решения, назначать исполнителей (assignee), помечать тегами. Помимо этого в Issues еще можно предлать новую функциональность, обсуждать направления разработки и просто приводить примеры оформления других issue. Issue может открыть любой пользователь.
Pull request - предложение влить свой код в какую-то ветку. Это похоже на git merge
, который был описан выше, но есть дополнения:
- Pull request (PR) можно открыть как в пределах репозитория (одну ветку влить в другую), так и из форка в основной (например, влить ветку
dev
из своего форка в веткуdev
оригинального репо). - Pull request не сразу же вливает код. Это делает вручную человек с нужными полномочиями. На PR можно также навесить защиты: запретить принимать PR, пока не пройдут тесты или его не одобрят как минимум N человек (настраиваемо).
- Pull requsts можно и нужно обсуждать. Люди могут смотреть все предлагаемые изменения построчно и построчно же комментировать их. Это очень удобно на code review. Комментарии можно также оставлять ко всему PR в целом.
- Pull requests можно связывать с Issue, при этом issue автоматически закрывается (помечается как "Closed") после принятия PR.
Задание
- Зарегистрироваться в github, если Вы ещё не зарегистрированы
- Разбиться на группы по два человека для выполнения семестрового проекта
- Один человек из каждой группы создаёт приватный репозиторий для проекта на python (см. рисунок ниже)
- Владелец репозитория даёт доступ к нему второму студенту и преподавателю
- Каждый студент создаёт свою ветку, в которой ведёт дальнейшую разработку своей части проекта до конца семестра, отправляя в
master
рабочие версии файлов. - До следующей пары придумать семестровый проект и дать его короткое описание в файле README Вашего совместного проекта
ограничения на размеры групп, темы проектов, сроки, уточняйте у своего преподавателя