Линус Торвальдс как-то написал в своей книге, что создавал Linux для развлечения, но в итоге это привело к революции. Git, его второе творение, также оказалось «случайной революцией» — и сегодня это стандартный инструмент для людей в ИТ. Однако процесс его создания был уже не таким «весёлым» — по крайней мере, для самого Линуса. 


Линус не масштабируется

1998 — важный год для Linux. Операционную систему начали использовать крупные компании: Sun, IBM и Oracle. Той же весной у Линуса родилась вторая дочь. Прошел почти год с тех пор, как его семья переехала из Финляндии в Калифорнию. Несмотря на то, что Linux ещё не принес Линусу большой финансовой выгоды, дела его шли неплохо как в карьере, так и в семейной жизни.

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

28 сентября 1998 года Линус, как обычно, читал рассылку ядра Linux и наткнулся на сообщение:

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

Сообщение раздражало Линуса. Изменения в коде Linux в значительной степени зависели от него самого. Если вы хотели внести изменения, то отправляли письмо, и если Линус видел и одобрял правки, он включал ваш патч в свою версию и время от времени выпускал новые версии по FTP. Линусу нравилось работать таким образом: это позволяло ему контролировать все изменения. И все доверяли Линусу управление Linux.

Однако, поскольку Дэвид Миллер, старший разработчик ядра Linux, поднял CVS-сервер под названием vger, некоторые думали, что могут просто в обход Линуса отправить изменения в vger. Это был не первый раз, когда Линус столкнулся с этой проблемой, и он недовольно ответил:

Заметьте: говорить «это есть в vger, так что вы зря тратите свое время» совершенно глупо. Тот факт, что это есть в vger, не имеет абсолютно никакого значения, тем более, в vger есть много вещей, которые, вероятно, никогда не попадут в 2.2.

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

«Эти люди должны посмотреть на себя в зеркало», — подумал Линус. «Каждый день мне приходится читать массу писем. Если отправка трёх имейлов доставляет так много хлопот, я предпочел бы вообще не делать патч». Напоследок он оставил сообщение:

Откровенно говоря, эта конкретная дискуссия (и другие до неё) раздражительна и лишь ДОБАВЛЯЕТ давления.

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

Эмоциональный всплеск Линуса побудил некоторых людей предложить помощь.

Один из лидеров опенсорс-движения, Эрик С. Рэймонд, автор знаменитого эссе «Собор и базар», спокойно настаивал:

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

Ларри МакВой также протянул руку помощи. В письме под названием «Решение проблем роста» он написал:

Проблема в том, что Линус не масштабируется. Мы не можем рассчитывать, что он будет поспевать за темпом поступления изменений в ядро, которое растёт и усложняется с каждым днем. Но мы также не хотим, чтобы Линус потерял контроль над ядром и окончательное право голоса; он неоднократно демонстрировал, что хорошо справляется с этой задачей.

Нужно сделать так, чтобы Линус мог окружить себя людьми, берущими на себя часть его работы. Внедрить инструменты, которые сделают это возможным.

Речь о распределенной системе управления исходным кодом…

Ларри разрабатывал новую систему контроля версий под названием BitKeeper.

Зарождение BitKeeper

В начале 1990-х годов компания Sun Microsystems представила внутренний инструмент под названием Network Software Environment (NSE) для управления кодом, но NSE был медленным и ужасным в плане пользовательского опыта. От разочарования некоторые инженеры даже уволились.

Ларри МакВой, разработчик ОС с опытом работы над производительностью, получил предложение от руководства Sun улучшить эффективность NSE.

Когда Ларри взглянул на код NSE, он был удивлен. «Эта штука вообще не была разработана с учётом производительности». Он также обнаружил, что NSE была построена на базе SCCS, системы контроля версий 1970-х годов, более старой, чем CVS и Subversion. Вместо того чтобы пытаться исправить глубоко ошибочный NSE, Ларри выбрал другой путь: он написал NSElite на Perl, реализовав команды resync/resolve поверх SCCS, аналогичные сегодняшним командам clone/pull/push в Git.

NSElite был намного быстрее, чем NSE, поэтому инженеры Sun начали отказываться от NSE в пользу NSElite. Здесь вице-президент Sun увидел возможность для бизнеса — и сформировал команду из восьми человек, чтобы переписать Perl-скрипты Ларри на C++ и превратить их в продукт под названием TeamWare.

