1 == Многопользовательский Git ==
3 Сначала я использовал Git для личного
4 проекта, в котором был единственным
5 разработчиком. Среди команд, связанных
6 с распределенными свойствами Git, мне
7 требовались только *pull* и *clone*,
8 чтобы хранить один и тот же проект в
11 Позднее я захотел опубликовать свой код
12 при помощи Git и включать изменения
13 помощников. Мне пришлось научиться
14 управлять проектами, которые
15 разрабатываются множеством людей со
16 всего мира. К счастью, в этом сильная
17 сторона Git и, возможно, сам смысл его
22 Каждый коммит содержит имя автора и
23 адрес электронной почты, которые
24 выводятся командой *git log*. По
25 умолчанию Git использует системные
26 настройки для заполнения этих полей.
27 Чтобы установить их явно, введите
29 $ git config --global user.name "John
31 $ git config --global user.email
34 Чтобы установить эти параметры только
35 для текущего хранилища, опустите флаг
38 === Git через SSH, HTTP ===
40 Предположим, у вас есть SSH доступ к
41 веб-серверу, но Git не установлен. Git
42 может связываться через HTTP, хотя это
43 и менее эффективно, чем его собственный
46 Скачайте, скомпилируйте, установите Git
47 в вашем аккаунте; создайте хранилище в
48 каталоге, доступном через web:
50 $ GIT_DIR=proj.git git init
52 $ git --bare update-server-info
53 $ cp hooks/post-update.sample
56 Для старых версий Git команда
57 копирования выдаст ошибку, и вы должны
60 $ chmod a+x hooks/post-update
62 Теперь вы можете публиковать свои
63 последние правки через SSH с любого
67 web.server:/path/to/proj.git master
69 и кто угодно сможет взять ваш проект
72 $ git clone http://web.server/proj.git
74 === Git через что угодно ===
76 Хотите синхронизировать хранилища без
77 серверов или вообще без сетевого
78 подключения? Вынуждены изобретать
79 средства на ходу в непредвиденной
80 ситуации? Мы видели, как
81 <<makinghistory, *git fast-export* и
82 *git fast-import* могут преобразовать
83 хранилища в один файл и обратно>>.
84 Посредством обмена такими файлами мы
85 можем переносить хранилища git любыми
86 доступными средствами, но есть более
87 эффективный инструмент: *git bundle*.
89 Отправитель создает пакет (bundle):
91 $ git bundle create некий-файл HEAD
93 Затем передаёт «пакет», +некий-файл+,
94 другой команде любыми средствами, как
95 то: электронная почта, флешка, *xxd* печать и последующее распознавание текста, надиктовка битов по телефону, дымовые сигналы и т.д. Получатель восстанавливает коммиты из пакета, введя
99 Получатель может сделать это даже в
100 пустом хранилище. Несмотря на свой
101 размер, +некий-файл+ содержит всё
102 исходное хранилище Git.
104 В больших проектах для устраннения
105 излишков объема пакетируют только
106 изменения, которых нет в других
107 хранилищах. К примеру, пусть коммит «1b6d…» — последний, общий для обеих групп:
109 $ git bundle create somefile HEAD ^1b6d
111 Если это делается часто, можно легко
112 забыть, какой коммит был отправлен
113 последним. Справка предлагает для
114 решения этой проблемы использовать
115 теги. А именно, после передачи пакета
118 $ git tag -f последний-пакет HEAD
120 и создавайте обновления пакеты с
123 $ git bundle create новый-пакет HEAD
126 === Патчи: общее применение ===
128 Патчи это тексты изменений, вполне
129 понятные как человеку, так и
130 компьютеру. Это делает их очень
131 привлекательным форматом обмена. Патч
132 ожно послать разработчикам по
133 электронной почте, независимо от того,
134 какую систему контроля версий они
135 используют. Вашим корреспондентам
136 достаточно возможности читать
137 электронную почту, чтобы увидеть ваши
138 изменения. Точно так же, все, что
139 требуется с Вашей стороны, — это адрес
140 электронной почты: нет необходимости в
141 установке онлайн хранилища Git.
143 Вспомним первую главу:
147 выводит патч, который может быть
148 вставлен в письмо для обсуждения. В Git
151 $ git apply < мой.patch
153 для применения патча.
155 В более формальной обстановке, когда
156 нужно сохранить имя автора и подписи,
157 создавайте соответствующие патчи с
158 определенной точки, набрав
160 $ git format-patch 1b6d
162 Полученные файлы могут быть отправлены
163 с помощью *git-send-email* или вручную.
164 Вы также можете указать диапазон
167 $ git format-patch 1b6d..HEAD^^
169 На принимающей стороне сохраните email
174 Это применит входящие исправления, а
175 также создаст коммит, включающий такую
176 информацию, как автор.
178 С web-интерфейсом к электронной почте
179 вам, возможно, потребуется нажать
180 кнопку, чтобы посмотреть электронную
181 почту в своем первоначальном виде до
182 сохранения патча в файл.
184 Есть небольшие различия для клиентов
185 электронной почты, использующих mbox,
186 но если вы используете один из них, то
187 вы, по всей видимости, можете легко
188 разобраться в этом без чтения
191 === Приносим извинения, мы переехали
194 После клонирования хранилища команды
195 *git push* или *git pull* автоматически
196 отправляют и получают его по
197 первоначальному адресу. Каким образом
198 Git это делает? Секрет кроется в
199 настройках, заданных при создании клона. Давайте взглянём:
203 Опция +remote.origin.url+ контролирует
204 исходный адрес; «origin» — имя
205 первоначального хранилища. Как и имя
206 ветки «master», это соглашение: мы
207 можем изменить или удалить этот ник, но
208 как правило, нет причин для этого.
210 Если адрес оригинального хранилища
211 изменился, можно обновить его с
214 $ git config remote.origin.url git://новый.url/proj.git
216 Опция +branch.master.merge+ задает
217 удаленную ветку по умолчанию для
218 *git pull*. В ходе первоначального
219 клонирования она устанавливается на
220 текущую ветку исходного хранилища, так
221 что даже если HEAD исходного хранилища
222 впоследствии переместится на другую
223 ветку, pull будет верно следовать
226 Этот параметр обращается только к
227 хранилищу, который мы изначально
228 клонировали и который записан в
229 параметре +branch.master.remote+. Если
230 мы выполняем pull из других
231 хранилищ, то мы должны указать нужную
234 $ git pull git://пример.com/other.git master
236 Это объясняет, почему некоторых из
237 наших предыдущих примеров push и pull
240 === Удаленные ветки ===
242 Когда вы клонируете хранилище, вы также
243 клонируете все его ветки. Вы можете не
244 заметить это, потому что Git скрывает
245 их: вы должны спросить о них явно. Это
246 предотвращает противоречие между
247 ветками в удаленном хранилище и вашими
248 ветками, а также делает Git проще для
251 Список удаленных веток можно посмотреть
256 Вы должны увидеть что-то вроде
262 Эти имена отвечают веткам и HEAD в
263 удаленном хранилище; их можно
264 использовать в обычных командах Git.
265 Например, вы создали много коммитов, и
266 хотели бы сравнить текущее состояние с
267 последней загруженной версией. Вы
268 можете исать в журналах нужный SHA1
269 хеш, но гораздо легче набрать
271 $ git diff origin/HEAD
273 Также можно увидеть, для чего была
274 создана ветка «experimental», набрав:
276 $ git log origin/experimental
278 === Несколько удаленных хранилищ ===
280 Предположим, что над нашим проектом
281 работают ещё два разработчика, и мы
282 хотим следить за обоими. Мы можем
283 наблюдать более чем за одним
284 хранилищем одновременно так:
286 $ git remote add other git://пример.com/some_repo.git
287 $ git pull other некая_ветка
289 Сейчас мы сделали слияние с веткой из
290 второго хранилища. Теперь у нас есть
291 легкий доступ ко всем веткам во всех
294 $ git diff origin/experimental^
297 Но что, если мы просто хотим сравнить
298 их изменения, не затрагивая свою
299 работу? Иными словами, мы хотим, чтобы
300 изучить чужие ветки, не давая их
301 изменениям вторгаться в наш рабочий
302 каталог. Тогда вместо pull
305 $ git fetch # Перенести из origin, по
307 $ git fetch other # Перенести от
308 второго программиста.
310 Так мы переносим лишь их историю. Оставляя рабочий каталог нетронутыми, мы можем обратиться к любой ветке в любом хранилище команды, работающей с Git, т.к. теперь у нас есть рабочая копия. Держим в уме, что pull это просто *fetch*, а затем *merge*. Обычно мы используем *pull*, потому что мы хотим влить к себе последний коммит после получения чужой ветки; описанная ситуация — примечательное исключение.
312 О том, как отключить удаленные
313 хранилища, игнорировать определенные
314 ветки и многом другом см. *git help
317 === Мои Настройки ===
319 Для моих проектов я люблю использовать
320 готовые хранилища, из которых я могу
321 получить изменения. Некоторые Git хостинги позволяют создавать
322 собственные форки проекта в одно
325 После получения дерева из удалённого
326 хранилища я запускаю команды Git для
327 навигации и изучения изменении, в
328 идеале хорошо организованых и описаных.
329 Я вливаю свои изменения и возможно меняю что-то ещё. По окончании, я выгружаю изменения в главное хранилище.
331 Хотя со мной немного сотрудничают, я охотно верю, что этот подход хорошо масштабируется. См.
332 http://torvalds-family.blogspot.com/2009/06/happiness-is-warm-scm.html[этот
333 пост в блоге Линуса Торвальдса].
335 Оставаться в мире Git несколько удобнее, чем использовать патч-файлы, т.к. это избавляет меня от преобразования их в коммиты Git. Кроме того, Git управляет деталями вроде сохранения имени автора и адреса электронной почты, а также даты и времени, и просит автора описать свои изменения.