L'arbre contient des entrées de fichier dupliquées

après quelques problèmes avec notre hébergement, nous avons décidé de déplacer notre dépôt Git vers GitHub. Alors j'ai cloné le dépôt et essayé de pousser ça à GitHub. Cependant, je suis tombé sur quelques erreurs que nous n'avons jamais rencontrées auparavant:

 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'

quand je cours 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.

Quand je lance ls-tree avec le mauvais SHA1:

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

j'ai essayé toutes les réponses déjà données sur ce StackOverflow question , mais n'ont pas eu de succès. Puis-je empêcher ce dépôt et son histoire d'être condamnés?

24
demandé sur Community 2012-11-01 18:03:39
la source

3 ответов

Méthode 1.

Faire de la git fsck en premier.

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

si ça ne règle pas le problème, vous êtes en difficulté. Vous pouvez soit ignorer le problème, restaurer le dépôt à partir de la sauvegarde, ou déplacer les fichiers dans un nouveau dépôt. Si vous avez de la difficulté à pousser le rapport dans github, essayez de changer le dépôt en un autre ou cochez: ne peut pas pousser à l'erreur de GitHub: pack-objets est mort du signal 13 et ne peut pas pousser le nouveau dépôt git à github .


les méthodes ci-dessous sont seulement pour les utilisateurs git avancés . Merci de faire la sauvegarde avant de commencer. La solution n'est pas garantie par les étapes suivantes et elle peut la rendre encore pire, alors faites-le pour votre propre risque ou à des fins d'éducation.


Méthode 2.

utiliser un arbre à gitels pour identifier les fichiers en double.

$ 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

comme vous pouvez le voir, il contient les entrées de fichier dupliquées (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

encore une fois, vous pouvez voir les entrées de fichier dupliquées (commerce_coupon_per_user)!

Vous pouvez essayer d'utiliser git show pour chaque blob et vérifier le contenu, si chaque fichier.

alors continue de faire tourner ls-tree pour cet invalide ls-tree l'objet à travers vos différents git clones pour voir si vous pouvez suivre l'objet valide, ou si tous sont cassés.

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

si cela ne vous aide pas, vous pouvez annuler le changement par:

$ git replace -d NEWTREE4b825dc642cb6eb9a060e54bf8d69288fbee4904

Méthode 3.

lorsque vous savez quel fichier/Entrée dir est dupliqué, vous pouvez essayer de supprimer ce fichier et de le recréer plus tard. Par exemple:

$ 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.

lire la suite:


méthode 4.

Vérifiez votre propagation pour les entrées invalides.

revérifions notre arbre.

$ 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

il semble que le commit ci-dessus est invalide, permet de scanner notre journal git pour ce commit en utilisant l'une des commandes suivantes pour vérifier ce qui se passe:

$ 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

dans ce cas précis, notre commit pointe vers le mauvais objet, car il a été Commité dans le cadre du sous-projet git qui n'existe plus (cochez git submodule status ).

vous pouvez exclure cet objet invalide de l'arbre ls et recréer l'arbre sans ce mauvais objet par exemple:

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

$ git replace bb81a5af7e9203f36c3201f2736fca77ab7c8f29 b964946faf34468cb2ee8e2f24794ae1da1ebe20

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

Note: l'ancien objet devrait toujours jeter les entrées de fichier dupliquées, mais si vous avez maintenant des doublons dans le nouvel arbre, alors vous avez besoin pour enlever plus de choses de cet arbre. So:

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

essayons maintenant d'enlever toutes les propagations et les blobs de cet arbre, et replace est à nouveau:

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

Maintenant vous avez arbre vide pour cette entrée invalide.

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

si vous avez des changements bizarres pour stage, Réinitialisez votre dépôt par:

$ git reset HEAD --hard

si vous avez l'erreur suivante:

HEAD is now at 5a4ed8e Some message at bb81a5af7e9203f36c3201f2736fca77ab7c8f29

faites le rebase et supprimez ce commit (en remplaçant pick par 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

méthode 5.

essayer de supprimer et écraser les commits invalides contenant des objets invalides.

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

en Lire plus: Git Outils de Réécriture de l'Histoire et Comment puis-je rebase tout en sautant, en particulier s'engager?


méthode 6.

identification des objets git invalides par les méthodes suivantes pour l'enlèvement manuel:

  • pour les objets non compressés (*veuillez supprimer les deux premiers caractères, car git l'utilise pour le nom du répertoire):

    $ find . -name 81a5af7e9203f36c3201f2736fca77ab7c8f29
    
  • pour objets comprimés

    $ 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.
    

voir: comment déballer tous les objets d'un dépôt git?


Related:

5
répondu kenorb 2017-05-23 15:23:56
la source

la seule solution que j'ai rencontrée est d'utiliser git-replace et git-mktree. Ce n'est pas la solution la plus facile au monde, mais elle fonctionne.

consultez ce lien pour un guide de référence.

arbre git contient dupliquer les entrées du fichier

1
répondu user3447739 2017-05-23 13:28:15
la source

Note: Git 2.1 va ajouter deux options à git replace qui peuvent être utiles lors de la modification d'une entrée corrompue dans un repo git:

éditez le contenu d'un objet de façon interactive. Le contenu existant pour <object> est assez imprimés dans un fichier temporaire, un éditeur est lancé sur le fichier, et le résultat est analysé pour créer un nouvel objet du même type que <object> .

Un ref de remplacement est alors créé pour remplacer <object> par l'objet nouvellement créé.

voir git-var pour plus de détails sur la façon dont l'éditeur sera choisi.

et commit 2deda62 by Jeff King ( peff ) :

Remplacer: Ajouter un -- mode brut pour -- modifier

L'un des buts de " git replace --edit " est d'aider un utilisateur à réparer des objets qui sont malformés ou corrompus.

Habituellement, nous pretty-print arbres avec " ls-tree ", ce qui est beaucoup plus facile à travailler que les données binaires brutes.

toutefois, certains formulaires de la corruption cassent l'arbre-marcheur, dans ce cas notre pretty-printing échoue, rendant " --edit " inutile pour l'utilisateur.

ce patch introduit une option " --raw ", qui vous permet d'éditer les données binaires dans ces instances.

sachant comment Jeff est utilisé pour déboguer Git (comme dans ce cas ), Je ne suis pas trop surpris de voir cette option.

0
répondu VonC 2014-08-03 23:59:57
la source

Autres questions sur git object duplicates