TeamWare, вероятно, была первой распределённой системой контроля версий (DVCS), и в итоге стала незаменимой при разработке ОС Solaris от Sun. Инженеры, использовавшие TeamWare, уже не могли вернуться назад: в отличие от CVS и Subversion, TeamWare позволяла клонировать проект на локальной машине, вносить изменения локально и мёрджить свою версию обратно в удалённую, когда всё готово.

Команда состояла из восьми опытных программистов на языке C. Поскольку C++ был популярным новым языком, они изучали его во время создания TeamWare. Ещё до завершения разработки TeamWare Ларри продолжил делать NSElite, что выставляло команду TeamWare в плохом свете: один парень с Perl опережал восемь человек с C++. Тогда вице-президент сказал Ларри: «Об этом доложили Скутеру (Скотту Макнили, генеральному директору Sun). Если ты выпустишь это ещё раз, то будешь уволен».

В 1991 году Ларри прекратил разработку NSElite, но не мог избавиться от идеи создания DVCS. Он думал, что коммерческое ПО последует примеру TeamWare, однако этого не произошло. В 1997 году Ларри начал разработку DVCS под названием BitKeeper. И только в сентябре 1998 года, увидев в рассылке, что Линус находится на грани выгорания, он почувствовал мотивацию заняться BitKeeper всерьёз.

Ядро Linux принимает BitKeeper

Осенним днем 1998 года Ларри пригласил к себе домой Линуса Торвальдса, Дэвида Миллера и Ричарда Хендерсона. После ужина они сели на пол и начали мозговой штурм, чтобы понять, как уменьшить нагрузку на Линуса. Они рисовали диаграммы на полу в течение трёх или четырёх часов, в основном опираясь на механику того, как TeamWare работала в Sun Microsystems. Ларри очень хорошо знал эти процессы.

Идея предполагала, что разработчики могут использовать BitKeeper для независимой работы, не мешая друг другу. А Линус, производя окончательную интеграцию, не терял бы историю изменений, что облегчало ему проверку кода.

«Хорошо. Если вы это создадите и оно будет работать так, как вы говорите, я буду это использовать», — сказал Линус.

«Нет проблем, я уже делал это раньше. Займет около шести месяцев», — ответил Ларри.

Ларри быстро понял, что недооценил сложность задачи. Он основал компанию BitMover и нанял несколько экспертов по контролю версий для помощи в создании BitKeeper. Девятнадцать месяцев спустя, в мае 2000 года, была выпущена первая версия BitKeeper. К тому времени BitMover представляла собой команду из семи человек.

Первая версия BitKeeper включала в себя инструмент командной строки bk и некоторые инструменты графического интерфейса. Команды bk clone/pull/push функционировали аналогично git clone/pull/push.

В то время TeamWare от Sun уже была хорошо известна, а BitKeeper представлял собой «TeamWare на стероидах». Например, если TeamWare позволяла передавать данные только через файловые системы NFS, то BitKeeper мог передавать файлы по HTTP, что делало его более распространённым. Вскоре BitKeeper принёс BitMover ощутимый денежный поток. К 2002 году BitMover выросла до команды из 25 человек, полностью самодостаточной, без внешнего финансирования.

Ларри МакВой, Linux Expo, 1999
Ларри МакВой, Linux Expo, 1999

В январе 2002 года проблема загруженности Линуса всплыла вновь. Патчи, присылаемые разработчиками, либо слишком долго не рассматривались, либо игнорировались. Появилось «скромное предложение», чтобы попытаться решить эту проблему. В ходе обсуждения кто-то вскользь упомянул: «BitKeeper — действительно хороший инструмент», напомнив Линусу о том ужине три года назад в доме Ларри. Линус спросил: «Сколько людей уже используют BitKeeper для ядра?».

Как оказалось, некоторые разработчики ядра уже использовали BitKeeper. Команда Linux PowerPC (PPC) начала тестировать BitKeeper в декабре 1999 года, и BitMover подняла сервер bkbits.net для их поддержки.

Через несколько дней, 5 февраля 2002 года, в рассылке появилось сообщение о том, что Линус начал тестировать BitKeeper. С этого момента BitKeeper начали внедрять основные разработчики ядра Linux. Вам не обязательно было использовать его, чтобы внести свой вклад в разработку, но если вы это делали, то процесс проходил примерно так:

# Download the repository
bk clone bk://linux.bkbits.net/linux-2.5 linux-2.5
bk clone linux-2.5 alpha-2.5

# Pull changes from another place
cd alpha-2.5
bk pull bk://gkernel.bkbits.net/alpha-2.5

# Edit files and push changes back to the remote
bk vi fs/inode.c 
bk push bk://gkernel@bkbits.net/alpha-2.5 

