Системы контроля версий все увереннее занимают место обязательного инструмента в обойме рядового разработчика. И не знать что это, и как с ними обращаться становится на самом деле дурным тоном. Поговорим о самом любимом в среде СПО - GIT.
( это невнятный и занудный текст, цель написания которого была напрочь забыта автором )
Лирическое вступление :)
Git - второе по известности творение "почти легендарного" финского парня - Линуса Торвальдса. Первое его детище мы все ежедневно используем, даже если в глаза не видели :)
(Для непосвященных - подавляющая часть веб-серверов, составляющих наш бесценный интернет, работает на операционной системе Linux.)
Git бил написан Торвальдсом на Си за две недели. Написан по причине, в общих чертах звучащей так: "не нашел ничего подходящего". Можно спорить о справедливости его критики в адрес существовавших на тот момент систем, но факт остается фактом: после выхода в сообщество программистов Git быстро и надежно занял одну из ведущих позиций. Не смотря на отсутствие графического интерфейса, что не особо актуально для удаленного администрирования серверов. И намного более плотной работой с ветвлением проекта, чем, например, у SVN, что, на самом деле - плюс. Так или иначе, де-факто, в современном мире существует тройка ведущих систем контроля версий с распределенной организацией (еще Mercurial и Bazaar). И пальма первенства по популярности принадлежит торвальсовскому Git.
Системы контроля версий - "что это?"
Если рассматривать разработку ПО как непрерывный процесс поиска и реализации решений для встающих перед разработчиком проблем, то можно предположить (а для разработчика с опытом - это истина, подтвержденная кровью и потом "головной болью и слезами"), что время от времени будут возникать более удачные решения взамен уже реализованных. Что влечет за собой переделывание части работы, возможно, даже в масштабе всего немаленького проекта. И, следую логике "Законов Мерфи", можно предположить, что новое решение, иногда (а бывает что и часто), оказывается менее удачным, чем затертое старое. Или, что оно "сломает" такое количество зависимых от него частей проекта, что польза от него окажется сильно меньше созданных проблем. Надо ли говорить, что с ненулевой вероятностью в одном решении может вопролиться оба вида негативных последствий. Т.е., кажущееся удачным решение, на самом деле было совершенно ошибочным. И вот тут у нас возникает словосочетание "откат версии".
Как это обычно происходит, если мы ничего не знаем о таком "волшебном" (а местами просто шаманском) средстве, как система контроя версий? Первое, что приходит в голову - сохранение копий проекта через некоторый промежуток времени. Вероятно - с архивацией, для экономии времени. Еще вариант - автоматический "бекап" с сохранинием какого-то количество последних "снимков" директории. И тоже архивирование. В первом случае, как нетрудно догадаться, с каждым днем проект будет занимать стремительно увеличивающееся количество места, в геометрической прогрессии. Во втором - только размер проекта, умноженный на количество хранимых копий. И в обоих вариантах - архивы, напрочь отбивающие охоту что-либо искать в этих сохраненных версиях. Зачастую бывает быстрее исправить все "руками", чем искать по многочисленным версиям мегабайтного кода куски, нужные нам для исправления ситуации.
Второй аспект - обмен кодом между несколькими разработчиками в контексте общей работы. Здесь тоже не все гладко. Даже если весь код хранится централизованно на одном сервере, и все участники проекта выкладывают изменения по мере продвижения работы.
Если вы работали на проекте, где над одним участком работают хотя бы 2 человека, то вы должныпонимать, что такое - перезаписывание чужого кода своим обновлением со старым файлом (или старым участком кода). Тут проблемы множатся в зависимости от количества разработчиков, связности между элементами кода, вероятности одновременного внесения изменений в один файл и т.д.
Вероятно, перечисленные примеры не исчерпывают всего спектра проблем, мешающих разработчику полноценно заниматься работой, не отвлекаясь на рутину, выяснение отношений и вырывание волос по случаю удаленных строк кода.
Все это приводит нас к следующему вопросу, а чем нам тут помогут т.н. системы контроля версия (сократим до СКВ)? Что они вообще могут? Договоримся, что мы рассматриваем современные решения такого типа. А не устаревшие и самодельные утилитки с ограниченным набором функций.
Возможности СКВ.
1. Первое. СКВ позволяют без лишних усилий сохранять "снимки" текущего состояния файлов проекта, с возможностью в будущем перемещаться между этими "снимками". Откатывать неудачные версии и пересматривать решения.
2. Более гибкий и мощный способ работы с версиями - ветвление. В любой момент времени мы можем создать ветвь, в которой будем создавать альтернативную версию нашего проекта. Это может быть и версия для воплощения с отличающимися нюансами, но, скорее всего, это будет новая или оптимизированная функциональность, неприменимая в своем промежуточном виде в основном русле проекта. Но после завершения и проверки совместимости способная влиться обратно в проект.
3. Имея инструмент, умеющий отследить изменение каждой строки в проекте, мы можем контролировать очередность вливания новых версий в проект со стороны нескольких разработчиков, предотвращая, таким образом, конфликты между версиями кода.
4. Исходя из предыдущего пункта, было бы логично возложить на СКВ слияние файлов, измененных несколькими разработчиками, автоматически разрешая конфликты слияния или предоставляя варианты решения этих конфликтов, если таковые окажутся неразрешимыми в логике автоматической обработки. Разрешение конфликтов особенно актуально при слиянии ветвей проекта.
5. Все вышеперечисленное решает для нас и задачу синхронизации состояния проекта для нескольких разработчиков. Остается, конечно, обычное человеческое разгильдяйство и злой умысел, но тут все в руках правильного руководства :)
В общем и целом, системы контроля версий работают как программная "машина времени", отчасти игнорирую парадоксы временных петель и разрешая конфликт параллельных вселенных.
Централизованные и распределенные СКВ.
Вечные споры о том, "что лучше", наверное, никогда не прекратятся. Диспут между сторонниками двух путей реализации удаленной работы с СКВ продолжается с момента появления первых реализаций обоих видов. Для начала рассмотрим отличия, а затем - преимущества и недостатки.
Централизованные СКВ предполагают, что сердцевина управления проектом - репозиторий кода, должна быть одна, храниться на корпоративном (арендованном) сервере и открывать доступ разработчику для скачивания и отправки кода. Управление ветвями и прочие управленческие моменты, как правило, происходят на уровне центрального репозитория.
Распределенные СКВ рассматривают код проекта, как общую абстракцию, право на управление которой принадлежит каждому участнику разработки, а ветви проектных версий - это вообще банальный и частный инструмент комфортного добавления новый фич (или отладки), а не раздвоение глобальной стратегии развития. Часть озвучиваемых характеристик довольно субъективна, часть - не столько следствие подхода, сколько исторически сложивщееся обстоятельство.
Централизованные СКВ:
а) проще в работе для начинающего разработчика.
б) более управляемы и жестче контролируются менеджером проекта (или администрацией), что очень соответствует корпоративному духу компаний.
Но.
в) работа с ветвями, как правило, превращается в подвиг.
г) отсутствие "легких" ветвей делает работу менее гибкой и комфортной, порождает частые конфликты во время обновления версий.
Распределенные СКВ:
а) как правило, имеют простой и легкий механизм управления ветвями: созданием, переключением, слиянием.
б) каждый разработчик - хранит свой собственный репозиторий, чаще всего, имеющий свои уникальные участки/версии/ветви. Головной репозиторий, если такой существует - это просто место слияния всех коллегиально принятых решений.
в) в связи с тотальной распределенностью, целостность и сохранность проекта не зависит от одного физического носителя. Многочисленны истории о том, как вышедший из строя винчестер унес в небытие локальный репозиторий, но последний был восстановлен по копиям соратников со всего мира.
Но.
г) использование распределенных СКВ зачастую связано с необходимостью помнить некоторый объем команд и иметь более-менее внятное понимание принципа работы СКВ.
д) некоторые из них (например Git) как правило не имеет графического интерфейса.
Сложилось некоторое мнение, что Git и его распределенные собратья - инструмент для продвинутых девелоперов (а то и вовсе гиков), а централизованные системы, вроде SVN - для корпоративных работников и джуниоров. Мнение поддерживается и распространяется, в основном, корпоративными работниками и дилетантами :)
Общие моменты систем контроля версий.
Стоит рассмотреть общие принципы работы СКВ. Без вникания в нюансы реализации на конкретных системах. Применимость данных принципов в различных СКВ может различаться.
1. Система контроля версий - это механизм отслеживания изменений в файлах. Как правило, система отслеживает изменения строк. И именно строки являются атомарными единицами, которыми оперирует система.
2. СКВ - это свое рода непрерывная череда патчей. Как только мы делаем коммит (commit), система пробегает по всем директориям и файлам, сравнивает построчно с имеющейся версией и составляет список файлов и строк, которые были изменены. После чего все измененные строки записываются в хранилище, как "отличие" или "расхождение" с предыдущей версией. Это вот "отличие" и хранится как срез состояния, или "версия". Понятно, что пользователь видит не эти патчи-отличия, а текстовые файлы, которые он сам и редактирует. Но система оперирует именно списками строки, привязанными к файлу и месту в файле.
3. Т.к. для работы системы проект - это совокупность строк, разбитых по файлам, ей очень легко отслеживать перемещение или вставки новых строк внутри файла. Как следствие, процесс сливания ветвей тоже не представляет особой сложности. Всего-то нужно найти списки строк, между которыми были изменения, и сопоставить измененные части с промежутками между не измененными строками.
4. пункт 3 влечет за собой несколько следствий.
а) перемещение строк внутри файла не считается изменением, пока сохраняется порядок последовательности между старыми строками.
б) блок кода, к которому было применено изменение отступа уже считается измененным кодом. Что верно с точки зрения последовательности байт, но ошибочно с точки зрения логики кода. Это стоит учитывать при просмотре истории изменений. А также при использовании автоформатирования в IDE.
в) изменение внесенного в репозиторий бинарного файла (изображения, аудио и т.п.) требует записать в качестве изменения весь файл, что в итоге оказывается для репозитория накладнее, чем многомесячная история редактирования текстового файла.
5. Ветвление. Когда у нас возникает необходимость создать ветвь (branch), система начинает вести параллельный список патчей-версий от той версии, которая была нами выбрана для создания от нее ветви. Впоследствии альтернативная ветвь может быть слита с основной. Для Git такая практика и вовсе является обычной. Особенно для внесения функциональных новшевств (фич).
6. Обновление, сохраниние и заливка (update (pull), commit, push). В разных СКВ эти операции называются по-разному. Фактически, в первом случае мы запрашиваем у удаленного сервера самую новую версию (фактически - набор патчей, залитых туда другими участниками разработки). Во втором - заливаем свою версию, т.е. свой собственный набор новых патчей.
7. На систему ложится функция отслеживания последовательности применения изменений. Т.е. если вы изменили некий файл и попытались залить его новую версию на сервер, но оказалось, что там уже есть более новая версия, чем та, которую вы редактировали, то система откажет вам, посоветовав сначала скачать обновление, слить его с вашей локальной копией, разрешить конфликты, если такие будут иметь место. И только потом примет от вас ваши изменения.
Тут стоит добавить, что в реальном проекте, как правило, правила работы предполагают не только слить версии перед отправкой, а и провести тестирование проекта с внесенными изменениями, чтоб ваш "коммит" не сломал проект в головном хранилище.
8. Слияние версий. Как правило, система сама умеет красиво и правильно сливать две версии одного файла. Чаще всего, это апдейт из внешнего репозитория, либо, для таких систем как Git - слияние ветвей. Общий принцип довольно прост - если в более целевом файле есть отличия от исходного, то старые строки заменяются новыми. Если система успешно отследила смещение строк - она смещает строки вместо замещения. Если есть новые строки - они вставляются в соответствующие позиции, раздвигая и смещая старые.
9. Конфликты. Если при слиянии возникают ситуации, не имеющие однозначной трактовки, то система, как правило предлагает пользователю несколько вариантов решения:
а) выбор версии файла.
б) выбор версии блока в файле.
в) ручное редактирование.
Рассмотрение конкретной реализации "машины времени" в следующей части статьи.
( это невнятный и занудный текст, цель написания которого была напрочь забыта автором )
Лирическое вступление :)
Git - второе по известности творение "почти легендарного" финского парня - Линуса Торвальдса. Первое его детище мы все ежедневно используем, даже если в глаза не видели :)
(Для непосвященных - подавляющая часть веб-серверов, составляющих наш бесценный интернет, работает на операционной системе Linux.)
Git бил написан Торвальдсом на Си за две недели. Написан по причине, в общих чертах звучащей так: "не нашел ничего подходящего". Можно спорить о справедливости его критики в адрес существовавших на тот момент систем, но факт остается фактом: после выхода в сообщество программистов Git быстро и надежно занял одну из ведущих позиций. Не смотря на отсутствие графического интерфейса, что не особо актуально для удаленного администрирования серверов. И намного более плотной работой с ветвлением проекта, чем, например, у SVN, что, на самом деле - плюс. Так или иначе, де-факто, в современном мире существует тройка ведущих систем контроля версий с распределенной организацией (еще Mercurial и Bazaar). И пальма первенства по популярности принадлежит торвальсовскому Git.
Системы контроля версий - "что это?"
Если рассматривать разработку ПО как непрерывный процесс поиска и реализации решений для встающих перед разработчиком проблем, то можно предположить (а для разработчика с опытом - это истина, подтвержденная
Как это обычно происходит, если мы ничего не знаем о таком "волшебном" (а местами просто шаманском) средстве, как система контроя версий? Первое, что приходит в голову - сохранение копий проекта через некоторый промежуток времени. Вероятно - с архивацией, для экономии времени. Еще вариант - автоматический "бекап" с сохранинием какого-то количество последних "снимков" директории. И тоже архивирование. В первом случае, как нетрудно догадаться, с каждым днем проект будет занимать стремительно увеличивающееся количество места, в геометрической прогрессии. Во втором - только размер проекта, умноженный на количество хранимых копий. И в обоих вариантах - архивы, напрочь отбивающие охоту что-либо искать в этих сохраненных версиях. Зачастую бывает быстрее исправить все "руками", чем искать по многочисленным версиям мегабайтного кода куски, нужные нам для исправления ситуации.
Второй аспект - обмен кодом между несколькими разработчиками в контексте общей работы. Здесь тоже не все гладко. Даже если весь код хранится централизованно на одном сервере, и все участники проекта выкладывают изменения по мере продвижения работы.
Если вы работали на проекте, где над одним участком работают хотя бы 2 человека, то вы должныпонимать, что такое - перезаписывание чужого кода своим обновлением со старым файлом (или старым участком кода). Тут проблемы множатся в зависимости от количества разработчиков, связности между элементами кода, вероятности одновременного внесения изменений в один файл и т.д.
Вероятно, перечисленные примеры не исчерпывают всего спектра проблем, мешающих разработчику полноценно заниматься работой, не отвлекаясь на рутину, выяснение отношений и вырывание волос по случаю удаленных строк кода.
Все это приводит нас к следующему вопросу, а чем нам тут помогут т.н. системы контроля версия (сократим до СКВ)? Что они вообще могут? Договоримся, что мы рассматриваем современные решения такого типа. А не устаревшие и самодельные утилитки с ограниченным набором функций.
Возможности СКВ.
1. Первое. СКВ позволяют без лишних усилий сохранять "снимки" текущего состояния файлов проекта, с возможностью в будущем перемещаться между этими "снимками". Откатывать неудачные версии и пересматривать решения.
2. Более гибкий и мощный способ работы с версиями - ветвление. В любой момент времени мы можем создать ветвь, в которой будем создавать альтернативную версию нашего проекта. Это может быть и версия для воплощения с отличающимися нюансами, но, скорее всего, это будет новая или оптимизированная функциональность, неприменимая в своем промежуточном виде в основном русле проекта. Но после завершения и проверки совместимости способная влиться обратно в проект.
3. Имея инструмент, умеющий отследить изменение каждой строки в проекте, мы можем контролировать очередность вливания новых версий в проект со стороны нескольких разработчиков, предотвращая, таким образом, конфликты между версиями кода.
4. Исходя из предыдущего пункта, было бы логично возложить на СКВ слияние файлов, измененных несколькими разработчиками, автоматически разрешая конфликты слияния или предоставляя варианты решения этих конфликтов, если таковые окажутся неразрешимыми в логике автоматической обработки. Разрешение конфликтов особенно актуально при слиянии ветвей проекта.
5. Все вышеперечисленное решает для нас и задачу синхронизации состояния проекта для нескольких разработчиков. Остается, конечно, обычное человеческое разгильдяйство и злой умысел, но тут все в руках правильного руководства :)
В общем и целом, системы контроля версий работают как программная "машина времени", отчасти игнорирую парадоксы временных петель и разрешая конфликт параллельных вселенных.
Централизованные и распределенные СКВ.
Вечные споры о том, "что лучше", наверное, никогда не прекратятся. Диспут между сторонниками двух путей реализации удаленной работы с СКВ продолжается с момента появления первых реализаций обоих видов. Для начала рассмотрим отличия, а затем - преимущества и недостатки.
Централизованные СКВ предполагают, что сердцевина управления проектом - репозиторий кода, должна быть одна, храниться на корпоративном (арендованном) сервере и открывать доступ разработчику для скачивания и отправки кода. Управление ветвями и прочие управленческие моменты, как правило, происходят на уровне центрального репозитория.
Распределенные СКВ рассматривают код проекта, как общую абстракцию, право на управление которой принадлежит каждому участнику разработки, а ветви проектных версий - это вообще банальный и частный инструмент комфортного добавления новый фич (или отладки), а не раздвоение глобальной стратегии развития. Часть озвучиваемых характеристик довольно субъективна, часть - не столько следствие подхода, сколько исторически сложивщееся обстоятельство.
Централизованные СКВ:
а) проще в работе для начинающего разработчика.
б) более управляемы и жестче контролируются менеджером проекта (или администрацией), что очень соответствует корпоративному духу компаний.
Но.
в) работа с ветвями, как правило, превращается в подвиг.
г) отсутствие "легких" ветвей делает работу менее гибкой и комфортной, порождает частые конфликты во время обновления версий.
Распределенные СКВ:
а) как правило, имеют простой и легкий механизм управления ветвями: созданием, переключением, слиянием.
б) каждый разработчик - хранит свой собственный репозиторий, чаще всего, имеющий свои уникальные участки/версии/ветви. Головной репозиторий, если такой существует - это просто место слияния всех коллегиально принятых решений.
в) в связи с тотальной распределенностью, целостность и сохранность проекта не зависит от одного физического носителя. Многочисленны истории о том, как вышедший из строя винчестер унес в небытие локальный репозиторий, но последний был восстановлен по копиям соратников со всего мира.
Но.
г) использование распределенных СКВ зачастую связано с необходимостью помнить некоторый объем команд и иметь более-менее внятное понимание принципа работы СКВ.
д) некоторые из них (например Git) как правило не имеет графического интерфейса.
Сложилось некоторое мнение, что Git и его распределенные собратья - инструмент для продвинутых девелоперов (а то и вовсе гиков), а централизованные системы, вроде SVN - для корпоративных работников и джуниоров. Мнение поддерживается и распространяется, в основном, корпоративными работниками и дилетантами :)
Общие моменты систем контроля версий.
Стоит рассмотреть общие принципы работы СКВ. Без вникания в нюансы реализации на конкретных системах. Применимость данных принципов в различных СКВ может различаться.
1. Система контроля версий - это механизм отслеживания изменений в файлах. Как правило, система отслеживает изменения строк. И именно строки являются атомарными единицами, которыми оперирует система.
2. СКВ - это свое рода непрерывная череда патчей. Как только мы делаем коммит (commit), система пробегает по всем директориям и файлам, сравнивает построчно с имеющейся версией и составляет список файлов и строк, которые были изменены. После чего все измененные строки записываются в хранилище, как "отличие" или "расхождение" с предыдущей версией. Это вот "отличие" и хранится как срез состояния, или "версия". Понятно, что пользователь видит не эти патчи-отличия, а текстовые файлы, которые он сам и редактирует. Но система оперирует именно списками строки, привязанными к файлу и месту в файле.
3. Т.к. для работы системы проект - это совокупность строк, разбитых по файлам, ей очень легко отслеживать перемещение или вставки новых строк внутри файла. Как следствие, процесс сливания ветвей тоже не представляет особой сложности. Всего-то нужно найти списки строк, между которыми были изменения, и сопоставить измененные части с промежутками между не измененными строками.
4. пункт 3 влечет за собой несколько следствий.
а) перемещение строк внутри файла не считается изменением, пока сохраняется порядок последовательности между старыми строками.
б) блок кода, к которому было применено изменение отступа уже считается измененным кодом. Что верно с точки зрения последовательности байт, но ошибочно с точки зрения логики кода. Это стоит учитывать при просмотре истории изменений. А также при использовании автоформатирования в IDE.
в) изменение внесенного в репозиторий бинарного файла (изображения, аудио и т.п.) требует записать в качестве изменения весь файл, что в итоге оказывается для репозитория накладнее, чем многомесячная история редактирования текстового файла.
5. Ветвление. Когда у нас возникает необходимость создать ветвь (branch), система начинает вести параллельный список патчей-версий от той версии, которая была нами выбрана для создания от нее ветви. Впоследствии альтернативная ветвь может быть слита с основной. Для Git такая практика и вовсе является обычной. Особенно для внесения функциональных новшевств (фич).
6. Обновление, сохраниние и заливка (update (pull), commit, push). В разных СКВ эти операции называются по-разному. Фактически, в первом случае мы запрашиваем у удаленного сервера самую новую версию (фактически - набор патчей, залитых туда другими участниками разработки). Во втором - заливаем свою версию, т.е. свой собственный набор новых патчей.
7. На систему ложится функция отслеживания последовательности применения изменений. Т.е. если вы изменили некий файл и попытались залить его новую версию на сервер, но оказалось, что там уже есть более новая версия, чем та, которую вы редактировали, то система откажет вам, посоветовав сначала скачать обновление, слить его с вашей локальной копией, разрешить конфликты, если такие будут иметь место. И только потом примет от вас ваши изменения.
Тут стоит добавить, что в реальном проекте, как правило, правила работы предполагают не только слить версии перед отправкой, а и провести тестирование проекта с внесенными изменениями, чтоб ваш "коммит" не сломал проект в головном хранилище.
8. Слияние версий. Как правило, система сама умеет красиво и правильно сливать две версии одного файла. Чаще всего, это апдейт из внешнего репозитория, либо, для таких систем как Git - слияние ветвей. Общий принцип довольно прост - если в более целевом файле есть отличия от исходного, то старые строки заменяются новыми. Если система успешно отследила смещение строк - она смещает строки вместо замещения. Если есть новые строки - они вставляются в соответствующие позиции, раздвигая и смещая старые.
9. Конфликты. Если при слиянии возникают ситуации, не имеющие однозначной трактовки, то система, как правило предлагает пользователю несколько вариантов решения:
а) выбор версии файла.
б) выбор версии блока в файле.
в) ручное редактирование.
Рассмотрение конкретной реализации "машины времени" в следующей части статьи.
Комментариев нет:
Отправить комментарий