How to apply git patch
How to apply git patch
How to apply git patch
This command applies the patch but does not create a commit. Use git-am[1] to create commits from patches generated by git-format-patch[1] and/or received by email.
OPTIONS
The files to read the patch from. — can be used to read from the standard input.
Instead of applying the patch, output diffstat for the input. Turns off «apply».
Instead of applying the patch, output a condensed summary of information obtained from git diff extended headers, such as creations, renames and mode changes. Turns off «apply».
Instead of applying the patch, see if the patch is applicable to the current working tree and/or the index file and detects errors. Turns off «apply».
Newer git diff output has embedded index information for each blob to help identify the original version that the patch applies to. When this flag is given, and if the original versions of the blobs are available locally, builds a temporary index containing those blobs.
When a pure mode change is encountered (which has no index information), the information is read from the current index instead.
Apply the patch in reverse.
For atomicity, git apply by default fails the whole patch and does not touch the working tree when some of the hunks do not apply. This option makes it apply the parts of the patch that are applicable, and leave the rejected hunks in corresponding *.rej files.
Without this option, pathnames with «unusual» characters are quoted as explained for the configuration variable core.quotePath (see git-config[1]).
Ensure at least lines of surrounding context match before and after each change. When fewer lines of surrounding context exist they all must match. By default no context is ever ignored.
Note, for the reasons stated above usage of context-free patches is discouraged.
If you use any of the options marked «Turns off apply» above, git apply reads and outputs the requested information without actually applying the patch. Give this flag after those flags to also apply the patch.
When applying a patch, ignore additions made by the patch. This can be used to extract the common part between two files by first running diff on them and applying the result with this option, which would apply the deletion part but not the addition part.
Historically we did not allow binary patch applied without an explicit permission from the user, and this flag was the way to do so. Currently we always allow binary patch application, so this is a no-op.
Don’t apply changes to files matching the given path pattern. This can be useful when importing patchsets, where you want to exclude certain files or directories.
Apply changes to files matching the given path pattern. This can be useful when importing patchsets, where you want to include certain files or directories.
When applying a patch, detect a new or modified line that has whitespace errors. What are considered whitespace errors is controlled by core.whitespace configuration. By default, trailing whitespaces (including lines that solely consist of whitespaces) and a space character that is immediately followed by a tab character inside the initial indent of the line are considered whitespace errors.
nowarn turns off the trailing whitespace warning.
warn outputs warnings for a few such errors, but applies the patch as-is (default).
error outputs warnings for a few such errors, and refuses to apply the patch.
error-all is similar to error but shows all errors.
Under certain circumstances, some versions of diff do not correctly detect a missing new-line at the end of the file. As a result, patches created by such diff programs do not record incomplete lines correctly. This option adds support for applying such patches by working around this bug.
Report progress to stderr. By default, only a message about the current patch being applied will be printed. This option will cause additional information to be reported.
Suppress stderr output. Messages about patch status and progress will not be printed.
Do not trust the line counts in the hunk headers, but infer them by inspecting the patch (e.g. after editing the patch without adjusting the hunk headers appropriately).
Prepend to all filenames. If a «-p» argument was also passed, it is applied before prepending the new root.
By default, a patch that affects outside the working area (either a Git controlled working tree, or the current working directory when «git apply» is used as a replacement of GNU patch) is rejected as a mistake (or a mischief).
Don’t return error for patches containing no diff. This includes empty patches and patches with commit text only.
CONFIGURATION
Set to change if you want changes in whitespace to be ignored by default. Set to one of: no, none, never, false if you want changes in whitespace to be significant.
SUBMODULES
If the patch contains any changes to submodules then git apply treats these changes as follows.
How to apply git patch
This command applies the patch but does not create a commit. Use git-am[1] to create commits from patches generated by git-format-patch[1] and/or received by email.
OPTIONS
The files to read the patch from. — can be used to read from the standard input.
Instead of applying the patch, output diffstat for the input. Turns off «apply».
Instead of applying the patch, output a condensed summary of information obtained from git diff extended headers, such as creations, renames and mode changes. Turns off «apply».
Instead of applying the patch, see if the patch is applicable to the current working tree and/or the index file and detects errors. Turns off «apply».
Newer git diff output has embedded index information for each blob to help identify the original version that the patch applies to. When this flag is given, and if the original versions of the blobs are available locally, builds a temporary index containing those blobs.
When a pure mode change is encountered (which has no index information), the information is read from the current index instead.
Apply the patch in reverse.
For atomicity, git apply by default fails the whole patch and does not touch the working tree when some of the hunks do not apply. This option makes it apply the parts of the patch that are applicable, and leave the rejected hunks in corresponding *.rej files.
Without this option, pathnames with «unusual» characters are quoted as explained for the configuration variable core.quotePath (see git-config[1]).
Ensure at least lines of surrounding context match before and after each change. When fewer lines of surrounding context exist they all must match. By default no context is ever ignored.
Note, for the reasons stated above usage of context-free patches is discouraged.
If you use any of the options marked «Turns off apply» above, git apply reads and outputs the requested information without actually applying the patch. Give this flag after those flags to also apply the patch.
When applying a patch, ignore additions made by the patch. This can be used to extract the common part between two files by first running diff on them and applying the result with this option, which would apply the deletion part but not the addition part.
Historically we did not allow binary patch applied without an explicit permission from the user, and this flag was the way to do so. Currently we always allow binary patch application, so this is a no-op.
Don’t apply changes to files matching the given path pattern. This can be useful when importing patchsets, where you want to exclude certain files or directories.
Apply changes to files matching the given path pattern. This can be useful when importing patchsets, where you want to include certain files or directories.
When applying a patch, detect a new or modified line that has whitespace errors. What are considered whitespace errors is controlled by core.whitespace configuration. By default, trailing whitespaces (including lines that solely consist of whitespaces) and a space character that is immediately followed by a tab character inside the initial indent of the line are considered whitespace errors.
nowarn turns off the trailing whitespace warning.
warn outputs warnings for a few such errors, but applies the patch as-is (default).
error outputs warnings for a few such errors, and refuses to apply the patch.
error-all is similar to error but shows all errors.
Under certain circumstances, some versions of diff do not correctly detect a missing new-line at the end of the file. As a result, patches created by such diff programs do not record incomplete lines correctly. This option adds support for applying such patches by working around this bug.
Report progress to stderr. By default, only a message about the current patch being applied will be printed. This option will cause additional information to be reported.
Suppress stderr output. Messages about patch status and progress will not be printed.
Do not trust the line counts in the hunk headers, but infer them by inspecting the patch (e.g. after editing the patch without adjusting the hunk headers appropriately).
Prepend to all filenames. If a «-p» argument was also passed, it is applied before prepending the new root.
By default, a patch that affects outside the working area (either a Git controlled working tree, or the current working directory when «git apply» is used as a replacement of GNU patch) is rejected as a mistake (or a mischief).
Don’t return error for patches containing no diff. This includes empty patches and patches with commit text only.
CONFIGURATION
Set to change if you want changes in whitespace to be ignored by default. Set to one of: no, none, never, false if you want changes in whitespace to be significant.
SUBMODULES
If the patch contains any changes to submodules then git apply treats these changes as follows.
How to Create and Apply Patches in GIT using diff and apply Command
Creating a patch in GIT is a great way to share changes that you are not yet ready to push to a public branch of a project.
To better understand how we will create a patch, let’s first discuss a little about how GIT stores changes.
If you are new to GIT, install git and get a jumpstart from this GIT introduction article.
Knowing now how GIT stores commits, it is easy to see that a patch file will simply be a concatenation of the diffs for each of the commits that the patch will span.
For our example, let’s assume the following situation: We have a simple project with 2 branches: master and experimental.
Master is currently at the first commit, while experimental is 2 commits ahead of it. In each commit, I added a file named file1, file2, and file3 respectively. Here is the current state of each branch:
On master, we only have file1:
While on experimental, we have all 3 files:
In this tutorial, we’ll explain how to create a patch of the changes on the experimental branch and apply them to the master.
Creating the GIT Patch
We will use the git diff command to create the diff output, then redirect it into a file. The form of the diff command we will use is as follows:
Note: if either from-commit or to-commit are omitted, they will be assumed to be HEAD
We specify the two commits by their unique hash. Generally, you only have to specify enough of the commit hash to ensure its uniqueness (4 characters will probably do it).
As you see from the above output, the patch file has been created.
In this special case, where we want to create a patch of the entire branch, we can let GIT do some of the work for us. We can let GIT determine the point at which our experimental branch diverged from the master branch using the git merge-base command:
Again, the patch file has been created. These patch files are identical.
Applying the GIT Patch
Once the patch file has been made, applying it is easy. Make sure that the branch you have checked out is the one that you want to apply the patch to (master in our case). Then you can apply the patch using the git apply command: git apply
The changes from the experimental branch have now been replicated on master.
Warning: Although applying a patch in this way will exactly replicate content, no commit history will be replicated. This means that even if the patch you create spans several commits, it will appear as a single set of changes when applied. You will lose both the knowledge of how the commits were broken up and also the messages for each commit. Let’s compare the commit history for both branches:
On experimental, we had 3 commits, each with a meaningful commit message.
However, our patch simply applied the actual changes to the master branch.
Applying the patch did not commit the changes, nor did it bring any of the commit history associated with these changes with it. Be cautious of this when using patches in GIT.
How to apply git patch
This command applies the patch but does not create a commit. Use git-am[1] to create commits from patches generated by git-format-patch[1] and/or received by email.
OPTIONS
The files to read the patch from. — can be used to read from the standard input.
Instead of applying the patch, output diffstat for the input. Turns off «apply».
Instead of applying the patch, output a condensed summary of information obtained from git diff extended headers, such as creations, renames and mode changes. Turns off «apply».
Instead of applying the patch, see if the patch is applicable to the current working tree and/or the index file and detects errors. Turns off «apply».
Newer git diff output has embedded index information for each blob to help identify the original version that the patch applies to. When this flag is given, and if the original versions of the blobs are available locally, builds a temporary index containing those blobs.
When a pure mode change is encountered (which has no index information), the information is read from the current index instead.
Apply the patch in reverse.
For atomicity, git apply by default fails the whole patch and does not touch the working tree when some of the hunks do not apply. This option makes it apply the parts of the patch that are applicable, and leave the rejected hunks in corresponding *.rej files.
Without this option, pathnames with «unusual» characters are quoted as explained for the configuration variable core.quotePath (see git-config[1]).
Ensure at least lines of surrounding context match before and after each change. When fewer lines of surrounding context exist they all must match. By default no context is ever ignored.
Note, for the reasons stated above usage of context-free patches is discouraged.
If you use any of the options marked «Turns off apply» above, git apply reads and outputs the requested information without actually applying the patch. Give this flag after those flags to also apply the patch.
When applying a patch, ignore additions made by the patch. This can be used to extract the common part between two files by first running diff on them and applying the result with this option, which would apply the deletion part but not the addition part.
Historically we did not allow binary patch applied without an explicit permission from the user, and this flag was the way to do so. Currently we always allow binary patch application, so this is a no-op.
Don’t apply changes to files matching the given path pattern. This can be useful when importing patchsets, where you want to exclude certain files or directories.
Apply changes to files matching the given path pattern. This can be useful when importing patchsets, where you want to include certain files or directories.
When applying a patch, detect a new or modified line that has whitespace errors. What are considered whitespace errors is controlled by core.whitespace configuration. By default, trailing whitespaces (including lines that solely consist of whitespaces) and a space character that is immediately followed by a tab character inside the initial indent of the line are considered whitespace errors.
nowarn turns off the trailing whitespace warning.
warn outputs warnings for a few such errors, but applies the patch as-is (default).
error outputs warnings for a few such errors, and refuses to apply the patch.
error-all is similar to error but shows all errors.
Under certain circumstances, some versions of diff do not correctly detect a missing new-line at the end of the file. As a result, patches created by such diff programs do not record incomplete lines correctly. This option adds support for applying such patches by working around this bug.
Report progress to stderr. By default, only a message about the current patch being applied will be printed. This option will cause additional information to be reported.
Do not trust the line counts in the hunk headers, but infer them by inspecting the patch (e.g. after editing the patch without adjusting the hunk headers appropriately).
Prepend to all filenames. If a «-p» argument was also passed, it is applied before prepending the new root.
By default, a patch that affects outside the working area (either a Git controlled working tree, or the current working directory when «git apply» is used as a replacement of GNU patch) is rejected as a mistake (or a mischief).
CONFIGURATION
Set to change if you want changes in whitespace to be ignored by default. Set to one of: no, none, never, false if you want changes in whitespace to be significant.
SUBMODULES
If the patch contains any changes to submodules then git apply treats these changes as follows.
Сопровождение проекта
В дополнение к эффективному участию в проекте, было бы неплохо знать как его сопровождать. Сопровождение может включать в себя принятие и применение патчей, сгенерированных с помощью format-patch и отправленных вам по почте, или интеграцию изменений в ветках удалённых репозиториев. Независимо от того, поддерживаете ли вы канонический репозиторий или просто хотите помочь в проверке или применении патчей, вам необходимо знать каким образом следует принимать работу, чтобы это было наиболее понятно для других участников и было бы приемлемым для вас в долгосрочной перспективе.
Работа с тематическими ветками
Теперь вы можете добавить новые изменения в созданную тематическую ветку и определить хотите ли слить эти изменения в ваши долгосрочные ветки.
Применение патчей, полученных по почте
Применение патча командой apply
Если ошибок не выведено, то патч может быть применён без проблем. Так же, в случае ошибки эта команда возвращает отличное от 0 значение, что позволяет использовать её в скриптах.
Применение патча командой am
Если участник проекта пользователь Git и умеет пользоваться командой format-patch для генерации патчей, то вам будет легче, так как в патч включается информация об авторе и сообщение коммита. Если возможно, требуйте от ваших участников использовать команду format-patch вместо diff для генерации патчей. Вам останется использовать git apply только для устаревших патчей и подобного им.
Так или иначе, если кто-нибудь загрузит созданный с помощью format-patch патч файл в систему управления задачами, то вы сможете сохранить его себе и применить локально с помощью git am :
Commit информация указывает на того, кто применил патч и когда это было сделано. Author информация указывает на того, кто изначально создал патч и когда это было сделано.
Однако, возможна ситуация, когда патч не может быть бесконфликтно применён. Возможно, ваша основная ветка сильно расходится с той веткой, на основании которой был создан патч, или он зависит от другого, ещё не применённого патча. В таком случае работа git am будет прервана, а так же выведена подсказка со списком возможных действий:
Если вы применяете несколько патчей из файла mbox, то можно запустить git am в интерактивном режиме, в котором перед обработкой каждого патча будет задаваться вопрос о дальнейших действиях:
Это отличная возможность посмотреть содержимое патча перед его применением или пропустить его, если он уже был применён.
Когда все патчи применены и созданы коммиты в текущей ветке, вы уже можете решить стоит ли и как интегрировать их в более долгоживущую ветку.
Извлечение удалённых веток
Если участник проекта создал свой Git репозиторий, отправил в него свои изменения, а затем прислал вам ссылку и название ветки, куда были отправлены изменения, то вы можете добавить этот репозиторий как удалённый и провести слияние локально.
К примеру, Джессика отправила вам письмо, в котором сказано, у неё есть новый функционал в ветке ruby-client её репозитория. Добавив удалённый репозиторий и получив изменения из этой ветки, вы можете протестировать изменения извлекая их локально:
Это очень полезно, когда вы постоянно работаете с этим человеком. Однако, от тех, кто редко отправляет небольшие патчи, будет проще принимать их по почте, чем требовать от всех поддержания собственных серверов с репозиториями, постоянно добавлять их как удалённые, а затем удалять и всё это ради нескольких патчей. Так же вы вряд ли захотите иметь сотни удалённых репозиториев, каждый из которых нужен только для одного или нескольких патчей. К счастью, скрипты и различные сервисы облегчают задачу, но во многом зависят от того как работаете вы и участники вашего проекта.
Определение применяемых изменений
На текущий момент у вас есть тематическая ветка, содержащая предоставленные изменения. Сейчас вы можете определиться что с ними делать. В этом разделе рассматривается набор команд, которые помогут вам увидеть что именно будет интегрировано, если вы решите слить изменения в основную ветку.
Для просмотра полной разницы того, что произойдёт если вы сольёте изменения в другую ветку, вам понадобится использовать возможно странный способ для получения корректных результатов:
Это не проблема, если ветка master является непосредственным родителем вашей тематической ветки, но если история обоих веток изменилась, то разница будет выглядеть как добавление всех изменений из тематической ветки и удаление всего нового из master ветки.
Что действительно нужно видеть, так это изменения тематической ветки, которые предстоит слить в master ветку. Это можно сделать, сказав Git сравнивать последний коммит тематической ветки с первым общим родителем для обоих веток.
Технически это делается за счёт явного указания общего коммита и применения разницы к нему:
или более кратко:
Интеграция совместной работы
Когда все изменения в текущей тематической ветке готовы к интеграции с основной веткой, возникает вопрос как это сделать. Кроме этого, какой рабочий процесс вы хотите использовать при сопровождении вашего проекта? У вас несколько вариантов, давайте рассмотрим некоторые из них.
Схемы слияния
Это, пожалуй, простейший рабочий процесс и его использование проблематично в больших или более стабильных проектах, где вы должны быть более осторожны с предоставленными изменениями.
Схема с большим количеством слияний
Схема с перебазированием и отбором
Другим способом переместить предлагаемые изменений из одной ветки в другую является их отбор коммитов (cherry-pick). Отбор в Git похож на перебазирование для одного коммита. В таком случае формируется патч для выбранного коммита и применяется к текущей ветке. Это полезно, когда в тематической ветке присутствует несколько коммитов, а вы хотите взять только один из них, или в тематической ветке только один коммит и вы предпочитаете использовать отбор вместо перебазирования. Предположим, ваш проект выглядит так:
Для применения коммита e43a6 к ветке master выполните команду:
Теперь тематическую ветку можно удалить, отбросив коммиты, которые вы не собираетесь включать в проект.
Возможность «Rerere»
Если вы часто производите перебазирование и слияние или поддерживаете долгоживущие тематические ветки, то в Git есть специальная возможность под названием «rerere», призванная вам помочь.
Rerere означает «reuse recorded resolution» (повторно использовать сохранённое решение) — это способ сокращения количества операций ручного разрешения конфликтов. Когда эта опция включена, Git будет сохранять набор образов до и после успешного слияния, а также разрешать конфликты самостоятельно, если аналогичные конфликты уже были разрешены ранее.
После этого любое разрешение конфликта слияния будет записано на случай повторного использования.
Помечайте свои релизы
После выпуска релиза, возможно, вы захотите пометить текущее состояние так, чтобы можно было вернуться к нему в любой момент. Для этого можно добавить тег, как было описано в главе Основы Git. Кроме этого, вы можете добавить цифровую подпись для тега, выглядеть это будет вот так:
Теперь, когда ваш публичный ключ находится в репозитории, можно поставить указывающий на него тег, используя полученное ранее значение SHA-1:
Генерация номера сборки
Git не использует монотонно возрастающие идентификаторы для коммитов, поэтому если вы хотите получить читаемые имена коммитов, то воспользуйтесь командой git describe для нужного коммита. Git вернёт имя ближайшего тега, количество коммитов после него и частичное значение SHA-1 для указанного коммита (с префиксом в виде буквы «g» — означает Git):
Подготовка релиза
Время делать релиз сборки. Возможно, вы захотите сделать архив последнего состояния вашего кода для тех, кто не использует Git. Для создания архива выполните команду git archive :
В итоге получим tarball- и zip-архивы с релизом проекта, которые можно загрузить на сайт или отправить по почте.
Краткая история (Shortlog)
Сейчас самое время оповестить людей из списка рассылки, которые хотят знать что происходит с вашим проектом. С помощью команды git shortlog можно быстро получить список изменений, внесённых в проект с момента последнего релиза или предыдущей рассылки. Она собирает все коммиты в заданном интервале; например, следующая команда выведет список коммитов с момента последнего релиза с названием v1.0.1:
И так, у вас есть готовая к отправке сводка коммитов начиная с версии v1.0.1, сгруппированных по авторам.
Источники информации:
- http://book.git-scm.com/docs/git-apply
- http://www.thegeekstuff.com/2014/03/git-patch-create-and-apply/
- http://git-scm.com/docs/git-apply/2.29.0
- http://git-scm.com/book/ru/v2/%D0%A0%D0%B0%D1%81%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9-Git-%D0%A1%D0%BE%D0%BF%D1%80%D0%BE%D0%B2%D0%BE%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B0