Чтобы отправить изменения Линусу, нужно было написать в рассылке что-то вроде:

Here is an update for something something...

Please pull from: bk://gkernel.bkbits.net/alpha-2.5

example/file1.c | 6 ++++++
example/file2.c | 4 ----
2 files changed, 6 insertions(+), 4 deletions(-)

Больше никакого бесплатного BitKeeper 

Ларри МакВой разрешил разработчикам ядра Linux использовать BitKeeper бесплатно, при этом были некоторые ограничения. Среди требований бесплатной пользовательской лицензии:

  • Нельзя было отключать Open Logging, который отправлял логи на сервер BitMover.

  • Нельзя было использовать BitKeeper для контроля версий, если вы разрабатывали ПО для контроля версий.

  • Вы должны были получить разрешение BitMover, если хотели запустить BitKeeper вместе с другими подобными программами.

Сообщество Linux, полное сторонников свободного ПО, отреагировало неоднозначно. Одни насмехались над этими правилами, другие избегали их. Однако для Линуса и основных разработчиков ядра ключевым моментом было то, что BitKeeper снижал их рабочую нагрузку. Поскольку в то время не было лучших альтернатив, они приняли условия BitKeeper — ради того удобства, которое он предлагал.

Линус всегда непредвзято относился к проприетарному софту. Он выбрал GPL для ядра Linux лишь для того, чтобы не дать коммерческому рынку «запятнать» Linux. GPL соответствовала его потребностям, поэтому он её использовал. Но он никогда не считал, что все программы должны быть свободными; он верил, что авторы имеют право распространять свои программы так, как им хочется. Для Линуса использование софта не было общественным движением.

Сторонники свободного ПО не разделяли его точку зрения. Некоторые экстремалы даже считали проприетарный софт злом. Удобству BitKeeper эти хакеры предпочитали свободу модификации ПО.

Ларри чувствовал давление со стороны сообщества. Чтобы решить проблему, команда BitKeeper в 2003 году создала зеркало BitKeeper-to-CVS, позволяющее тем, кто не хочет устанавливать BitKeeper, получить доступ к истории кода через CVS. Однако история из CVS была неполной по сравнению с BitKeeper, и люди были недовольны. «Почему наши данные должны быть заперты в проприетарном формате BitKeeper, и почему нам запрещено использовать другие инструменты для чтения наших собственных данных?»

В ответ на это Эндрю Триджелл (Тридж), австралийский программист, стоящий за Samba и rsync, в феврале 2005 года начал разработку бесплатного клиента BitKeeper, чтобы решить проблемы, с которыми сталкиваются пользователи свободного ПО.

Тридж сделал следующее.

«Вот адрес BitKeeper, bk://thunk.org:5000. Давайте попробуем подключиться с помощью telnet».

$ telnet thunk.org 5000
Trying 69.25.196.29...
Connected to thunk.org.
Escape character is '^]'.

«Мы подключены. Почему бы не ввести команду help?»

help
? - print this help
abort - abort resolve
check - check repository
clone - clone the current repository
help - print this help
httpget - http get command
[...]

«Сервер BitKeeper достаточно любезен, чтобы вывести список всех команд».

«Значит, clone —  это команда для загрузки репозитория?»

Он набрал clone и обнаружил, что на выходе получилась серия файлов в формате SCCS. На этом реверс-инжиниринг был в основном закончен; оставалось только написать программу.

Линус каким-то образом узнал, чем занимается Тридж, — возможно, Тридж рассказал ему об этом в частном порядке. Затем Линус сообщил об этом своему другу Ларри. Ларри не был впечатлен. Бесплатный сторонний клиент разрушил бы бизнес-модель BitKeeper. Ларри, обратившись за помощью к Линусу и Стюарту Коэну (тогдашнему генеральному директору OSDL, ныне Linux Foundation), хотел попросить Триджа остановиться.

Стюарт Коэн предпочёл не вмешиваться, считая, что это не дело OSDL. Но Линус не хотел терять BitKeeper, поэтому упорно работал в качестве посредника, пытаясь найти компромисс, приемлемый для обеих сторон. Тридж твёрдо верил, что не делает ничего плохого, считая, что сторонний клиент будет выгоден и BitKeeper, и разработчикам ядра. В апреле 2005 года он выпустил SourcePuller на Freshmeat (позже поглощённом SourceForge). В README он написал:

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

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

