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

Дерево содержит дубликаты файлов

После некоторых проблем с нашим хостингом мы решили переместить наш репозиторий Git в GitHub. Поэтому я клонировал репозиторий и попытался подтолкнуть его к GitHub. Однако я наткнулся на некоторые ошибки, с которыми мы никогда не сталкивались раньше:

 C:\repositories\appName [master]> git push -u origin master
 Counting objects: 54483, done.
 Delta compression using up to 2 threads.
 Compressing objects: 100% (18430/18430), done.
 error: object 9eac1e639bbf890f4d1d52e04c32d72d5c29082e:contains duplicate file entries
 fatal: Error in object
 fatal: sha1 file '<stdout>' write error: Invalid arguments
 error: failed to push some refs to 'ssh://[email protected]/User/Project.git'

Когда я запустил fsck:

C:\repositories\appName [master]> git fsck --full
Checking object directories: 100% (256/256), done.
error in tree 0db4b3eb0e0b9e3ee41842229cdc058f01cd9c32: contains duplicate file entries
error in tree 9eac1e639bbf890f4d1d52e04c32d72d5c29082e: contains duplicate file entries
error in tree 4ff6e424d9dd2e3a004d62c56f99e798ac27e7bf: contains duplicate file entries
Checking objects: 100% (54581/54581), done.

Когда я запускаю ls-tree с плохой SHA1:

C:\repositories\appName [master]> git ls-tree 9eac1e639bbf890f4d1d52e04c32d72d5c29082e
160000 commit 5de114491070a2ccc58ae8c8ac4bef61522e0667  MenuBundle
040000 tree 9965718812098a5680e74d3abbfa26f527d4e1fb    MenuBundle

Я попробовал все ответы, уже заданные по этому вопросу qaru.site/info/217368/..., но не имел никакого успеха. Есть ли способ предотвратить создание этого репозитория и его истории?

4b9b3361

Ответ 1

Способ 1.

Сначала выполните git fsck.

$ git fsck --full
error in tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29: contains duplicate file entries

Если это не решит проблему, у вас проблемы. Вы можете игнорировать проблему, восстановить репозиторий из резервной копии или переместить файлы в новый репозиторий. Если у вас возникли проблемы с нажатием на репо в github, попробуйте изменить хранилище на другое или проверьте: Невозможно нажать на ошибку GitHub: объекты пакета умерли от сигнала 13 и Невозможно нажать новый репозиторий git на github.


Приведенные ниже методы предназначены только для продвинутых пользователей git. Перед началом работы сделайте резервную копию. Исправление не гарантируется следующими шагами, и это может сделать его еще хуже, так что сделайте это ради собственного риска или образовательных целей.


Способ 2.

Используйте git ls-tree для идентификации повторяющихся файлов.

$ git read-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 # Just a hint.
$ git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 # Try also with: --full-tree -rt -l
160000 commit def08273a99cc8d965a20a8946f02f8b247eaa66  commerce_coupon_per_user
100644 blob 89a5293b512e28ffbaac1d66dfa1428d5ae65ce0    commerce_coupon_per_user
100644 blob 2f527480ce0009dda7766647e36f5e71dc48213b    commerce_coupon_per_user
100644 blob dfdd2a0b740f8cd681a6e7aa0a65a0691d7e6059    commerce_coupon_per_user
100644 blob 45886c0eda2ef57f92f962670fad331e80658b16    commerce_coupon_per_user
100644 blob 9f81b5ca62ed86c1a2363a46e1e68da1c7b452ee    commerce_coupon_per_user

Как вы можете видеть, он содержит дублированные записи файла (commerce_coupon_per_user)!

$ git show bb81a5af7e9203f36c3201f2736fca77ab7c8f29
tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29

commerce_coupon_per_user
commerce_coupon_per_user
commerce_coupon_per_user
commerce_coupon_per_user
commerce_coupon_per_user
commerce_coupon_per_user

