git говорит: «роковое: запутано нестабильными исходными данными объекта» - PullRequest
21 голосов
/ 12 декабря 2010

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

Ответы [ 6 ]

23 голосов
/ 13 декабря 2010

Либо

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

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

Из-за схемы *, которую 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.

14 голосов
/ 10 июля 2012

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

4 голосов
/ 13 декабря 2010

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

  • write_sha1_file_prepare
  • write_loose_object

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

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

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

3 голосов
/ 12 декабря 2010

Две теории:

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

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

0 голосов
/ 10 мая 2018

Несмотря на то, что другие ответы предоставили очень хорошее объяснение того, почему возникает ошибка, это возможное решение проблемы:

Отслеживание проблемного файла, добавление -v к вашей команде git add даст вам некоторыеподсказка о проблемном файле:

git add -Av

Проблема может заключаться просто в том, что файл слишком велик (сжатый источник, некоторый файл данных sql): добавьте его в .gitignore

ФактическиХорошей практикой является регулярная настройка файла .gitignore, чтобы избежать скомпилированных и сжатых файлов, например: https://gist.github.com/octocat/9257657

0 голосов
/ 17 февраля 2017

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

Пример:

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 .

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

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

Тогда он не должен выходить из строя (и работать быстрее).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...