Ларри не согласился с идеей. Поддержка разработки ядра стоила денег. Они не только не зарабатывали, но и рисковали навредить своей существующей бизнес-модели. Чтобы защитить средства к существованию BitMover, он решил отозвать лицензию на свободное использование BitKeeper.

После нескольких недель переговоров Линусу надоело играть роль посредника. Не имея больше свободного BitKeeper, Линус был в ярости. Он публично обвинил Триджа на форуме, сказав, что тот «просто разрушил что-то новое» и «обманул людей». Линус мог бы сам заплатить за BitKeeper, но он не мог попросить других разработчиков ядра сделать то же самое, поэтому ему нужно было новое решение. Он продолжал писать:

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

6 апреля 2005 года Линус объявил в рассылке, что ядро Linux расстается с BitKeeper. Сначала он поблагодарил Ларри и его команду за помощь в течение последних трех лет. Затем он сказал, что уйдет на неделю в офлайн для поиска замены. Наконец, он добавил:

Не утруждайте себя, рассказывая мне о subversion. Начните читать про «monotone». Это, похоже, самая жизнеспособная альтернатива.

Monotone

Monotone была создана Грейдоном Хоаром. В 2001 году Грейдон, живший в Канаде, захотел упростить работу со своим австралийским другом. Поэтому они разработали систему, похожую на современную непрерывную интеграцию (Continuous Integration, CI), которая тогда ещё не была широко известна. Их система гарантировала, что код всегда проходит тесты.

В 2002 году Грейдону стало интересно объединить контроль версий с CI. В то время подобная концепция существовала только у Aegis. Грейдон также увидел, как его друзья используют BitKeeper, и подумал, что объединение Aegis с DVCS может стать отличной возможностью. Так появилась компания Monotone.

К сожалению, Линус выбрал неудачное время для опыта с Monotone. Monotone 0.7 имел приличную производительность, но начиная с версии 0.14 разработчики начали добавлять множество механизмов проверки. Как раз перед тем, как Линус загрузил Monotone, Грейдон выпустил версию 0.17, а затем уехал в отпуск. Эта версия включала множество строгих проверок для обеспечения целостности данных перед записью в базу, но проверки не были оптимизированы, что снижало производительность. В примечаниях к выпуску 0.17 упоминалось:

ещё не полностью оптимизирован; «pull» может быть очень медленным и потреблять много ресурсов процессора

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

Линус сообщил о проблемах с производительностью разработчикам Monotone. 10 апреля 2005 года была выпущена версия Monotone 0.18, в которой многие операции выполнялись как минимум вдвое быстрее. Хотя Линус был указан в релизе 0.18 как контрибьютор, по словам разработчика Monotone Натаниэля Смита:

Линус на самом деле не вносил никакого кода в Monotone или, насколько мне известно, в любую SCM, кроме git. Он также не предоставил никаких предложений, кроме «это слишком медленно!» ;-). Его заслуга в том, что именно в дискуссиях с ним я нашел правильный тестовый пример, чтобы отследить одну из наших основных ошибок в производительности. Я немного поразмышлял, стоит ли мне указывать его имя, ведь это может натолкнуть людей на странные мысли, но, полагаю, если бы это был кто-то другой, я бы так и сделал, так что... *пожимает плечами*.

Тем временем, вдохновившись дизайном Monotone, Линус начал писать код на C с нуля.

Git v0.01: первый взгляд

7 апреля 2005 года Линус загрузил штуку под названием Git и написал в рассылку:

Вот вам каверзная задачка: если хотите поиграться с чем-то очень неприятным (но при этом очень быстрым), загляните на kernel.org:/pub/linux/kernel/people/torvalds/.

Первый, кто пришлёт мне дерево изменений sparse-git (и инструмент для фиксации, а также отправки на сервер и получения с сервера дальнейших изменений), получит золотую звезду и почётное упоминание. Я вложил туда чертовски много подсказок.

Это было первое публичное упоминание Линусом Git'а.

URL-адрес содержал следующие файлы и каталоги:

git.git/                  09-Apr-2005 16:09    -
sparse.git/               07-Apr-2005 20:07    -
git-0.01.tar.bz2          07-Apr-2005 14:25   39K
git-0.01.tar.bz2.sign     07-Apr-2005 14:25  248
git-0.01.tar.gz           07-Apr-2005 14:25   40K
...
sparse-git.tar.bz2        08-Apr-2005 17:26   15M

В git-0.01.tar.bz2 было около 1000 строк кода на языке C:

