Патч файл, который работает на разных базовых коммитах?

62
7

У меня есть патч, который изменяет файл foo.txt. Он был создан с использованием diff из commit a. Тем не менее, теперь я хочу применить этот патч поверх коммита b но это не foo.txt если foo.txt отличается в foo.txt a от коммита b.

    Можно ли создать патч, который просто заменяет foo.txt, независимо от того, над чем он применяется? Если нет, есть ли альтернатива патч файлам, которую я могу использовать, которая поддерживает это поведение?

РЕДАКТИРОВАТЬ: Следует также отметить, что мне не нужно иметь возможность отменить применение патча.

спросил(а) 2021-01-19T16:05:15+03:00 2 месяца, 3 недели назад
1
Решение
76

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

Конечно, есть возможность развернуть свое собственное программное обеспечение для патчей (например, без использования git apply), которое делает все, что вы хотите.

Учитывая, что вы добавили это в git, git, что вывод git diff включает в себя index: line:

diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN
index 216beefc50..d1a2814ec7 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh

GVF=GIT-VERSION-FILE
-DEF_VER=v2.20.0
+DEF_VER=v2.20.1

LF='
'

Использование --full-index расширяет эту строку:

index 216beefc50d54d132991636d5f049ea0916f1696..d1a2814ec7e415a525e58ac234df8184a2d0f93c 100755

Два больших уродливых идентификатора хеша здесь - это изображения файла "до" и "после". Это позволяет Git выполнять полное трехстороннее слияние, если это необходимо. (100755 в конце или 100644 в других случаях дает +x или -x файла для опции git update-index --chmod=.)

Предположим, например, что вы хотите применить патч к (как вы сказали) foo.txt где патч основан на foo.txt A, но вместо этого текущей версией foo.txt является коммит B Строка index сообщает Git: идентификатор хэша версии foo.txt равен <...> (где недостающая часть - из git rev-parse A:foo.txt, т. git rev-parse A:foo.txt BLOB- git rev-parse A:foo.txt, сохраненный в git rev-parse A:foo.txt A). Поэтому Git может извлечь коммит A из репозитория, успешно применить патч к A:foo.txt и создать правильный обновленный файл, так как патч теперь будет применяться. Теперь, когда Git имеет изображения "до" и "после", он может также B:foo.txt изображение "до" с вашим текущим B:foo.txt, чтобы он знал, что вы изменили.

Теперь Git может поместить каждый из этих трех файлов где-то - на самом деле, в индекс, в слоты 1, 2 и 3, как и в любой другой операции, основанной на слиянии. Это дает Git возможность выполнять трехстороннее слияние на трех входах (базовое, наше, их) и либо завершать слияние самостоятельно, либо дает вам возможность разрешать конфликты.

Используя эту же базовую идею, вы можете, если хотите, - это не очень хорошая идея в целом - использовать строку index чтобы найти блоб, пропатчить его (с гарантированным успехом, поскольку патч применяется к этому файлу A:foo.txt) и использовать полученный файл напрямую.

ответил(а) 2021-01-19T16:05:15+03:00 2 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема