Введение в Git

Итак, начинаем мы как не странно с git и github. Почему эти инструменты? Все просто! Неотъемлемая чать разработки — это работа в команде.

Кодовая база большинства крупных компаний исчилсяется миллионами строк кода. Например: около 2 миллиардов строк кода содержат проекты Google.

Резонный вопрос: как поддерживать данный код? Как вносить изменения, если параллельно с проектами работают десятки разработчиков? Каким образом отслеживать изменения кода? Если кто-то накасячил, как узнать кто это был?

Системы контроля версий

Одним из решений являются системы контроля версий. Системы контроля версий — это хранилище версий файлов. То есть, если вы изменили файл, вы сможете вернуться к его предыдущей версии.

На рисунке выше, представлен пример СКВ (системы контроля версий), при которой для каждого файла хранится информация о его предыдущих версиях. Например: Файл 1 менялся 28.11, 11.12, 15.12 и мы можем откатить его к V1.

Существует локальные, централизованные система контроля версий, когда все версии файлов хранятся на центральном сервере, и децентрализованные (Больше информации о типах вы можете узнать тут). Нас интересует последняя, к которой и относится Git.

Централизованные СКВ в каждой версии хранят изменения файлов относительно первой версии. Децентрализованные СКВ и в частности 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

И получим следующие строчки:

Git показал нам, что README.md находится в секции Untracked files. То есть README.md - неотслеживаемый файл (см. рисунок выше).

Чтоб добавить данный файл в следующий снимок, введите команду git add README.md.

Теперь при вызове git status мы увидем, что README.md добавлен в Staging Area - область подготовленных файлов для последующего коммита (см. рисунок выше):

Итак, мы добавили все необходимые изменения. Теперь мы хотим создать снимок. Вводим команду:

git commit

У вас октроется редактор, в котором вы можете ввести комментраий к коммиту. Старайтесь писать то, что было сделано в рамках данного коммита. В данном случае: Мы добавили файл README.md.

В итоге изменения внесенные нами стали зафиксированными и файл был добавлен в git-директорию (см. рисунок выше).

Отлично. Теперь давайте попробуем изменить наш файл README.md.

nano README.md

И добавим или изменим предыдущую строку: Привет Мир!.

В итоге, при вызове git status мы получим следующий вывод:

Наши файл находится в измененном состоянии (см. рисунок выше).

Проделаем ту же последовательность комманд: git add, git commit и добавим наши изменения в снимок.

Работа с Github

Перейдем к работе с github. Итак, чтобы создать репозиторий на github переходим сюда. Вводим название, описание.

Чтобы инициализировать наш удаленный репозиторий, введем команду:

git remote add origin https://github.com/[ваш_логин]/[имя_репозитория]

Затем:

git push -u origin master

Команда push позволит вам отправить изменения, которые вы внесли в своем локальном репозитории, на удаленный репозиторий. В результате, обновив страницу репозитория, мы увидем там наш файл README.md.

Давайте изменим наш файл в github. Для этого:

  1. Нажимаем на файл README.md;
  2. Затем на карандашик.
  3. Меняем текст на любой.
  4. Снизу пишем комментарий к коммиту и нажимаем 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

Если у вас есть конфликты, которые нельзя автоматически слить, то вы получите следующие строчки:

Вам необходимо зайти в файл README.md, там будут несколько разделов:

Верхняя часть с текущей ветки (master). Нижняя часть с ветки english. Решаем этот конфлик, оставив необходимый текст. Делаем git add ., git commit.

На самом деле лучше использовать для решения конфликтов графический редактор. Например: Intellij Idea имеет втроенный резолвер конфликтов.

Итог

Мы рассмотрели основные понятия, связанные с системой контроля версий Git. Ваша задача изучить их более подробно, используя материалы на плафторме vectree.


Originally published at gist.github.com.