128 votes

Parcourir les commits orphelins dans Git

Mon dépôt git s'est en quelque sorte détraqué - j'ai chargé msysgit ce matin et au lieu d'afficher le nom de la branche après le répertoire courant, il indique "((ref : re...))", 'git status' rapporte tout comme un nouveau fichier, 'git log' et 'git reflog' me disent "fatal : bad default revision 'HEAD'", et ainsi de suite.

En faisant 'git reflog --all' ou 'gitk --all', je vois que le reste du dépôt est intact, mais il semble que la branche sur laquelle je travaillais a disparu, ce qui explique pourquoi HEAD ne semble pas exister/pointer vers quoi que ce soit.

Je sais que git conserve toutes sortes d'informations, et je suppose que mes commits ont juste été orphelins d'une manière ou d'une autre, alors y a-t-il une commande qui me montre ces commits pour que je puisse réinitialiser HEAD sur eux ?

EDIT : Oh mon dieu. J'ai découvert 'git fsck', et 'git fsck --full' rapporte "fatal : object 03ca4... is corrupted". Que diable puis-je faire à ce sujet ?

EDIT : Oh dear oh dear. J'ai vérifié une autre branche, puis essayé de recréer la branche originale avec le même nom en utilisant 'git checkout -b lostbranchname', et git dit "error : unable to resolve reference refs/heads/lostbranchname : No error, fatal : Failed to lock ref for update : No error". "No error" doit être une erreur particulièrement désagréable. Il semble donc qu'il traîne toujours, mais qu'il ne peut être ni utilisé ni tué.

EDIT : Super duper oh dear. J'ai fait un tas de déballage et de remballage et de remplacement de choses comme suggéré ici : Comment récupérer les objets Git endommagés par une panne de disque dur ? mais maintenant je reçois un autre hash signalé comme corrompu, pour quelque chose d'aussi inoffensif que "git status". Je pense que tout est fichu. Git est charmant et tout, mais je ne devrais pas avoir à faire face à ce genre de choses.

0 votes

Concernant git checkout -b lostbranchname - si vous ne vous souciez que du nom de la branche (et non de son contenu), vous pouvez supprimer manuellement (ou renommer) .git/refs/heads/lostbranchname - qui, espérons-le, fera l'affaire.

0 votes

Chkdsk rapporte que tout est ok. J'ai supprimé la branche pendante dans .git/refs/heads/ car elle causait des problèmes, mais maintenant d'autres commandes se plaignent de la corruption d'autres objets, donc je pense que ce n'est pas aussi simple qu'un objet corrompu maintenant.

1 votes

Et vous n'avez pas d'amont où pousser ce dossier git ?

164voto

Ben Hymers Points 3912

Plutôt que de laisser cette question ouverte, je pense que je vais répondre à ma propre question. Utilisation de git reflog --all est un bon moyen de parcourir les commits orphelins - et en utilisant les hashs SHA1 de ceux-ci, vous pouvez reconstruire l'historique.

Dans mon cas cependant, le référentiel était corrompu et cela n'a pas aidé ; git fsck peut vous aider à trouver et parfois à corriger des erreurs dans le référentiel lui-même.

4 votes

Merci. C'est le seul endroit où j'ai trouvé cette information lorsque j'ai essayé de tirer une pull request orpheline sur github. Cela a résolu mon problème.

6 votes

Au cas où quelqu'un voudrait tout en gitk : [alias] orphank = !gitk --all --date-order ``git reflog | cut -c1-7``& (edit : imaginez ces doubles backticks à la place des simples - l'échappement ne semble pas fonctionner ici)

1 votes

Superbe astuce @mbx ! Très utile de pouvoir voir les liens entre les commits orphelins graphiquement !

28voto

jamesdlin Points 13455

Je trouve généralement git reflog pour être confus. Il est beaucoup plus facile pour moi de comprendre un graphique de commit à partir de git log --graph --reflog . Remplacer le log pour ne montrer que les résumés des engagements peut également rendre le graphique plus facile à suivre :

$ git config --global alias.graph \
    "log --graph --all --format='%h %s%n        (%an, %ar)%d' --abbrev-commit"

$ git graph --reflog

* f06abeb Add feature
|         (Sue Dakota, 4 days ago) (HEAD -> master)
* f126291 Fix the build
|         (Oski M. Wizard, 5 days ago) (origin/master, master)
* 3c4fb9c Move fast, break things
|         (Alyssa P. Hacker, 5 days ago)
| * e3124bf fixup! More work for feature
| |         (Sue Dakota, 4 days ago)
| | * 6a7a52e Lost commit
| |/          (Sue Dakota, 4 days ago)
| * 69d9438 More work for feature
| |         (Sue Dakota, 2 weeks ago)
| * 8f69aba Initial work for feature
|/          (Sue Dakota, 3 weeks ago)
* d824fa9 Fix warnings from the linter
|         (Theo Rhys Tudent, 4 weeks ago)
* 9f782b8 Fix test flakes
|         (Tess Driven, 5 weeks ago)

A partir de là, il est clair que e3124bf y 6a7a52e sont des orphelins non référencés, et il y a un contexte de leurs commits ancêtres.

21voto

VonC Points 414372

Avec git 2.9.x/2.10 (Q3 2016), vous n'aurez plus à utiliser git reflog --all plus, git reflog sera suffisant.

Voir commettre 71abeb7 (03 juin 2016) par SZEDER Gábor ( szeder ) .
(fusionné par Junio C Hamano -- gitster -- sur commettre 7949837 , 06 Jul 2016)

reflog : continuer à marcher le reflog commits Root passés

Si un dépôt contient plus d'un commit Root, alors son reflog HEAD peut contenir plusieurs "événements de création", c'est-à-dire des entrées dont la valeur "from" est le null sha1.
L'énumération d'un tel reflog s'arrête actuellement prématurément à la première entrée de ce type, même si le reflog contient encore des entrées plus anciennes.
Cela peut effrayer les utilisateurs en leur faisant croire que leur reflog a été tronqué après '. git checkout --orphan '.

Continuez à faire passer le reflog devant de tels événements de création en vous basant sur les éléments suivants valeur "nouveau" de l'entrée précédente du reflog.

5voto

Jamey Hicks Points 928

Une bonne caractéristique de git est qu'il détecte la corruption. Cependant, il n'inclut pas de correction d'erreur pour se protéger de la corruption.

J'espère que vous avez poussé le contenu de ce référentiel vers une autre machine ou que vous avez des sauvegardes pour récupérer les parties corrompues.

Je n'ai pas d'expérience avec git sous Windows mais je n'ai jamais vu ce genre de comportement avec git sous Linux ou OS X.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X