Введение в Git

7 января 2015
Git – это простая и удобная программная система для хранения и управления версиями файлов. Гит позволяет вести хронологию разработки проекта, даёт возможность использовать ветки, откатывать изменения, объединять изменённые фрагменты проекта. В 2014 году вышел мажорный релиз Git 2.0.0, который изменил поведение некоторых команд и параметров (список изменений https://git.kernel.org/pub/scm/git/git.git/tree/Documentation/RelNotes/2.0.0.txt). Далее пойдёт речь о Гите второй версии.

Официальная документация: https://git-scm.com/docs

Словать терминов

Репозиторий (repository) – служебная папка с именем .git, в которой Git хранит файлы проекта, журнал действий, индекс файлов и другую служебную информацию.

Локальный репозиторий (local repository) – репозиторий на компьютере разработчика, где тот ведёт работу на проектом (правит, реализует новые функции) и в следствии чего возникают изменения в файлах проекта: изменяются текущие, создаются новые, удаляются ненужные.

Удалённый репозиторий (remote repository) – репозиторий на внешнем сервере. Как правило, удалённый репозиторий является главным и на него отправляют свои правки разработчики, а так же с него разработчики клонируют локальные репозитории.

Рабочая область (working directory) – родительская папка репозитория (папка на уровень выше .git), в которую загружаются файлы и папки проекта для их правки разработчиком. В рабочую папку Git загружает файлы проекта и из неё Git берёт файлы для записи в репозиторий.

Индекс, область подготовленных файлов (index, staging area) – помеченные файлы проекта, которые подготовлены для записи в репозиторий.

Ветка (branch) – последовательность изменений проекта (файлы), хранимые в репозитории. В рамках одного репозитория Гит позволяет вести несколько веток. Ветки решают споры по проекту: каждый разработчик может вести своё видение функционала в отдельных ветках, а на выходе выбрать лучшую реализацию.

Мастер (master) – главная ветка репозитория, создается автоматически вместе с репозиторием.

Коммит (commit) – запись файлов проекта в ветку репозитория. Коммит берёт только файлы из индекса (области подготовленных файлов).

HEAD – указатель на текущий коммит.

Сheckout – инструкция по смене веток, переходу к заданному коммиту или откат до действия из журнала действий.


Начало работы

Существует два концептуальных вида Гита – консольный (Git Bash) и графический (Git GUI). Я использую чаще консольный вариант, так как он гибче. В примере у нас есть тестовый сайт, который хотим начать вести с Гитом. Сайт находится в папке C:\OSPanel\domains\test.ru\www

Шаг 1 - открытие проекта

Запускаем консольный Git Bash.


Так как сайт ранее не использовался с Гитом, то нам нужно создать репозиторий. Для этого командой cd C:/OSPanel/domains/test.ru/www переходим в папку сайта и вводим команду git init, которая создаст репозиторий (служебную папку .git).

Готово, репозиторий создан. Дополнительно у нас автоматически создалась и открылась главная ветка проекта – master.


Если для сайта уже есть репозиторий, тогда после открытия Git Bash просто вводим команду cd C:/OSPanel/domains/test.ru/www, которая переместит нас в папку с репозиторием и откроет ветку master.

Шаг 2 - добавление файлов в индекс

Далее нам нужно сохранить рабочие файлы проекта в Гите. Git разделяет файлы на три вида:
  • Отслеживаемые (tracked) – файлы, которые разработчики правят и которые должны отслеживаться Гитом для учёта изменений.
    Отслеживаемые файлы имеют следующие состояния:
    изменён (m, modified): файл хранился в репозитории, был изменён и обновлённая версия ещё не записана в репозиторий;
    индексирован (s, staged): файл добавлен в индекс для записи в репозиторий через коммит;
    зафиксирован (c, committed): файл хранится в репозитории и с момента своей последней записи (коммита) не менялся;
    удалён (d, deleted): файл хранится в репозитории, но был удалён в процессе разработки и в новом коммите его уже нету.
  • Неотслеживаемые (untracked) – остальные файлы проекта, не запрещённые к индексации;
    не запрещены к добавлению в репозиторий: файлы, которые не добавлены в репозиторий или индекс;
    игнорируются для отслеживания (ignored): файлы намеренно исключаются для отслеживания. Шаблон для исключений задаётся в файле .gitignore, который может быть создан разработчиком в любой папке проекта и количество этих файлов в разных папках не ограничивается.

Если файл был отправлен (закоммичен) в репозиторий и при следующем коммите не изменялся, то Гит не записывает ещё один дубликат файла, а использует ссылку на прошлый вариант, который уже есть в репозитории. Это делается для экономии места и увеличения скорости работы программы.


Вернёмся к сайту. Корневая папка тестового сайта содержит два файла:


Вводим в консоль Гита команду git status, которая отобразит текущее состояние рабочей области и индекса


Консоль вывела два файла, которые не отслеживаются Гитом (строка Untracked files): index.php и readme.txt. Так как два этих файла являются рабочими и входят в интересы для учёта версий, то добавим их в репозиторий.

Выполняем команду git add ., которая добавляет содержимое текущей папки рабочей области в индекс для последующего коммита.

Готово, теперь index.php и readme.txt, которыее ранее были некотслеживаемыми, стали отслеживаться Гитом и были помещены в индекс с состоянием "новые файлы". Проверить это можно командой git status


Шаг 3 - отправка индекса в репозиторий (коммит)

Теперь необходимо записать файлы из индекса в репозиторий, что делается командой git commit -m "Старт проекта". Строка "Старт проекта" это комментарий к коммиту. Текст комментария можно указывать любой, но нужно стараться писать осмысленные и развёрнутые заметки, чтобы в дальнейшем по истории было проще отыскать тот или иной коммит.


Готово, проект записан в репозиторий.

Шаг 4 - правки на следующий день

Допустим, на следующий день мы решили чуть подправить сайт. Открываем папку с сайтом и правим index.php. Далее запускаем Git, переходим к репозиторию сайта и вводим команду git status. В результате увидим, что есть один изменённый файл – index.php


Чтобы сразу отправить изменения в репозиторий, введём команду git commit -a -m "Изменил значения переменных и заменил сложение вычитанием". В команде появился новый параметр -a, который перед началом процесса коммита добавляет изменённые файлы и сведения об удалённых файлах в индекс, таким образом мы минуем команду git add.

Готово, второй коммит отправлен.

Изменим файл index.php ещё раз и отправим третий коммит git commit -a -m "Заменил вычитание умножением".

Теперь у нас в репозитории три коммита. Чтобы посмотреть историю коммитов, вводим команду git log


Для более компактного вывода истории можно использовать команду git log --oneline


В данном примере коды c55facc, db3b7e1 и d0c1029 это хэш-суммы указателей на коммиты. По указателям (ссылкам) мы можем загружать файлы проекта из выбранного коммита в рабочую область .

Шаг 5 - загрузка старой версии проекта

Бывают случаи, когда нужно вернуть проект к ранней версии. Для этого через команду git log --oneline получаем список коммитов, выбираем указатель нужного коммита (в нашем примере это d0c1029) и вводим команду git checkout d0c1029. Данная команда загружает в рабочую область файлы проекта по состоянию на коммит d0c1029, а так же переводит на этот коммит указатель HEAD.


Вот так выглядит ветка коммитов (указатели master и HEAD ссылаются на разные коммиты):


Если мы снова хотим вернуться в самый свежий коммит ветки master, то вводим команду git checkout master, по результатам которой указатель HEAD станет ссылаться на master, а в рабочей области проекта снова будут находиться файлы из самого свежего коммита ветки.


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