Entry tags:
Как нам обустроить патчи
Сгребу-ка я сюда все свои не очень оформленные мысли, а заодно и ссылки.
Вводная. У меня есть два основных пакета, с которыми я на работе ковыряюсь, OpenSSH и OpenSSL. И там и там 60+ патчей, которые при каждом ребейзе приносят адскую боль. OpenSSL я знаю хорошо и поэтому с этой болью я почти смирился, OpenSSH я знаю средне.
Случаи, когда код переписан содержательно, всегда требуют индивидуального подхода и деваться от этого некуда. Но хочется минимизировать технические вещи.
Очевидно, что чисто по времени при ребейзе дофига жрут сцепленные патчи. Мы поправили строку из контекста, и теперь у нас конфликт. Мы решили конфликт, нарушив тем самым контекст следующего патча. Возможно, эти два патча стоит склеить в один (или нет, если они решают разные проблемы). Но для этого их надо идентифицировать как "сцепленные".
Ещё очевидно, что патчи к одной подсистеме лучше прикладывать подряд, потому что контекст (в голове). И опять же склеить там, где возможно.
В общем, я задумался о том, что надо как-то строить график зависимостей патчей между собой. Вроде бы всё просто. Вот есть файл, вот мы добавили-убрали-изменили, вот номера затронутых строк, вот номера строк контекста до и после. Дальше эту информацию можно впихнуть хоть в базу данных и как-то анализировать.
Номера затронутых строк и строк контекста так просто из patch/diff не получить. Во всяком случае, я не нашёл. Ну теоретически эту часть я могу хоть на Perl написать, не rocket science. Найти сцепленные патчи так можно, и дальше уже решать, что с этим делать.
Следующий интересный вопрос - а что ещё с этим можно сделать, чтобы улучшить поддерживаемость набора патчей in the long run.
На уровне разработки я нашёл совершенно чудный инструмент git absorb, который разбирает свежие изменения на fixup-ы и новые содержательные. Не знаю, как он потянет 60+ коммитов, конечно.
Вот тут пишут про замену diff для GitHub, но в основном для web-интерфейса.
Difftastic - продвинутый diff, не по строкам, а по логическим блокам
Mergiraf - продвинутый merge.
В дискуссию приглашается, например,
spamsink
Вводная. У меня есть два основных пакета, с которыми я на работе ковыряюсь, OpenSSH и OpenSSL. И там и там 60+ патчей, которые при каждом ребейзе приносят адскую боль. OpenSSL я знаю хорошо и поэтому с этой болью я почти смирился, OpenSSH я знаю средне.
Случаи, когда код переписан содержательно, всегда требуют индивидуального подхода и деваться от этого некуда. Но хочется минимизировать технические вещи.
Очевидно, что чисто по времени при ребейзе дофига жрут сцепленные патчи. Мы поправили строку из контекста, и теперь у нас конфликт. Мы решили конфликт, нарушив тем самым контекст следующего патча. Возможно, эти два патча стоит склеить в один (или нет, если они решают разные проблемы). Но для этого их надо идентифицировать как "сцепленные".
Ещё очевидно, что патчи к одной подсистеме лучше прикладывать подряд, потому что контекст (в голове). И опять же склеить там, где возможно.
В общем, я задумался о том, что надо как-то строить график зависимостей патчей между собой. Вроде бы всё просто. Вот есть файл, вот мы добавили-убрали-изменили, вот номера затронутых строк, вот номера строк контекста до и после. Дальше эту информацию можно впихнуть хоть в базу данных и как-то анализировать.
Номера затронутых строк и строк контекста так просто из patch/diff не получить. Во всяком случае, я не нашёл. Ну теоретически эту часть я могу хоть на Perl написать, не rocket science. Найти сцепленные патчи так можно, и дальше уже решать, что с этим делать.
Следующий интересный вопрос - а что ещё с этим можно сделать, чтобы улучшить поддерживаемость набора патчей in the long run.
На уровне разработки я нашёл совершенно чудный инструмент git absorb, который разбирает свежие изменения на fixup-ы и новые содержательные. Не знаю, как он потянет 60+ коммитов, конечно.
Вот тут пишут про замену diff для GitHub, но в основном для web-интерфейса.
Difftastic - продвинутый diff, не по строкам, а по логическим блокам
Mergiraf - продвинутый merge.
В дискуссию приглашается, например,
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
no subject
На тему
git absorb
ещё естьgit autofixup
. Кажется, с немного другим принципом действия, но той же решаемой задачей.no subject
Ну как не получить номера строк?
Берем типичный патч, context unified diff. И ччто мы там видим?
Вот то что после @@ это номер первой строки блока и через запятую количество затрнутых строк.
no subject
Потом, я бы посмотрел на твой набор патчей, если таки их меньше, чем мейнстрим меняется ... Возможно, их можно поделить на части, которые будут проще автоматом применяться к мейнстриму.
dft и mf я себе в конфигурацию прикрутил, но пока особо не использовал.
no subject
В другую сторону не получится, потому что патч не просто меняет несколько строчек кода, но еще и документирует это изменение.
no subject
no subject
Потому что патчи, применямые мейнтейнером пакета в дистрибутиве лежать в src.rpm отдельно от апстримовского тарболла. А тарболл должен быть именно апстримовским.
no subject
no subject
Нам сначала надо взять мэйнстримное текущее состояние, и наложить на него все имеющиеся "наши" патчи. И только после того, как у нас все нормально наложилось, проектировалось и т.д, уже идет шаг изготовления текущего набора патчей, которые будут упакованы в этот rpm?
no subject
no subject
no subject
https://andrewlock.net/working-with-stacked-branches-in-git-is-easier-with-update-refs/
no subject
Они имеют самое прямое отношение к реальности той версии, куда они накладываются без fuzz.
В debian процесс приведения патчей к текущему состоянию кода автоматизирован посредством утилиты quilt.
no subject
no subject
no subject
no subject
no subject
no subject
no subject
no subject
Каждый патч знает, от какого коммита он отрос, и при мерже номера строк автоматически сдвигаются, куда надо. Блейм после мержа обычно тоже вразумительный, кроме мест с конфликтами. Даунстрим, патч от которого принят, знает свой коммит и не удивляется, увидев его клон после ребейза. В общем, сплошные плюсы.
Единственный минус стандартного гитового мержа - что после него бывает сложно понять, что было в той же ветке до мержа, а что приехало с мержом, так что бисекция может показывать лажу, ну так эту проблему ребейз тоже не решает.
no subject
no subject
no subject
Процесс пакетирования программы или библиотеки для Debian («дебианизация») состоит в том, что Мейнтейнер берёт релизный слепок исходников Апстрима и обеспечивает, чтобы этот слепок собирался в контексте целевой версии системы и удовлетворял представлениям Debian’а о прекрасном. (Использует системные версии библиотек, а не таскает свои; не содержит несвободных или нарушающих прайваси компонентов; не имеет функциональности самообновления в обход apt’а и пр.) Иногда для этого приходится менять исходники, таким образом получаются патчи.
Веселье здесь в том, что процесс не требует от Апстрима использования Git’а. И даже вообще какой-нибудь системы контроля версий. От Апстрима требуется предоставлять тарболы тех версий, которые он считает стабильными, остальное забота Мейнтейнера.
Более того, когда конечный пользователь говорит в шелле
apt-get source {somepackage}
, то ему приезжает исходный тарбол Апстрима + патчи от Мейнтейнера, это часть контракта. Так что Мейнтейнеру нельзя локально смёржить свои патчи и время от времени подмёрживать Апстрим и собирать бинарные пакеты. Нужно уметь выдать наружу версию серии патчей, соответствующую каждому релизу.Вот процесс получения серии патчей для нового релиза, когда есть тарболы старого и нового релизов, и называется обобщённо ребейзом, и это не обязан быть буквально
git rebase
, иногда это последовательностьquilt push
— чиним реджекты —quilt refresh
— следующийquilt push
— пока не наложатся все патчи.no subject
no subject
no subject
Не, патчи для сорцов. Но (1) сорцы не обязаны лежать в гиту, (2) конечный пользователь должен мочь собрать бинарники из сорцов с патчами самостоятельно, и (3) конечный пользователь должен мочь читать патчи по отдельности.
С оценкой нелёгкой доли мейнтейнеров согласен, хоть бы бинарники патчить и не приходилось.