Опять же, вы можете увидеть дублированные записи файла (commerce_coupon_per_user)!

Вы можете попытаться использовать git show для каждого перечисленного блоба и проверить содержимое, если каждый файл.

Затем продолжайте работать ls-tree для этого недопустимого ls-tree-объекта через ваши различные git -долоны, чтобы увидеть, можете ли вы отслеживать действительный объект или все сломаны.

git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29

If you found the valid object containing non-duplicated file entries, save it into the file and re-create by using `git mktree` and `git replace`, e.g.

remote$ git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 > working_tree.txt
$ cat working_tree.txt | git mktree
NEWTREEbb81a5af7e9203f36c3201f2736fca77ab7c8f29
$ git replace bb81a5af7e9203f36c3201f2736fca77ab7c8f29 NEWTREE4b825dc642cb6eb9a060e54bf8d69288fbee4904

Если это не поможет, вы можете отменить изменение:

$ git replace -d NEWTREE4b825dc642cb6eb9a060e54bf8d69288fbee4904

Способ 3.

Когда вы знаете, какая запись файла /dir дублируется, вы можете попытаться удалить этот файл и повторно создать его позже. В примере:

$ find . -name commerce_coupon_per_user # Find the duplicate entry.
$ git rm --cached `find . -name commerce_coupon_per_user` # Add -r for the dir.
$ git commit -m'Removing invalid git entry for now.' -a
$ git gc --aggressive --prune # Deletes loose objects! Please do the backup before just in case.

Подробнее:


Способ 4.

Проверьте фиксацию для недопустимых записей.

Позволяет снова проверить наше дерево.

$ git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 --full-tree -rt -l
160000 commit def08273a99cc8d965a20a8946f02f8b247eaa66  commerce_coupon_per_user
100644 blob 89a5293b512e28ffbaac1d66dfa1428d5ae65ce0     270    commerce_coupon_per_user
....
$ git show def08273a99cc8d965a20a8946f02f8b247eaa66
fatal: bad object def08273a99cc8d965a20a8946f02f8b247eaa66
$ git cat-file commit def08273a99cc8d965a20a8946f02f8b247eaa66
fatal: git cat-file def08273a99cc8d965a20a8946f02f8b247eaa66: bad file

Кажется, что вышеуказанная фиксация недействительна, позволяет сканировать наш журнал git для этого фиксации, используя одну из следующих команд, чтобы проверить, что происходит:

$ git log -C3 --patch | less +/def08273a99cc8d965a20a8946f02f8b247eaa66
$ git log -C3 --patch | grep -C10 def08273a99cc8d965a20a8946f02f8b247eaa66

commit 505446e02c68fe306aec5b0dc2ccb75b274c75a9
Date:   Thu Jul 3 16:06:25 2014 +0100

    Added dir.

new file mode 160000
index 0000000..def0827
--- /dev/null
+++ b/sandbox/commerce_coupon_per_user
@@ -0,0 +1 @@
+Subproject commit def08273a99cc8d965a20a8946f02f8b247eaa66

В этом конкретном случае наша фиксация указывает на плохой объект, поскольку он был включен как часть проекта git, который больше не существует (проверьте git submodule status).

Вы можете исключить этот недопустимый объект из дерева ls и воссоздать дерево без этого плохого объекта, например:

$ git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 | grep -v def08273a99cc8d965a20a8946f02f8b247eaa66 | git mktree
b964946faf34468cb2ee8e2f24794ae1da1ebe20

$ git replace bb81a5af7e9203f36c3201f2736fca77ab7c8f29 b964946faf34468cb2ee8e2f24794ae1da1ebe20

$ git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 # Re-test.
$ git fsck -full

Примечание. Старый объект должен по-прежнему бросать повторяющиеся записи файла, но если вы теперь дублируете новое дерево, вам нужно удалить больше материала из этого дерева. Итак:

$ git replace # List replace objects.
bb81a5af7e9203f36c3201f2736fca77ab7c8f29
$ git replace -d bb81a5af7e9203f36c3201f2736fca77ab7c8f29 # Remove previously replaced object.

