Git: qu'est-ce qu'un commit / blob pendant et d'où viennent-ils?

149

Je recherche les informations de base sur les commits et les blobs pendantes.

Mon repo semble bien. Mais j'ai couru git fsckpour la première fois pour voir ce que cela faisait et j'ai une longue liste de «blobs pendantes» et un seul «commit pendant».

Quelles sont ces choses? D'où viennent-ils? Indiquent-ils quelque chose d'inhabituel (bon ou mauvais) sur l'état de mon repo?

doub1ejack
la source

Réponses:

96

Au cours de l'utilisation de votre référentiel git, vous pouvez finir par vous retirer des opérations et effectuer d'autres mouvements qui provoquent des blobs intermédiaires, et même certaines choses que git fait pour vous aider à éviter la perte d'informations.

Finalement (conditionnellement, selon la page de manuel git gc ), il effectuera un garbage collection et nettoiera ces choses. Vous pouvez également forcer en invoquant le processus de collecte des ordures, git gc.

Pour plus d'informations à ce sujet, consultez Maintenance et récupération de données sur le site git-scm.

Une exécution manuelle du GC laissera par défaut 2 semaines avant l'exécution de cette commande d'un filet de sécurité. Il est en fait encouragé d'exécuter occasionnellement le GC pour garantir une utilisation performante de votre référentiel git. Comme tout, cependant, vous devez comprendre ce qu'il fait avant de détruire les choses qui peuvent être importantes pour vous.

vgoff
la source
10
Il est donc juste de dire que 1) à moins que je ne pense qu'il y a quelque chose qui ne va pas avec mon repo, il est sûr de les supprimer avec git gc, et 2) je n'ai pas besoin de m'inquiéter à ce sujet parce que ces bits pendants sont normaux et git déjà les gérer?
doub1ejack
7
Ce serait une évaluation juste.
vgoff
9
De plus, chaque fois que vous ajoutez un fichier, mais que vous ne validez pas cette version exacte du fichier, vous vous retrouvez avec un blob suspendu. Rien d'inquiétant.
canton7
7
doub1ejack - En règle générale, vous ne devriez pas exécuter le ramasse-miettes manuellement. C'est une mauvaise habitude d'entrer et git fait de toute façon le ramasse-miettes en cas de besoin. L'inconvénient de l'exécuter manuellement est que vous avez perdu la possibilité de récupérer des blobs et des commits suspendus que vous ne voulez peut-être pas maintenant mais que vous voudrez peut-être à l'avenir. Une fois que vous exécutez le garbage collection, vous supprimez une fonctionnalité de retour assez puissante de git. À utiliser avec prudence et comme exception, pas comme règle. --- Laisse juste git faire son truc.
Elijah Lynn
96

Dangling blob = Une modification qui a été apportée à la zone de préparation / index mais n'a jamais été validée. Une chose qui est incroyable avec git est qu'une fois qu'il est ajouté à la zone de préparation, vous pouvez toujours le récupérer car ces blobs se comportent comme des commits en ce sens qu'ils ont aussi un hachage !!

Dangling commit = Un commit qui n'est pas directement lié par un commit enfant, une branche, une balise ou une autre référence. Vous pouvez aussi les récupérer!

Elijah Lynn
la source
5
Les «ancêtres» devraient-ils lire «descendants»? En général, vous ne pouvez atteindre aucun commit git via ses ancêtres.
Phil Miller
@Novelocrat J'ai eu la même pensée, je suis d'accord qu'il devrait probablement lire les descendants.
stkent
1
Je lis toujours "ascendants" dans votre réponse. Il semble que votre édition du 2 juillet n'ait pas corrigé la faute de frappe.
iclman
Comment récupérer une goutte pendante?
HelloGoodbye
1
@ElijahLynn Vous avez raison. Je pense avoir lu un peu trop vite les discussions. Un commit suspendu n'a pas de descendant / enfant et n'est pas référencé par une balise ou une branche.
iclman
44

HOWTO supprimer tous les commits pendantes de votre dépôt git de http://www.tekkie.ro/news/howto-remove-all-dangling-commits-from-your-git-repository/

git reflog expire --expire=now --all
git gc --prune=now

Assurez-vous de vraiment vouloir les supprimer, car vous pourriez décider que vous en avez besoin après tout.

qxo
la source
5
En réalité, la plupart des utilisateurs ne devraient jamais en avoir besoin et s'ils le font, c'est probablement pour un cas d'utilisation programmatique. L'espace disque économisé ou la vitesse augmentée en supprimant les commits pendants ne valent pas l'effort à mon avis.
Elijah Lynn
1
Cela répond à une question différente.
Elijah Lynn
6

Un commit suspendu est un commit qui n'est pas associé à une référence, c'est-à-dire qu'il n'y a aucun moyen d'y accéder.

Par exemple, considérez le diagramme ci-dessous. Supposons que nous supprimions la branche featureX sans fusionner ses modifications, alors le commit D deviendra un commit suspendu car il n'y a pas de référence qui lui est associée. S'il avait été fusionné dans master, alors les références HEAD et master auraient pointé vers le commit D et cela ne serait plus en suspens, même si nous supprimions featureX. Lisez la note après le diagramme pour mieux comprendre cela.

Git récupère automatiquement (c'est-à-dire supprime) les commits pendants. Nous pouvons utiliser le git reflogpour récupérer une branche (de commits en suspens) qui a été supprimée sans la fusionner. Nous ne pouvons récupérer les commits supprimés que s'ils sont présents dans le magasin d'objets local. S'il s'agit d'un ramasse-miettes, nous ne pouvons pas le récupérer.

entrez la description de l'image ici

NOTEZ qu'un nom de branche, c'est-à-dire une étiquette de branche, est en fait une référence au dernier commit sur une branche, c'est-à-dire la pointe de la branche. Dans le diagramme ci-dessus, featureX, master et HEAD ne sont que des références à des commits spécifiques. Les libellés featureX et master font référence aux derniers commits sur leurs branches respectives. HEAD fait généralement référence à la pointe de la branche actuellement extraite (master dans ce cas). Si vous extrayez un commit plus ancien sur votre branche actuelle, alors HEAD sera dans un état détaché, c'est-à-dire qu'il pointera vers l'ancien commit au lieu du dernier. Notez également que HEAD est appelé une référence symbolique car il pointe en fait vers l'étiquette de branche actuelle et toute étiquette de branche pointe toujours vers l'extrémité de la branche. Ainsi, dans des circonstances normales, HEAD pointe indirectement vers le dernier commit.

En passant, notez que Git représente son graphe / historique de commit comme un graphe acyclique dirigé . Chaque commit a une référence à son parent. Par conséquent, les flèches dans un diagramme de validation pointent de la validation enfant à la validation parent. Nous avons besoin d'une référence au dernier commit enfant pour atteindre les commits plus anciens sur une branche.

PS - Le diagramme et la compréhension ci-dessus ont été obtenus à partir de ce cours gratuit . Même si le cours est assez ancien, les connaissances sont toujours pertinentes.

MasterJoe2
la source