Содержание:
- Что такое системы контроля версий?
- Разновидности систем контроля версий
- Что такое репозиторий?
- Структура проекта Git
- Основы работы с репозиторием
- Как Git хранит данные
- Что такое ветка в git?
- История коммитов
- Назад в прошлое
- Работа с удаленными репозиториями
Система контроля версий (англ. Version Control System, сокращенно VCS) — это система, записывающая изменения в файл или набор файлов в течение времени и позволяющая вернуться позже к определённой версии. Важно отметить, что речь идет о любых файлах, а не только о файлах с программным кодом, поэтому, при необходимости, системы контроля версий можно использовать для работы над любыми проектами.
Существуют следующие виды VCS:
-
Локальные VCS. Представляют собой связку программы для отслеживания изменений файлов с простой базой данных для хранения изменений.
Сильные стороны:
- Решение проблем версионирования
Слабые стороны:
- Невозможность командной работы над проектом
- При критической поломке компьютера вы теряете ваш проект со всей историей изменений
-
Централизованные VCS. Следующий этап развития систем контроля версий, призванный устранить недостатки локальных VCS. Централизованные VCS представляют собой связку программы для отслеживания изменений файлов и базу данных, расположенную на удаленном сервере. После внесения изменений разработчики отправляют их на сервер, чтобы другие разработчики имели возможность работать с актуальной версией проекта. Актуальную версию проекта разработчики также получают от сервера.
Сильные стороны:
- Возможность командной работы над проектом
- Легкость администрирования проекта
Слабые стороны:
- Единая точка отказа. Если сервер с базой данных упадет на некоторое время, разработчики потеряют возможность вносить и получать изменения. Если сервер выйдет из строя, то вся история изменений будет потеряна.
-
Распределенные VCS. Распределенные VCS объединяют в себе сильные стороны локальных и централизованных VCS. Как и в случае с локальными VCS, распределенные VCS организуют на стороне клиента хранение полной истории изменений, а также позволяют обмениваться данными через удаленный сервер, как это было с централизованными VCS. Однако, в отличие от централизованных VCS, в случае с отказом сервера разработчики имеют возможность продолжать работу с проектом путем сохранения изменений в локальную историю проекта. После устранения проблем с удаленным сервером вся локальная история с актуальными изменениями может быть отправлена на сервер. В случае же выхода сервера из строя данные не будут потеряны, поскольку на стороне каждого разработчика хранится полная история изменений проекта.
Сильные стороны:
- Решение проблем версионирования
- Возможность командной работы над проектом
- Высокая отказоустойчивость системы
Git является распределенной системой контроля версий.
Репозиторий Git - это хранилище изменений вашего проекта и сопутствующих метаданных. Все эти данные хранятся в каталоге .git
.
Репозиторий Git может быть создан двумя способами:
-
Создан с нуля на основе текущего проекта. Для этого используется команда:
git init
-
Скопирован с удаленного сервера с помощью команды:
git clone <url> [folder_name]
Проект, находящийся под контролем git, состоит из трех основных секций:
-
Рабочая копия (working tree) - это одна из версий проекта, которая была извлечена из сжатой базы данных каталога
.git
, разжата и помещена на диск. Рабочая копия содержит файлы, в которые вы можете вносить изменения. -
Область индексирования (index) - это специальный файл, хранящийся в каталоге
.git
, который содержит информацию об изменениях, попадущих в базу изменений во время следующего коммита. -
Каталог .git - место хранения всех изменений и метаданных проекта. Этот каталог - самая важная часть проекта Git, которая будет передаваться при клонировании репозитория и работе с удаленным сервером.
Все файлы, которые хранятся в проекте под системой контроля версий git, могут находиться в одном из 4 состояний:
- Untracked - неотслеживаемые файлы. Это новые файлы, информации о которых нет в списке изменений.
- Modified - измененные файлы. Это файлы, которые были изменены, и изменения которых не были зафиксированы.
- Added - индексированные файлы. Это файлы, которые были добавлены в индекс, но не были закоммичены.
- Commited - файлы, изменения которых были зафиксированы, т.е. сохранены в локальной базе изменений.
Для того, чтобы просмотреть статус файлов в вашем репозитории, необходимо выполнить команду:
git status
Вывод этой команды является очень подробным. Чтобы опустить подробности, воспользуйтесь командой:
git status -s
Пример результата выполнения этой команды:
M create_lesson.py
M scripts_utils/lesson_template.py
?? lessons/
Ведущая буква M указывает на то, что файл был изменен. Ведущие знаки вопроса, говорят нам, что файл является неотслеживаемым.
Чтобы добавить, как неотслеживаемые, так и измененные файлы в индекс, необходимо выполнить команду:
git add <file_name_1> <file_name_2> ... <file_name_N>
В случае, если вы хотите проиндексировать сразу все изменения, выполните команду:
git add .
Чтобы зафиксировать индексированные изменения, необходимо выполнить команду:
git commit -m "Add file_name_1 with very useful algo"
Важно: следите за тем, чтобы сообщение коммита (текущего изменения) начиналось с заглавной буквы, было информативным, а также являлось ответом на вопрос: Что делает этот коммит?
Пример, как надо:
git commit -m "Add new log format to also track actions's datetime"
- What does this commit do?
- Add new log format to also track actions's datetime
Примеры, как не надо:
-
Сообщение коммита начинается не с заглавной буквы:
git commit -m "add new log format to also track actions's datetime"
-
Сообщение коммита неинформативно:
git commit -m "Update files"
-
Сообщение коммта не является ответом на вопрос Что делает этот коммит?:
git commit -m "New log format for tracking actions's datetime"
Git хранит данные в виде последовательности снимков. Предположим, что у нас есть проект со следующей структурой:
├───A1
├───A2
Т.е. наш проект состоит всего из трех файлов: A1 и A2.
Во время индексации (выполнение команды git add
) Git вычислит контрольную сумму каждого файла (SHA-1 хеш), добавит файлы в репозиторий, а хеш - в файл индекса. Все файлы сохраняются в репозиторий в виде бинарных файлов и называются большими бинарными файлами или блобами.
Во время коммита (выполнение команды git commit
) Git вычисляет контрольные суммы каждого каталога (в нашем случае, только корневого каталога) и сохраняет все в репозиторий в виде объекта дерева каталогов. Этот объект и называется снимком. Затем Git создает объект коммита, который содержит указатель на дерево и метаданные. Это нужно, чтобы иметь возможность восстановить данные, соответствующие определенной версии.
Возвращаясь к нашему примеру, после выполнения коммита, наш репозиторий будет хранить 4 объекта: два блоба - по одному для каждого файла проекта, объект дерева каталогов, содержащий список файлов и соответствующих им блобов, а так же объект коммита, содержащий метаданные и указатель на объект дерева каталогов.
Если вы внесете изменения в ваши файлы и закоммитите их, то новый объект коммита также будет содержать указатель на предыдущий объект коммита.
Ветка в Git - это просто указатель на один из объектов коммитов в дереве коммитов. По умолчанию в вашем проекте есть основная ветка с именем master
. После добавления новых коммитов в ветку указатель будет автоматически перемещаться на последний коммит.
Поскольку Git рассчитан на одновременную работу с несколькими ветками, неясно, как Git определяет с какой веткой работает пользователь? Для этих целей в Git существует специальный указатель HEAD
- указатель на текущую локальную ветку. При переключении ветки Git просто перемещает этот указатель с одной цепочки коммитов на другую.
Теория работы с ветками будет изложена подробнее в других курсах. В рамках данного курса от вас не трубется знания ветвления.
Для просмотра истории коммитов воспользуйтесь командой:
git log
Стандартный вывод команды будет выглядеть следующим образом:
commit 5f6f5982322a5145512d31470e4eb8690eba548f (HEAD -> intro-les1, origin/intro-les1)
Author: EvgrafovMichail <[email protected]>
Date: Sat Aug 10 18:04:09 2024 +0300
Improve sem_id validation in lesson_template to create lessons for sem_00
Из стандартного вывода команды git log
можно извлечь следующую информацию:
- Хеш-сумму коммита, которая также является идентефикатором коммита: 5f6f5982322a5145512d31470e4eb8690eba548f
- Автора коммита: Author: EvgrafovMichail <[email protected]>
- Дату и время коммита: Date: Sat Aug 10 18:04:09 2024 +0300
- Сообщение коммита: Improve sem_id validation in lesson_template to create lessons for sem_00
Однако, вы всегда можете настроить формат вывода истории коммитов под свои нужды, прочитав документацию.
Все мы люди, а значит время от времени мы совершаем ошибки. Одной из таких ошибок может быть добавление неверных изменений или автоматически генерируемых файлов в репозиторий. Однако, посокльку Git является системой контроля версий, вы всегда можете вернуться к нужной версии проекта, откатив нежелательные изменения.
Для того, чтобы вернуться к определенной версии проекта, используйте команду:
git reset <commit_hash>
Важно: команду стоит использовать только в том случае, если над данной веткой проекта работаете только вы. После применения команды история ветки будет переписана, а значит, вы можете причинить много неудобств человеку, который работал над данной веткой вместе с вами.
Команды git reset
имеет три возможных режима отката измений:
--soft
- позволяет откатиться до указанного коммита с сохранением добавленных изменений в индексе.--mixed
(настройка по умолчанию) - позволяет откатиться до указанного коммита, изменения останутся в файлах, но не будут внесены в индекс (перед коммитом придется выполнять командуgit add
).--hard
- позволяет откатиться до указанного коммита, все внесенные изменения будут утеряны. Перед выполненимgit reset
с этой опцией, хорошенько подумайте, точно ли вы хотите потерять все внесенные изменения.
Поскольку Git является распределенной системой контроля версий, он поддерживает возможность работы с удаленными репозиториями. Удаленный репозиторий - это репозиторий Git, расположенный не на вашей локальной машине. Примером удаленного репозитория может являться репозиторий, размещенный в GitHub, как, например, репозиторий данного курса.
Для того, чтобы начать работать с удаленными репозиториями, необходимо добавить их в список удаленных репозиториев, с которыми вы осуществляете работу. Сделать это можно командой:
git remote add <name> <url>
При клонировании репозитория Git автоматически добавит удаленный репозиторий, который вы клонировали, в список под именем origin
.
Для отправки изменений в удаленный репозиторий используйте команду:
git push
Для скачивания изменений из удаленного репозитория используйте команду:
git pull
Для удаления удаленного репозитория из списка удаленных репозиториев для текущего локального репозитория используйте команду:
git remote remove <repo_name>