---------------------------------------------------------------------
File                             blank        comment           code
---------------------------------------------------------------------
./read-cache.c                      31             14            219
./update-cache.c                    32             23            198
./commit-tree.c                     23             26            128
./show-diff.c                        8              5             73
./cache.h                           17             23             53
./write-tree.c                      11              7             53
./read-tree.c                        4              5             39
./init-db.c                          4             14             38
./Makefile                          14              0             26
./cat-file.c                         2              5             21
---------------------------------------------------------------------
SUM:                               146            122            848
---------------------------------------------------------------------

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

  • init-db

  • update-cache

  • show-diff

  • write-tree

  • read-tree

  • commit-tree

  • cat-file

Команда init-db была очень простой. Она создавала каталог с именем .dircache/objects в текущем каталоге, а затем создавала 256 подкаталогов, пронумерованных шестнадцатеричной нумерацией от 00 до ff внутри .dircache/objects.

Каталог .dircache/objects представляет собой базу данных объектов со следующими типами объектов:

  • Blob: содержимое файлов.

  • Дерево: каталоги, по сути, содержащие имена файлов (blob) и каталогов (деревья).

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

Здесь имена объектов — это не имена файлов или каталогов, а SHA-1-хэш их сжатого содержимого. Линус позаимствовал эту идею у Monotone, но в то время как Monotone использовал SQLite для хранения имен и содержимого объектов SHA-1, Линус решил использовать системные вызовы и файловую систему напрямую.

Уникальность SHA-1 означала, что в базе данных Git почти никогда не будет двух объектов с разными именами, но одинаковым содержимым. Если имя объекта было ba93e701c0fe6dcd181377068f6b3923babdc150, Git будет хранить его в .dircache/objects/ba/ как файл с именем 93e701c0fe6dcd181377068f6b3923babdc150.

Семь исполняемых файлов посвящены различным операциям с этой «контентно-адресной» файловой системой. Например:

  • write-tree: создает дерево, записывая снэпшот директории в базу данных.

  • commit-tree: создает changeset, связывая два дерева в базе данных, аналогично сегодняшнему git commit.

  • update-cache: Добавляет файл в .dircache/index, аналогично сегодняшнему git add в область подготовленных файлов.

Идея именования на основе SHA-1 понравилась Линусу, как только он увидел ее в Monotone — потому что она была простой. Простота также была тем, что Линусу нравилось в Unix. В своей книге «Just for Fun» он описал Unix:

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

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

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

Прототип Git, который Линус написал за два дня, был прост. Никакой дополнительной проверки. Никакой реляционной базы данных. Только код на С, хэши SHA-1 и системные вызовы, полностью адаптированные под нужды Линуса. Между тем проект Monotone, которому шёл третий год, был многофункционален и должен был удовлетворять широкому кругу пользователей. Кроме того, первоначальный автор Monotone Грейдон перед отпуском добавил много неоптимизированного кода, оставив его без «присмотра». Monotone не мог сравниться в плане скорости с Git, так как находился в невыгодном положении.

Файл sparse-git.tar.bz2, который Линус первоначально загрузил, был, вероятно, первым Git-репозиторием в истории. Sparse — это статический анализатор для языка C, который Линус написал в 2003 году. Если вас все еще интересует задача Линуса, вы можете слегка изменить извлеченный sparse-git.tar.bz2 и использовать современную команду git log для чтения истории изменений:

# Assuming you are in the sparse-git directory
mv .dircache .git
mkdir .git/refs
git log

Первые контрибьюторы Git

Первая версия Git вызвала оживленную дискуссию. Через несколько дней Линус создал специальную рассылку для Git, что позволило рассылке ядра Linux вернуться к работе. В первый месяц в рассылке Git появилось около 2600 сообщений, в то время как в ядре Linux, самом коллективном программном проекте в истории, ежемесячно появлялось 7 000-9000 сообщений за тот же период.

Для экспертов в области контроля версий Git был просто очередным проектом. Первая версия Git, загруженная Линусом, содержала лишь несколько низкоуровневых операций. В ней отсутствовали такие важные команды, как clone и merge, что делало её далёкой от пригодности для использования системой контроля версий. А постоянные похвалы Линуса в адрес Git непреднамеренно принижали другие системы контроля версий. Это раздражало Брэма Коэна, создателя BitTorrent.

В то время Брэм продвигал свою собственную систему контроля версий, Codeville. Codeville уже была зрелой DVCS, сравнимой с Monotone, и имела продвинутый алгоритм слияния. Видя, как Линус и его последователи говорят об алгоритмах мёрджа, Брэм почувствовал, что Линус, будучи вне контекста, заново изобретает колесо. «Git — это халтура, которая выглядит как халтура», — написал Брэм.

