Quelle est la différence entre git reflog et log?

158

La page de manuel indique que le journal affiche les journaux de validation et que reflog gère les informations de reflog. Que sont exactement les informations de reflog et que contiennent-elles que le journal ne contient pas? Le journal semble beaucoup plus détaillé.

Noich
la source

Réponses:

221

git logmontre la tête actuelle et son ascendance. Autrement dit, il imprime les points HEAD de validation, puis son parent, son parent, etc. Il parcourt l'ascendance du repo, en recherchant récursivement le parent de chaque commit.

(En pratique, certains commits ont plus d'un parent. Pour afficher un journal plus représentatif, utilisez une commande comme git log --oneline --graph --decorate.)

git reflogne traverse pas du tout l'ascendance de HEAD. Le reflog est une liste ordonnée des commits vers lesquels HEAD a pointé: c'est l'historique des annulations de votre repo. Le reflog ne fait pas partie du repo lui-même (il est stocké séparément dans les commits eux-mêmes) et n'est pas inclus dans les push, les récupérations ou les clones; c'est purement local.

À part: comprendre le reflog signifie que vous ne pouvez pas vraiment perdre les données de votre dépôt une fois qu'il a été engagé. Si vous réinitialisez accidentellement un commit plus ancien, ou un rebase incorrect, ou toute autre opération qui "supprime" visuellement les commits, vous pouvez utiliser le reflog pour voir où vous étiez avant et git reset --hardrevenir à cette référence pour restaurer votre état précédent. Rappelez-vous, les refs n'impliquent pas seulement le commit, mais toute l'histoire derrière.

ben_h
la source
26
Un mot d'avertissement: vous POUVEZ parfois perdre des données parce que les entrées de reflog ne persistent pas éternellement - elles sont purgées sous certaines conditions. Voir cette réponse et la documentation pour git-reflog et git-gc . Généralement, si l'opération destructrice n'a pas eu lieu il y a plus de 2 semaines, vous êtes probablement en sécurité.
mcmlxxxvi
@mcmlxxxvi J'ai deux dossiers locaux pour le même référentiel, puis-je fusionner les reflogs des deux dossiers?
Tmx
@Tmx, je ne comprends pas très bien votre cas - qu'entendez-vous par deux dossiers locaux pour le même dépôt ? Si vous avez deux clones du même référentiel, qui sont à jour, et que vous souhaitez «fusionner» leur historique d'édition, les .git/logs/refs/<branch>entrées ont le format <old_rev> <new_rev> [...] <timestamp> [...]. Vous pouvez essayer de concaténer et de trier par horodatage. Cependant, certaines lignes new_revpeuvent ne pas correspondre à la suivante old_rev, auquel cas je suppose que le reflog sera invalide. Vous pouvez alors essayer d'insérer de fausses entrées pour "corriger" la séquence, mais cela me semble trop compliqué.
mcmlxxxvi
62
  • git log affiche le journal de validation accessible depuis les références (têtes, balises, télécommandes)
  • git reflogest un enregistrement de tous les commits qui sont ou ont été référencés dans votre repo à tout moment.

C'est pourquoi git reflog(un enregistrement local qui est élagué après 90 jours par défaut) est utilisé lorsque vous effectuez une opération "destructive" (comme la suppression d'une branche), afin de récupérer le SHA1 qui a été référencé par cette branche.
Voir git config:

gc.reflogexpire
gc.<pattern>.reflogexpire

git reflogexpire supprime les entrées de reflog plus anciennes que cette heure; par défaut, 90 jours.
Avec " <pattern>" (par exemple " refs/stash") au milieu, le réglage s'applique uniquement aux références qui correspondent au <pattern>.

filet de sécurité

git reflogest souvent appelé " votre filet de sécurité "

En cas de problème, le conseil général, lorsque git log ne vous montre pas ce que vous recherchez, est:

" Reste calme et utilisegit reflog "

rester calme

Encore une fois, reflog est un enregistrement local de votre SHA1.
Par opposition à git log: si vous transférez votre repo vers un repo en amont , vous verrez la même chose git log, mais pas nécessairement la même chose git reflog.

VonC
la source
14

Voici l' explication du refloglivre Pro Git :

L'une des choses que Git fait en arrière-plan pendant que vous travaillez est de garder un reflog - un journal de l'endroit où se trouvent vos références HEAD et branche ces derniers mois.

Vous pouvez voir votre reflog en utilisant git reflog:

$ git reflog
734713b... HEAD@{0}: commit: fixed refs handling, added gc auto, updated
d921970... HEAD@{1}: merge phedders/rdocs: Merge made by recursive.
1c002dd... HEAD@{2}: commit: added some blame and merge stuff
1c36188... HEAD@{3}: rebase -i (squash): updating HEAD
95df984... HEAD@{4}: commit: # This is a combination of two commits.
1c36188... HEAD@{5}: rebase -i (squash): updating HEAD
7e05da5... HEAD@{6}: rebase -i (pick): updating HEAD

Chaque fois que votre astuce de branche est mise à jour pour une raison quelconque, Git stocke ces informations pour vous dans cet historique temporaire. Et vous pouvez également spécifier des commits plus anciens avec ces données.

La reflogcommande peut également être utilisée pour supprimer des entrées ou expirer des entrées du reflog qui sont trop anciennes. De la documentation officielle du noyau Linux Git pourreflog :

La sous-commande expire - est utilisée pour élaguer les anciennes entrées Reflog.

Pour supprimer des entrées uniques du reflog, utilisez la sous-commande deleteet spécifiez l'entrée exacte (par exemple git reflog delete master@{2}).

Communauté
la source
Mais ne git logvous fournit-il pas les mêmes informations? Désolé si cela semble évident, je suis très nouveau sur GIT et j'aimerais avoir quelques notions de base juste avant mon premier OMG.
Noich
2
Le journal Git est un enregistrement de vos commits . Le reflog, comme l'indique le livre Pro Git, est un enregistrement de vos références (en gros, vos pointeurs de branche et votre HEADpointeur), et les validations sur lesquelles elles pointent. Cela a-t-il du sens? Sur une note de côté, logpeut aussi montrer que vous reflog informations, mais vous devez passer un drapeau d'option spécial comme argument à lui, --walk-reflogs.
3
De plus, puisque vous êtes un débutant en Git, je vous recommande vivement de lire le livre Pro Git, c'est ainsi que j'ai appris la plupart de ce que j'ai appris sur Git. Je recommande les chapitres 1-3 et 6-6.5. Je vous recommande également vivement d'apprendre à rebaser à la fois de manière interactive et non interactive.
8

J'étais aussi curieux à ce sujet et je veux juste élaborer et résumer un peu:

  1. git logaffiche un historique de tous vos commits pour la branche dans laquelle vous vous trouvez. Vérifiez une autre branche et vous verrez un historique de commit différent. Si vous voulez voir votre historique de validation pour toutes les branches, tapez git log --all.

  2. git reflogmontre un enregistrement de vos références comme l'a dit Cupcake. Il y a une entrée à chaque fois qu'un commit ou un checkout est effectué. Essayez de basculer entre deux branches plusieurs fois en utilisant git checkoutet exécutez git reflogaprès chaque vérification. Vous verrez l'entrée supérieure mise à jour à chaque fois comme une entrée de «paiement». Vous ne voyez pas ces types d'entrées dans git log.

Références: http://www.lornajane.net/posts/2014/git-log-all-branches

mitch
la source
1

J'aime penser à la différence entre git log et reflog comme étant la différence entre un enregistrement privé et un enregistrement public.

Privé vs public

Avec le git reflog, il garde une trace de tout ce que vous avez fait localement. Vous êtes-vous engagé? Reflog le suit. Avez-vous effectué une réinitialisation matérielle? Reflog le suit. Avez-vous modifié un commit ? Reflog le suit. Tout ce que vous avez fait localement, il y a une entrée pour cela dans le reflog.

Ce n'est pas vrai pour le journal. Si vous modifiez un commit, le journal affiche uniquement le nouveau commit. Si vous effectuez une réinitialisation et que vous sautez quelques validations dans votre historique, les validations que vous avez ignorées n'apparaîtront pas dans le journal. Lorsque vous transmettez vos modifications à un autre développeur ou à GitHub ou quelque chose du genre, seul le contenu suivi dans le journal apparaît. Pour un autre développeur, il semblera que les réinitialisations ne se sont jamais produites ou que les modifications ne se sont jamais produites.

Le journal est poli. Le reflog est lapidaire.

Alors oui, j'aime l'analogie «privé vs public». Ou peut-être un meilleur journal vs reflog analogie est «poli vs lapidaire». Le reflog montre tous vos essais et erreurs. Le journal montre simplement une version propre et raffinée de votre historique de travail.

Jetez un œil à cette image pour souligner le point. Un certain nombre de modifications et de réinitialisations ont eu lieu depuis l'initialisation du référentiel. Le reflog montre tout cela. Pourtant, la commande log donne l'impression qu'il n'y a jamais eu qu'un seul commit contre le repo:

Le journal est poli.  Reflog est lapidaire.

Retour à l'idée du 'filet de sécurité'

De plus, comme le reflog garde une trace des choses que vous avez modifiées et des validations que vous réinitialisez , il vous permet de revenir en arrière et de trouver ces validations car il vous donnera les identifiants de validation. En supposant que votre référentiel n'a pas été purgé des anciens commits, cela vous permet de ressusciter des éléments qui ne sont plus visibles dans le journal. C'est ainsi que le reflog finit parfois par sauver la peau de quelqu'un lorsqu'il a besoin de récupérer quelque chose qu'il pensait avoir perdu par inadvertance.

Cameron McKenzie
la source
-6

En fait, reflog est un alias pour

 git log -g --abbrev-commit --pretty=oneline

la réponse devrait donc être: c'est un cas particulier.

user10028634
la source
9
Dans git log, -gest la forme abrégée de --walk-reflogs. Donc, cela n'explique rien.
Adrian W