Двадцать седьмой урок. Основы Git

Git — это система контроля версий и используется для того, чтобы периодически фиксировать изменения в проекте (каталоге, файлах) и при необходимости возвращаться к предыдущей версии. Кроме того git позволяет делать различные ответвления. Скажем вы решили внести такие изменения, в которых не уверены. С помощью git делается новая ветка, в ней работаете, и если что-то не понравилось, то можно откатиться назад. И наоборот, понравилось, тогда изменения объединяются с основной веткой.

Git работает локально и отслеживает состояние каталога проекта, включая все файлы в подкаталогах. Таким образом в терминологии git — проект или репозиторий — это самый обычный каталог.

С помощью git можно организовать и командную работу. Создается удаленный репозиторий, куда сливаются все изменения от других участников. Главная особенность git в том, что каждый участник работает со своей копией данных без риска что-либо повредить. Для создания удаленного репозитория можно воспользоваться сайтом github.com — он самый известный и популярный среди разработчиков. Есть похожий сайт — bitbucket.org, который позволяет создавать закрытые репозитории (куда можно приглашать других участников / до 5 — бесплатно).

Поскольку у нас секретов нет, то мы будем использовать github. Сразу отмечу, то git — это программа, а github — сайт, поддерживающий git. Не путайте их межу собой.

Для начала git следует установить на свой компьютер. Скачать нужную версию нужно на официальном сайте. По умолчанию загружается установщик для 64-битной версии Windows. Если у вас 32-разрядная, то отмените загрузку (если она автоматом началась) и выберите нужную версию. Запустите установщик и выполните инсталяцию.

После установки на рабочем столе появится иконка Git Bash. Запустите её. Это консоль. Наберите в ней:

git --version

Если ошибок нет, то вы увидите номер версии, например git version 2.15.1.

Для того, чтобы создать репозиторий из какого-нибудь каталога, в Проводнике или в Total Commander, на этом каталоге кликните второй кнопкой мыши, и в появившемся меню выберите пункт Git Bash Here — это запустит консоль для этого каталога (его имя будет в подсказке).

Перед началом работы с git следует указать имя и email (любые), которые будут использоваться для идентификации автора изменений (то есть вас). Наберите в консоли, указав свои данные.

git config --global user.name "ИМЯ"
git config --global user.email "EMAIL"

Сделать это достаточно один раз, и после этого можно начинать работу.

Для инициализации нового репозитория нужно выполнить команду:

git init

В этом каталоге появится скрытый подкаталог .git, который собственно и хранит все нужные данные. Если вручную его удалить, то это приведет к потере всей информации о версиях, ветках и т.п.

После того, как инициализация выполнена, можно посмотреть текущий статус:

git status

Появится сообщение что-то вроде такого:

On branch master

No commits yet

Untracked files:
	...

«On branch master» указывает на текущую ветку master — это главная или основная ветка проекта.

«No commits yet» — говорит о том, что нет коммитов (изменений), чтобы что-то фиксировать (индексировать).

В «Untracked files» выводится список файлов, которые git не отслеживает. В git принято явно указывать файлы, которые нужно отслеживать. Делается это для того, чтобы в публичный репозиторий попали только нужные файлы.

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

git add .

Точка указывает на «включить всё». Также git может добавить (проиндексировать) файлы из какого-то каталога:

git add assets

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

Теперь, если проверить стутус (git status), то появится сообщение

Changes to be committed:
	...

с теми файлами, которые были добавлены для отслеживания, но ещё не зафиксированы. Теперь мы можем выполнить первую фиксацию с помощью commit.

git commit -m "Первый коммит"

В git принято каждую фиксацию сопровождать каким-то комментарием. И хотя формально его можно опустить, но в своей практике считайте это обязательным условием. Сам комментарий должен быть кратким, но понятным.

Опять проверьте статус и вы увидите, что изменений больше нет.

Теперь попробуем изменить какой-нибудь файл проекта и опять посмотреть статус. Появится сообщение Changes not staged for commit, сигнализирующее о том, что есть изменения.

Если нужно посмотреть какие именно были изменения в файле, следует выполнить команду diff:

git diff ФАЙЛ

В результате git покажет изменения в файле в особой цветовой раскраске. Например новый текст будет отмечен зеленым цветом. Если не указывать файл, то git покажет все изменения по всем файлам.

Обратите внимание, что команда diff работает только до фиксации через commit.

Предположим, что эти изменения нам не понравились и нужно их отметить. Если фиксации не было, то отмена выполняется командой checkout:

git checkout -- ФАЙЛ

Если теперь посмотреть на файл, то увидим, что все внесенные изменения были отменены.

Бывает ситуации, когда файл был ошибочно добавлен для индексации через add до выполнения commit. Чтобы исключить его для фиксации (commit), следует выполнить:

git reset HEAD ФАЙЛ

Сам файл при этом не меняется — просто отменяется его добавление (через add).