Брэм был прав, но это была не просто халтура — это была халтура Линуса Торвальдса, создателя ядра Linux. Как народный герой в мире ПО с открытым исходным кодом, Линус находился под пристальным вниманием. Молодые разработчики равнялись на него, видя в нем пример для подражания. Поэтому после того, как Линус загрузил Git, он быстро привлек группу юных разработчиков, жаждущих присоединиться к обсуждению и разработке.

Одним из первых был Петр Баудис из Чехии. В тот день, когда Линус анонсировал Git, Петр скачал код, был очарован и начал вносить свой вклад. Учитывая проблемы с удобством использования раннего Git'а, Петр разработал git-pasky (pasky —  псевдоним Петра), который в итоге стал Cogito. Если основой Git'а был «трубопровод» (plumbing), то Cogito был «фарфором» (porcelain) — удобным интерфейсом.

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

Кроме того, Петр создал первую домашнюю страницу проекта Git, git.or.cz, и хостинг, repo.or.cz. Эти сайты были «официальными» сайтами Git до тех пор, пока их место не занял GitHub.

Петр вносил вклад со стороны — поверх Git'а и создавая сервисы на его основе. Другой ранний участник, Джунио Хамано, был контрибьютором непосредственно из самого Git'а. Позже он принял от Линуса должность мейнтейнера Git, и занимает эту должность по сей день.

Преемник

Джунио Хамано — инженер-программист из Японии. В 1995 году, примерно через год после окончания университета, он был направлен в Лос-Анджелес своим работодателем, компанией Twin Sun, и с тех пор живет в США. Там он познакомился с Полом Эггертом, который в то время работал в той же компании.

Пол Эггерт поддерживал многие проекты бесплатного или открытого ПО, включая RCS (раннюю систему контроля версий) и Tar. В настоящее время он профессор Калифорнийского университета и разработчик базы данных часовых поясов.

Под влиянием Пола, Джунио заинтересовался миром ПО с открытым исходным кодом. Он не был разработчиком ядра, но подписывался на рассылку открытых проектов, таких как ядро Linux, просто ради интереса.

В апреле 2005 года Джунио увидел в рассылке объявление Линуса о том, что ядро Linux расстается с BitKeeper. Джунио всегда хотел заявить о себе в мире открытого кода, и новый проект под названием Git показался ему отличной возможностью — совершенно новый, без исторического багажа, лёгкий для освоения. Он скачал tarball и потратил около двух часов на чтение начального кода Git в одной установке. Он был впечатлён тем, насколько хорошо код был написан.

После первого выпуска Git'а Линус оперативно добавил команды commit и diff, но merge еще не было.

Хотя Линус никогда раньше не писал программ для контроля версий, он использовал BitKeeper в течение трёх лет. До этого у него было десять лет «человеческого опыта управления версиями». Он знал, какой алгоритм мёрджа ему нужен. Однако, поскольку логика мёрджа была более сложной, Линус решил, что она может лучше подойти для скриптового языка, написав:

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

Прошла неделя, желающих не нашлось. У Джунио, который в то время был между проектами, появилось свободное время, поэтому он написал на Perl то, что хотел Линус, и опубликовал это в рассылке.

Теперь у меня есть Perl-скрипт, который использует rev-tree, cat-file, ... и merge (из RCS). Дёшево и сердито.

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

Был уже час ночи, а поскольку его дети просыпались в 7 утра, Линус обычно ложился спать к 10 вечера. Но, увидев Perl-скрипт Джунио, Линус был в восторге и не мог не ответить:

Это именно то, чего я хотел. Q'n'D — отличная отправная точка.

Он охотно продолжил обсуждение с Джунио.

«Слияние с git-pasky II» началось с того, что Петр спросил Линуса о слиянии его версии, но вскоре они перешли к обсуждению алгоритмов мёрджа. В ходе дискуссии Линус также объяснил, почему внутренним механизмам Git'а не нужно обрабатывать переименования файлов.

В течение следующих 48 часов, начиная с полуночи 14 апреля, Джунио и Линус обменялись дюжиной писем в этой ветке. Джунио терпеливо пересматривал код, чтобы удовлетворить видение Линуса относительно мёрджа. Из его слов было ясно, что Джунио был большим поклонником Линуса. Например, Джунио цитировал слова Линуса, сказанные им четыре года назад: «Я всегда прав», и в достаточной степени льстил Линусу.

В полночь 16 апреля Линуса осенило, и он заявил, что у него есть «хитрый план».

Чёрт возьми, этот хитрый план — отличная штука.

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

Линус ловко использовал существующий индекс, введя поверх него концепцию «этапов», что значительно упростило реализацию слияния.

Джунио восхитился решением Линуса:

Мне очень нравится. Просто, понятно, гибко и элегантно. Это одна из тех вещей, про которые я бы с радостью сказал: Чёёёрт! Почему я не подумал об этом первым!!!».

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

Алгоритм слияния был только началом. Джунио продолжал предоставлять Линусу все новые и новые патчи, постепенно завоёвывая его доверие.

Линус уже говорил, что не будет поддерживать Git в течение длительного времени. Когда придёт время, он передаст Git кому-нибудь другому и вернётся к своей основной работе над ядром Linux. Джунио был очевидным выбором, поскольку Линус ценил его «хороший вкус» в написании кода. Итак, три месяца спустя, 26 июля, Линус объявил, что передает роль мейнтейнера Git Джунио.

Джунио также опубликовал объявление:

Как некоторые из вас, похоже, заметили ещё до объявления Линуса, официальный GIT-репозиторий на kernel.org теперь принадлежит мне. Как сказал Линус в своем сообщении, это не означает, что он покидает нас, так что, пожалуйста, не паникуйте.

Я также хотел бы поблагодаритьTwin Sun Inc (моего работодателя) и NEC за обещание поддерживать меня в работе над GIT на условиях неполного рабочего дня. Я рассчитываю тратить от 8 до 12 часов в неделю днём; вечера и выходные, как и раньше, будут моим личным временем. Предварительно я планирую сделать среду и субботу основными днями работы над GIT.

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

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

Под руководством Джунио 21 декабря был выпущен Git 1.0.0. Спустя 19 лет (по состоянию на июль 2024 года) Джунио работает в Google и по-прежнему поддерживает Git.

В этой статье Линус упоминается чаще, чем Джунио, но наибольший вклад в создание Git в том виде, в котором он существует сегодня, внесли настойчивые усилия Джунио и других разработчиков второго плана. «1% вдохновения и 99% усилий» — возможно, клише, но оно очень справедливо для таких успешных проектов, как Git и ядро Linux.

GitHub и люди из Ruby

Хотя Git и привлёк к себе внимание в самом начале, он все ещё оставался довольно нишевым. В январе 2006 года команда X Window System перешла с CVS на Git. И этого уже было достаточно, чтобы поразить Джунио. Он не ожидал, что такой большой проект, как X Window System, пойдёт на смену системы контроля версий.

После BitKeeper появилось множество DVCS. Помимо Monotone, это были Mercurial, Darcs, Bazaar, Arch и Fossil. Самой заметной среди них была Mercurial, созданная Оливией Маколл. Система была выпущена всего через несколько дней после Git, обладала более полными возможностями и более удобным интерфейсом. Ее также поддержали Google Code и BitBucket. Рынок систем контроля версий был похож на Дикий Запад, каждая система держалась особняком.

Что действительно подтолкнуло Git к вершине и сделало его мейнстримом, так это GitHub. Или, как сказал Линус, это люди из Ruby, странные люди, которые в одночасье сделали Git успешным.

В феврале 2007 года была выпущена версия Git 1.5, наконец-то сделавшая Git более удобным для использования простыми людьми. В то время Git был горячей новинкой, о которой говорили на Ruby-митапах в Сан-Франциско. Том Престон-Вернер, сооснователь GitHub, впервые услышал о Git от своего коллеги Дэйва Файрама. Том считал Дейва «нулевым пациентом» в распространении Git в сообществе Ruby.

Несмотря на популярность Git'а в сообществе Ruby, единственным доступным Git-хостингом в то время был repo.or.cz Петра Баудиса, который был довольно прост. Например, ваш код должен был быть публичным, без возможности создания частных репозиториев. Том увидел там большие возможности.

В 2007 году социальные сети переживали бум, и Том придумал идею под названием GitHub: хаб для программистов, где они могли бы делиться репозиториями Git и обмениваться идеями.

Однажды в октябре 2007 года Том встретил Криса Ванстрата в спортивном баре в Сан-Франциско. Они виделись раньше на Ruby-митапах, но не были хорошо знакомы друг с другом. Том завязал разговор и поделился своей идеей GitHub. Крису она показалась интересной, и он согласился присоединиться.

