Linus a suggéré (voir ci-dessous pour le post complet de la liste de diffusion) de n'utiliser git gc --aggressive
que lorsque vous avez, selon ses mots, "un très mauvais pack" ou "vraiment horriblement mauvais deltas", mais "presque toujours, dans d'autres cas, c'est en fait un très mauvais chose à faire." Le résultat peut même laisser votre référentiel dans un état pire que lorsque vous avez commencé!
La commande qu'il suggère pour faire cela correctement après avoir importé «une histoire longue et complexe» est
Date: Wed, 5 Dec 2007 22:09:12 -0800 (PST)
From: Linus Torvalds <torvalds at linux-foundation dot org>
To: Daniel Berlin <dberlin at dberlin dot org>
cc: David Miller <davem at davemloft dot net>,
ismail at pardus dot org dot tr,
gcc at gcc dot gnu dot org,
git at vger dot kernel dot org
Subject: Re: Git and GCC
In-Reply-To: <4aca3dc20712052111o730f6fb6h7a329ee811a70f28@mail.gmail.com>
Message-ID: <alpine.LFD.0.9999.0712052132450.13796@woody.linux-foundation.org>
References: <4aca3dc20712051947t5fbbb383ua1727c652eb25d7e@mail.gmail.com>
<20071205.202047.58135920.davem@davemloft.net>
<4aca3dc20712052032n521c344cla07a5df1f2c26cb8@mail.gmail.com>
<20071205.204848.227521641.davem@davemloft.net>
<4aca3dc20712052111o730f6fb6h7a329ee811a70f28@mail.gmail.com>
Le jeudi 6 décembre 2007, Daniel Berlin a écrit:
En fait, il s'avère que git-gc --aggressive
cela fait parfois cette chose stupide de compresser des fichiers, que vous ayez ou non converti à partir d'un dépôt SVN.
Absolument. git --aggressive
est la plupart du temps stupide. Ce n'est vraiment utile que dans le cas de "Je sais que j'ai un très mauvais pack, et je veux jeter toutes les mauvaises décisions d'emballage que j'ai prises."
Pour expliquer cela, cela vaut la peine d'expliquer (vous en êtes probablement conscient, mais laissez-moi tout de même passer en revue les bases) comment fonctionnent les chaînes delta git et en quoi elles sont si différentes de la plupart des autres systèmes.
Dans d'autres SCM, une chaîne delta est généralement fixe. Cela peut être «vers l'avant» ou «vers l'arrière», et cela peut évoluer un peu à mesure que vous travaillez avec le référentiel, mais il s'agit généralement d'une chaîne de changements vers un seul fichier représenté comme une sorte d'entité SCM unique. Dans CVS, c'est évidemment le *,v
fichier, et beaucoup d'autres systèmes font des choses assez similaires.
Git fait aussi des delta-chains, mais il les fait beaucoup plus «vaguement». Il n'y a pas d'entité fixe. Les deltas sont générés contre toute autre version aléatoire que git considère comme un bon candidat delta (avec diverses heuristiques assez réussies), et il n'y a absolument aucune règle de regroupement dure.
C'est généralement une très bonne chose. C'est bon pour diverses raisons conceptuelles ( c'est-à - dire que git en interne n'a jamais vraiment besoin de se soucier de toute la chaîne de révision - il ne pense pas vraiment en termes de deltas), mais c'est aussi génial parce que se débarrasser des règles de delta inflexibles signifie que git n'a aucun problème avec la fusion de deux fichiers ensemble, par exemple - il n'y a tout simplement pas de *,v
«fichiers de révision» arbitraires qui ont une signification cachée.
Cela signifie également que le choix des deltas est une question beaucoup plus ouverte. Si vous limitez la chaîne delta à un seul fichier, vous n'avez vraiment pas beaucoup de choix sur ce qu'il faut faire avec les deltas, mais dans git, cela peut vraiment être un problème totalement différent.
Et c'est là que le très mal nommé --aggressive
entre en jeu. Alors que git essaie généralement de réutiliser les informations delta (parce que c'est une bonne idée, et qu'il ne perd pas de temps CPU à retrouver tous les bons deltas que nous avons trouvés plus tôt), parfois vous Je veux dire "recommençons, avec une ardoise vierge, ignorons toutes les informations delta précédentes et essayons de générer un nouvel ensemble de deltas."
Il --aggressive
ne s'agit donc pas vraiment d'être agressif, mais de perdre du temps CPU à refaire une décision que nous avons déjà prise plus tôt!
Parfois, c'est une bonne chose. Certains outils d'importation en particulier pourraient générer des deltas vraiment horribles. Tout ce qui utilise git fast-import
, par exemple, n'a probablement pas une grande disposition en delta, il peut donc être utile de dire "Je veux partir d'une table rase."
Mais presque toujours, dans d'autres cas, c'est en fait une très mauvaise chose à faire. Cela va gaspiller du temps CPU, et surtout si vous avez fait du bon travail de deltaing plus tôt, le résultat final ne va pas réutiliser tous ces bons deltas que vous avez déjà trouvés, vous vous retrouverez donc avec beaucoup pire résultat final aussi!
Je vais envoyer un correctif à Junio pour simplement supprimer la git gc --aggressive
documentation. Cela peut être utile, mais il n'est généralement utile que lorsque vous comprenez vraiment à un niveau très profond ce qu'il fait, et cette documentation ne vous aide pas à le faire.
En règle générale, faire progressivement git gc
est la bonne approche, et mieux que de faire git gc --aggressive
. Il va réutiliser les anciens deltas, et quand ces anciens deltas ne peuvent pas être trouvés (la raison pour laquelle le GC incrémental est en premier lieu!), Il va en créer de nouveaux.
D'un autre côté, il est tout à fait vrai qu'une «importation initiale d'une histoire longue et complexe» est un moment où il peut valoir la peine de passer beaucoup de temps à trouver les très bons deltas. Ensuite, chaque utilisateur après (tant qu'il n'utilise pas git gc --aggressive
pour l'annuler!) Bénéficiera de cet événement unique. Donc, en particulier pour les grands projets avec une longue histoire, cela vaut probablement la peine de faire un travail supplémentaire, en disant au code de recherche de delta de se déchaîner.
Donc, l'équivalent de git gc --aggressive
- mais fait correctement - est de faire (du jour au lendemain) quelque chose comme
git repack -a -d --depth=250 --window=250
où cette question de profondeur est à peu près la profondeur des chaînes delta (allongez-les pour l'histoire ancienne - cela en vaut la peine), et la fenêtre concerne la taille d'une fenêtre d'objet que nous voulons que chaque candidat delta scanne.
Et ici, vous voudrez peut-être ajouter le -f
drapeau (qui est le «supprimer tous les anciens deltas», puisque vous essayez maintenant de vous assurer que celui-ci trouve réellement de bons candidats.
Et puis ça va prendre une éternité et un jour ( c'est -à- dire , une chose «faire du jour au lendemain»). Mais le résultat final est que tout le monde en aval de ce référentiel obtiendra de bien meilleurs packs, sans avoir à y consacrer aucun effort.
Linus