Если же commit уже выполнен, то есть прошла фиксация изменений, то можно посмотреть всю историю командой

git log

Git выводит код (хэш/hash) коммита, его автора, время и комментарий.

Вывести лог можно и в более компактном виде, хотя набирать такой код неудобно.

git log --pretty=oneline --graph --all

Коммиты можно отменять. Есть три вида отмены. Первый — --soft — удаление всех коммитов до указанного, при этом изменений в самих файлах не происходит.

git reset --soft ХЭШ
Второй — --hard — делает отмену до указанного коммита и меняет состояние файлов и каталогов (делает «откат»).
git reset --hard ХЭШ
Третий — отмена последнего коммита. Здесь происходит возврат предыдущего состояния файлов:
git reset HEAD ХЭШ
Хэш (код коммита) довольно длинный, но набирать его полностью не обязательно. Достаточно набрать первые 4 символа, вроде 7d2b.

Использовать reset не самая лучшая практика, поскольку теряется вся проделаная работа. Если стоит задача оттестировать какой-то новый код, то лучше использовать отдельную ветку. Об этом пойдет речь ниже.

В целом же работа с git происходит такой схеме:

В проекте могут находиться файлы и каталоги, которые не нужно отслеживать. Чтобы их исключить нужно создать файл .gitignore, где указать что именно git должен игнорировать. Например:

.htaccess
.gitignore
index.php
license-LPF.txt
lpf-core/*
lpf-content/*

Символ звездочки * указывает на «любые файлы». Если теперь проверить статус, то указанные файлы и каталоги git больше не видит.

Git отслеживает только файлы, но не пустые каталоги. Это его особенность. Поэтому, если в вашем проекте должен быть какой-то обязательный каталог, и чтобы git его увидел, в него следует поместить пустой файл с именем .gitkeep. Когда мы будем рассматривать работу с удалённым репозиторием, этот прием вам пригодится.

Теперь я расскажу о более сложных вещах — ветвлении.

По умолчанию git создает только одну главную ветку master. В процессе работы, иногда нужно сделать такие изменения, которые потребуют какого-то тестирования, или вообще могут быть отменены. Для этого делается новая ветка, например dev которая будет копией master. Дальше нужно будет переключиться на ветку dev и работать уже с ней, как обычно.

Когда работа будет сделана, можно будет слить эту ветку с master, то есть ветки опять станут одинаковыми. Если же ветка dev оказалась ошибочной, то можно переключиться на master, а dev, если не нужна, удалить.

Перед созданием новой ветки зафиксируйте все изменения (commit).

Создание новой ветки делается коммандой branch:

git branch dev

В данном случае будет создана ветка dev. При этом, обратите внимание, мы всё ещё находимся в ветке master. Чтобы переключаться между веток используется команда checkout

git checkout dev

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

В ветке dev сделаем несколько изменений и зафиксируем их. Если теперь переключиться на master, то этих изменений не будет. Обратное переключение на dev — опять видим изменения. Git запоминает измененные файлы в каждой ветке.

Теперь мы хотим выполнить слияние master и dev. Вначале нужно зафиксировать все изменения в dev, иначе git не позволит выполнить слияние. После этого переключаемся на ветку master и выполняем слияние с помощью команды merge:

git merge dev

В сообщении будет указано, что это было «быстрое слияние» Fast-forward — когда нет сложного ветвления или конфликта, то git выполняет все изменения простым копированием истории из одной ветки в другую.

Если посмотреть историю через log, то увидим все коммиты из dev.

Ветки dev и master после слияния опять одинаковые. Если нужно дальше продолжать работу, то переключаемся на dev, вносим изменения, а после опять слияние с master. В принципе почти вся работа с ветками как раз и происходит по такой схеме. Если же ветка не нужна, то её можно удалить:

git branch -d dev

Если опять попробовать переключиться на dev, то git выдаст сообщение, что про такую он не в курсе. Узнать текущую ветку можно так:

git branch

А если нужно посмотреть все существующие ветки:

git branch -a

Git очень мощная программа. Для её полного изучения требуется много времени, но на самом деле, для основной работы требуется лишь самая малость, описанная в этом уроке. Вы будете встречать в Интернете много других руководств по Git'у, где рассказывается от различных хитростях, настройках, особых ключах и коротких сокращений. Мой совет — начать с основ, которые будут работать всегда и везде. Если в своей работе вам придется работать в команде, где над кодом работает сразу несколько разработчиков, то вам придётся изучить git для решения более сложных задач. Пока же вам нужно выучить только то, что требуется обычному разработчику, который в одиночку работает над своим проектом.

На официальном сайте вы найдёте книгу для изучения git. Используйте её в качестве своего учебника на будущее.

Задание

Проверьте все примеры на каком-то тестовом каталоге. Если нужно, создайте небольшую шпаргалку с командами git.

Проверить уровень знаний git довольно сложно, поэтому просто начинайте им пользоваться. :-)