мерзавец: патч не применяется

290

У меня есть определенный патч под названием my_pcc_branch.patch.

Когда я пытаюсь применить его, я получаю следующее сообщение:

$ git apply --check my_pcc_branch.patch
warning: src/main/java/.../AbstractedPanel.java has type 100644, expected 100755
error: patch failed: src/main/java/.../AbstractedPanel.java:13
error: src/main/java/.../AbstractedPanel.java: patch does not apply

Что это означает?

Как я могу решить эту проблему?

Дмитрий Писаренко
источник
Есть ли какие-нибудь файлы AbstractedPanel.java.rej? Как правило, это означает, что линейный бот изменился как в источнике, так и в патче (здесь строка 13, похоже, затронута).
Руди
Нет, я не нашел никаких * .rej файлов.
Дмитрий Писаренко
Не уверен, почему принятый ответ это исправит (поэтому я подозреваю, что это красная сельдь), но не has type 100644, expected 100755означает ли это, что где-то есть несоответствие разрешений chmod?
ruffin

Ответы:

326

git apply --reject --whitespace=fix mychanges.patch работал на меня.

объяснение

--rejectВариант будет инструктировать мерзавец , чтобы не потерпеть неудачу , если он не может определить , как применить патч, но вместо того, чтобы применить indivdual ломтей можно применять и создавать отклонять файлы ( .rej) для скряги не может применяться. Wiggle может «применять [эти] отклоненные патчи и выполнять разносторонние сравнения».

Кроме того, --whitespace=fixбудет предупреждать об ошибках пробелов и пытаться их исправить, вместо того, чтобы отказываться от применения другого подходящего блока.

Обе опции вместе делают применение исправления более устойчивым к сбоям, но требуют дополнительного внимания к результату.

Для полной документации см. Https://git-scm.com/docs/git-apply .

user1028904
источник
8
Это на самом деле работало лучше для меня, потому что не полностью изменило мой файл
Уэйн Вернер
10
Это круто. Просто отклоняет то, что он не может решить сам, и вы можете просто изменить отклоненные файлы вручную.
Деннис
1
patch -p1 <mychanges.patch # применяет изменения чанка к чанку. Если изменения не удаются, создаются патч <sourcefile> .orig и <sourcefile> .rej, и вы можете применить изменения вручную. Я предполагаю, что git apply --reject делает то же самое, и --whitespace = fix волшебно лучше.
gaoithe
7
эта команда создает .rejфайлы, когда не может автоматически определить, как применить исправление. Вы можете использовать покачивание, чтобы решить такие проблемы.
goodniceweb
14
Этот ответ ничего не объясняет, в частности, в каких случаях он будет работать. Люди, вы действительно должны быть более требовательны к качеству ответов, это ТАК не форум.
Оливер
319

Йоханнес Сикст из списка рассылки msysgit@googlegroups.com предложил использовать следующие аргументы командной строки:

git apply --ignore-space-change --ignore-whitespace mychanges.patch

Это решило мою проблему.

Дмитрий Писаренко
источник
25
Кто-нибудь может мне помочь и объяснить, почему это работает? Другой ответ мне не помог, и у меня возникла та же проблема, что и в вопросе, который задает вопрос. Какое отношение имеют атрибуты файла к игнорированию пробелов?
скреббель
1
Использование windows powershell Патч, созданный с помощью git diff, был успешно применен следующим образом: git diff HEAD..613fee - myfile.xml | git apply --ignore-space-change --ignore-whitespace, тогда как первое сохранение вывода diff в виде файла не сработало, если кто-то столкнется с той же проблемой
tjb
2
также попробуйте -C1переключиться для применения, это уменьшает контекст вокруг дополнений, которые рассматриваются как важные.
Амир Али Акбари
2
@EricWalker, git magic с CR / LF не обязательно плохая вещь. Альтернативой может быть то, что половина ваших наборов изменений состоит из каждой отдельной строки в каждом файле, к которой было произведено прикосновение, которая изменяется с одной строки, заканчивающейся на другую, с фактическим изменением, скрытым где-то в середине.
JWG
3
Это помогает иногда. Но иногда я все еще получаю «патч не применяется», хотя патч должен применяться без проблем.
Томас Левеск
119

Когда все остальное терпит неудачу, попробуйте git apply«s --3wayвариант .

git apply --3way patchFile.patch

--3way
Если исправление применяется некорректно, используйте трехстороннее объединение, если исправление записывает идентификаторы BLOB-объектов, к которым он должен применяться, и у нас есть эти BLOB-объекты, доступные локально, возможно оставляя маркеры конфликта в файлах в рабочее дерево для пользователя, чтобы решить. Этот параметр подразумевает параметр --index и несовместим с параметрами --reject и --cached.

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

Ruffin
источник
2
Это ответ, который работал для меня. Файл, который я патчил, не отражал изменения, из которых я сгенерировал патч (потому что я удалил изменения после того, как создал патч.)
Christia
3
Хорошее общее решение. Разница в 3way не выглядела так, как обычно, она немного смущена этим, но тем не менее это дало мне возможность разрешить конфликт и применить патч.
Steinybot
8
Я думаю, что это --3wayдолжно быть поведение по умолчанию. Когда исправление не удается, по крайней мере, скажите мне, что не удалось, чтобы я мог исправить это вручную. git applyпросто терпит неудачу и не сообщает, почему что-то терпит неудачу. Я даже не мог найти *.rejфайлы, подобные тем, которые hgгенерирует.
Паван Манджунат
4
Определенно, лучшее решение. Позвольте пользователю разрешать его собственные конфликты!
Mosh Feu
56

