minor edit in ru/branch.txt
[gitmagic/gitmagic.git] / ru / branch.txt
blobaa75a71a28fbcfdb927df0d94f36b48ca51682ed
1 == Чудеса ветвления == 
3 Возможности мгновенного ветвления и слияния — самые потрясающие особенности Git.
5 *Задача*: во время работы неизбежны внешние факторы, влекущие переключение контекста. Серьезная ошибка в уже выпущенной версии проявляется без предупреждения. Срок сдачи конкретного функционала не стоит на месте. Разработчик, помощь которого нужна вам в работе над ключевой частью проекта, собирается в отпуск. Одним словом, вам нужно срочно бросить все, над чем вы трудитесь в настоящий момент, и переключиться на совершенно другие дела.
7 Прерывание хода ваших мыслей может серьезно снизить эффективность работы, и чем сложнее переключение между процессами, тем больше будет потеря. При централизованном управлении версиями мы вынуждены скачивать свежую рабочую копию с центрального сервера. Распределенная система лучше: мы можем клонировать нужную версию локально.
9 Однако клонирование все же предполагает копирование всего рабочего каталога, как и всей истории изменений до настоящего момента. Хотя Git и позволяет сэкономить средства за счет возможности совместного использования файлов и жестких ссылок, но все файлы проекта придется полностью воссоздать в новом рабочем каталоге.
11 *Решение*: у Git есть более удобный инструмент для этих целей, который сэкономит и время, и дисковое пространство по сравнению с клонированием — это *git branch* (branch — ветка, прим. пер.).
13 Этим волшебным словом файлы в вашем каталоге мгновенно преобразуются с одной версии на другую. Это изменение позволяет сделать намного больше, чем просто вернуться назад или продвинуться вперед в истории. Ваши файлы могут изменится с последней выпущенной версии на экспериментальную, с экспериментальной — на текущую версию в разработке, с неё — на версию вашего друга и так далее.
15 === Кнопка босса ===
17 Наверняка, вы играли в одну из таких игр, где при нажатии определеной клавиши («кнопки босса»), игра быстро сворачивается и на экране отображается рабочая таблица или что-нибудь другое? То есть, если в офис зашел начальник, а вы играете в игру, вы должны уметь быстро ее скрыть.
19 В каком-нибудь каталоге:
21  $ echo "Я хитрее моего босса" > myfile.txt 
22  $ git init 
23  $ git add .  
24  $ git commit -m "Начальный коммит"
26 Мы создали хранилище Git, содержащее один текстовый файл с определенным сообщением. Теперь выполните
28  $ git checkout -b boss # вероятно, это последнее изменение
29  $ echo "Мой босс меня умнее" > myfile.txt
30  $ git commit -a -m "Другой коммит"
32 Похоже на то, как будто мы перезаписали файл и сделали коммит. Но это иллюзия. Наберите
34  $ git checkout master # переключиться на оригинальную версию файла
36 Вуаля! Текстовый файл восстановлен. И если босс решить сунуть нос в этот каталог, запустите
38  $ git checkout boss # перейти на специальную версию для босса
40 Вы можете переключаться между двумя версиями этого файла так часто, как вам хочется и делать коммиты каждой из них независимо.
42 === Грязная работа ===
44 [[branch]]
45 Допустим, вы работаете над созданием какой-либо функции, и вам зачем-то понадобилось вернуться на три версии назад и временно добавить несколько операторов вывода, чтобы посмотреть как что-либо работает. Тогда введите
47  $ git commit -a
48  $ git checkout HEAD~3
50 Теперь вы можете добавлять временный черновой код в любых местах. Можно даже закоммитить эти изменения. Когда закончите, выполните
52  $ git checkout master
54 чтобы вернуться к исходной работе. Заметьте, что любые изменения, не внесенные в коммит, будут перенесены.
56 А что, если вы все-таки хотели сохранить временные изменения? Запросто:
58  $ git checkout -b dirty
60 а затем сделайте коммит перед возвращением в ветку master. Всякий раз когда вы захотите вернуться к черновым изменениям, просто выполните
62  $ git checkout dirty
64 Мы говорили об этой команде в одной из предыдущих глав, когда обсуждали загрузку старых состояний. Теперь у нас перед глазами полная картина: файлы изменились к нужному состоянию, но мы должны оставить ветвь master. Любые коммиты, сделанные с этого момента, направят файлы по другому пути, который может быть указан позже.
66 Другими словами, после переключения на более старое состояние Git автоматически направляет вас в новую безымянную ветвь, которой можно дать имя и сохранить с помощью *git checkout -b*.
68 === Быстрые исправления ===
70 Ваша работа в самом разгаре, когда вдруг выясняется, что нужно все бросить и исправить только что обнаруженную ошибку в коммите «1b6d…»:
72  $ git commit -a
73  $ git checkout -b fixes 1b6d
75 Затем, после того, как вы исправили ошибку, сделайте
77  $ git commit -a -m "Ошибка исправлена"
78  $ git push # в центральное хранилище
79  $ git checkout master
81 и вернитесь к работе над вашими исходными задачами.
83 Вы можете даже «влить» только сделанное вами исправление ошибки, набрав
85  $ git merge fixes
87 или
89  $ git pull
91 т.к. вы уже отправили это исправление в основное хранилище.
93 === Слияния ===
95 В некоторых системах контроля версий создавать ветки легко, а вот сливать их воедино трудно. В Git слияние столь тривиально, что вы можете его не заметить.
97 Действительно, хотя мы только познакомились с *git merge*, мы сталкивались со слияниями уже давно. Команда *pull* по сути получает коммиты, а затем сливает их с вашей текущей веткой. Если у вас нет локальных изменений, слияние вырожденное: это то же самое, что и получение последней версии в централизованной системе контроля версий. Если же у вас есть локальные изменения, Git автоматически произведёт слияние и сообщит о любых конфликтах.
99 Обычно у коммита есть один «родитель», а именно, предыдущий коммит. Слияние веток приводит к коммиту как минимум с двумя родителями. Отсюда возникает вопрос: к какому коммиту на самом деле отсылает HEAD~10? Коммит может иметь несколько родителей, так за которым из них следовать далее?
101 Оказывается, такая запись всегда выбирает первого родителя. Это хороший выбор, потому что коммиты в текущей ветке становятся первыми родителями во время слияния. Часто вас интересуют только изменения, сделанные вами в текущей ветке, а не те, которые влились из других веток.
103 Вы можете обращаться к конкретному родителю с помощью символа «^». Например, чтобы показать запись в журнале от второго родителя,
105  $ git log HEAD^2
107 Вы можете опустить номер для первого родителя. Например, чтобы показать разницу с первым родителем,
109  $ git diff HEAD^
111 Вы можете сочетать такую запись с другими. Например,
113  $ git checkout 1b6d^^2~10 -b ancient
115 создаст новую ветку «ancient» («древняя», прим. пер.), отражающую состояние на десять коммитов назад от второго родителя первого родителя коммита, начинающегося с 1b6d.
117 === Непрерывный рабочий процесс ===
119 В производстве техники часто бывает, что второй шаг плана должен ждать завершения первого шага. Автомобиль, нуждающийся в ремонте, может тихо стоять в гараже до прибытия с завода конкретной детали. Прототип может ждать производства чипа, прежде чем разработка будет продолжена.
121 И в разработке ПО может быть то же. Вторая часть нового функционала может быть вынуждена ожидать выпуска и тестирования первой части. Некоторые проекты требуют проверки вашего кода перед его принятием, так что вы должны дождаться утверждения первой части, прежде чем начинать вторую.
123 Благодаря безболезненному ветвлению и слиянию, мы можем изменить правила и работать над второй частью до того, как первая официально будет готова. Допустим, вы закоммитили первую часть и выслали её на проверку. Скажем, вы в ветке master. Теперь смените ветку:
125  $ git checkout -b part2 # часть2
127 Затем работайте над второй частью, попутно внося коммиты ваших изменений. Человеку свойственно ошибаться, и часто вы хотите вернуться и поправить что-то в первой части. Если вы везучи или оченрь искусны, можете пропустить эти строки.
129  $ git checkout master  # Возвращаемся к первой части.
130  $ edit files           # Исправляем её.
131  $ git checkout part2   # Возвращаемся ко второй части.
132  $ git merge master     # Вливаем сделанные исправления.
134  В конечном счёте, первая часть утверждена:
136  $ git checkout master  # Возвращаемся к первой части.
137  $ некая_команда        # Некая команда, которую вам нужно выполнить,
138                         # когда текущий рабочий каталог формально готов.
139  $ git merge part2      # Вливаем вторую часть.
140  $ git branch -d part2
142 Теперь вы снова в ветке master, а вторая часть — в вашем рабочем каталоге.
144 Этот приём легко расширить на любое количество частей. Столь же легко сменить ветку задним числом: предположим, вы заметили с опозданием, что должны были создать ветку семь коммитов назад. Тогда введите:
146  $ git branch -m master part2
147  $  # Переименовываем ветку master в part2.
148  $ git checkout HEAD~7 -b master
150 Теперь ветка master содержит только первую часть, а ветка part2 — всё остальное.
152 === Изменяем состав смеси ===
154 Предположим, вам нравится работать над всеми аспектами проекта в одной и той же ветке. Вы хотите закрыть свой рабочий процесс от других, чтобы все видели ваши коммиты только после того, как они будут хорошо оформлены. Создайте пару веток:
156  $ git checkout -b sanitized
157  $ git checkout -b medley
159 Далее делайте всё что нужно: исправляйте ошибки, добавляйте новые функции, добавляйте временный код и т.д., при этом почаще выполняя коммиты. После этого
161  $ git checkout sanitized 
162  $ git cherry-pick medley^^
164 применит коммит «пра-родителя» головы ветки «medley» к ветке «sanitized». Правильно подбирая элементы, вы сможете создать ветку, в которой будет лишь окончательный код, а связанные между собой коммиты будут собраны вместе.
166 === Управление Ветками ===
168 Для просмотра списка всех веток наберите:
170  $ git branch
172 По умолчанию вы начинаете работать с ветки под названием «master». Кому-то нравится оставлять ветку «master» нетронутой и создавать новые ветки со своими изменениями.
174 Опции *-d* и *-m* позволяют удалять и перемещать (переименовывать) ветки.
176 См. *git help branch*.
178 Ветка «master» — это удобная традиция. Другие могут предполагать, что в вашем хранилище есть ветка с таким именем, содержащая официальную версию проекта. Хотя вы можете переименовать или удалить ветку «master», лучше соблюсти общее соглашение.
180 === Временные Ветки ===
182 Через какое-то время вы можете обнаружить, что создаете множество временных веток для одной и той же краткосрочной цели: нужно сохранить текущее состояние, чтобы была возможность вернуться назад и исправить грубую ошибку или сделать что-то еще.
184 Это похоже на то, как вы переключаете телевизионные каналы, чтобы посмотреть что показывают по другим. Но здесь, вместо того, чтобы нажать на пару кнопок на пульте, нужно будет создавать, выбирать (checkout), сливать (merge) а затем удалять временные ветки. К счастью, в Git есть удобная команда, имитирующая работу пульта дистанционного управления.
186  $ git stash
188 Эта команда сохранит текущее состояние в во временном месте («тайнике») и востановит предыдущее состояние. Ваш каталог становиться точно таким, каким был до начала редактирования, и вы можете исправить ошибки, загрузить удаленные изменения и т.п. Когда вы хотите вернуться назад в состояние «тайника», наберите:
190  $ git stash apply # Возможно, понадобится устранить какие-либо конфликты.
192 Можно создавать несколько тайников, используя их разными способами. См. *git help stash*. Как вы могли догадаться, Git удерживает ветки «за кадром» при выполнении этого чудесного приема.
194 === Работайте как вам нравится ===
196 Возможно, вы сомневаетесь, стоят ли ветки таких хлопот. В конце концов, клоны почти столь же быстрые и вы можете переключаться между ними с помощью *cd* вместо загадочных команд Git.
198 Посмотрим на веб-браузеры. Зачем нужна поддержка вкладок вдобавок к окнам?