Поиск по сайту:

Как применить изменения Git Commit к разным файлам


Git — это мощная система контроля версий, которая позволяет создавать несколько разветвленных версий вашего проекта с автоматическим слиянием. Это здорово, но иногда это ломается, когда файлы переименовываются или находятся не в том месте. К счастью, вы можете вручную применять исправления к различным файлам.

Проблема

При использовании веток Git часто необходимо применять изменения из одной ветки в другую. Обычный вариант использования этого — версионные ветки — если у вас есть старая версия LTS, вы можете захотеть применить случайное исправление к старой версии. Или, возможно, вы предоставляете две сборки программного обеспечения, предназначенные для разных наборов инструментов или сред, и вам необходимо синхронизировать их.

Если ваши ветки имеют одинаковый макет, вы можете использовать git cherry-pick, который может копировать отдельные коммиты из одной ветки в другую. Например, перетащите фиксацию из ветки функций в master до того, как все это будет объединено:

Однако программное обеспечение не всегда бывает чистым, и в процессе рефакторинга вы можете столкнуться со случаями, когда файлы были перемещены или переименованы. Git работает с путями к каталогам, поэтому это полностью нарушает git cherry-pick, поскольку Git не может применять изменения к несуществующим файлам.

Однако в Git есть инструменты для исправления этого, поэтому, когда обычное слияние не работает, вы можете вручную исправить файлы с обновлениями, используя git patch.

Использование различий и исправлений Git

Чтобы продемонстрировать это, мы создадим пустой репозиторий с одним файлом: Old.java. С этим файлом создается новая ветвь старая-версия с некоторыми изменениями. Этот файл был переименован с некоторыми более поздними изменениями в ветке master на New.java, что нарушило совместимость между ветвями.

А вот как выглядит история веток, показанная в графическом интерфейсе Git-программы Fork:

В этом примере нам нужно переместить фиксацию «Добавить код» в ветку old-version. Для этого вам нужно получить идентификатор этой фиксации из справочного журнала:

git reflog

Затем запустите format-patch с идентификатором и флагом -1 , который создаст файл исправления:

git format-patch 82176b5 -1

Это создаст файл исправления в текущем каталоге. Вы можете переместить его в другую папку в конфигурации .gitignore, чтобы на нее не повлияло изменение веток.

Затем извлеките ветку старая версия и примените исправления с помощью утилиты Linux patch . У Git есть собственные инструменты, git apply и git am, которые могут с этим справиться, но, если не считать ручного редактирования файла исправления, у них нет возможности изменить цель. файл в случаях переименования/перемещения.

Вы можете передать имя файла с помощью параметра -p1 и передать файл исправления с помощью -i.

patch -l -p1 old -i Patches/0001-Add-more-code.patch

Это должно отредактировать файл и добавить изменения, которые вам нужно будет зафиксировать. Одним из недостатков patch по сравнению с git am является то, что он не сохраняет информацию о коммите, хотя вы можете найти ее в файле .patch , если вы хотите сохранить исходное сообщение.

Тем не менее, конфликты слияния все еще могут возникать, если целевая ветка тем временем редактируется, и в этом случае вы застрянете на ручном редактировании, поскольку git merge не может решить эту проблему за вас. patch выведет файлы, содержащие различия, которые вам нужно будет исправить вручную.

В качестве альтернативы вы можете переместить целевой файл в целевой каталог, который ожидает Git, что позволит Git выбрать вишенки и применить изменения. Затем скопируйте файл обратно в исходное место и удалите временный файл.

Патч также может иметь проблемы с окончанием перевода строки (LF) и переводом строки возврата каретки (CRLF), которые могут возникнуть в результате редактирования Windows. Возможно, вам придется переключиться на LF в текстовом редакторе, чтобы патч применялся правильно.