≪ На главную

Почему вы должны использовать Git вместо Subversion
21/6/2010

Представляю вашему вниманию перевод статьи Скота Чакона (Scott Chacon), автора книги “Pro Git”. В статье рассмотрены основные преимущества распределенных систем управления версиями в лице Git над централизованными в лице Subversion.

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

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

Итак, это не справочник по Git - я не буду описывать множество команд или рассказывать как “установить и запустить”. Это перечень аргументов в пользу того, почему вы должны серьезно задуматься о Git, если вы до сих пор используете Subversion. Чтобы научиться работать с Git, существует бесплатная онлайн-книга, под названием “Pro Git”, написанная мной, которая шаг за шагом проведет вас через функционал этой системы, к чему вас должна соблазнить данная статья. Для каждой части здесь, я буду ссылаться на соответствующий раздел этой книги, где вы сможете узнать больше об особенностях Git. Сначала мы рассмотрим преимущества распределенных систем над централизованными. Есть вещи, которые системы, вроде Subversion, просто не умеют делать. Далее мы рассмотрим мощь переключения контекста и инструменты для работы с файлами, которые технически возможны в Subversion, но Git делает их простыми настолько, что вы захотите использовать их. Эти средства должны полностью изменить ваш подход к работе и представление о ней.

Преимущества распределенности

Git это распределенная система управления версиями. Но что на самом деле означает данный термин? А то, что вместо выполнения svn checkout (url), для получения последней версии вашего репозитория, в Git нужно выполнить git clone (url), что даст вам полную копию истории проекта. Поэтому, сразу же после клонирования, вы не располагаете историей проекта на сервере. Интересно, Subversion является настолько неэффективной в этом, что в целом выполнить svn checkout репозитория в Subversion почти так же быстро, как клонировать его весь в Git.

Итак, это дает вам два преимущества. Во-первых, практически каждая операция выполняется с данными на локальном диске, а значит, что это невероятно быстро и может быть выполнено в оффлайн режиме. Вы можете выполнять команды commit, diff, log, branch, merge, создавать аннотации к файлам и многое другое, полностью в оффлайн режиме, моментально. Большинство команд в Git дольше набираешь на клавиатуре, чем они на самом деле выполняются. Теперь остановитесь на минуту и попытайтесь вспомнить, сколько раз вы ходили выпить чашечку кофе, пока Subversion выполняла какую-либо команду. Или быстро набросайте список случаев, когда вы хотели выполнить коммит, но не имели подключения к Интернету или не могли подключиться к корпоративной VPN.

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

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

Вы можете продолжать пользоваться централизованной схемой процесса, с одним центральным сервером, куда все могут выкладывать изменения и получать их оттуда. Однако, вы в состоянии делать и более интересные вещи. К примеру, предоставить удаленный репозиторий для каждого пользователя или подгруппы, где предоставлены права на запись, а затем ответственный пользователь (QA, например) может объединить воедино работу каждого члена и выполнить push в “боевой” репозиторий.

Пример распределенных рабочих процессов с участием нескольких репозиториев Git

Также с Git возможно создать любую иерархическую или “peer-based” модель рабочего процесса, о которой можете только подумать, в дополнение к возможности использовать ее в качестве централизованного сервера, как Subversion. Рабочий процесс может развиваться и адаптироваться вместе с вашей бизнес-моделью.

Еще один интересный пример, это Ruby-хостинг компании Heroku. Для развертывания своих систем, просто выполните push в удаленный репозиторий “heroku”. Вы можете работать в других удаленных репозиториях, а затем, когда будет необходимо разместить свой код на рабочем сервере, то просто выполняете push в репозиторий Heroku. Представьте себе попытку сделать такое с Subversion.

Простые ветвления, простые переключения контекста

Прежде чем я начну объяснять, что на самом деле из себя представляет моя любимая особенность в Git, прошу вас сделать мне одолжение. Забудьте все, что вы знаете о ветках. Ваши знания о них в понятиях Subversion вредны, особенно, если вы приобрели их с версией меньшей 1.5, как это сделал я, прежде чем, Subversion, наконец-то, усовершенствовала некоторые возможности слияний. Забудьте, как тяжело было выполнять слияния, забудьте, сколько времени отнимало переключение на другую ветвь, забудьте, что невозможно было выполнить слияние ветки более одного раза - Git дает вам совершенно новый мир, когда речь идет о ветвлениях и слияниях.

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

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

$ time git branch myidea
real 0m0.009s
user 0m0.002s
sys  0m0.005s

$ time git checkout myidea
Switched to branch "myidea"
real 0m0.298s
user 0m0.004s
sys  0m0.017s

Речь о трети секунды для обеих команд. А вот аналог в Subversion - запуск copy, а затем переключение switch:

$ time svn copy -m 'my idea' https://svn.example.com/trunk https://svn.example.com/svn/branches/myidea
real 0m5.172s
user 0m0.033s
sys 0m0.016s

$ time svn switch https://svn.example.com/branches/myidea
real 0m8.404s
user 0m0.153s
sys 0m0.835s

В принципе, разница между 1/3 секунды и 13-ю секундами (не говоря уже о времени потраченном на запоминание таких длинных ссылок) не кажется на первый взгляд огромной, но психологически разница существенна. Добавьте ко всему тот факт, что скорость работы сети, загрузка сервера и статус соединения, все это может отразиться на времени в Subversion, однако в Git это по-прежнему 1/3 секунды, и разница становится довольно большой. Тем не менее, ветвление считается быстрой операцией в Subversion - вы заметите еще более выраженные различия по скорости в других распространенных операциях, таких как log и diff.

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

