Git: руководство для начинающих. Разбираемся с основными концепциями системы контроля версий

0
1749
views

Перевод статьи «Git: The Beginner’s Guide to Understanding Core Version Control Concepts».

Git похож на работу с фотоальбомом

Git это жизненно важный инструмент в арсенале любого разработчика.

Например, буквально на днях этот инструмент позволил мне исправить большую ошибку, которую я отправил в продакшен (исключительно моя вина), и ушло на это всего 20 минут. Без Git исправление такой проблемы, вероятно, заняло бы несколько дней.

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

Примечание: в этой статье не будет ничего о GitHub — стороннем сервисе, позволяющем сохранять код в облаке. Git локален, а GitHub это облачное приложение. Это два совершенно разных инструмента, несмотря на общее назначение.

Что такое контроль версий?

Если вы достаточно взрослый человек, вы, вероятно, помните мир до появления Google Drive/Docs/Sheets и вам знакомы ситуации вроде такой, как на картинке:

Как выглядела групповая работа над проектом до появления Git
Group_Paper_All_4_Members_Sections_Included_Final_Draft_Final_3😔.docx

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

Реального способа контролировать разные версии проекта просто не существовало. Это был Дикий Запад.

Git решает эту проблему

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

Ладно, а как именно Git может помочь?

Основная функция Git — создание точек сохранения в ваших файлах. Мне нравится представлять это в виде точек сохранения в видеоиграх: вы доходите до какого-то уровня, сохраняетесь, и после этого, что бы вы ни сделали, вы всегда можете просто вернуться к точке сохранения, вам не придется проходить всю игру заново.

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

Как работает Git?

Этот основной функционал Git работает в два этапа:

  1. Добавление измененного кода и файлов в зону стейджинга, т. е., подготовка этих файлов к сохранению (коммиту)
  2. Собственно сохранение подготовленных файлов и кода (коммит).

Обязательная аналогия

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

Старинный фотоальбом
Ну ладно, я не НАСТОЛЬКО стар.

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

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

Наконец, когда все готово, вы надежно прикрепляете фотографии на страницу фотоальбома. Причем для создания хорошего альбома важно добавлять к фотографиям какие-нибудь подписи или названия, описывающие события на фото.

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

Какое это имеет отношение к Git?

Давайте применим эту аналогию к Git.

  • Сам процесс фотосъемки — аналог внесения изменений в файлы проекта (написание кода, создание или удаление файлов).
  • Выбор фотографий, которые вы хотите поместить в альбом, напоминает добавление изменений в зону стейджинга.
  • Прикрепление фотографий на страницу альбома это коммит — сохранение изменений.

Давайте разберем все это подробнее.

Фотосъемка напоминает изменение файлов проекта

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

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

Примечание: помните, что мы говорим о процессе, совершенно отдельном от сохранения файлов на жестком диске. Современные текстовые редакторы могут сохранять ваш код ежесекундно, но мы не это здесь разбираем. Когда я говорю о сохранении в Git, я имею в виду создание коммита, который сохраняет ваши изменения в истории изменений.

Распечатка (подготовка) выбранных фотографий напоминает добавление внесенных в проект изменений в зону стейджинга

В Git эта фаза предшествует созданию нового коммита. Сам процесс называется добавлением в стейджинг. При этом коммит не создается, это лишь подготовка к коммиту.

После добавления каких-нибудь файлов в стейджинг, вы можете решить еще что-нибудь изменить. Никаких проблем! Поскольку Git еще ничего по сути не сохранил, вы можете добавить в стейджинг и новые изменения, даже если они внесены в тот же файл, что и раньше. Как будто вы решили снять и распечатать еще несколько фотографий, чтобы затем добавить их в альбом.

Прикрепление фотографий на странице альбома напоминает коммит кода

Помещение фотографий в альбом
Photo by Julie Johnson / Unsplash

