в Книги, Разработка

Ошибка при открытии и сохранении PDF в Okular

Недавно наткнулся на книгу в PDF, которая благополучно открывается в Окуляре, но при открытии файла на несколько секунд отображается ошибка: Some errors were found in the document, Okular might not be able to show the content correctly.

В процессе чтения понаделал кучу заметок внутри книги (выделял маркером, рисовал диаграммы, подчёркивал, зачёркивал). Затем сохранил. И ошибка отобразилась снова. Все мои заметки при этом в книге успешно сохранились (как я тогда думал, бгг) и при повторном открытии всё было в норме. Спустя несколько дней решил почитать книгу на телефоне (Android): открываю её через PDF-браузер, а там пусто. Никакие заметки, увы, не сохранились внутрь документа, всё осталось в Окуляре на десктопе.

Заметки, конечно, никто уже не вернёт, придётся вручную по-новой писать. Но как пофиксить ошибку и сделать так, чтобы заметки всё-таки сохранялись как обычно — внутрь PDF? Надо этот файл просто пересохранить.

Но если вы пересохраните его в самом Окуляре, ошибка никуда не уйдёт. В моём случае, ошибка ушла лишь после пересохранения в Xodo (PDF-браузере, который я использую на Андроиде).

  1. Открываем книгу в Xodo
  2. Заходим в меню Export > Identical Copy (либо другие варианты экспорта на ваш вкус)

Это создаст копию PDF книги, в которой уже не будет никаких ошибок. Можно и по-другому поступить:

  1. После открытия книги в Xodo, добавляем любую заметку
  2. Xodo сразу автоматом пытается её сохранить, у него не получается и вам предлагают сохранить копию документа
  3. Соглашаемся

Старый PDF с ошибкой отправляем в утиль и открываем в Окуляре копию созданную Xodo. Теперь никакой ошибки там отображаться не будет, а все новые заметки в книге будут корректно сохраняться и отображаться на всех устройствах.

Сама ошибка известна и по поводу неё уже создано несколько баг репортов. Проблема в библиотеке Poppler, которую использует бэкэнд Окуляра для рендеринга PDF. Если глянуть исходный код Окуляра, в самом конце файла okular/generators/poppler/generator_pdf.cpp можно обнаружить функцию, которая как раз и кидает ошибку на стадии генерации PDF. Ошибка возникает скорей всего либо из-за того, что PDF был сгенерирован в какой-то кривой программе, либо, как пишут люди в баг-репортах, из-за того что в PDF, при создании, были вложены какие-то приватные данные.

Какой способ мёрджить ветки в Гит лучше?

Тема холиварная и если мало опыта, то можно днями сидеть читать бесконечные мнения и так ни к чему и не прийти.

Естественно нет ни лучшего, ни худшего способа, каждому своё. Зависит в первую очередь от того какую с какой веткой вы мёрджите, один ли вы работаете или в команде и от ваших/командных привычек.

Сделать выбор поможет только личный опыт. А пока (если) его нет, то на вопрос как мёрджить я бы ответил так.

На ГитХабе у нас есть 4 основных способа мёрджить ветки:

  1. Fast-Forward Merge
  2. Merge Commit (это когда мы пушим нашу ветку, затем ручками создаём PR на сайте ГитХаба, ревьюим код, апрувим и кликаем кнопку «Merge» (типично при командной работе). Ну либо просто выполняем git merge --no-ff в CLI (типично при работе соло); в обоих случаях результат один и тот же, просто когда мы мёрджим через CLI, то пропускаем стадии код ревью и апрув)
  3. Squash Merge (aka «Squash + Merge»)
  4. Rebase Merge (aka «Rebase + Merge»)

Способы мёрджить с точки зрения Гит Это не относися к теме, но если рассматривать способы мёрджить с точки зрения самого Гит, а не ГитХаба, то список должен быть немного другим: 1) fast-forward merge, 2) 3-way merge, 3) squash + merge, 4) rebase + merge

Способы 1 и 2 — это дёшево просто и сердито, а способы 3 и 4 — для любителей фапать на красивую линейную историю в ущерб всему остальному.

Если вы не боитесь нелинейной истории – мёрджите через способ 2 (Merge Commit). Из плюсов: у вас теперь максимально подробная история комитов с подробнейшим графом. Из минусов: история местами грязная (хотя не обязательно) и нелинейная (нелинейность ухудшает удобочитаемость истории), и иногда бывает сложно откатить изменения.

Если же вы наоборот, такой маленький, а уже адепт линейной истории — мёрджите через способ 3 (Squash + Merge). Из плюсов: чистая история. Из минусов: чистая история достигается, по сути, за счёт частичного стирания этой самой истории, в смысле все наши комиты на feature-бренче после скваша превращаются в один комит.

С вышеописанного можно начать, ну а со временем и с опытом уже разберётесь какой из всех способ и когда использовать.

Способ 1 (Fast-forward Merge) я не рекомендую из-за каши в истории, способ 4 (Rebase + Merge) – из-за более частых мёрдж-конфликтов. Да и в целом, что squash, что rebase излишне усложняют процесс, который должен быть максимально простым (KISS).

Рефы: