Глава 7. Многопользовательский Git
Сначала я использовал Git для личного проекта, в котором был единственным разработчиком. Среди команд, относящихся к распределенным свойствам Git, мне были нужны только pull и clone , чтобы хранить один и тот же проект в разных местах.
Позднее я захотел опубликовать свой код при помощи Git и включать изменения помощников. Мне пришлось научиться управлять проектами, в которых участвуют многие люди по всему миру. К счастью, в этом сильная сторона Git и, возможно, сам смысл его существования.
Кто я?
Каждый коммит содержит имя автора и адрес электронной почты, которые выводятся командой git log . По умолчанию Git использует системные настройки для заполнения этих полей. Чтобы установить их явно, введите
Чтобы установить эти параметры только для текущего хранилища, опустите флаг --global.
Git через SSH, HTTP
Предположим, у вас есть SSH доступ к веб-серверу, но Git не установлен. Git может связываться через HTTP, хотя это и менее эффективно, чем его собственный протокол.
Скачайте, скомпилируйте, установите Git в вашем аккаунте; создайте хранилище в каталоге, доступном через web:
Для старых версий Git команда копирования не сработает, и вы должны будете запустить
Теперь вы можете публиковать свои последние правки через SSH с любого клона:
и кто угодно сможет взять ваш проект с помощью
Git через что угодно
Хотите синхронизировать хранилища без серверов или вообще без сетевого подключения? Вынуждены импровизировать на ходу в непредвиденной ситуации? Мы видели, как git fast-export и git fast-import могут преобразовать хранилища в один файл и обратно. Посредством обмена такими файлами мы можем переносить хранилища git любыми доступными средствами, но есть более эффективный инструмент: git bundle .
Отправитель создает пакет (bundle):
Затем передает «пакет», некий-файл , другой команде любыми средствами, как то: электронная почта, флешка, xxd печать и последующее распознавание текста, надиктовка битов по телефону, дымовые сигналы и так далее. Получатель восстанавливает коммиты из пакета, введя
Получатель может сделать это даже в пустом хранилище. Несмотря на свой небольшой размер, некий-файл содержит всё исходное хранилище Git.
В больших проектах для устранения излишков объема пакетируют только изменения, которых нет в других хранилищах. К примеру, пусть коммит «1b6d…» — последний общий для обеих групп:
Если это делается часто, можно легко забыть, какой коммит был отправлен последним. Справка предлагает для решения этой проблемы использовать теги. А именно, после передачи пакета введите
и создавайте обновленные пакеты с помощью
Патчи: общее применение
Патчи это тексты изменений, вполне понятные как человеку, так и компьютеру. Это делает их очень привлекательным форматом обмена. Патч можно послать разработчикам по электронной почте, независимо от того, какую систему управления версиями они используют. Вашим корреспондентам достаточно возможности читать электронную почту, чтобы увидеть ваши изменения. Точно так же, с Вашей стороны требуется лишь адрес электронной почты: нет нужды в настройке онлайн хранилища Git.
Вспомним из первой главы:
выводит патч, который может быть вставлен в письмо для обсуждения. В Git хранилище введите
для применения патча.
В более формальных случаях , когда нужно сохранить имя автора и подписи, создавайте соответствующие патчи с заданной точки, набрав
Полученные файлы могут быть отправлены с помощью git-send-email или вручную. Вы также можете указать диапазон коммитов:
На принимающей стороне сохраните письмо в файл и введите:
Это применит входящие исправления и создаст коммит, включающий имя автора и другую информацию.
С web-интерфейсом к электронной почте вам, возможно, потребуется нажать кнопку, чтобы посмотреть электронную почту в своем первоначальном виде перед сохранением патча в файл.
Для клиентов электронной почты, использующих mbox, есть небольшие отличия; но если вы используете один из них, то вы, по всей видимости, можете легко разобраться в этом без чтения описаний!
Приносим извинения, мы переехали
После клонирования хранилища команды git push или git pull автоматически отправляют и получают его по первоначальному адресу. Каким образом Git это делает? Секрет кроется в настройках, заданных при создании клона. Давайте взглянем:
Опция remote.origin.url задает исходный адрес; origin — имя первоначального хранилища. Как и имя ветки master, это соглашение. Мы можем изменить или удалить это сокращённое имя, но как правило, нет причин для этого.
Если оригинальное хранилище переехало, можно обновить его адрес командой
Опция branch.master.merge задает удаленную ветку по умолчанию для git pull . В ходе первоначального клонирования она устанавливается на текущую ветку исходного хранилища, так что даже если HEAD исходного хранилища впоследствии переместится на другую ветку, pull будет верно следовать изначальной ветке.
Этот параметр обращается только к хранилищу, которое мы изначально клонировали и которое записано в параметре branch.master.remote . При выполнении pull из других хранилищ мы должны указать нужную ветку:
Это объясняет, почему некоторых из наших предыдущих примеров push и pull не имели аргументов.
Удаленные ветки
При клонировании хранилища вы также клонируете все его ветки. Вы можете не заметить этого, потому что Git скрывает их: вы должны запросить их явно. Это предотвращает противоречие между ветками в удаленном хранилище и вашими ветками, а также делает Git проще для начинающих.
Список удаленных веток можно посмотреть командой
Вы должны увидеть что-то вроде
Эти имена отвечают веткам и «голове» в удаленном хранилище; их можно использовать в обычных командах Git. Например, вы сделали много коммитов, и хотели бы сравнить текущее состояние с последней загруженной версией. Вы можете искать в журналах нужный SHA1 хеш, но гораздо легче набрать
Также можно увидеть, для чего была создана ветка experimental:
Несколько удаленных хранилищ
Предположим, что над нашим проектом работают еще два разработчика, и мы хотим следить за обоими. Мы можем наблюдать более чем за одним хранилищем одновременно, вот так:
Сейчас мы сделали слияние с веткой из второго хранилища. Теперь у нас есть легкий доступ ко всем веткам во всех хранилищах:
Но что если мы просто хотим сравнить их изменения, не затрагивая свою работу? Иными словами, мы хотим изучить чужие ветки, не давая их изменениям вторгаться в наш рабочий каталог. Тогда вместо pull наберите
Так мы лишь переносим их историю. Хотя рабочий каталог остается нетронутыми, мы можем обратиться к любой ветке в любом хранилище команды, работающей с Git, так как теперь у нас есть локальная копия.
Держим в уме, что pull это просто fetch , а затем merge . Обычно мы используем pull , потому что мы хотим влить к себе последний коммит после получения чужой ветки. Описанная ситуация — примечательное исключение.
О том, как отключить удаленные хранилища, игнорировать отдельные ветки и многом другом смотрите в git help remote .
Мои Настройки
Я предпочитаю, чтобы люди, присоединяющиеся к моим проектам, создавали хранилища, из которых я смогу получать изменения с помощью pull. Некоторые хостинги Git позволяют создавать собственные форки проекта в одно касание.
После получения дерева из удаленного хранилища я запускаю команды Git для навигации и изучения изменений, в идеале хорошо организованных и описанных. Я делаю слияние со своими изменения и возможно вношу дальнейшие правки. Когда я доволен результатом, я заливаю изменения в главное хранилище.
Хотя со мной мало сотрудничают, я верю, что этот подход хорошо масштабируется. Смотрите эту запись в блоге Линуса Торвальдса.
Оставаться в мире Git несколько удобнее, чем использовать файлы патчей, так как это избавляет меня от преобразования их в коммиты Git. Кроме того, Git управляет деталями вроде сохранения имени автора и адреса электронной почты, а также даты и времени, и просит авторов описывать свои изменения.