Obtenez une liste de tous les commits git, y compris ceux `` perdus ''

139

Disons que j'ai un graphique comme celui-ci:

A---B---C---D (master)
     \
      \-E---F (HEAD)

Si je le fais git log --all --oneline, j'obtiendrai mes six engagements.

Mais si le graphique est

A---B---C---D (master, HEAD)
     \
      \-E---F

Je ne verrai pas E et F. Puis-je demander à git de me dire tous les commits, y compris ceux des branches qui ne sont pas nommées?

Merci

Amadan
la source

Réponses:

63

Pas particulièrement facile - si vous avez perdu le pointeur sur la pointe d'une branche, c'est un peu comme trouver une aiguille dans une botte de foin. Vous pouvez trouver tous les commits qui ne semblent plus être référencés - le git fsck --unreachableferont pour vous - mais qui incluront les commits que vous avez jetés après un git commit --amend, vieux commits sur des branches que vous avez rebasées, etc. à la fois, il y a probablement beaucoup trop d'informations à parcourir.

Donc, la réponse désinvolte est de ne pas perdre de vue les choses qui vous intéressent. Plus sérieusement, les reflogs contiendront par défaut des références à tous les commits que vous avez utilisés au cours des 60 derniers jours. Plus important encore , ils donneront un contexte à ce que ces livraisons sont .

araqnid
la source
7
+1: Il n'y a absolument aucune différence entre un commit délibérément orphelin par commit --amendou rebaseet un orphelin accidentellement en travaillant avec un HEAD détaché, par exemple.
Cascabel
3
En effet. probablement le moyen le plus simple de se remettre de cette situation sera de regarder le reflog pour HEAD lui-même.
araqnid
@Jefromi: Excellente remarque sur git commit --amendetc. laissant des impasses, des commits perdus. J'ai fait quelques rebasages et autres et je me suis retrouvé avec des commits inaccessibles à partir d'aucune succursale, et je me suis senti un peu sale en les laissant dans le repo. Maintenant, la pensée n'est plus aussi troublante. :)
Emil Lundberg
2
@araqnid Je me suis retrouvé dans le même cornichon que l'affiche originale et votre suggestion de regarder le reflog était juste la chose à faire.
Ignazio
7
Je suis d'accord avec cette réponse, mais dans le cas où quelqu'un a besoin de voir tous les commits, y compris les orphelins, qu'ils soient délibérés ou accidentels, git fsck --unreachablecela ne le fournit pas. J'ai juste essayé. La meilleure approche est l' --reflogoption pour git log, comme kenorb a répondu . Ce qui est particulièrement agréable à ce sujet, c'est que, combiné à --graph, vous obtenez un contexte visuel facile à analyser, un peu comme celui illustré dans la question originale. Par exemple, essayez:git log --graph --all --oneline --reflog
Inigo
111

Essayer:

git log --reflog

qui répertorie tous les commits git en prétendant que tous les objets mentionnés par reflogs ( git reflog) sont répertoriés sur la ligne de commande sous la forme <commit>.

Kenorb
la source
1
C'est ce que je recherchais - la fonctionnalité de l'argument --reflog.
Anomalie du
3
Btw, gitk prend également en charge cela: gitk --reflog.
ald.li
50

Lorsque j'aborde ce problème, j'utilise la commande suivante:

git reflog |  awk '{ print $1 }' | xargs gitk

Cela me permet de visualiser les commits récents qui sont devenus sans tête.

J'ai enveloppé cela dans un assistant de script appelé ~/bin/git-reflog-gitk.

Kieran
la source
1
Cela m'a sauvé beaucoup de temps ... MERCI!
Bret Royster
C'est génial! Merci! il visualise vraiment les parties importantes de l'arbre.
Mladen B.
Juste un conseil: cela ne fonctionnera que pour votre travail local en tant que enregistrements reflog when the tips of branches and other references were updated in the *local repository*. Vous pouvez utiliser git log --reflogsi vous souhaitez faire cela pour les changements de référence non locaux
Krishna Gupta
29

Ce qui m'a sauvé la vie, c'est la commande suivante:

git reflog

Vous y trouverez un écran avec l'historique des validations effectuées sur git comme celui-ci:

entrez la description de l'image ici

À ce stade, il vous suffit de trouver HEAD@{X}celui dont vous avez besoin, de créer une branche temporaire et de vous y déplacer comme ceci:

git checkout -b temp_branch HEAD@{X}

De cette façon, vous aurez une branche temporaire avec votre commit perdu sans rebaser ou casser encore plus votre dépôt git.

J'espère que cela t'aides...

Sonhja
la source
26

Comme la réponse de @Kieran, mais pour la console: git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')

Florian Fida
la source
Avez-vous besoin d'inclure la dernière partie: $ (git reflog | awk '{print $ 1}')? Qu'est-ce que cela fait? Après avoir essayé votre solution, il semble qu'elle produit le même résultat même sans cette dernière partie.
wmock
Si vous déplacez votre pointeur de branche et laissez certains commits sans référence (comme OP l'a fait), ils n'apparaîtront plus dans git log --all. Un exemple rapide: après un git reset --hard @^commit HEAD @ {0} ne sera que dans le reflog, et comme git reflogil ne prend pas en charge, --graphvous devez transmettre les commits à git log --graphpour obtenir une représentation visuelle.
Florian Fida
5
vous pouvez utiliser à la --reflogplace de $(git reflog | awk '{print $1}')
Sild
J'ai comparé git log --oneline --all --graph --decorate $(git reflog | awk '{print $1}')à git log --oneline --all --graph --decorate --reflog, ils sont presque identiques sauf --reflog inclus des détails tels que les entrées WIP.
Script Wolf
@FlorianFida, au lieu de reflogpourquoi ne pas l'utiliser à la log --reflogplace?
Pacerier
9

Comment résoudre ce problème? Utilisation git fscket journalisation!

Créez d'abord un fichier contenant des commits et des blobs perdus (inaccessibles). (REMARQUE: si vous avez fait quelque chose comme git gccela, tous les commits seront récupérés et vous ne les trouverez pas ici!)

$git fsck --lost-found > lost_found.commits

Cela vous donne un fichier comme celui-ci:

ballants commettre dec2c5e72a81ef06963397a49c4b068540fc0dc3
ballants blob f8c2579e6cbfe022f08345fa7553feb08d60a975
ballants blob 0eb3e86dc112332ceadf9bc826c49bd371acc194
blob ballants 11cbd8eba79e01f4fd7f496b1750953146a09502
ballants commettre 18733e44097d2c7a800650cea442febc5344f9b3
blob ballants 1e53a5cdb3ecdde27081ec6e8b31e4070106ee05

Vous pouvez ensuite ouvrir ce fichier avec votre éditeur de texte préféré pour copier les hachages de commit / blog à partir de là. (Les macros * toux * vim fonctionnent très bien pour cette * toux *)

Vous pouvez maintenant vous reconnecter à partir de ce commit avec quelque chose comme git log --oneline <commit hash>. Alternativement, gitk, tig ou tout autre visualiseur git devrait fonctionner.

Dans votre cas, si vous trouvez le hachage pour commit F, le journal vous montrera quelque chose comme ça,

A---B---E---F

Rapide et facile! Vous pouvez maintenant trouver le contexte derrière tous ces commits pendants.

PS Oui, je sais, post tardif, mais bon, quelqu'un pourrait le trouver ici et le trouver utile. (Probablement moi dans 6 mois quand je google à nouveau)

bsimmons
la source
5

J'ai eu de la chance de récupérer le commit en regardant le reflog, qui se trouvait à .git/logs/HEAD

J'ai ensuite dû parcourir jusqu'à la fin du fichier et j'ai trouvé le commit que je venais de perdre.

GameScripting
la source
C'est ce que j'ai fini par faire quand j'ai foiré quelque chose. J'ai essayé de m'engager auprès du maître et Stash a hésité quand j'ai poussé. J'ai réinitialisé - hard, puis j'ai réalisé mon erreur. Le commit était dans le reflog, donc je l'ai vérifié, en ai fait une branche, puis je l'ai poussé. Tout a fonctionné à la fin.
David
5

Il git logn'est parfois pas bon d'obtenir tous les détails des commits, alors pour voir ceci ...

Pour Mac: entrez dans votre projet git et tapez:

$ nano .git/logs/HEAD

pour afficher tous les commits dans ce domaine, ou:

$ gedit .git/logs/HEAD

pour vous voir tous les engagements dans ce domaine,

alors vous pouvez éditer dans n'importe lequel de vos navigateurs préférés.

Vinod Joshi
la source
3

@bsimmons

git fsck --lost-found | grep commit

Créez ensuite une branche pour chacun:

$ git fsck --lost-found | grep commit
Checking object directories: 100% (256/256), done.
dangling commit 2806a32af04d1bbd7803fb899071fcf247a2b9b0
dangling commit 6d0e49efd0c1a4b5bea1235c6286f0b64c4c8de1
dangling commit 91ca9b2482a96b20dc31d2af4818d69606a229d4

$ git branch  branch_2806a3 2806a3
$ git branch  branch_6d0e49 6d0e49
$ git branch  branch_91ca9b 91ca9b

Maintenant, de nombreux outils vous montreront une visualisation graphique de ces commits perdus.

yakoda
la source
2

Si vous utilisez l'interface graphique Git Extensions, elle peut vous montrer une visualisation graphique des commits en suspens si vous cochez "Afficher -> Afficher les références de reflog". Cela montrera les commits en suspens dans l'arborescence, comme tous les autres référencés. De cette façon, il est beaucoup plus facile de trouver ce que vous recherchez.

Voir cette image pour une démonstration. Les validations C2, C3, C4 et C5 sur l'image sont pendantes mais toujours visibles.

Zdovc
la source
2
git log --reflog

m'a sauvé! J'ai perdu mon tout en fusionnant HEAD et je n'ai pas pu trouver mon dernier commit! Ne s'affiche pas dans l'arborescence des sources mais git log --reflogaffiche tous mes commits locaux avant

Sultanmyrza Kasymbekov
la source