Это второй (и последний) этап создания «точки сохранения» (коммита). При создании коммита есть одно главное требование: нужно обязательно добавлять сообщение коммита. В фотоальбоме вы можете подписывать фотографии, чтобы человек, который в будущем будет просматривать альбом, мог понять, что эти снимки значат для вас. В Git вы пишете сообщение, чтобы описать те изменения, которые вы сохраняете в вашей кодовой базе.

Если вы будете писать плохие сообщения коммитов, просмотр истории изменений вашего кода будет бесполезен для любого читателя, в том числе и для вас. (Что хорошего в сообщении «Внесены некоторые изменения», если вы понятия не имеете, что это за изменения? Представьте, что вы находите в альбоме фотографию с подписью «Здесь сняты какие-то люди»).

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

Плозхе сообщения коммитов
Не делайте так! https://xkcd.com/1296/

Работа с Git

Но достаточно аналогий, идем дальше!

Установка

Во-первых, возможно, что Git у вас уже установлен. Откройте терминал (командную строку) и попробуйте запустить команду git --version. Если высветится номер версии, пропускайте шаг установки и читайте дальше. Если ваш терминал не будет знать, что вы имели в виду под словом «git», значит, его еще нужно установить. Для установки git в вашей операционной системе следуйте этим инструкциям.

Создание репозитория

Git отслеживает только те проекты, которые вы пометили в качестве репозиториев. Если применять все ту же аналогию с фотографиями, мы не можем прикреплять снимки в фотоальбом, если у нас нет фотоальбома.

Когда вы готовы начать новый проект, одним из первых ваших шагов (после создания папки проекта и перехода в нее) должен быть запуск команды:

git init
Вывод команды git init

Благодаря этой команде Git сразу начнет отслеживать любые изменения, которые вы внесете в этот проект. Если заглянуть под капот, мы увидим, что при этом в папке проекта создается новая скрытая папка .git, в которой содержится все необходимое для отслеживания изменений. Заглядывать в эту папку вам вряд ли понадобится, за исключением случаев, когда вы захотите сделать какую-то тонкую настройку, так что пока оставим ее, как есть.

Внесение изменений в проект

В этом руководстве я постараюсь делать все как можно проще. В папке моего проекта (которая одновременно является Git-репозиторием) будет один файл в разметке markdown — README.md. Если вам это поможет, можете представить, что любое вносимое мной изменение в этом файле это добавление каких-то функций и десятков строк кода в проекте. Так все будет выглядеть внушительнее.

Основные команды

git status

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

Вывод команды git status

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

Сейчас я добавлю мой файл README.md и снова запущу команду git status:

Вывод команды git status после добавления файла в директорию
Команда touch это тличный способ быстро создать пустой файл.

Git увидел, что я добавил новый файл в свой проект! Круто. Давайте теперь создадим точку сохранения — на всякий случай, ведь было бы жалко выполнять столько работы заново!

git add

Команда git add помещает файлы в стейджинг. Это как распечатка сделанных фотографий перед добавлением их в альбом. Но команде нужно указать, что именно нужно внести в стейджинг. Я укажу свой новый файл.

git add README.md
git status

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

Вывод команды git status после добавления файла в стейджинг.

Что же я фактически сделал, выполнив команду git add README.md? Я сказал Git, что хочу включить в будущий коммит все изменения, внесенные мной в файл README.md со времени последнего коммита.

Но вносить файлы по одному неудобно, особенно если учитывать, что мы часто работаем одновременно со многими файлами. Вместо того чтобы запоминать каждый файл, с которым вы работали, можно автоматически добавить в стейджинг все файлы, в которые были внесены изменения. Я предпочитаю использовать для этого флаг -А:

git add -A

Флаг -А говорит добавить в стейджинг все файлы с изменениями.

