Итак, начинаем мы как не странно с git и github. Почему эти инструменты? Все просто! Неотъемлемая чать разработки - это работа в команде.
Кодовая база большинства крупных компаний исчилсяется миллионами строк кода. Например: около 2 миллиардов строк кода содержат проекты Google.
Резонный вопрос: как поддерживать данный код? Как вносить изменения, если параллельно с проектами работают десятки разработчиков? Каким образом отслеживать изменения кода? Если кто-то накасячил, как узнать кто это был?
Одним из решений являются системы контроля версий. Системы контроля версий - это хранилище версий файлов. То есть, если вы изменили файл, вы сможете вернуться к его предыдущей версии.
На рисунке выше, представлен пример СКВ (системы контроля версий), при которой для каждого файла хранится информация о его предыдущих версиях. Например: Файл 1 менялся 28.11, 11.12, 15.12 и мы можем откатить его к V1.
Существует локальные, централизованные система контроля версий, когда все версии файлов хранятся на центральном сервере, и децентрализованные (Больше информации о типах вы можете узнать тут). Нас интересует последняя, к которой и относится Git.
Централизованные СКВ в каждой версии хранят изменения файлов относительно первой версии. Децентрализованные СКВ и в частности Git хранят снимок всех файлов в определенный момент времени (см. рисунок выше). Такой снимок называется коммит.
Кроме того, в децентрализованных СКВ разработчики полностью копируют все снимки себе на компьютер. И, если откажет центральный сервер, любой разработчик может его восстановить.
Перейдем к Git - мастодонту систем контроля версий.
Зайдем в любую папку, например /tmp/
, используя терминал (больше информации о терминале тут):
cd /tmp/
Создадим там папку hello
, в которой будет наш проект с помощью команды:
mkdir hello
Перейдем в нее:
cd hello
Инициализируем git-репозиторий:
git init
По итогу получим сообщение:
Initialized empty Git repository in /tmp/hello/.git/
которое означает, что мы успешно создали репозиторий. Теперь мы можем сохранять информацию о изменениях в файлах. Ура!
Проверим. Создадим файл README.md
с помощью команды:
touch README.md
Зайдем в файл README.md
:
nano README.md
И добавим строчку Hello world!
.
Прежде чем перейти к следующей команде поговорим о состояниях, в которых могут быть файлы.
Каждый файл в git может быть в двух состояниях:
- Отслеживаемые - под версионным контролем, которые хранятся в последнем коммите. Это состояние делится на три подсостояния:
- Зафиксированные (committed) - сохраненные в локальной базе;
- Подготовленные (staged) - отмеченные для включения в следующий коммит;
- Измененные (modified) - файлы, изменения которых не были зафиксированы;
- Неотслеживаемые - все остальные файлы.
Больше информации вы можете узнать тут.
Git состоит их трех секций:
- Git-директория (.git directory) - та часть git'а, в которой хранятся все снимки, все метаданные проекта;
- Рабочая директория (working directory) - то, что вы видите, зайдя в свой проект. По сути рабочая директория - это текущий выбранный вами снимок, файлы которого вы можете менять.
- Область подготовленных файлов (Staging Area, Индекс) - тут хранится информация о файлах, которые попадут в следующий коммит.
Больше информации вы можете узнать тут.
Теперь введем команду, которая проверяет состояние файлов в репозитории:
git status
И получим следующие строчки:
https://gist.github.com/b5f6cdb9414808e04079d363f96f37c7
Git показал нам, что README.md
находится в секции Untracked files
. То есть README.md
- неотслеживаемый файл (см. рисунок выше).
Чтоб добавить данный файл в следующий снимок, введите команду git add README.md
.
Теперь при вызове git status
мы увидем, что README.md
добавлен в Staging Area - область подготовленных файлов для последующего коммита (см. рисунок выше):
https://gist.github.com/356c53a6fddd50c20c171e7bd35cab3d
Итак, мы добавили все необходимые изменения. Теперь мы хотим создать снимок. Вводим команду:
git commit
У вас октроется редактор, в котором вы можете ввести комментраий к коммиту. Старайтесь писать то, что было сделано в рамках данного коммита. В данном случае: Мы добавили файл README.md
.
В итоге изменения внесенные нами стали зафиксированными и файл был добавлен в git-директорию (см. рисунок выше).
Отлично. Теперь давайте попробуем изменить наш файл README.md
.
nano README.md
И добавим или изменим предыдущую строку: Привет Мир!
.
В итоге, при вызове git status
мы получим следующий вывод:
https://gist.github.com/cddd1e7f964b98024f798aaaa44af571
Наши файл находится в измененном состоянии (см. рисунок выше).
Проделаем ту же последовательность комманд: git add
, git commit
и добавим наши изменения в снимок.
Перейдем к работе с github. Итак, чтобы создать репозиторий на github переходим сюда. Вводим название, описание.
Чтобы инициализировать наш удаленный репозиторий, введем команду:
git remote add origin https://github.com/[ваш_логин]/[имя_репозитория]
Затем:
git push -u origin master
Команда push позволит вам отправить изменения, которые вы внесли в своем локальном репозитории, на удаленный репозиторий.
В результате, обновив страницу репозитория, мы увидем там наш файл README.md
.
Давайте изменим наш файл в github. Для этого:
- Нажимаем на файл
README.md
; - Затем на карандашик.
- Меняем текст на любой.
- Снизу пишем комментарий к коммиту и нажимаем
Commit changes
.
Чтобы получить эти изменения на вашем компьютере, выполним команду:
git pull origin master
Перейдем к не менее интересной теме - ветвление. Работая в команде, вы решайте множество различных задач и обычно для каждой задачи создается отдельная ветка в репозитории, что позволяет не вмешиваться в основную линию. Хороший пример тут.
Ветка в git по сути является указателем на коммит. На рисунке выше есть две ветки: master
(основная ветка) и english
. Ветка master
указывает на коммит C31. Ветка english
указывает на коммит C42. Каждый раз, когда мы делаем коммит, указатель текущей ветки будет "передвигаться" на него.
Как определить на какой мы ветке? Для этого есть специальный указатель - HEAD
. С помощью команды git checkout [ветка]
мы можем менять ветку и соответсвенно указатель HEAD
. В примере выше текущая ветка - master
.
Рассмотрим ветвление на предыдущем примере (см. рисунок выше). Итак, мы сделали два коммита (С1 и C2). Вдруг нашему разработчику пришло в голову вернуть английский в файл и посмотреть результат.
Для данной задачи создаем отдельную ветку english
командой:
git branch english
Теперь внося изменения, мы не будем влиять на главную ветку.
Меняем файл README.md
и добавим строку Hello World!
, затем git add .
и git commit
.
В результате получим ветвление и коммит C32 (см. рисунок выше).
Больше информации о ветвлении тут.
Обычно в проектах для каждой задачи создаются отдельные ветки, что упрощает разработку.
В предыдущем примере у нас было две ветки: master
, english
. Мы закончили работу на задачей по переводу на английский и хотим слить эти изменения в основную ветку.
Для этого мы переходим в ветку master
с помощью команды:
git checkout master
Теперь сольем ветку english
в master
:
git merge english
Если у вас есть конфликты, которые нельзя автоматически слить, то вы получите следующие строчки:
https://gist.github.com/ca45a94831cfa6139121820e830aa9da
Вам необходимо зайти в файл README.md
, там будут несколько разделов:
https://gist.github.com/c444c00be3c69e1a75c03c89294cfde7
Верхняя часть с текущей ветки (master
). Нижняя часть с ветки english
.
Решаем этот конфлик, оставив необходимый текст. Делаем git add .
, git commit
.
На самом деле лучше использовать для решения конфликтов графический редактор. Например: Intellij Idea имеет втроенный резолвер конфликтов.
Мы рассмотрели основные понятия, связанные с системой контроля версий Git. Ваша задача изучить их более подробно, используя материалы на плафторме vectree.