В то время и Том, и Крис имели постоянную работу, поэтому они проводили вечера и субботы за созданием GitHub. Том разработал пользовательский интерфейс и использовал библиотеку Ruby под названием Grit для взаимодействия с репозиториями Git, а Крис создал сайт на Ruby on Rails.

Через три месяца они начали рассылать друзьям приглашения протестировать GitHub. В феврале 2008 года третьим соучредителем стал Пи Джей Хайетт. 10 апреля GitHub был официально запущен с лозунгом «Социальный хостинг кода».

GitHub, август 2008
GitHub, август 2008

Rails, флагманское приложение от Ruby, перешло с Subversion на GitHub как раз перед запуском GitHub, что ещё сильнее продвинуло Git в Ruby-сообществе. Большинство людей, пишущих на Ruby, в то время разрабатывали приложения на Rails. Когда они увидели, что их основной фреймворк использует GitHub, всё больше Ruby-разработчиков последовали их примеру.

Слияние Git и GitHub с конфликтом

Скотт Чакон не был типичным парнем из категории «Git + Ruby». Помимо написания кода на Ruby, он был отличным оратором, писателем и ИТ-евангелистом. Создавал видеоролики, писал документацию и учил людей, как использовать Git. Он также глубоко разбирался во внутреннем устройстве Git и написал электронную книгу под названием «Внутреннее устройство Git».

В течение трех лет «официальной» домашней страницей Git'а был git.or.cz, созданный Петром Баудисом в 2005 году. Скотт хотел создать более удобный лендинг для новичков. В июле 2008 года он реорганизовал содержимое git.or.cz и запустил новую домашнюю страницу, git-scm.com. Затем он обратился к разработчикам ядра Git (особенно к Петру) за отзывами в рассылке Git.

Хотя Git уже некоторое время был популярен в сообществе Ruby, в рассылке Git редко встречались люди, занимающиеся Ruby. Большинство разработчиков ядра Git были опытными программистами на C, активно участвующими в рассылке, в то время как люди из Ruby, в основном молодые веб-разработчики, общались на встречах, веб-форумах и GitHub и, вероятно, никогда в жизни не пользовались рассылкой. Эти две группы мало взаимодействовали друг с другом, и сообщение Скотта о git-scm.com в рассылке Git было одним из немногих ранних взаимодействий между ними.

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

На сайте Git-scm.com висел баннер с надписью «Хостинг предоставлен GitHub», что заставило некоторых усомниться в мотивах Скотта. Люди выражали недовольство тем, что GitHub зарабатывает на Git, а разработчики основного Git не получают от этого никакой доли. Однако большинство отзывов были положительными, и в итоге git-scm.com стал официальной домашней страницей Git, а git.or.cz ушел в отставку.

Том познакомился со Скоттом на Ruby-митапе. Он подумал: «Этот парень может стать либо могущественным союзником, либо опасным врагом». В октябре 2008 года Скотт присоединился к GitHub, продолжая свою миссию по распространению информации о Git. Он писал больше документации, консультировал и обучал компании, как использовать Git. Он также написал книгу «Pro Git», которая стала официальным учебником по Git. Стратегия продвижения GitHub сработала отлично, расширив сферу влияния Git за пределы сообщества Ruby. А сам GitHub оказался самым большим бенефициаром.

В октябре 2008 года компания Google выступила спонсором первой конференции GitTogether. Около 20 человек из команд Git и GitHub собрались в штаб-квартире Google в Маунтин-Вью. Они отбросили свои разногласия, понимая, что только работая вместе смогут стать сильнее.

GitTogether 2008
GitTogether 2008

Эпилог

Не выдержав конкуренции с Git и GitHub, BitKeeper в итоге был вынужден уйти с рынка. В 2016 году команда открыла открытый доступ к своему коду. Этот дедушка DVCS, вдохновивший Git, Mercurial, Monotone и другие, теперь стал частью истории, которую люди могут наблюдать и изучать. Когда Ларри МаКвоя спросили, что он думает, тот ответил:

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

С другой стороны, мы не заработали достаточно, чтобы каждый из команды мог уйти на пенсию, если бы захотел. Мы предлагали сервис, похожий на github, и совершенно очевидно, что мы должны были вложить в него кучу денег и сделать BitKeeper с открытым исходным кодом .

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

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

Сейчас Ларри наслаждается своей пенсией. Он любит проводить время на рыбалке со своими детьми.

***

В исследовании Stack Overflow, проведенном в 2022 году, доля Git на рынке составила 94 %. В следующем году Stack Overflow и вовсе перестал спрашивать, какую систему контроля версий используют люди.

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

Комментарии (0)