Подтвердить что ты не робот

Git говорит "фатальный: путают данные о нестабильных объектах"

Просто для удовольствия, я пытаюсь добавить около 85 ГБ бинарных файлов размером около 6 МБ в git. Git chugs на некоторое время, но неизменно терпит неудачу примерно на полпути с сообщением "фатальный: запутанный нестабильными исходными данными объекта", за которым следует SHA1. Ты знаешь почему? Есть ли способ исправить это?

4b9b3361

Ответ 1

Либо

  • один или несколько файлов изменяются во время вашей работы или
  • что-то вызывает несовместимые чтения (например, неисправное оборудование).

Краткая версия: разработчики Git s не предполагали, что они будут использоваться в летучих файлах.

Из-за макета * который Git использует для "свободных объектов" и ограниченную семантику файловой системы, которую он принимает ** Git должен знать первый байта (два шестнадцатеричных символа) имени объекта (SHA-1) нового объекта, прежде чем он сможет начать хранить этот объект.

* Каталоги objects/[0-9a-f][0-9a-f]/. См. gitrepository-layout.
** В частности, он должен иметь возможность выполнять "атомарные" переименования файлов. Некоторые файловые системы (обычно сетевые файловые системы, в частности AFS, я считаю) гарантируют только переименование атомарности, когда источник и место назначения переименования находятся в одном каталоге,

В настоящее время Git пропускает два SHA-1 над каждым новым файлом. Первый проход используется для проверки того, знает ли Git о содержимом файла (существует ли его имя объекта SHA-1 в хранилище объектов). Если объект уже существует, второй проход не выполняется.

Для нового содержимого (объект еще не был в хранилище объектов), файл читается второй раз при сжатии и вычислении SHA-1 сжатых данных. Сжатые данные записываются во временный файл, который только переименовывается в его окончательное имя потерянного объекта, если начальная проверка SHA-1 ( "уже сохраненная?" ) Соответствует более позднему SHA-1 (хеш данных, которые были сжаты и записаны), Если эти хэши SHA-1 не совпадают, то Git показывает сообщение об ошибке, которое вы видите и прерываете. Эта проверка ошибок была добавлена ​​в 748af44c63, которая была впервые выпущена в Git 1.7.0.2.

Ответ 2

Есть еще одна возможность, даже если она удалена. Это был бы очень большой файл (например, 3 или более gb), просто говоря, git не может его обработать. Мы обнаружили, что ошибка при попытке создать репозиторий в структуре с огромными файлами

Ответ 3

Из источника, blob sha1 вычисляется дважды:

  • write_sha1_file_prepare
  • write_loose_object

оба вызываются из write_sha1_file (также есть путь от force_object_loose, но он используется для repacks).

Первый хеш используется для проверки того, является ли объект уже известным (хотя git делает все возможное, чтобы получить подтверждение файловой системы о том, что файлы не модифицированы, touch или, таким образом, потеряет трек); второй - хеш данных, которые фактически подаются в zlib для сжатия, затем записываются.

Второй хэш может быть немного дороже для вычисления из-за zlib, что может объяснить, почему вычисляются два хэша (хотя это кажется исторической ошибкой, и я предполагаю, что стоимость производительности при добавлении нового объекта больше чем выигрыш процессора при обнаружении ложных изменений). Кто-то может добавить резерв, чтобы логика проверки существования write_changed_sha1 была переделана с новым sha1, чтобы эти неустойчивые файлы также можно было добавить. Это было бы полезно для резервных копий, когда несколько добавляемых файлов открыты.

Ответ 4

Две теории:

  • Что-то записывает эти файлы, когда вы пытаетесь поместить их в git.

  • У вас есть какая-то ошибка диска/памяти, вызывающая повреждение данных.

Ответ 5

Это может произойти, если вы попытаетесь выполнить git svn clone или git svn извлечь репозиторий в файловой системе btrfs, возможно, что-то связанное с состоянием гонки или атомарностью внутри функции btrfs cow.

Пример:

git svn --authors-file=authors.map clone http://svn.example.com/svn/repo repo

или

cd repo; git svn --authors-file=../authors.map fetch

Я нашел обходной путь, установив базовый рабочий каталог без копирования-на-записи:

chattr +C .

Затем вам нужно будет дублировать все ваши данные (например):

cp -fr repo repo.new; rm -fr repo; mv -f repo.new repo

cp authors.map authors.map.new; mv -f authors.map.new authors.map

Затем он не должен прерываться (и запускаться быстрее).