Git format-patch/bundle для читабельного sneakernet "pull/push"

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

Ограничения:

  1. Из соображений безопасности две комнаты не подключены к сети.
  2. Только текстовые файлы (удобочитаемые) могут покинуть комнату развертывания.

Переместить изменения в комнату развертывания просто, используя git bundleи отслеживание последнего коммита, который мы перенесли в комнату развертывания. Переместить изменения из комнаты сложнее из-за ограничения только текста.

Цель: перемещение совершает взад и вперед между двумя не связанными комнатами, как будто git pull произошло, то есть идентичные хэши SHA1 в обеих комнатах.

До сих пор:

  • я пробовал git format-patch переместить изменения из deploy обратно в dev, но это не записывает слияния, и, следовательно, требует, чтобы для каждого непрерывного набора изменений генерировался другой набор исправлений вместе с некоторой записью о том, как воспроизвести точный коммит слияния, произошедший между ними. Существует некоторая дискуссия о создании различий для коммитов слияний, но, похоже, это не отражает фактическое происхождение, только изменения. Кажется, что исправления могут быть недостаточно богатым форматом для предоставления необходимой информации.

  • Некоторые сценарии связки в текст могут быть использованы для преобразования пакета в формат без zip и удобочитаемого (ish) формата (и затем обратно после загрузки), но я не нашел никаких доказательств того, что такой сценарий существует.

  • Возможно, можно написать сценарий, чтобы пройти историю от какого-то общего предка до самого нового коммита и либо а) сделать патч, либо б) воссоздать слияние некоторых общеизвестных ссылок.

Резервный вариант: я всегда мог бы сжать коммиты, выходящие из комнаты развертывания, всего в один необработанный патч и разбить историю, но затем дальнейшие загрузки из dev->deploy сломали бы любые существующие рабочие копии. Не идеально.

Обновление: я верю git fast-export может делать то, что мне нужно, хотя в большинстве примеров это работает на целые репозитории, а не на частичные истории, такие как git bundle, У меня есть пример работающей игрушки, в котором я могу экспортировать частичную историю в устаревший клон, но он требует, чтобы я вручную отредактировал вывод быстрого экспорта, чтобы добавить from <sha1> на первый коммит. Без этой модификации импорт создает разные sha1s и затем жалуется Not updating refs/heads/master (new tip <hash> does not contain <master's hash>),

Обновление 2: мой git fast-export Решение действительно работает, но оно имеет проблему пропускной способности, так как оно работает, предоставляя совершенно новые файлы, а не отличия от предыдущих файлов. Это неприемлемо, поскольку мне действительно нужно прочитать все эти дополнительные строки.

1 ответ

Решение

Я никогда не находил идеального решения, но то, что мы делаем сейчас, похоже, работает. Основным недостатком является то, что коммиты в комнате развертывания изначально имеют один SHA1, который затем объединяется с другим SHA1 после объединения с комнатой разработки. Хорошая новость в том, что git довольно легко распознает их, так как те же коммиты могут merge прямо через них.

  • Есть 3 контрольных пункта, которые мы должны отслеживать:
    • dev/master который имеет новейшую разработку в комнате разработчиков.
    • deploy/master который имеет новейшую разработку в комнате развертывания.
    • dev_deploy_common который является последним коммитом, который разделяют две истории.

,

  1. Когда мы перемещаем код из dev в развертывание (используя пакет), мы вносим коммиты как часть dev_deploy_common ветвь в комнате развертывания (git pull в dev_deploy_common), а затем из deploy/master сделать git merge dev_deploy_common и разрешать и конфликтовать тут и там.

  2. Когда мы перемещаем код из deploy в dev (который должен быть текстовым файлом), мы делаем несколько дополнительных шагов:

  3. Сначала мы перебазируем deploy/master на dev_deploy_common так что все наши патчи смежные. Как правило, это легко, так как мы уже обрабатывали любые конфликты во время слияний, возникающие при переносе пакета из dev в развертывание.

  4. Во-вторых, мы генерируем набор патчей, используя

    git format-patch -M25 -C25 --find-copies-harder -k --ignore-if-in-upstream
    

    -M25 -C25 --find-copies-harder параметры просто уменьшают размер выходного текста. -k Опция сохраняет коммит предметов нетронутыми. --ignore-if-in-upstream ограничивает наши коммиты только новыми, так как dev_deploy_common,

    Результатом этого является patchset.txt Коллекция патчей. Этот файл можно просмотреть вручную, а затем перенести в комнату разработчиков.

  5. В комнате разработчиков мы импортируем набор патчей с помощью следующей команды:

    git am -k -3 --keep-cr --committer-date-is-author-date patchset.txt
    

    К сожалению, несмотря на то, что мы используем все команды, чтобы сохранить патч одинаковым, некоторые атрибуты меняются, в первую очередь, коммиттер. В результате "один и тот же" коммит будет иметь разные SHA1 в комнатах разработчиков и развертывания. Эта разница будет сохраняться до тех пор, пока мы не переместим пакет обратно в комнату развертывания.

  6. При перемещении пакета из dev в развертывание, merge Операция (обычно) распознает идентичные патчи и плавно заменяет фиксацию на фиксацию в истории разработки. Смотрите Шаг 1.

Другие вопросы по тегам