ITT1608: Управление разработкой программного обеспечения

Электронная версия курса

2019 © РФЭТ: Прикладная информатика

Сгенерировано для пользователя Базаров Евгений Васильевич

Выходные сведения

Этот документ является автоматически сгенерированной печатной версией электронного курса РФЭТ: Прикладная информатика

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

http://it.rfet.ru/course/~flIg

Данная электронная книга сгенерирована системой EduTerra.pro в соответствии со спецификацией EPUB 3.0.1.

Получив данную печатную версию, Вы со своей стороны обязуетесь:

использовать предоставленные Вам ресурсы только лично;

не обращаться к помощи третьих лиц или технических средств для улучшения результатов взаимодействий;

использовать ресурсы системы исключительно в образовательных целях;

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

Документ автоматически сгенерирован 03 сентября 2019, 10:43:55

Подготовлено для двусторонней печати на бумаге формата A4.

Информация о курсе

Концепции управления версиями в широком смысле призваны облегчить совместную работу больших коллективов над изменяющейся информацией. Управление версиями получило широкое распространение в сфере информационных технологий при разработке программного обеспечения благодаря появлению систем управления версиями (от англ. Version Control Systems или VCS). Практика показала, что управление версиями с успехом используется и в других областях, в которых ведется работа с большим количеством непрерывно изменяющихся электронных документов.

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

Пройдя этот курс, Вы научитесь:

производить установку Git и подготовку рабочего окружения на различных платформах;

создавать репозитории, записывать изменения в репозиторий;

просматривать истории ревизий, отменять изменения;

работать с удаленными репозиториями, ветвями и тэгами;

понимать рабочие процессы для организации коллективной разработки;

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

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

Рекомендованная литература

Информационные технологии Авторы: Шандриков А. С. Минск: РИПО, 2015 г. , 443 с.

Информационные технологии отраслевой направленности : учебник [Электронный ресурс] ; Региональный финансово-экономический техникум. — Курск, 2011. — 158 с.

Информационные технологии отраслевой направленности : практикум [Электронный ресурс] ; Региональный финансово-экономический техникум. — Курск, 2011. — 108 с.

Основы программирования : учебник [Электронный ресурс] ; Региональный финансово-экономический техникум. — Курск, 2015. — 257 с.

Основы программирования : практикум [Электронный ресурс] ; Региональный финансово-экономический техникум. — Курск, 2015. — 56 с.

Распределенная система контроля версий Git, документация – электронный ресурс

Подготовка к работе

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

Введение

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

Процесс работы над документами (исходными кодами, проектами и т. д.) можно сравнить с прохождением компьютерной игры. По ходу продвижения Вы регулярно сохраняетесь, чтобы в случае неудачи не приходилось начинать сначала. Так и при работе с документом: Вы нажимаете кнопку «Сохранить» в своём редакторе, чтобы в случае случайного сбоя электроэнергии Вам не приходилось воспроизводить всю свою работу заново. Этот подход знаком практически каждому пользователю на Земле.

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

Подходы к версионности

Многие люди, незнакомые с современными системами контроля версий, имея в виду обозначенную проблему, стараются «изобрести велосипед» для решения повседневных задач, связанных с работой над изменяющейся информацией. Чтобы понять, как системы контроля версий позволяют облегчить этот процесс, рассмотрим вкратце эволюцию подходов к обеспечению версионности.

Версионность «вручную»

Самый наивные подходы, которые можно встретить и по сей день в работе некоторых коллективов, подразумевают сохранение в другие файлы («Сохранить как...» в редакторе) или копирование файлов в другую папку перед сохранением; некоторые даже используют дату и время в названии таких файлов и папок.

Эти подходы чрезвычайно просты, именно поэтому они так популярны среди обычных пользователей, но у них есть ряд серьезных недостатков:

человеческий фактор — очень легко случайно перепутать имена файлов или папки, непреднамеренно сохранив документ поверх очень важной ревизии;

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

большая избыточность при хранении, поскольку каждый раз приходится сохранять целиком копии документов, которые отличаются лишь небольшим количеством изменений;

сложность просмотра истории изменений (этот недостаток сопряжен с предыдущим) — если Вас интересуют только изменения, Вам придется искать их вручную.

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

Традиционные модели

Локальные системы контроля версий

Разработчики программного обеспечения были первыми, кто погрузился в решение проблем версионности. В основе первых систем управления версиями лежали алгоритмы сравнения файлов и простые локальные базы данных объектов. Изменения записывались в базу данных «снимками», которые фиксировали все совершенные изменения.

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

Централизованные системы контроля версий

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

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

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

Кроме того, централизованные системы управления версиями вынуждают Вас для всех операций использовать сетевые ресурсы, которые во всех отношениях «дороже» локальных.

Распределенная модель

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

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

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

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

Основные понятия

Следует отметить, что устоявшейся терминологии в области управления версиями не существует и по сей день. Зачастую такие термины, как «управление версиями» и «контроль версий», «версия» и «ревизия», «управление версиями» и «версионность», «репозиторий» и «хранилище», а также их английские аналоги употребляются как синонимы. Кроме того, в различных контекстах под «управлением версиями» довольно часто понимают «систему управления версиями».

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

Итак, при работе с Git Вы неизбежно столкнетесь со следующими основными понятиями.

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

Один проект — один репозиторий

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

Операция создания ревизии (committing changes в англ.) является грубым аналогом операции «Сохранить» в текстовом редакторе — в общем случае ею нужно пользоваться как можно чаще, чтобы не потерять ничего важного; любые незафиксированные изменения (uncommitted changes в англ.) не могут быть отслежены с помощью Git.

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

Объект (object или blob в англ.) — это файл, сохраненный в локальной базе данных в определенной ревизии. О том, как Git хранит объекты, Вы узнаете в главе «Базовые операции».

Вы также можете встретить термин «Конфигурационное управление» (прямой аналог английского термина «Software configuration management (SCM)») в отношении контроля версий. Следует иметь в виду, что контроль версий — это одна из задач более общей области знаний. Однако в некоторых контекстах термин «SCM» также употребляется как синоним для «VCS».

Установка Git

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

Linux

Самый простой и надежный способ установки бинарных пакетов Git в Linux — с помощью встроенного менеджера пакетов.

Если у Вас Fedora, можно воспользоваться yum:

sudo yum install git-core

Если же у Вас Ubuntu или другой дистрибутив, основанный на Debian, воспользуйтесь apt-get:

sudo apt-get install git

Для подтверждения того, что Git установлен корректно, воспользуйтесь следующей командой:

git --version

Вы должны увидеть номер версии Git, установленного на Вашей машине. Например:

git version 1.7.2.2

Mac OS X

Для установки Git на Ваш Mac воспользуйтесь графическим установщиком, который Вы можете скачать с официального сайта:

http://code.google.com/p/git-osx-installer

Графический установщик Git для Mac OS X

Для подтверждения того, что Git установлен корректно, воспользуйтесь следующей командой:

git --version

Вы должны увидеть номер версии Git, установленного на Вашей машине. Например:

git version 1.7.2.2

Windows

Для установки Git на компьютер с Windows воспользуйтесь проектом msysgit — Git for Windows:

http://msysgit.github.io/

Графический установщик Git для Windows

После установки у Вас будет как консольная версия (включающая SSH-клиент, который пригодится позднее), так и стандартная графическая.

Для подтверждения того, что Git установлен корректно, воспользуйтесь следующей командой:

git --version

Вы должны увидеть номер версии Git, установленного на Вашей машине. Например:

git version 1.7.2.2

Первоначальная настройка

Итак, Git успешно установлен на Вашем компьютере. Теперь, подобно тому, как Вы подготавливаете своё рабочее место перед началом работы, Вы должны подготовить Git с помощью команды git config. Большинство настроек требуется выполнить только один раз после установки, однако Вы можете захотеть поменять те или иные конфигурационные параметры в дальнейшем.

Git использует следующие файлы для хранения конфигурационных параметров:

файл /etc/gitconfig позволяет определить системные настройки, общие для всех репозиториев всех пользователей системы (в Windows этот файл находится внутри корневого каталога msysgit);

файл ~/.gitconfig, находящийся в домашней папке текущего пользователя операционной системы, позволяет переопределить системные настройки глобальными, распространяющимися на все репозитории конкретного пользователя (в Windows этот файл находится в C:\Documents and Settings\$USER);

файл .git/config в каждом репозитории позволяет переопределить системные и глобальные настройки конкретными, которые распространяются только на указанный репозиторий.

Настройки авторства

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

git config --global user.name "John Doe"
git config --global user.email johndoe@example.com

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

Установки окончаний строк

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

для пользователей Unix/Mac

git config --global core.autocrlf input
git config --global core.safecrlf true

для пользователей Windows

git config --global core.autocrlf true
git config --global core.safecrlf true

Выбор редактора

Для многих интерактивных команд Git использует текстовый редактор. По умолчанию используется стандартный редактор Вашей системы, обычно это vi или vim. Если Вы хотите использовать другой редактор, например, TextWrangler выполните следующую команду:

$ git config --global core.editor edit

Настройка отображения цвета

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

Для включения отображения цвета выполните следующие команды:

git config --global color.branch auto
git config --global color.diff auto
git config --global color.status auto

Получение помощи

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

Ваш главный источник информации о командах Git — это встроенный в Git механизм помощи под названием git help. Использовать его предельно просто: Вы пишете в терминал git help <команда>, где <команда> — это интересующий Вас инструмент. Например, получить помощь по уже известной Вам команде git config можно, набрав в терминале следующее:

git help config

Как правило, справка отображается с помощью Unix утилиты man. Вы можете использовать навигационные стрелки для прокрутки содержимого, а также клавишу q для выхода из справки.

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

Тест «Подготовка к работе»

К этому моменту Вы должны иметь базовое представление о системах управления версиями.

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

Варианты заданий

Задание 1

Системы управления версиями

производят автоматическое сохранение документов, чтобы не потерять изменения

позволяют хранить несколько версий одного и того же документа

позволяют коллективно редактировать один и тот же файл в режиме реального времени

помогают в определении автора того или иного изменения

усложняют совместную разработку крупных проектов

Задание 2

Основным недостатком централизованных VCS является

отсутствие понятия «ревизии»

невозможность установить авторство изменений

наличие «узкого места» системы — центрального сервера

невозможность организации совместной работы

наличие «узкого места» системы — центрального администратора, разрешающего конфликты

Задание 3

Git-репозиторием может быть

только папка, содержащая текстовые файлы

любая папка, не находящаяся под контролем версий Git

только папка, находящаяся внутри папки «Мои документы»

любая папка

любая папка, не находящаяся под контролем версий других VCS

Перейти к выполнению заданий

Базовые операции

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

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

В предыдущей главе Вы узнали о том, что такое Git-репозиторий. Первый шаг к управлению версиями с помощью Git — это получение репозитория. Git позволяет создать новый репозиторий или клонировать существующий.

Создание нового репозитория в Git осуществляется с помощью команды git init. Её необходимо выполнить в терминале, находясь в папке, содержимое которой Вы хотите поместить под управление версиями.

Выполним простое упражнение. Откройте терминал и введите следующие команды:

mkdir my_first_repo
cd my_first_repo
git init

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

Initialized empty Git repository in my_first_repo/.git/

Поздравляем, Вы только что создали Ваш первый Git репозиторий!

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

Повторим, что Git-репозиторий можно создать из любой папки, не находящейся под контролем версий Git (иными словами, репозитории Git не допускают вложенности).

Клонирование репозитория

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

Git позволяет клонировать как локальные, так и удаленные репозитории, с помощью команды git clone. Базовый синтаксис этой команды довольно прост: Вы указываете путь к репозиторию, а также, если необходимо, наименование папки, в которую будет помещен его клон.

Локальное клонирование

Вы можете клонировать репозитории на своей рабочей машине. Например, клонируем созданный нами ранее репозиторий my_first_repo:

cd ..
git clone my_first_repo/ my_first_clone

Вы должны получить следующее сообщение:

Cloning into my_first_clone...
done.
warning: You appear to have cloned an empty repository.

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

По умолчанию Git не будет копировать объекты при локальном клонировании репозитория. Вместо этого он создаст жёсткие ссылки (hard links) в целях экономии места. Если Вы хотите сделать полноценную копию репозитория (например, в целях резервного копирования), используйте параметр --no-hardlinks:

git clone --no-hardlinks /path/to/repo destination_directory

Клонирование удаленных репозиториев

Для ведения совместной разработки как правило используют удалённое клонирование: разработчики получают локальные копии центрального репозитория, работают с ними и периодически синхронизируют свои изменения с центральным репозиторием.

Для примера создайте клон тренировочного репозитория (этот репозиторий специально подготовлен для занятий этого курса и размещен на GitHub):

cd ..
git clone git://github.com/inca/gitbook-sample

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

Cloning into gitbook-sample...
remote: Counting objects: 18, done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 18 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (18/18), done.

Хранение объектов

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

Схема хранения

Главное отличие Git от любых других VCS (например, Subversion и ей подобных) заключается в понятии о данных: как правило они хранят информацию как наборы изменений файлов — «changesets». Эти системы относятся к хранимым данным как к набору файлов и изменениям в каждом из них во времени.

Схема хранения «changeset storage».

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

Схема хранения «snapshot storage».

Целостность данных

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

Git использует хэш-алгоритм SHA-1 для вычисления контрольных сумм. Это шестнадцатиричное число длиной в 40 знаков, оно вычисляется на основе содержимого файла или структуры папки, хранимой Git.

089a26f2402c94b00c819f0ebae69f1547317a88

Пример хэша SHA-1.

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

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

О состояниях

Концепция о состояниях объектов очень важна для изучения Git. Все файлы Git-репозитория находятся в одном из следующих состояний:

зафиксированные (committed) — файлы, сохраненные в локальной базе данных Git в результате создания ревизии (как Вы помните из главы «Подготовка к работе», в Git принято называть эти файлы объектами);

измененные (changed) — файлы, измененные с момента последнего создания ревизии;

актуальные (unchanged) — соответственно, файлы, не измененные с момента последнего создания ревизии;

подготовленные (staged) — измененные файлы, отмеченные для включения в следующую ревизию;

неотслеживаемые (untracked) — файлы, о которых Git еще «не знает» (т.е. файлы, не добавленные под контроль версий Git).

Таким образом, Git-репозиторий состоит из следующих логических частей:

служебная папка .git — это хранилище метаинформации и объектов, здесь хранятся зафиксированные объекты, ревизии, ветви и прочая служебная информация;

область подготовленных файлов (staging area или index в более ранних версиях Git) — это файл, также расположенный внутри .git, содержащий информацию об изменениях, которые необходимо включить в ревизию при следующем её создании;

рабочее дерево (working tree) или рабочая папка (working directory) — это актуальные, измененные и неотслеживаемые файлы и папки репозитория; именно с ними Вы производите основную работу: создание, редактирование и удаление.

Следует отметить, что, технически, термин «репозиторий» относится именно к папке .git, однако в менее строгих контекстах принято называть репозиторием папку, содержащую .git и рабочее дерево.

Внесение изменений

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

Вы добавляете, удаляете и изменяете файлы в рабочей папке;

Вы отмечаете файлы для внесения в ревизию;

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

Рассмотрим подробнее эти операции.

Текущее состояние

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

Откройте тренировочный репозиторий, клонированный ранее и просмотрите его статус:

cd gitbook-sample
git status

Если Вы не вносили в репозиторий никаких изменений, Вы должны увидеть следующий текст:

# On branch master
nothing to commit (working directory clean)

На слэнге Git слово «чистый» («clean» в англ.) означает, что все файлы рабочей папки находятся в актуальном состоянии (т.е. не были изменены с момента создания последней ревизии).

Добавление файлов

Операция добавления файлов в репозиторий Git подразумевает следующий простой алгоритм:

Вы создаете файл и сохраняете его в рабочей папке;

Вы добавляете файл в репозиторий с помощью команды git add.

Рассмотрим этот алгоритм на практике. Cоздайте в рабочей папке тренировочного репозитория файл test.txt и еще посмотрите на состояние репозитория:

echo "Git is awesome" > test.txt
git status

Только что созданный файл еще не находится под контролем версий Git, поэтому Вы можете увидеть его в разделе «Untracked files»:

# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	test.txt
nothing added to commit but untracked files present (use "git add" to track)

Чтобы добавить файл под контроль версий используйте команду git add. Эта команда отмечает файлы для включения в ревизию, или добавляет их в область подготовленных файлов. Вы можете указать отдельный файл, папку или шаблон пути (например, чтобы добавить все файлы с расширением scala Вам необходимо выполнить команду git add *.scala).

Для добавления всех файлов репозитория в staging area введите следующую команду:

git add .

Проверьте статус репозитория. Файл test.txt должен быть отмечен в подготовленной области (в разделе «Changes to be commmitted») репозитория как новый файл («new file»):

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   test.txt
#

Запомните, что вновь создаваемые файлы всегда должны помещаться под контроль версий Git явно, с помощью команды git add.

Редактирование файлов

Операция редактирования файлов аналогична операции добавления.

Перейдите в тренировочный репозиторий и откройте файл doc1.txt в текстовом редакторе. Удалите фразу Sample content и введите следующий текст:

I'm having a lot of fun learning Git.

Сохраните файл и убедитесь, что файл doc1.txt находится в разделе «Changed but not updated» сообщения о состоянии репозитория:

# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   doc1.txt
#

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

git add .

Убедитесь, что соответствующее изменение было помещено в staging area:

# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	modified:   doc1.txt
#

Удаление файлов

Теперь рассмотрим еще одну распространенную операцию: удаление. По своей сути удаление файла — это такое же изменение репозитория, как и уже известные Вам операции добавления и редактирования файлов. Однако есть одно важное отличие: для внесения в ревизию информации о том, что файл должен быть удален, недостаточно простого удаления файла из рабочей папки. Вы также должны отметить этот файл в staging area как удаленный с помощью команды git rm.

Перейдите в тренировочный репозиторий и удалите файл README:

rm ./README

Статус репозитория теперь должен содержать следующие строки:

# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	deleted:    README
#

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

git rm ./README

Обратите внимание, что теперь файл внесен в подготовленную область как удаленный:

# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	deleted:    README

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

Подготовка изменений

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

При обычной работе с Git-репозиториями изменения, внесенные с момента последней ревизии, остаются только в рабочем дереве. Перед созданием очередной ревизии Вы выбираете, какие изменения необходимо в неё включить.

Самый распространенный подход — это включение всех изменений с помощью следующей команды:

git add -A

Эта команда отмечает неотслеживаемые, измененные и удаленные файлы в staging area для включения в следующую ревизию. Таким образом, после выполнения этой команды рабочее дерево становится полностью синхронизированным с областью подготовленных файлов.

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

Еще немного о Staging Area

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

Область подготовленных файлов — это макет будущей ревизии.

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

«Очистка» рабочего дерева

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

git reset -- .
git checkout .
git clean -fd

Эти команды будут подробнее рассмотрены в последующих главах курса, пока остановимся на кратком описании результатов их выполнения:

команда git reset -- . удаляет все изменения из области подготовки, в Git эта операция называется «unstaging»; при этом сами изменения не исчезают и остаются в рабочем дереве; файлы, добавленные в рабочее дерево с момента создания последней ревизии, становятся неотслеживаемыми;

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

команда git clean -fd удаляет неотслеживаемые файлы.

Таким образом, после выполнения этих команд рабочее дерево становится «чистым», т.е. полностью синхронизированным с последней ревизией.

На слэнге Git такая последовательность действий называется «hard reset», она может быть выполнена с помощью одной команды:

git reset --hard

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

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

Создание ревизии

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

Если Вы следовали всем примерам этой главы, Ваш тренировочный репозиторий должен находиться в следующем состоянии:

# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	deleted:    README
#	modified:   doc1.txt
#	new file:   test.txt

Для создания новой ревизии в Git используется команда git commit. При этом Вам обязательно необходимо ввести сообщение, которое будет сопровождать новую ревизию в истории. Сообщение необходимо указать с помощью параметра -m (как правило, для указания сообщения используют одинарную кавычку '). Если Вы пропустите параметр -m, Вам будет предложено ввести сообщение с помощью внешнего редактора (например, vim).

Зафиксируйте подготовленные изменения с помощью следующей команды:

git commit -m 'Learned how to add, edit and delete files and how to stage changes for commit.'

После выполнения команды Git покажет Вам следующее сообщение:

[master eb47b56] Learned how to add, edit and delete files and how to stage changes for commit.
3 files changed, 2 insertions(+), 2 deletions(-)
delete mode 100644 README
create mode 100644 test.txt

Это сообщение содержит заголовок ревизии — название ветви, сокращенный SHA-1 идентификатор ревизии и введенное Вами сообщение, а также статистику изменений: сколько файлов было изменено, сколько строк было добавлено и сколько удалено. Также сообщение содержит список файлов, добавившихся или удалившихся из рабочего дерева с момента прошлой ревизии.

Важные моменты

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

Очень часто Вам будет необходимо включать все изменения рабочего дерева в ревизию. Для этого Вы можете воспользоваться параметром -a. Например, следующая команда:

git commit -a -m 'Fixed issue #37, detailed review pending.'

Эквивалента двум следующим:

git add -u
git commit -m 'Fixed issue #37, detailed review pending.'

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

Подготовка нового репозитория

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

Выполним простое упражнение. Перейдите во временную папку и создайте там пустую папку с именем new-repo. Затем добавьте в нее файл README с любым содержанием и создайте репозиторий с помощью уже знакомой Вам команды git init:

cd /tmp
mkdir new-repo
cd new-repo
echo "Testing new repository creation" > README
git init

Как отмечалось ранее, команда git init создает пустой репозиторий. Этот репозиторий не содержит ни одной ревизии, следовательно, ни один из существующих в рабочем дереве файлов не находится под контролем версий. В этом легко убедиться, проверив статус репозитория:

# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	README
nothing added to commit but untracked files present (use "git add" to track)

На этом этапе Вы владеете всеми необходимыми навыками, чтобы внести все файлы в репозиторий и создать в нем первую ревизию. Эту ревизию обычно называют исходной (initial commit в англ.):

git add -A
git commit -m "Initial commit."

Рекомендации

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

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

git commit --author='Alexander Ivanov <alexander_ivanov@mydomain.lan>'

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

Каждую ревизию должно сопровождать сообщение, кратко описывающее характер произведенных в ней работ.

Официальные источники рекомендуют начинать сообщения короткой строкой (менее 50 символов), описывающей изменения в целом, а затем, если требуется, включить пустую строку и детальное объяснение работ.

Вы всегда должны давать ревизиям осмысленные сообщения по ряду причин:

это дисциплинирует и упорядочивает Вашу работу;

сообщения помогают определить границу ревизий и отсеять изменения, не подходящие по смыслу;

это значительно упрощает поиск необходимых изменений в истории;

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

Тест «Базовые операции»

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

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

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

Варианты заданий

Задание 1

В папке /Shared/projects/satellite находится Git-репозиторий.

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

Укажите команду для клонирования этого репозитория в папку The_Satellite_Project относительно текущей папки:

git clone

--no-hardlinks

--no-softlinks

--no-links

/Shared/projects/satellite

satellite

The_Satallite_Project

/Shared/projects/satellite

satellite

The_Satallite_Project

Примечание. Используйте абсолютный путь к репозиторию.

Задание 2

Восстановите пропущенные команды в следующем сценарии.

echo "You're not supposed to read this" > TOPSECRET

git

# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	TOPSECRET

git TOPSECRET

git

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   TOPSECRET

Задание 3

Ревизии необходимо создавать

после каждого сохранения любого файла, чтобы не потерять ни одно изменение

по своему усмотрению, ориентируясь на характер выполненных работ

как можно реже, чтобы избежать высоких затрат на хранение изменений

руководствуясь временными интервалами (например, раз в день)

Задание 4

Выберите правильную команду для создания пустого репозитория:

git init

git clone

git create

git new

git commit

git status

git show

Задание 5

Восстановите пропущенные команды в следующем сценарии.

git

# On branch master
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	deleted:    README
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	TOPSECRET
no changes added to commit (use "git add" and/or "git commit -a")

git -A

git -m “Replaced README with confidential information”

[master 26f15c5] Replaced README with confidential information
 1 files changed, 1 insertions(+), 0 deletions(-)
 delete mode 100644 README
 create mode 100644 TOPSECRET

Перейти к выполнению заданий