Теперь, когда вы работаете с парой веток, как насчет слияния? Если вы из мира Subversion, вы можете съежиться, услышав это слово. Поскольку Git записывает историю коммитов как направленный граф, ему как правило проще автоматически вычислить наилучшую основу для выполнения трехэтапного слияния (3-way merge, прим. переводчика). Большинство пользователей Subversion привыкли делать такое вручную, что чревато ошибками и продолжительностью по времени - Git делает это тривиальным. Кроме того, вы можете объединять одну и ту же ветку несколько раз и необходимость решать одни и те же конфликты снова и снова отпадает.Я часто выполняю десятки слияний в день в определенных проектах Git и редко сталкиваюсь при этом даже с тривиальными конфликтами. Поднимите руку, если вы когда-нибудь сделали десяток объединений веток в проекте с Subversion, по крайней мере раз в неделю, и не заканчивали этот день грандиозной попойкой.

Как это не смешно, посмотрите на мою книгу “Pro Git”. Я разместил исходник книги в формате Markdown на GitHub, социальной сети для разработчиков, с которой я работаю. В течение нескольких дней, я начал получать десятки форков моего проекта, возможных изменений, исправлений ошибок и даже переводов. В Git, каждое из этих разветвлений пришло как ветка, которую я мог получить и выполнить слияние индивидуально. Я провожу по несколько минут, один или два раза в неделю, чтобы получить все присланные изменения, проверить каждую ветку и объединить одобренные с моей основной.

Граф проекта "Pro Git"

На момент написания этой статьи, я сделал 34 объединения примерно за 2 недели - я сажусь утром и объединяю с моей ветки, которые мне нравятся. Как пример, в последнюю такую “посиделку” я рассмотрел и объединил 5 различных веток за 13 минут. В качестве упражнения, подумайте, как это бы получилось в Subversion.

Стать творцом кода

Вы пришли домой в пятницу после долгой рабочей недели. Сидя в кресле-мешке, попивая пиво и уплетая Cheetos, вам в голову приходит шальная идея. Такая, что вы хватаете ноутбук и начинаете работать все выходные над вашей отличной идеей, создаете несколько файлов в проекте, которые делают его в 87 раз “круче”. И вот, работа закончена, вы подключились к VPN и готовы зафиксировать изменения. Вопрос, что вы будете делать дальше? Один большой коммит? Какие еще варианты?

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

1
2
3
4
$ git add file1.c file2.c file3.c
$ git commit -m 'files 1-3 for feature A'
$ git add file4.c file5.c file6.c
$ git commit -m 'files 4-6 for feature B'

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

Мало того, что данная возможность является довольно мощной сама по себе, Git также позволяет легко подготавливать к коммиту части отдельных файлов. Такой возможности очень не хватало, до знакомства с Git. Если кто-то изменил 100 строк файла, 96 из которых добавления пробелов и изменения форматирования комментариев, а остальные четыре - значительные изменения бизнес-логики, то их экспертный обзор как одного единственного изменения - кошмар наяву. Возможность подготовить для одного коммита изменения пробелов с соответствующим описанием, а для второго изменения бизнес-логики - спасение (в буквальном смысле, это может спасти вашу жизнь от ваших коллег). Для этого, вы можете использовать еще одну возмжность в Git, подготовку патча, которая спрашивает, если вы хотите подготовить все изменения в файле одновременно (git add -p).

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

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

Не только для команд разработчиков

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

Ну, будучи на стороне одиночек, я скажу - все, что мне нравится в Git, многое из чего я описал здесь, нравится мне потому, что это помогает мне, а не потому, что помогает мои коллегам. К черту их.

Локальные ветвления и легкие переключения контекста всецело полезны одному и, возможно, наиболее уникальные и революционные возможности Git. На самом деле я очень часто использую Git, как вы, может быть, используете свою СУВ - просто “выполняю git init” в каком-либо локальном каталоге и изредка проверяю содержимое, не имея удаленных репозиториев вовсе. Создание коммитов, как логически разделенных наборов изменений является очень полезным, чтобы вспомнить, почему вы сделали это месяц назад, в том числе полезно и на индивидуальном уровне, наконец, скорость и надежность это всегда хорошие вещи, независимо команда вы или одиночка.

Если вы действительно не разработчик, я уже перечислил примеры использования Git для объединения усилий при работе над книгой. “Pro Git” был выпущен компанией Apress, основной издательской компании, и большинство из написанного, а также рецензия на книгу были сделаны в Markdown, с использованием Git для совместной работы. Все исправления и переводы выполняются в отдельных ветках Git. Вы не узнаете, какое это на самом деле блаженство, пока не объедините изменения технических рецензентов или редакторов с помощью очень простой команды git merge.

В заключение…

В заключение скажу, что в действительности это лишь верхушка айсберга возможностей Git. В ней есть тонны фантастических и полезных возможностей, которые помогают с отладкой, комплексными сравнениями и слияниями и др. Существует также большое сообщество разработчиков, к которым вы можете присоединиться, а также несколько действительно хороших свободных онлайн-ресурсов, которые помогут вам изучить и использовать Git. Некоторые вещи, которые я уже упомянул здесь, это просто те возможности, которые больше всего изменили мое представление о работе и управлении версиями. Они являются основными причинам, из-за которых я уже никогда не вернусь к системам, вроде Subversion. Это похоже на то, если бы мне сказали “Ты должен ездить на Toyota вместо Mercedes”, или “Ты должен использовать пишущую машинку вместо компьютера” - это навсегда поменяло мой подход и мышление о создании чего-либо.

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

Ссылки

  1. Оригинал статьи (англ.)
  2. Официальный сайт Git (англ.)
  3. Онлайн-книга о Git (англ.)
  4. Официальный сайт Subversion (англ.)
  5. Сравнение Git с другими популярными СУВ (англ.)
  6. Git в Wiki
  7. Subversion в Wiki