Эта команда будет применять патч, не устраняя его, оставляя плохие файлы как *.rej:

git apply --reject --whitespace=fix mypath.patch

Вы просто должны решить их. После разрешения выполните:

git -am resolved
Иван Ворошилин
источник
7
как решить *.rej- все, что я могу найти, - это внести изменения вручную в исходный файл и удалить эти .rejфайлы. Любым другим путем ?
coding_idiot
1
@coding_idiot Как обычно, просто проверьте файлы .rej, сравните их с конфликтующими файлами и, наконец, добавьте фиксированные файлы в индекс (с помощью «git add FIXED_FILES»)
Иван
2
@coding_idiot вы можете использовать покачивание, чтобы решить его. Например: wiggle --replace path/to/file path/to/file.rej. Эта команда будет применять изменения из .rejфайла в исходный файл. Также он создает копию оригинального файла, как path/to/file.porig. Пожалуйста, ознакомьтесь с документацией для получения дополнительной информации о
маневре
22

Попробуйте использовать решение, предлагаемое здесь: https://www.drupal.org/node/1129120

patch -p1 < example.patch

Это помогло мне.

Пини Чейни
источник
3
Я знаю, что ты не должен этого делать, но СПАСИБО ТАМ! Спасли меня часы. Я получал "патч не применяется" и всевозможные ошибки.
sudo rm -rf slash
@ sudorm-rfslash, почему мы не должны этого делать и почему вы все же это делаете?
Черный
git: 'patch' is not a git command.наgit version 2.21.1 (Apple Git-122.3)
Шридхар Сарнобат
16

Это происходит, когда вы смешиваете git-клиенты UNIX и Windows, потому что в действительности Windows не имеет понятия бита «x», поэтому извлечение rw-r--r--файла (0644) в Windows «продвигается» слоем msys POSIX до rwx-r-xr-x(0755) , git считает, что разница в режиме в основном совпадает с текстовой разницей в файле, поэтому ваш патч не применяется напрямую. Я думаю , что ваш единственный хороший вариант здесь , чтобы установить core.filemodeна false(используя git-config).

Вот проблема msysgit с некоторой связанной информацией: http://code.google.com/p/msysgit/issues/detail?id=164 (перенаправлена ​​в копию archive.org от 3 декабря 2013 г.)

Бен Джексон
источник
2
Я попытался запустить команду "git config core.filemode false", но это не помогло - я все еще получаю то же сообщение.
Дмитрий Писаренко
Предполагая, что у вас нет незафиксированных изменений в вашем дереве, попробуйте git reset --hard HEADзаставить git повторно извлекать ваши файлы с новой действующей опцией.
Бен Джексон
Только что попробовал выполнить "git reset --hard HEAD". Это было успешно (я видел сообщение "HEAD is at ..."), но проблема с "git apply" сохраняется.
Дмитрий Писаренко
7

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

Если вы мастер и делаете git diff branch-name > branch-name.patch, это попытается удалить все добавления, которые вы хотите выполнить, и наоборот (что было невозможно для git, поскольку, очевидно, никогда не выполненные добавления не могут быть удалены).

Поэтому убедитесь, что вы зашли в свою ветку и выполните git diff master > branch-name.patch

змееподобный
источник
3

ВНИМАНИЕ: Эта команда может удалить старые потерянные коммиты ПОСТОЯННО. Сделайте копию всего своего хранилища, прежде чем пытаться это сделать.

Я нашел эту ссылку

Я понятия не имею, почему это работает, но я пробовал много обходных путей, и это единственный, который работал для меня. Короче говоря, выполните три команды ниже:

git fsck --full
git reflog expire --expire=now --all
git gc --prune=now
Archmede
источник
3
Это очень опасная команда, которая может навсегда удалить старые потерянные коммиты из reflog. Если ваш репо находится в шатком состоянии, НЕ ПРИМЕНЯЙТЕ ЭТО.
ET
0

То, что я искал, точно не указано здесь, в SO, я пишу для пользы других, которые могут искать подобное. Я столкнулся с проблемой удаления одного файла (присутствующего в старом репо) в репо. И когда я применяю патч, он терпит неудачу, так как не может найти файл для применения. (так что мой случай - git patch не удалась, когда файл был удален) '#git apply --reject' определенно дал представление, но не совсем помогло мне исправить. Я не мог использовать покачивание, поскольку оно недоступно для наших серверов сборки. В моем случае я справился с этой проблемой, удалив запись «файл, который был удален в репо» из файла исправления, который я пытался применить, поэтому все остальные изменения были применены без проблем (с использованием трехстороннего слияния, избегая ошибки пробела), а затем вручную объединить содержимое файла, удаленного туда, куда его переместили.

Bhanu
источник
0

Моя проблема в том, что я побежал git diff, затем побежалgit reset --hard HEAD , затем понял, что хотел отменить, поэтому я попытался скопировать вывод из git diffв файл и использовать git apply, но я получил ошибку, что «патч не применяется». После переключения patchи пытается использовать его, я понял , что кусок в дифф был повторен по какой - то причине, и после удаления дубликатов , patch(и , предположительно , также git apply) работал.

Соломон Уцко
источник