Примечание. Вы наверняка не раз столкнетесь с рекомендацией использовать git add . с той же целью (добавления всех измененных файлов в стейджинг). Это рабочий метод, но чтобы команда затронула все изменения, вы должны непременно находиться корневой директории проекта (точка означает текущую директорию). Поэтому, если вы перешли в какую-то вложенную директорию, а файл с изменениями находится вне этой директории, выполнив git add ., вы пропустите этот файл. А команда git add -A касается всего проекта, и не важно, в какой именно директории вы находитесь в данный момент.

git commit

Когда вы готовы сохранить свои изменения, вы делаете это при помощи команды git commit. Но вы же не забыли, что нужно добавить сообщение коммита? Если вы просто запустите git commit и нажмете Enter, в терминале откроется окно редактора (например, Vi или Nano), в котором вы сможете написать сообщение коммита.

Но можно написать сообщение сразу, добавив к команде флаг -m с последующим текстом сообщения в кавычках. Примерно так:

git commit -m "Added some really important information to the
README"

Если до сих пор все было в порядке, то теперь вы успешно сохранили свой код в Git! Теперь у вас есть точка, к которой вы всегда сможете вернуться, если в дальнейшем что-то пойдет не так.

Давайте еще раз посмотрим на весь этот процесс в гифке:

Примечание: в гифке используется git add, но мне стоило использовать git add -A для большей точности. Ну, и сообщения коммитов должны быть получше, чем у меня!

git log

Вы можете просмотреть историю своих коммитов, запустив команду git log. Чтобы перемещаться по логу, используйте стрелки на клавиатуре. В логе вы можете видеть даты и сообщения коммитов, а также авторов (людей, сделавших коммит). Каждый коммит имеет хэш — длинный уникальный ID, по которому можно обращаться к коммиту при необходимости.

Путешествие во времени

«Вы все время говорите, что Git позволяет перемещаться вперед-назад во времени. А как именно это происходит?»

git checkout

Термин checkout означает процесс переключения с одного коммита на другой. Помните, что каждый коммит имеет уникальный ID (хэш)? Я могу просмотреть свою историю коммитов, выбрать один из этих уникальных хэшей и использовать его с командой git checkout. Если коммит, который я хочу посмотреть, имеет хэш а2 (на самом деле хэши гораздо длиннее, это скорее что-то вроде 0c9b8f7c23dea4cf0a0285f14211124b6d5891e9), я могу запустить следующую команду:

git checkout a2

И после этого вся моя кодовая база откатывается назад во времени и все в ней теперь выглядит, как было сразу после того коммита. Это может пугать, потому что кажется, будто все изменения со времени того коммита утрачены, но не волнуйтесь! Они все сохранены и ждут вас… в будущем!

Вот этот процесс в гифке:

Имейте в виду, что третий коммит и все изменения внутри него находятся в полной сохранности. Вы можете к нему вернуться при помощи команды git checkout a3 или (более распространенный вариант) git checkout master.

Теперь, вернувшись в прошлое, вы увидите сообщение от Git. Что-то вроде следующего:

Note: checking out 'a2'.
 You are in 'detached HEAD' state. You can look around, make experimental
 changes and commit them, and you can discard any commits you make in this
 state without impacting any branches by performing another checkout.
 If you want to create a new branch to retain commits you create, you may
 do so (now or later) by using -b with the checkout command again. Example:
 git checkout -b 
 HEAD is now at a2 Another Message

На данный момент вы больше не находитесь в ветке master. Вы можете вносить какие-то экспериментальные изменения и даже создавать новые коммиты, и все это не затронет код в ветке master (в гифке это коммит с хэшем а3).

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

Заключение

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

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

Это означает, что нужно заставлять себя делать нечто большее, чем просто читать статьи в надежде чему-то научиться. Создайте новый репозиторий в пустой папке, начните добавлять туда файлы, почаще используйте git status и git log, чтобы увидеть, как все будет выглядеть.

Когда вы преодолеете кривую обучения Git, вам будет даже странно, как вы раньше могли без него обходиться!

ОСТАВЬТЕ ОТВЕТ

Please enter your comment!
Please enter your name here