Теперь попробуйте удалить все коммиты и капли из этого дерева, а затем снова заменить:

$ git ls-tree bb81a5af7e9203f36c3201f2736fca77ab7c8f29 | grep -ve commit -e blob | git mktree
4b825dc642cb6eb9a060e54bf8d69288fbee4904
$ git replace bb81a5af7e9203f36c3201f2736fca77ab7c8f29 4b825dc642cb6eb9a060e54bf8d69288fbee4904

Теперь у вас есть пустое дерево для этой недопустимой записи.

$ git status # Check if everything is fine.
$ git show 4b825dc642cb6eb9a060e54bf8d69288fbee4904 # Re-check
$ git ls-tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 --full-tree # Re-check

Если у вас есть некоторые странные изменения для этапа, reset ваш репозиторий:

$ git reset HEAD --hard

Если у вас будет следующая ошибка:

HEAD is now at 5a4ed8e Some message at bb81a5af7e9203f36c3201f2736fca77ab7c8f29

Сделайте rebase и удалите это commit (изменив pick на edit):

$ git rebase -i
$ git commit -m'Fixed invalid commit.' -a
rebase in progress; onto 691f725
You are currently editing a commit while rebasing branch 'dev' on '691f725'.
$ git rebase --continue
$ git reset --hard
$ git reset HEAD --hard
$ git reset origin/master --hard

Способ 5.

Попробуйте удалить и раздавить недопустимые коммиты, содержащие недопустимые объекты.

$ git rebase -i HEAD~100 # 100 commits behind HEAD, increase if required.

Подробнее: git Инструменты - История перезаписи и Как мне переустановить при пропуске конкретная фиксация?


Метод 6.

Идентификация недопустимых объектов git следующими способами для ручного удаления:

  • для несжатых объектов (* удалите первые два символа, так как git использует его для имени каталога):

    $ find . -name 81a5af7e9203f36c3201f2736fca77ab7c8f29
    
  • для сжатых объектов

    $ find . -name \*.idx -exec cat {} \; | git show-index | grep bb81a5af7e9203f36c3201f2736fca77ab7c8f29
    # Then you need to find the file manually.
    $ git unpack-objects $FILE # Expand the particular file.
    $ git unpack-objects < .git/objects/pack/pack-*.pack # Expand all.
    

Смотрите: Как распаковать все объекты репозитория git?


по теме:

Ответ 2

Единственное решение, с которым я столкнулся, - использовать git -replace и git -mktree. Это не самое легкое решение в мире, но оно действительно работает.

Посмотрите на эту ссылку для справочного руководства.

git дерево содержит повторяющиеся записи файла

Ответ 3

Примечание: Git 2.1 добавит два параметра git replace, которые могут быть полезны при изменении поврежденной записи в Git Сделки рЕПО:

Редактировать содержимое объекта в интерактивном режиме. Существующий контент для <object> довольно печатается во временном файле, в файл запускается редактор, и результат анализируется для создания нового объекта того же типа, что и <object>.
Затем создается замена ref, чтобы заменить <object> на новый объект.
Подробнее о выборе редактора см. git-var.

И зафиксировать 2deda62 Джефф Кинг (peff):

replace: добавить режим -raw для -edit

Одна из целей "git replace --edit" заключается в том, чтобы помочь пользователю восстановить объекты, которые были искажены или повреждены.
Обычно мы красиво печатаем деревья с "ls-tree", с которыми гораздо легче работать, чем с необработанными двоичными данными.

Однако некоторые формы коррупции ломают древовидную структуру, и в этом случае наша симпатичная печать терпит неудачу, рендеринг "--edit" бесполезен для пользователя.

Этот патч вводит параметр "--raw", который позволяет редактировать двоичные данные в этих экземплярах.

Зная, как Jeff используется для отладки Git (например, в этом случае), я не удивлен, увидев эту опцию.