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 Это применит входящие исправления и создаст коммит, включающий имя автора и другую информацию.
176 С web-интерфейсом к электронной почте
177 вам, возможно, потребуется нажать
178 кнопку, чтобы посмотреть электронную
179 почту в своем первоначальном виде до
180 сохранения патча в файл.
182 Есть небольшие различия для клиентов
183 электронной почты, использующих mbox,
184 но если вы используете один из них, то
185 вы, по всей видимости, можете легко
186 разобраться в этом без чтения
189 === Приносим извинения, мы переехали
192 После клонирования хранилища команды
193 *git push* или *git pull* автоматически
194 отправляют и получают его по
195 первоначальному адресу. Каким образом
196 Git это делает? Секрет кроется в
197 настройках, заданных при создании клона. Давайте взглянём:
201 Опция +remote.origin.url+ контролирует
202 исходный адрес; «origin» — имя
203 первоначального хранилища. Как и имя
204 ветки «master», это соглашение: мы
205 можем изменить или удалить этот ник, но
206 как правило, нет причин для этого.
208 Если адрес оригинального хранилища
209 изменился, можно обновить его с
212 $ git config remote.origin.url git://новый.url/proj.git
214 Опция +branch.master.merge+ задает
215 удаленную ветку по умолчанию для
216 *git pull*. В ходе первоначального
217 клонирования она устанавливается на
218 текущую ветку исходного хранилища, так
219 что даже если HEAD исходного хранилища
220 впоследствии переместится на другую
221 ветку, pull будет верно следовать
224 Этот параметр обращается только к
225 хранилищу, который мы изначально
226 клонировали и который записан в
227 параметре +branch.master.remote+. Если
228 мы выполняем pull из других
229 хранилищ, то мы должны указать нужную
232 $ git pull git://пример.com/other.git master
234 Это объясняет, почему некоторых из
235 наших предыдущих примеров push и pull
238 === Удаленные ветки ===
240 Когда вы клонируете хранилище, вы также
241 клонируете все его ветки. Вы можете не
242 заметить это, потому что Git скрывает
243 их: вы должны спросить о них явно. Это
244 предотвращает противоречие между
245 ветками в удаленном хранилище и вашими
246 ветками, а также делает Git проще для
249 Список удаленных веток можно посмотреть
254 Вы должны увидеть что-то вроде
260 Эти имена отвечают веткам и HEAD в
261 удаленном хранилище; их можно
262 использовать в обычных командах Git.
263 Например, вы создали много коммитов, и
264 хотели бы сравнить текущее состояние с
265 последней загруженной версией. Вы
266 можете исать в журналах нужный SHA1
267 хеш, но гораздо легче набрать
269 $ git diff origin/HEAD
271 Также можно увидеть, для чего была
272 создана ветка «experimental», набрав:
274 $ git log origin/experimental
276 === Несколько удаленных хранилищ ===
278 Предположим, что над нашим проектом
279 работают ещё два разработчика, и мы
280 хотим следить за обоими. Мы можем
281 наблюдать более чем за одним
282 хранилищем одновременно так:
284 $ git remote add other git://пример.com/some_repo.git
285 $ git pull other некая_ветка
287 Сейчас мы сделали слияние с веткой из
288 второго хранилища. Теперь у нас есть
289 легкий доступ ко всем веткам во всех
292 $ git diff origin/experimental^
295 Но что, если мы просто хотим сравнить
296 их изменения, не затрагивая свою
297 работу? Иными словами, мы хотим, чтобы
298 изучить чужие ветки, не давая их
299 изменениям вторгаться в наш рабочий
300 каталог. Тогда вместо pull
303 $ git fetch # Перенести из origin, по
305 $ git fetch other # Перенести от
306 второго программиста.
308 Так мы переносим лишь их историю. Оставляя рабочий каталог нетронутыми, мы можем обратиться к любой ветке в любом хранилище команды, работающей с Git, т.к. теперь у нас есть рабочая копия. Держим в уме, что pull это просто *fetch*, а затем *merge*. Обычно мы используем *pull*, потому что мы хотим влить к себе последний коммит после получения чужой ветки; описанная ситуация — примечательное исключение.
310 О том, как отключить удаленные
311 хранилища, игнорировать определенные
312 ветки и многом другом см. *git help
315 === Мои Настройки ===
317 Для моих проектов я люблю использовать
318 готовые хранилища, из которых я могу
319 получить изменения. Некоторые Git хостинги позволяют создавать
320 собственные форки проекта в одно
323 После получения дерева из удалённого
324 хранилища я запускаю команды Git для
325 навигации и изучения изменении, в
326 идеале хорошо организованых и описаных.
327 Я вливаю свои изменения и возможно меняю что-то ещё. По окончании, я выгружаю изменения в главное хранилище.
329 Хотя со мной немного сотрудничают, я охотно верю, что этот подход хорошо масштабируется. См.
330 http://torvalds-family.blogspot.com/2009/06/happiness-is-warm-scm.html[этот
331 пост в блоге Линуса Торвальдса].
333 Оставаться в мире Git несколько удобнее, чем использовать патч-файлы, т.к. это избавляет меня от преобразования их в коммиты Git. Кроме того, Git управляет деталями вроде сохранения имени автора и адреса электронной почты, а также даты и времени, и просит автора описать свои изменения.