Глава 3
Все о клонировании
В старых системах контроля версий checkout - это стандартная операция для получения файлов.
Вы получаете файлы в нужном сохраненном состоянии.
В Git и других распределенных системах контроля версий, клонирование - это обычно дело. Для получение файлов вы создаете клон всего репозитария. Другими словами, вы создаете зеркало центрального сервера. При этом все что можно делать в основном репозитарии, можно делать и в локальном.
3.1 Синхронизация компьютеров
По этой причине я начал использовать Git. Я вполне приемлю синхронизацию архивами или использование rsync для бэкапа или процедуры стандартной синхронизации. Но я работаю то на ноутбуке, то на стационарном компьютере, которые никак между собой не взаимодействуют.
Инициализируйте Git репозиторий и делайте коммит файлов на одном компьютере. А потом выполните следующие операции на другом:
$ git clone other.computer:/path/to/files для создания второй копии файлов и Git репозитария. С этого момента выполняйте,
$ git commit -a
$ git pull other.computer:/path/to/files HEAD
это синхронизирует состояние ваших файлов с состоянием файлов другого компьютера. Если вы внесли изменения, которые будут конфликтовать с таким же файлом, Git даст Вам знать об этом,
и вам придется сделать коммит еще раз, уже после устранения конфликтующих изменений.
3.2 Классический контроль исходного кода
Инициализируйте Git-репозитарий для ваших файлов:
$ git init
$ git add .
$ git commit -m "Initial commit"
Магия Git
9 / 41
На центральном сервере инициализируйте пустой Git-репозитарий с присвоением какого-нибудь имени,
и запустите Git-демон, если необходимо:
$ GIT_DIR=proj.git git init
$ git daemon --detach # возможно уже запущен
Публичные репозитарии, такие как repo.or.cz
, имеют собственные схемы по организации из- начально пустых Git-репозитариев, которые обычно предполагают регистрацию и заполнение формы.
Чтобы сохранить ваши изменения в центральный репозиторий, запустите:
$ git push git://central.server/path/to/proj.git HEAD
Для клонирования, как уже было описано выше, необходимо:
$ git clone git://central.server/path/to/proj.git
После внесения изменений, код записывается на главный сервер с помощью:
$ git commit -a
$ git push
Если в ходе работы на сервере уже происходили изменения, необходимо обновить локальную копию репозитария перед сохранением собственных изменений. Для синхронизации:
$ git commit -a
$ git pull
3.3 Создание форка проектаНе нравится путь развития проекта? Думаете можете сделать лучше? Тогда на Вашем сервере:
$ git clone git://main.server/path/to/files
Теперь расскажите всем, что новый проект находится на вашем сервере.
В любое время вы можете объединить изменения с изначальным проектом, используя:
$ git pull
3.4 Окончательные бэкапыХотите создать множество географически разнесенных, разных, защищенных, резервных архи- вов? Если в вашем проекте много разработчиков - делать ничего не надо! Каждый клон - это и есть бэкап, причем отражающий не только текущее состояние, но и всю историю изменений проекта. Благодаря криптографическому хэшированию, при нарушении какого-либо из клонов,
этот
клон будет помечен, и это будет видно при любой попытке взаимодействия с ним.
Если ваш проект не такой популярный, размещайте клоны на как можно большем количестве серверов.
Особо беспокоящимся рекомендуется всегда записывать самый последний 20-байтный SHA1
хэш HEAD в безопасном месте. В безопасном, но не тайном. Например, в газете, это будет эф- фективным, потому как сложно изменить каждую копию газеты.
Магия Git
10 / 41
3.5 Многозадачность со скоростью света
Скажем, вы хотите выполнять несколько задач параллельно. Тогда сохраните свой проект и за- пустите:
$ git clone . /some/new/directory
Git использует жесткие ссылки и обмен файлами настолько безопасно, насколько это возможно для создания такого клона, он будет готов мгновенно, после чего можно будет работать с раз- ными функциями одновременно. Например, можно редактировать один клон, компилируя в это время другой.
В любое время можно сделать коммит и вытянуть изменения из другого клона.
$ git pull /the/other/clone HEAD
3.6 Другие системы контроля версий
Вы работаете над проектом, который использует другую систему контроля версий, и вам не хватает Git? Тогда инициализируйте Git-репозиторий в свою рабочую папку:
$ git init
$ git add .
$ git commit -m "Initial commit"
затем клонируйте его:
$ git clone . /some/new/directory
Теперь перейдите в новую директорию и работайте в ней, используя для контроля версий Git.
Когда вам понадобиться синхронизировать изменения с другими, перейдите в изначальную ди- ректорию и произведите синхронизацию с помощью другой системы контроля версий, затем наберите:
$ git add .
$ git commit -m "Синхронизироваться с другими"
Теперь перейдите в новую директорию и запустите:
$ git commit -a -m "Описание моих изменений"
$ git pull
Процедура обмена изменениями с другими зависит от используемой системы контроля версий.
Новая директория содержит файлы с вашими изменениями. Для загрузки файлов в центральный репозиторий требуется запуск любых необходимых команд другой системы контроля версий.
Команда git svn автоматизирует этот процесс для репозиториев Subversion и может быть ис- пользована для экспорта Git проекта в Subversion репозиторий
Магия Git
11 / 41
Глава 4Чудеса ветвленияВозможности мгновенного разветвления и слияния - самые уникальные особенности Git.
Задача: какие-то причины требуют переключения процессов. В новой версии внезапно возника- ет серьезная ошибка. Срок завершения работы над определенным свойством близится к концу.
Разработчик, помощь которого очень нужна Вам в работе над ключевым разделом, собирается в отпуск. Итак, Вам нужно срочно бросить все, над чем Вы трудитесь в настоящий момент, и переключиться на совершенно другие дела.
Переключение внимания с одного на другое может серьезно снизить эффективность работы,
и чем сложнее переход между процессами, тем больше будет потеря. При централизованном управлении версиями необходимо скачивать вновь разработанную рабочую копию с централь- ного сервера. Распределенная система предоставляет лучшие возможности, так как позволяет клонировать нужную версию в локальное рабочее место.
Однако клонирование все же предполагает копирование всей рабочей директории, а, значит,
всей истории изменений до настоящего момента. Даже при том, что Git позволяет сэкономить средства за счет возможности совместного использования файлов и жестких ссылок, все файлы проекта придется полностью воссоздать в новой рабочей директории.
Решение: у Git есть более удобный инструмент для этих целей, который, в отличие от клониро- вания, сэкономит и время, и дисковое пространство - это
git branch.
С этой волшебной командой файлы в вашей директории мгновенно изменяются с одной версии на другую. Это
изменение позволяет сделать намного больше, чем просто вернуться назад или продвинуться вперед в истории. Ваши файлы могут изменится с последней версии на экспе- риментальную, с экспериментальной - на опытную, с опытной - на версию вашего друга и так далее.
4.1 Кнопка боссаНаверняка, вы играли в одну из тех игр, где при нажатии определеной клавиши ("кнопка босса"),
игра быстро сворачивается и на экране отображается рабочая таблица или что-нибудь другое?
То есть, если в офис зашел начальник, а вы играете в игру, вы должны уметь быстро ее скрыть.
В какой-нибудь директории:
$ echo "Я хитрее моего босса" > myfile.txt
$ git init
$ git add .
$ git commit -m "Начальный коммит"
Магия Git
12 / 41
Мы создали Git-репозиторий который содержит один текстовый файл с определенным сообще- нием. Теперь выполните:
$ git checkout -b boss # вероятно, это последнее изменение
$ echo "Мой босс меня умнее" > myfile.txt
$ git commit -a -m "Другой коммит"
Похоже на то, как будто мы перезаписали файл и сделали коммит. Но это иллюзия. Наберите:
$ git checkout master # переключиться на оригинальную версию файла
Вуаля! Текстовый файл восстановлен. И если босс будет рядом, запустите
$ git checkout boss # перейти на специальную версию для босса
Вы можете переключаться между двумя версиями этого файла так часто, как вам хочется и делать коммиты в каждый из них независимо.
4.2 Грязная работа
Допустим, вы работаете над созданием какой-либо функции, и по каким-то причинам необхо- димо вернуться назад к старой версии и временно загрузить старый код, чтобы посмотреть как что-либо работало, тогда введите:
$ git commit -a
$ git checkout SHA1_HASH
Теперь вы можете добавить везде, где необходимо, временный черновой код. Можно даже сде- лать коммит изменений. Когда закончите, выполните:
$ git checkout master чтобы вернуться к исходной работе. Заметьте, что любые изменения, не внесенные в коммит,
будут перенесены.
А что, если вы все-таки хотели сохранить временные изменения? Пожалуйста:
$ git checkout -b dirty а затем сделайте коммит перед тем, как переключетесь на ветвь master. Всякий раз когда вы захотите вернуться к черновым изменениям, просто выполните:
$ git checkout dirty
Мы говорили об этой команде ранее, в другой главе, когда обсуждали загрузку старых состоя- ний. Теперь у нас перед глазами полная картина: файлы меняются на нужное состояние, но мы должны оставить ветвь master. Любые коммиты, сделанные с этого момента, направят файлы по другому пути, который может быть назван позже.
Другими словами, после переключения с более старого состояния, Git автоматически направ- ляет вас в новую еще не названную ветвь, которой можно дать имя и сохранить с помощью git
checkout -b.
Магия Git
13 / 41
4.3 Быстрые исправленияВаша
работа в самом разгаре, когда вдруг выясняется, что нужно все бросить и исправить только что обнаруженную ошибку:
$ git commit -a
$ git checkout -b fixes SHA1_HASH
Затем, после того, как вы исправили ошибку:
$ git commit -a -m "Ошибка исправлена"
$ git push # в центральный репозиторий
$ git checkout master и вернитесь к работе над вашими исходными задачами.
4.4 Бесперебойный рабочий процессВ некоторых проектах необходимо проверять код до того, как выложить его. Чтобы облегчить задачу другим разработчикам, которые будут проверять ваш код, при внесении значительных изменений, разбивайте измененный проект на 2 или более частей и выкладывайте по одной для проверки.
А что, если вторую часть нельзя записать до того, как первая часть проверена и принята? Во многих системах управления версиями отправить на рассмотрение вторую часть можно только после утверждения первой части.
На самом деле это не совсем правда, но необходимость в таких системах редактировать часть
II перед тем, как отправить часть I, связана с трудностями и неудобствами. В Git, ветвление и слияние гораздо безболезненней (говоря техническим языком - это можно сделать быстрее и на локальном уровне). Поэтому, после того, как вы сделали коммит первой части, и направили его для рассмотрения:
$ git checkout -b part2
Далее, можно изменять вторую часть, не ожидая принятия первой части. После того, как первая часть утверждена и выложена,
$ git checkout master
$ git merge part2
$ git branch -d part2 # эта ветка больше не нужна и вторая часть правок готова к проверке.
Однако не торопитесь! Что, если не все так просто? Что, если в первой части вы сделали ошибку,
которую необходимо было исправить до отправки. Запросто! Во-первых, вернитесь в master-ветвь с помощью:
$ git checkout master
Исправьте изменения в первой части и отправьте на проверку. Если же они не будут приняты,
можно просто повторить этот шаг. Вы, вероятно, также захотите произвести слияние исправле- ний части I с частью II, тогда выполните:
Магия Git
14 / 41
$ git checkout part2
$ git merge master
И теперь - тоже самое. После того, как первая часть утверждена и выложена:
$ git checkout master
$ git merge part2
$ git branch -d part2
и снова, вторая часть готова к проверке.
Вы можете легко использовать этот трюк для любого количества частей.
4.5 Собрать все в кучу
Предположим, вам нравится работать над всеми аспектами проекта в одной и той же ветке. Вы хотите закрыть свой рабочий процесс от других, чтобы все видели ваши коммиты только после того, как они будут хорошо оформлены. Создайте несколько веток:
$ git checkout -b sanitized
$ git checkout -b medley
Далее, работайте над чем угодно: исправляйте ошибки, добавляйте новые функции, добавляйте временный код и т.д., при этом постоянно выполняя коммиты. Затем:
$ git checkout sanitized
$ git cherry-pick SHA1_HASH
применит данный коммит для ветви"sanitized". С правильно выбранными элементами вы сможе- те собрать ветвь, которая будет содержать только проверенный код и соответствующие коммиты,
сгруппированные вместе.
4.6 Управление Ветками
Для просмотра списка всех веток наберите:
$ git branch
Здесь всегда будет ветка с названием "master", с нее вы начинаете работать по умолчанию. Кому- то нравится оставлять ветку "master" нетронутой и создавать новые ветки со своими изменени- ями.
Опции -d и -m позволяют удалять и перемещать (переименовывать) ветки.
См. git help branch.
Ветка "master" - это полезная традиция. Все считают очевидным то, что ваш репозиторий дол- жен содержать ветку с таким именем, и эта ветка содержит официальную версию проекта. Вы можете переименовать или удалить ветку "master", однако лучше соблюсти всеобщую традицию.
Магия Git
15 / 41
4.7 Временные ВеткиЧерез какое-то время вы можете обнаружить, что создаете множество временных веток для од- ной и той краткосрочной цели: нужно сохранить текущее состояние, чтобы была возможность вернуться назад и исправить грубую ошибку или сделать что-то еще.
Это похоже на то, как вы
переключаете телевизионные каналы, чтобы посмотреть что показы- вают по другим. Но здесь, вместо того, чтобы нажать на пару кнопок на пульте, нужно будет создать, сделать отладку, а затем удалить временные ветки и коммиты. К счастью, в Git есть удобные ярлыки, имитирующие работу дистанционного пульта правления.
$ git stash
Это сохраняет текущее состояние в во временном месте (
копилке) и востанавливает предыдущее состояние. Ваша директория становиться точно такой, как и была до того, как вы начали редак- тирование, и вы можете исправить ошибки, загрузить удаленные изменения и прочее. Когда вы хотите вернуться назад в состояние копилки, наберите:
$ git stash apply # Возможно, понадобится устранить какие-либо конфликты.
Можно создавать несколько копилок, приумножать их и использовать по-разному. Смотрите
githelp stash. Как вы могли догадаться, этот чудесный прием возможен благодаря способности Git поддерживать создание закрытых "тайных" веток.
4.8 Работайте как вам нравитсяТакие приложения как
Mozilla Firefox позволяют открывать несколько вкладок, и несколько окон. Переключение вкладок позволяет обозревать разное содержание в одном и том же окне.
Ветки в Git подобны вкладкам для вашей рабочей директории. Если продолжить аналогию, кло- нирование в Git подобно открытию нового окна. Эти две возможности делают работу в Git удоб- ной и приятной для пользователя.
На более высоком уровне, многие оконные менеджеры Linux поддерживают несколько рабочих столов.
Ветки в Git подобны переключению на другой рабочий стол, а клонирование подобно подклю- чению дополнительно монитора для получения дополнительного рабочего стола.
Другой пример - это утилита
screen. Эта программа позволяет создавать, закрывать и переклю- чаться между множеством терминальных сессий в одном и том же терминале. Вместо открытия нового терминала (операция клонирования), можно использовать этот, запустив
screen (создать ветвь). На самом деле у
screen еще много возможностей, но это уже тема для другой главы.
Наличие возможностей клонирования, ветвления и быстрого локального слияния позволяет вам выбрать комбинировать их так, как удобно и нужно вам. Git позволяет работать именно так, как вам хочется.
Магия Git
16 / 41
Глава 5Уроки историиВследствие распределенной природы Git, историю изменений можно легко редактировать. Од- нако, если вы вмешиваетесь в прошлое, будьте осторожны: изменяйте только ту часть истории,
которой владеете вы и только вы. И также как государства бесконечно выясняют, кто же
именно совершил и какие бесчинства, так и у вас будут проблемы с примирением после взаимодействия деревьев истории.
Конечно, если вы также контролируете и все остальные деревья, то нет никаких проблем по- скольку вы можете переписать их.
Некоторые разработчики убеждены, что история должна быть неизменна со всеми огрехами и прочим. Другие считают, что деревья должны быть презентабельными, до того как они выпустят их в публичный доступ. Git учитывает оба мнения. Также как клонирование, ветвление и слия- ние, переписывание истории - это просто еще одна возможность, которую дает вам Git. Разумное ее использование зависит только от вас.
5.1 Оставаясь корректнымТолько что сделали коммит и уже хотите изменить запись в журнале? Запустите:
$ git commit --amend чтобы изменить последнее сообщение коммита. Осознали, что забыли добавить файл? Запустите
git add, чтобы это сделать и выполните вышеуказанную команду.
Захотелось добавить еще немного изменений в последний коммит? Так сделайте их и запустите:
$ git commit --amend -a
5.2 …И кое-что ещеДавайте представим себе, что предыдущая проблема на самом деле в десять раз хуже. После длительной работы вы сделали ряд фиксаций, но вы не очень-то довольны тем, как они органи- зованы и кое-какие записи в журнале (commit messages) надо бы слегка переформулировать. В
этом случае запустите:
$ git rebase -i HEAD10
Магия Git
17 / 41
и записи в журнале от последних 10-ти фиксаций появятся в вашем любимом редаторе (задается переменной окружения $EDITOR). Вот кусок примера:
pick 5c6eb73 Добавил ссылку repo.or.cz pick a311a64 Сменил порядок в "Работай как хочешь"
pick 100834f Добавил цель для push в Makefile
После чего:
• Убираем коммиты, удаляя строки.
• Меняем порядок коммитов, меняя порядок строк.
• Заменяем "pick" на "edit", если требуется внести изменения в коммиты.
• Заменяем "pick" на "squash" для слияния коммита с предыдущим.
Если вы отметили коммит для исправлений, запустите:
$ git commit --amend
Если нет, запустите:
$ git rebase --continue
В общем, делайте коммиты как можно раньше и как можно чаще - всегда потом сможете за собой подчистить при помощи rebase.
5.3 Локальные изменения сохраняются
Предположим, вы работаете над активным проектом. За какое-то время были проведены несколь- ко коммитов, после чего синхронизируетесь с официальным деревом через слияние. Цикл повто- ряется несколько раз до тех пор, пока вы не готовы отправить (push) изменения в центральное дерево.
Однако теперь история изменений в локальном клоне Git представляет собой кашу из ваших и официальных изменений. Вам бы хотелось видеть все изменения непрерывной секцией даже после слияния с официальными.
Это работа для команды git rebase в виде, описанном выше. Зачастую, имеет смысл использо- вать флаг --onto, чтобы не использовать интерактивный режим.
Также стоит взглянуть на вывод команды git help rebase для получения подробных примеров использования этой замечательной команды. Вы можете объединять фиксации, вы можете даже перестраивать ветки.
5.4 Переписывая историю
Время от времени вам может понадобиться эквивалент "замазывания" людей на официальных фотографиях, только для систем контроля версий, как бы стирая их из истории в духе сталиниз- ма. Например, предположим, что мы уже собираемся выпустить релиз проекта, но он содержит файл, который не должен стать достоянием общественности по каким-то причинам. Может я сохранил номер своей кредитки в текстовый файл и случайно добавил этот файл к файлам про- екта? Просто стирать файл бесполезно - из-за контроля версий всегда можно вытащить такую из старых версий, где этот документ еще есть. Нам надо удалить файл из всех версий когда-либо существовавших. Для этого:
Магия Git
18 / 41
$ git filter-branch --tree-filter 'rm top/secret/file' HEAD
Стоит посмотреть вывод команды
git help filter-branch, где обсуждается этот пример и даже предлагается более быстрый метод решения. Короче говоря,
filter-branch позволяет изменять существенные части истории при помощи одной-единственной команды.
В результате директория .git/refs/original будет описывать состояние дел до выполнения операции. Убедитесь, что команда filter-branch проделала все, что вы хотели, и, если хотите опять использовать команду, удалите эту директорию.
И, наконец, замените клоны вашего проекта обновленной версией, если собираетесь в дальней- шем с ними иметь дело.
5.5 Создавая ИсториюХотите перевести проект под управление Git? Если сейчас он находится под управлением какой- либо из хорошо известных систем контроля версий, то весьма велики шансы на то, что кто- нибудь уже позаботился и написал необходимые скрипты для экспорта всей истории проекта в
Git.
А если все-таки нет? Тогда смотрите в сторону команды
git fast-import, которая считывает тек- стовый ввод в специальном формате для создания истории Git "с нуля".
Обычно скрипт, использующий эту команду - это наспех состряпанное нечто, предназначенное для однократного использования, чтоб "перетащить" проект за один раз.
В качестве примера, вставьте следующий листинг в какой-нибудь файл, типа
/tmp/history:
commit refs/heads/master committer Alice
Thu, 01 Jan 1970 00:00:00 +0000
data <EOT
M 100644 inline hello.c data <#include
int main() {
printf("Hello, world!\n");
return 0;
}
EOT
commit refs/heads/master committer Bob Tue, 14 Mar 2000 01:59:26 -0800
data <EOT
M 100644 inline hello.c data <#include
int main() {
write(1, "Hello, world!\n", 14);
return 0;
}
EOT
Магия Git
19 / 41
Затем создайте репозиторий Git из этого временного файла при помощи команд:
$ mkdir project; cd project; git init $ git fast-import < /tmp/history
Вы можете извлечь (checkout) последнюю версию проекта при помощи команды:
$ git checkout master .
Команда git fast-export преобразует любой репозиторий Git в формат, понимаемый командой
git fast-import. То есть, ее выход может быть использован как образец для тех кто пишет скрипты- преобразователи и для того, чтобы переносить репозитории в формате, хоть как-то пригодном для чтения человеком. Естественно, при помощи этих команд можно пересылать репозитории текстовых файлов через каналы передачи текста.
5.6 Когда же все пошло не так?
Вы только что обнаружили, что кое-какой функционал вашей программы не работает, но вы совершенно отчетливо помните, что он работал всего несколько месяцев назад. Ну вот, блин!
Откуда же взялась ошибка? Вы же это проверяли сразу как разработали.
В любом случае, уже поздно сожалеть. Однако, если вам хватило ума фиксировать свои измене- ния часто, то Git сможет сильно помочь точно определить проблему.
$ git bisect start
$ git bisect bad SHA1_OF_BAD_VERSION
$ git bisect good SHA1_OF_GOOD_VERSION
Git извлечет состояние ровно посередине. Проверьте работает ли то, что сломалось, и если все еще нет, то введите:
$ git bisect bad
Если же работает, то замените "bad" на "good" в предыдущей команде. Git снова переместит вас в состояние посередине между "хорошей" и "плохой" ревизиями, при этом сузив круг подозре- ваемых ревизий вдвое.
После нескольких итераций, этот бинарный поиск приведет вас к тому коммиту, на котором все и сломалось. После окончания выяснения, вернуть исходное состояние можно командой:
$ git bisect reset
Вместо того, чтоб вручную тестировать каждое изменение - автоматизируйте этот процесс при помощи команды:
$ git bisect run COMMAND
Git использует возвращаемое значение заданной команды, обычно "одноразового" скрипта, чтоб определить "хорошее" это было изменение или "плохое". Скрипт должен вернуть 0, если "хоро- шее", 125 если изменение надо пропустить и любое число от 1 до 127 если "плохое". Отрица- тельное возвращаемое значение прерывает бинарный поиск.
На самом деле возможностей еще больше! На странице помощи объясняется как визуализи- ровать бинарный поиск, проанализировать или даже воспроизвести журнал поиска, исключить изменения в которых точно все в порядке для ускорения поиска.
Магия Git
20 / 41
5.7 Из-за кого все пошло наперекосяк?Как и многие другие системы конроля версий, Git поддерживает команду blame:
$ git blame FILE
которая показывает кто и когда изменил каждую строку выбранного файла. В отличие же от многих других систем контроля версий эта операция происходит оффлайн, то есть данные бе- рутся с локального диска.
5.8 Личный опытВ централизованных системах контроля версий, изменения истории - достаточно сложная опе- рация и для ее проведения необходимо привлечение администраторов. Процедуры клонирова- ния, ветвления и слияния невозможно осуществить без сетевого соединения. Также обстоят дела и с такими базовыми операциями как просмотр журнала изменений или фиксация изме- нений. В некоторых системах сетевое соединение требуется даже для просмотра собственных изменений или открытия файла для редактирования.
Централизованные системы исключают возможность работать оффлайн и требуют более доро- гой сетевой инфраструктуры, особенно с увеличением количества разработчиков. Еще более важно, из-за того все операции происходят медленнее, пользователи избегают пользоваться "продвинутыми" командами до тех пор пока не "припечет как следует". В особо "запущенных"
случаях это касается и большинства базовых команд тоже. Продуктивность страдает из-за оста- новок в работе, когда пользователи вынуждены запускать "долгоиграющие" команды.
Я испытал этот феномен на себе. Git был моей первой системой контроля версий. Я быстро при- вык нему и стал относится к его возможностям как к должному. Я предположил, что и другие системы похожи на него: выбор системы контроля версий не должен отличаться от выбора тек- стового редактора или браузера.
Когда, немного позже, я был вынужден использовать централизованную систему контроля вер- сий, я был шокирован. При использовании Git, мое, зачастую капризное, интернет-соединение не
имело большого значения, но теперь разработка стала невыносимой когда от него потребова- лась надежность как у жесткого диска. Плюс к этому, я обнаружил, что стал избегать использо- вать некоторые команды из-за получающихся в результате их выполнения задержек, а без них оказалось невозможным следовать моему стилю разработки.
Когда мне было нужно запустить "медленную" команду, нарушение хода цепочки моих мыслей оказывало несоизмеримый ущерб разработке. Ожидая окончания связи с сервером, я должен был заниматься чем-то другим, чтоб скоротать время, например, чтением почты или написанием документации. Через некоторое время я возвращался к первоначальной задаче, но приходилось тратить уйму времени, чтоб вспомнить на чем же я остановился и что хотел делать дальше.
Все-таки люди не очень приспособлены для многозадачности.
Есть еще один интересный эффект, так называемая, трагедия общин: предвидя будущую загруз- ку сети, некоторые люди начинают использовать более "широкие" каналы чем им реально требу- ются для текущих операций в попытке предотвратить будущие задержки. Суммарная активность увеличивает загрузку сети, поощряя людей задействовать еще более высокоскоростные каналы в следующий раз, чтоб избежать еще больших задержек.