Git Format Patch All Commits
Сопровождение проекта В дополнение к тому, как эффективно работать над проектом, вам, наверняка, необходимо также знать, как самому поддерживать проект. Сопровождение проекта может заключаться в принятии и применении патчей, сгенерированных с помощью 'format-patch' и отправленных вам по почте, или в интеграции изменений из веток тех репозиториев, которые вы добавили в качестве удалённых (remotes) для вашего проекта. Неважно, поддерживаете ли вы эталонный репозиторий проекта или хотите помочь с проверкой и утверждением патчей, вам необходимо выработать метод приёма наработок, который будет наиболее понятным для других участников и не будет изменяться в течение длительного срока.
Выполняю следующие инструкции 1) git commit -am 'Comment' 2) git format-patch master --stdout > 2011_08_16_project.patch.
Если вы решаете, интегрировать ли новые наработки, как правило, неплохо было бы опробовать их в какой-нибудь временной тематической ветке, специально созданной для их тестирования. Так будет легче подправить отдельные патчи или забросить их до лучших времён, если что-то не работает. Если вы дадите ветке простое имя, основанное на теме содержащейся в ней работы, например, rubyclient, или как-нибудь так же наглядно, то вы сможете легко вспомнить, для чего эта ветка, если вам вдруг придётся отложить работу с ней и вернуться к ней позднее. В проекте Git мейнтейнер, как правило, создаёт ветки с добавлением пространства имён — к примеру, 'sc/rubyclient', где 'sc' — это сокращённое имя автора, приславшего свою работу. Как вы уже знаете, создать ветку, основанную на вашей ветке master, можно следующим образом: $ git branch sc/rubyclient master Или, если вы хотите сразу переключиться на создаваемую ветку, можно воспользоваться командой checkout -b: $ git checkout -b sc/rubyclient master Теперь вы готовы к тому, чтобы принять изменения в данную тематическую ветку и определить, хотите ли вы влить их в свои стабильные ветки или нет. Если вы получили по электронной почте патч, который вам нужно интегрировать в свой проект, вам необходимо применить патч в тематической ветке, чтобы его оценить.
Есть два способа применения отправленных по почте патчей: с помощью команды git apply или команды git am. Применение патчей с помощью команды apply Если вы получили чей-то патч, сгенерированный с помощью команды git diff или Unix-команды diff, вы можете применить его при помощи команды git apply. Полагая, что вы сохранили патч в /tmp/patch-ruby-client.patch, вы можете применить его следующим образом: $ git apply /tmp/patch-ruby-client.patch Эта команда внесёт изменения в файлы в рабочем каталоге. Она практически идентична выполнению команды patch -p1 для применения патча, хотя она более параноидальна и допускает меньше нечётких совпадений, чем patch.
К тому же она способна справиться с добавлением, удалением и переименованием файлов, описанными в формате git diff, чего команда patch сделать не сможет. И, наконец, git apply реализует модель 'применить всё или ничего', тогда как patch позволяет частично применять патч-файлы, оставляя ваш рабочий каталог в странном и непонятном состоянии.
Команда git apply в целом гораздо более параноидальна, чем patch. Она не создаст для вас коммит — после выполнения команды вы должны вручную проиндексировать внесённые изменения и сделать коммит. Кроме того, вы можете использоваться git apply, чтобы узнать, чисто ли накладывается патч, ещё до того, как вы будете применять его на самом деле — для этого выполните git apply -check, указав нужный патч: $ git apply -check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply Если никакого вывода нет, то патч должен наложиться без ошибок. Если проверка прошла неудачно, то команда завершится с ненулевым статусом, так что вы можете использовать её при написании сценариев. Применение патчей с помощью команды am Если разработчик является достаточно хорошим пользователем Git'а и применил команду format-patch для создания своего патча, то ваша задача становится проще, так как такой патч содержит информацию об авторе и сообщение коммита.
По возможности поощряйте участников проекта на использование команды format-patch вместо diff при генерировании патчей для вас. Команду git apply стоит использовать, только если нет другого выхода, и патчи уже созданы при помощи diff. Чтобы применить патч, созданный при помощи format-patch, используйте команду git am. С технической точки зрения, git am читает mbox-файл, который является простым текстовым форматом для хранения одного или нескольких электронных писем в одном текстовом файле. Он выглядит примерно следующим образом: From 54092d704da8e76ca5c05c198e71a8 Mon Sep 17 00: From: Jessica Smith Date: Sun, 6 Apr 2008 10:17:23 -0700 Subject: PATCH 1/2 add limit to log function Limit log functionality to the first 20 Это начало вывода команды format-patch, который мы уже видели в предыдущем разделе. Это одновременно и правильный mbox формат для e-mail.
Если кто-то прислал вам по почте патч, правильно воспользовавшись для этого командой git send-email, и вы сохранили это сообщение в mbox-формате, тогда вы можете указать этот mbox-файл команде git am — в результате команда начнёт применять все патчи, которые найдёт. Если вы пользуетесь почтовым клиентом, способным сохранять несколько электронных писем в один mbox-файл, то можете сохранить всю серию патчей в один файл и затем использовать команду git am для применения всех патчей сразу. Однако, если кто-нибудь загрузил патч, созданный через format-patch, в тикет-систему или что-либо подобное, вы можете сохранить файл локально и затем передать его команде git am, чтобы его наложить: $ git am 0001-limit-log-function.patch Applying: add limit to log function Как видите, патч был применён без ошибок, и за вас автоматически был создан новый коммит. Информация об авторе берётся из полей From и Date письма, а сообщение коммита извлекается из поля Subject и тела (до начала самого патча) электронного письма. Например, если применить патч из mbox-файла приведённого выше примера, то созданный для него коммит будет выглядеть следующим образом: $ git log -pretty=fuller -1 commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 Author: Jessica Smith AuthorDate: Sun Apr 6 10: -0700 Commit: Scott Chacon CommitDate: Thu Apr 9 09: -0700 add limit to log function Limit log functionality to the first 20 В поле Commit указан человек, применивший патч, а в CommitDate — время его применения. Информация Author определяет человека, создавшего патч изначально, и время его создания.
Однако возможна ситуация, когда патч не наложится без ошибок. Возможно, ваша основная ветка слишком далеко ушла вперёд относительно той, на которой патч был основан, или этот патч зависит от другого патча, который вы ещё не применили.
В этом случае выполнение команды git am будет приостановлено, а у вас спросят, что вы хотите сделать: $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply Patch failed at 0001. When you have resolved this problem run 'git am -resolved'. If you would prefer to skip this patch, instead run 'git am -skip'. To restore the original branch and stop patching run 'git am -abort'. Эта команда выставляет отметки о конфликтах в каждый файл, с которым возникают проблемы, точно так же, как это происходит при операции слияния или перемещения с конфликтами.
И разрешается данная ситуация тем же способом — отредактируйте файл, чтобы разрешить конфликт, добавьте новый файл в индекс, а затем выполните команду git am -resolved, чтобы перейти к следующему патчу: $ (исправление файла) $ git add ticgit.gemspec $ git am -resolved Applying: seeing if this helps the gem Если вы хотите, чтобы Git постарался разрешить конфликт более умно, воспользуйтесь опцией -3, при использовании которой Git попытается выполнить трёхходовую операцию слияния. Эта опция не включена по умолчанию, так как она не работает в случае, если коммита, на котором был основан патч, нет в вашем репозитории.
Если этот коммит всё же у вас есть — в случае когда патч был основан на публичном коммите — то опция -3, как правило, гораздо умнее в наложении конфликтных патчей: $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply Using index info to reconstruct a base tree. Falling back to patching base and 3-way merge. No changes - Patch already applied.
В этом случае я пытался применить патч, который я уже применил. Без опции -3 это привело бы к конфликту. При применении серии патчей из mbox-файла, вы также можете запустить команду am в интерактивном режиме — в этом случае команда останавливается на каждом найденном патче и спрашивает вас, хотите ли вы его применить: $ git am -3 -i mbox Commit Body is: - seeing if this helps the gem - Apply? yes/no/edit/view patch/accept all Это удобно, если у вас накопилось множество патчей, так как вы сможете сначала просмотреть патч, если вы забыли, что он из себя представляет, или отказаться применять патч, если он уже применён.
После того как вы примените все патчи по интересующей вас теме и сделаете для них коммиты в своей ветке, вы можете принять решение — интегрировать ли их в свои стабильные ветки и если да, то каким образом. Если к вам поступили наработки от человека, использующего Git и имеющего свой собственный репозиторий, в который он и отправил свои изменения, а вам он прислал ссылку на свой репозиторий и имя удалённой ветки, в которой находятся изменения, то вы можете добавить его репозиторий в качестве удалённого и выполнить слияния локально.