Le guide ou le code que vous verrez dans cet article est la résolution la plus rapide et la plus efficace que nous ayons trouvée à ce problème ou problème.
Solution :
TLDR ; comme mentionné dans GitMerge 2019 :
git config --global core.commitGraph true
git config --global gc.writeCommitGraph true
cd /path/to/repo
git commit-graph write
En fait (voir à la fin), les deux premières configurations ne sont pas nécessaires avec Git 2.24+ (Q3 2019) : elles sont true
par défaut.
Git 2.18 (Q2 2018) améliorera le fonctionnement de l'application. git log
les performances :
Voir le commit 902f5a2 (24 Mar 2018) par René Scharfe (rscharfe
).
Voir le commit 0aaf05b, commit 3d475f4 (22 Mar 2018) par Derrick Stolee (derrickstolee
).
Voir le commit 626fd98 (22 Mar 2018) par brian m. carlson (bk2204
).
(Fusionné par Junio C Hamano -- gitster
-- dans le commit 51f813c, 10 Apr 2018)
sha1_name
: utilisationbsearch_pack()
pour les abréviationsLors du calcul des longueurs d'abréviations pour un ID d'objet par rapport à un seul
packfile, la méthodefind_abbrev_len_for_pack()
implémente actuellement
recherche binaire.
Il s'agit d'une implémentation parmi d'autres.
Un problème avec cette implémentation est qu'elle ignore la table de fanout dans la sectionpack-index
.Traduisez cette recherche binaire pour utiliser l'existant.
bsearch_pack()
méthode existante
qui utilise correctement une table de fanout.En raison de l'utilisation de la table de fanout, le calcul de l'abréviation est
légèrement plus rapide qu'auparavant.Pour une copie entièrement repackée du repo Linux, les commandes 'git log' suivantes ont été améliorées :
* git log --oneline --parents --raw
Before: 59.2s
After: 56.9s
Rel %: -3.8%
* git log --oneline --parents
Before: 6.48s
After: 5.91s
Rel %: -8.9%
Le même Git 2.18 ajoute un graphique des commits: Précalculer et stocker les informations nécessaires à la traversée des ancêtres dans un fichier séparé pour optimiser la marche du graphe.
Voir commit 7547b95, commit 3d5df01, commit 049d51a, commit 177722b, commit 4f2542b, commit 1b70dfd, commit 2a2e32b (10 Apr 2018), et commit f237c8b, commit 08fd81c, commit 4ce58ee, commit ae30d7b, commit b84f767, commit cfe8321, commit f2af9f5 (02 Apr 2018) par Derrick Stolee (derrickstolee
).
(Fusionné par Junio C Hamano -- gitster
-- dans le commit b10edb2, 08 Mai 2018)
commit
: intégrer le graphe de commit avec le parsing de commitApprendre à Git à inspecter un fichier commit graph pour fournir le contenu d'une
struct commit lors de l'appelparse_commit_gently()
.
Cette implémentation satisfait toutes les post-conditions sur le commit struct, y compris le chargement des parents, l'arbre racine et la date du commit.Si
core.commitGraph
estfalse
, il ne faut pas vérifier les fichiers graphiques.Dans le script de test t5318-commit-graph.sh, ajouter
output-matching
conditions sur
opérations sur les graphes en lecture seule.En chargeant les commits depuis le graphe au lieu de parcourir les buffers de commit, nous
gagnons beaucoup de temps sur les longues marches de commit..Voici quelques résultats de performance pour une copie du dépôt Linux où 'master' a 678 653 commits atteignables et est derrière '.
origin/master
' de 59 929 commits.
| Command | Before | After | Rel % |
|----------------------------------|--------|--------|-------|
| log --oneline --topo-order -1000 | 8.31s | 0.94s | -88% |
| branch -vv | 1.02s | 0.14s | -86% |
| rev-list --all | 5.89s | 1.07s | -81% |
| rev-list --all --objects | 66.15s | 58.45s | -11% |
Pour en savoir plus sur le graphe des commits, voir "How does 'git log --graph
' fonctionne ? ".
Le même Git 2.18 (Q2 2018) ajoute l'arbre de chargement paresseux.
Le code a été enseigné pour utiliser les informations dupliquées stockées
dans le fichier commit-graph pour apprendre le nom de l'objet arbre pour un commit.
pour éviter d'ouvrir et d'analyser l'objet commit lorsqu'il est logique de le faire.
de le faire.
Voir le commit 279ffad (30 Apr 2018) par SZEDER Gábor (szeder
).
Voir commit 7b8a21d, commit 2e27bd7, commit 5bb03de, commit 891435d (06 Apr 2018) par Derrick Stolee (derrickstolee
).
(Fusionné par Junio C Hamano -- gitster
-- dans le commit c89b6e1, 23 Mai 2018)
commit-graph
: arbres lazy-load pour les commitsLe fichier commit-graph fournit un accès rapide aux données de commit, y compris
l'OID de l'arbre racine pour chaque commit dans le graphe. Lorsque l'on effectue
une promenade profonde dans le graphe des commits, nous pouvons ne pas avoir besoin de charger la plupart des arbres
pour ces commits.Retarde le chargement de l'objet arbre pour un commit chargé depuis le graphe
jusqu'à ce qu'il soit demandé viaget_commit_tree()
.
Ne pas charger paresseusement les arbres pour les commits qui ne sont pas dans le graphe, car cela nécessite une analyse syntaxique dupliquée et l'amélioration relative des performances lorsque les arbres ne sont pas nécessaires est faible.Sur le référentiel Linux, des tests de performance ont été effectués pour les commandes suivantes
commande :git log --graph --oneline -1000 Before: 0.92s After: 0.66s Rel %: -28.3%
Git 2.21 (Q1 2019) ajoute... cache lâche.
Voir le commit 8be88db (07 Jan 2019), et le commit 4cea1ce, commit d4e19e5, commit 0000d65 (06 Jan 2019) par René Scharfe (rscharfe
).
(Fusionné par Junio C Hamano -- gitster
-- dans le commit eb8638a, 18 Jan 2019)
object-store
: utiliser unoid_array
par sous-répertoire pour un cache lâcheLe cache des objets libres est rempli un sous-répertoire à la fois, selon les besoins.
Il est stocké dans unoid_array
, qui doit être ressorti après chaque opération d'ajout.
Ainsi, lors de l'interrogation d'un large éventail d'objets, le tableau partiellement rempli doit être retrié jusqu'à 255 fois, ce qui prend plus de 100 fois plus de temps qu'un tri unique.Utilisez un
oid_array
pour chaque sous-répertoire.
Cela garantit que les entrées ne doivent être triées qu'une seule fois. Cela évite également huit étapes de recherche binaire pour chaque consultation du cache, ce qui constitue un petit bonus.Le cache est utilisé pour les contrôles de collision pour les placeholders du journal.
%h
,%t
et%p
et nous pouvons voir que le changement les accélère dans un référentiel avec environ 100 objets par sous-répertoire :$ git count-objects 26733 objects, 68808 kilobytes Test HEAD^ HEAD -------------------------------------------------------------------- 4205.1: log with %H 0.51(0.47+0.04) 0.51(0.49+0.02) +0.0% 4205.2: log with %h 0.84(0.82+0.02) 0.60(0.57+0.03) -28.6% 4205.3: log with %T 0.53(0.49+0.04) 0.52(0.48+0.03) -1.9% 4205.4: log with %t 0.84(0.80+0.04) 0.60(0.59+0.01) -28.6% 4205.5: log with %P 0.52(0.48+0.03) 0.51(0.50+0.01) -1.9% 4205.6: log with %p 0.85(0.78+0.06) 0.61(0.56+0.05) -28.2% 4205.7: log with %h-%h-%h 0.96(0.92+0.03) 0.69(0.64+0.04) -28.1%
Git 2.22 (avr. 2019) vérifie les erreurs avant d'utiliser les données lues dans le fichier commit-graph.
Voir commit 93b4405, commit 43d3561, commit 7b8ce9c, commit 67a530f, commit 61df89c, commit 2ac138d (25 Mar 2019), et commit 945944c, commit f6761fa (21 Feb 2019) par Ævar Arnfjörð Bjarmason (avar
).
(Fusionné par Junio C Hamano -- gitster
-- dans le commit a5e4be2, 25 Apr 2019)
commit-graph
write : ne pas mourir si le graphe existant est corrompu.Lorsque le
commit-graph
est écrite, nous finissons par appelerparse_commit()
. Ce dernier invoquera à son tour un code qui consultera le fichiercommit-graph
à propos du commit, si le graphe est corrompu nous mourrons.On se retrouve donc dans un état où un "
commit-graph verify
" ne peut pas être suivi d'un "commit-graph write
".commit-graph write
" sicore.commitGraph=true
est défini, le graphique doit être supprimé manuellement pour pouvoir continuer, ou alorscore.commitGraph
doit être mis à "false".Changez la valeur de "
commit-graph write
" pour utiliser un nouveauparse_commit_no_graph()
au lieu deparse_commit()
pour éviter cela.
Ce dernier appellerarepo_parse_commit_internal()
avecuse_commit_graph=1
comme on le voit dans 177722b ("commit
: intégrer le graphe de commit avec le parsing de commit ", 2018-04-10, Git v2.18.0-rc0).Ne pas utiliser l'ancien graphe du tout ralentit l'écriture du nouveau graphe d'une certaine petite quantité, mais c'est un moyen judicieux d'empêcher une erreur dans le commit-graph existant de se propager.
Avec Git 2.24+ (Q3 2019), la fonction commit-graph est actif par défaut.:
Voir le commit aaf633c, commit c6cc4c5, commit ad0fb65, commit 31b1de6, commit b068d9a, commit 7211b9e (13 août 2019) par Derrick Stolee (derrickstolee
).
(Fusionné par Junio C Hamano -- gitster
-- dans le commit f4f8dfe, 09 Sep 2019)
commit-graph
: activer commit-graph par défautLa fonctionnalité commit-graph a connu beaucoup d'activité au cours de la dernière
l'année dernière depuis son introduction.
La fonctionnalité est une amélioration de performance critique pour les repos de taille moyenne à grande, et ne nuit pas de manière significative aux petits repos.Changez les valeurs par défaut pour
core.commitGraph
etgc.writeCommitGraph
à true afin que les utilisateurs bénéficient de cette fonctionnalité par défaut..
Toujours avec Git 2.24 (Q4 2019), une variable de configuration indique "git fetch
" d'écrire le graphe de commit après avoir terminé.
Voir le commit 50f26bd (03 Sep 2019) par Derrick Stolee (derrickstolee
).
(Fusionné par Junio C Hamano -- gitster
-- dans le commit 5a53509, 30 Sep 2019)
fetch : ajouter le paramètre de configuration fetch.writeCommitGraph
La fonctionnalité commit-graph est maintenant activée par défaut, et elle est écrite pendant '.
git gc
' par défaut.
Typiquement, Git n'écrit un commit-graph que lorsqu'un 'git gc --auto
' passe l'étapegc.auto
pour effectuer un travail réel. Cela signifie qu'un commit-graph sera
typiquement en retard sur les commits qui sont utilisés tous les jours.Pour rester à jour avec les derniers commits, ajoutez une étape à '
git fetch
' pour écrire un commit-graph après avoir récupéré de nouveaux objets.
Le sitefetch.writeCommitGraph
paramètre de configuration permet d'écrire un commit-graph fractionné, donc en moyenne le coût d'écriture de ce fichier est très faible. Occasionnellement, la chaîne commit-graph s'effondrera à un seul niveau, et cela pourrait être lent pour les très grands repos.Pour une utilisation supplémentaire, ajustez la valeur par défaut pour qu'elle soit vraie lorsque...
feature.experimental
est activé.
Et toujours avec Git 2.24 (Q4 2019), l'élément commit-graph
est plus robuste.
Voir le commit 6abada1, commit fbab552 (12 Sep 2019) par Jeff King (peff
).
(Fusionné par Junio C Hamano -- gitster
-- dans le commit 098e8c6, 07 Oct 2019)
commit-graph
: bosseDIE_ON_LOAD
vérification du temps de chargement réelCommit 43d3561 (commit-graph write : don't die if the existing graph
est corrompu, 2019-03-25, Git v2.22.0-rc0) a ajouté une variable d'environnement que nous utilisons uniquement dans la suite de tests,$GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD
.
Mais il a mis la vérification de cette variable tout en haut deprepare_commit_graph()
qui est appelé chaque fois que nous voulons utiliser le graphe de commit.
Plus important encore, il vient avant nous vérifions le fast-path "avons-nous déjà essayé de charger ?", ce qui signifie que nous finissons par appelergetenv()
pour chaque utilisation unique du graphe de commit, plutôt que juste quand nous chargeons.
getenv()
est autorisé à avoir des effets secondaires inattendus, mais cela ne devrait pas
être un problème pour ellee; nous chargeons le graphe paresseusement pour qu'il soit clair qu'au moins une fois par semaine, le graphe est utilisé.
au moins un invocation de cette fonction va l'appeler.Mais c'est inefficace.
getenv()
doit typiquement faire une recherche linéaire
à travers l'espace de l'environnement.Nous pourrions mémoriser l'appel, mais il est encore plus simple de simplement déplacer la vérification vers l'étape de chargement réelle. C'est bien pour notre seul utilisateur dans t5318, et produit cette accélération mineure dans le monde réel :
[before] Benchmark #1: git -C linux rev-list HEAD >/dev/null Time (mean ± σ): 1.460 s ± 0.017 s [User: 1.174 s, System: 0.285 s] Range (min … max): 1.440 s … 1.491 s 10 runs [after] Benchmark #1: git -C linux rev-list HEAD >/dev/null Time (mean ± σ): 1.391 s ± 0.005 s [User: 1.118 s, System: 0.273 s] Range (min … max): 1.385 s … 1.399 s 10 runs
Git 2.24 (Q4 2019) inclut également un correctif de régression.
Voir le commit cb99a34, commit e88aab9 (24 Oct 2019) par Derrick Stolee (derrickstolee
).
(Fusionné par Junio C Hamano -- gitster
-- dans le commit dac1d83, 04 Nov 2019)
commit-graph
: correction de l'écriture du premier commit-graph pendant le fetchSignalé par : Johannes Schindelin
Assisté par : Jeff King
Assisté par : Szeder Gábor
Signé par : Derrick StoleeLe commit précédent inclut un test défaillant pour un problème autour de fetch.writeCommitGraph et de la récupération dans un repo avec un submodule. Ici, nous corrigeons ce bogue et définissons le test à...
"test_expect_success"
.Le problème se pose avec cet ensemble de commandes lorsque le repo distant at a un submodule. Notez que
--recurse-submodules
n'est pas nécessaire pour démontrer le bogue.$ git clone
test $ cd test $ git -c fetch.writeCommitGraph=true fetch origin Computing commit graph generation numbers: 100% (12/12), done. BUG: commit-graph.c:886: missing parent for commit Aborted (core dumped) En tant que correctif initial, j'ai converti le code de l'article
builtin/fetch.c
qui appellewrite_commit_graph_reachable()
pour lancer à la place un "git commit-graph
écrire--reachable --split
". Ce code a fonctionné, mais ce n'est pas la façon dont nous voulons que la fonctionnalité fonctionne à long terme.Ce test a bien démontré que le problème doit être quelque chose à voir avec l'état interne du processus " git fetch ".
Le site
write_commit_graph()
danscommit-graph.c
garantit que les commits que nous prévoyons d'écrire sont " fermés sous accessibilité " en utilisant la méthodeclose_reachable()
.
Cette méthode marche à partir des commits d'entrée, et utilise la méthodeUNINTERESTING
pour marquer les commits qui ont déjà été visités. Cela permet à la marche de prendreO(N)
temps, oùN
est le nombre de commits, au lieu deO(P)
temps, oùP
est le nombre de chemins. (Le nombre de chemins peut être exponentiel dans le nombre de commits).Cependant, le
UNINTERESTING
est utilisé à de nombreux endroits dans le codebase. Ce drapeau signifie généralement une certaine barrière pour arrêter une marche de commit, comme dans le revision-walking pour comparer les historiques.
Il n'est pas souvent effacé après la fin de la marche parce que les points de départ de ces marches n'ont pas le drapeauUNINTERESTING
etclear_commit_marks()
s'arrêterait immédiatement.Cela se passe pendant un '
git fetch
' avec un distant. La négociation de récupération compare les références distantes avec les références locales et marque certains commits comme...UNINTERESTING
.J'ai testé en exécutant
clear_commit_marks_many()
pour effacer l'indicateur UNINTERESTING à l'intérieur declose_reachable()
, mais les conseils n'avaient pas le drapeau, donc cela n'a rien fait.Il s'avère que le
calculate_changed_submodule_paths()
est en faute. Merci, Peff, d'avoir signalé ce détail ! Plus précisément, pour chaque sous-module, la méthodecollect_changed_submodules()
exécute un revision walk pour essentiellement faire l'historique des fichiers sur la liste des sous-modules. Cette marche de révision marque les commitsUNININTERESTING
s'ils sont simplifiés en ne modifiant pas le sous-module.Au lieu de cela, je suis finalement arrivé à la conclusion que je devrais utiliser un drapeau qui n'est utilisé dans aucune autre partie du code. Dans
commit-reach.c
, un certain nombre de drapeaux ont été définis pour les algorithmes de marche de commit. Le siteREACHABLE
semblait être le plus logique, et il semble qu'il n'ait pas été réellement utilisé dans le fichier.
Le siteREACHABLE
était utilisé dans les premières versions decommit-reach.c
mais a été supprimé par 4fbcca4 ("commit-reach
: fairecan_all_from_reach
... linéaire ", 2018-07-20, v2.20.0-rc0).Ajouter le
REACHABLE
àcommit-graph.c
et l'utiliser à la place de UNINTERESTING dans la sectionclose_reachable()
.
Cela corrige le bogue dans les tests manuels.
La récupération depuis plusieurs remotes dans le même dépôt en parallèle avait une mauvaise interaction avec le changement récent pour (optionnellement) mettre à jour le commit-graph après la fin d'un travail de récupération, car ces récupérations parallèles se font concurrence.
Cela a été corrigé avec Git 2.25 (Q1 2020).
Voir le commit 7d8e72b, commit c14e6e7 (03 Nov 2019) par Johannes Schindelin (dscho
).
(Fusionné par Junio C Hamano -- gitster
-- dans le commit bcb06e2, 01 Dec 2019)
fetch
: ajouter l'option de ligne de commande--write-commit-graph
Signé par : Johannes Schindelin
Cette option remplace le paramètre de configuration
fetch.writeCommitGraph
, si les deux sont définis.
Et :
fetch
: éviter les problèmes de verrouillage entre fetch.jobs/fetch.writeCommitGraph.Signé par : Johannes Schindelin
Lorsque les deux
fetch.jobs
etfetch.writeCommitGraph
sont définis, nous essayons actuellement d'écrire le graphe de commit dans chacun des jobs de fetch concurrents, ce qui conduit fréquemment à des messages d'erreur comme celui-ci :fatal: Unable to create '.../.git/objects/info/commit-graphs/commit-graph-chain.lock': File exists.
Évitons cela en retenant l'écriture du graphe de commit jusqu'à ce que tous les jobs de fetch soient terminés.
Le code pour écrire le(s) fichier(s) split commit-graph lors du fetch calculait une valeur bidon pour le paramètre utilisé dans la division des fichiers résultants, ce qui a été corrigé avec Git 2.25 (Q1 2020).
Voir le commit 63020f1 (02 Jan 2020) par Derrick Stolee (derrickstolee
).
(Fusionné par Junio C Hamano -- gitster
-- dans le commit 037f067, 06 Jan 2020)
commit-graph
: prefer defaultsize_mult
lorsqu'on lui donne zéroSigné par : Derrick Stolee
Dans 50f26bd ("
fetch
: add fetch.writeCommitGraph config setting", 2019-09-02, Git v2.24.0-rc0 -- merge listé dans le lot #4), le buildin fetch a ajouté la capacité d'écrire un commit-graph en utilisant le "--split
".
Cette fonctionnalité crée plusieurs fichiers commit-graph, et ceux-ci peuvent fusionner sur la base d'un ensemble d'" options de division ", y compris un multiple de taille.
Le multiple de taille par défaut est de 2, ce qui a pour but de fournir unelog_2
N profondeur de la chaîne commit-graph où N est le nombre de commits.Cependant, j'ai remarqué pendant le dogfooding que mes chaînes commit-graph devenaient assez grandes lorsqu'elles étaient laissées uniquement aux constructions par '
git fetch
'.
Il s'avère que danssplit_graph_merge_strategy()
, nous mettons par défaut lesize_mult
à 2, sauf que nous la surchargeons avec la variable du contextesplit_opts
s'ils existent.
Dansbuiltin/fetch.c
nous créons une tellesplit_opts,
mais ne le remplit pas de valeurs.Ce problème est dû à deux défaillances :
- Il n'est pas clair que l'on puisse ajouter le flag.
COMMIT_GRAPH_WRITE_SPLIT
avec unNULL
split_opts
.- Si nous avons une valeur non NULL
split_opts,
alors nous remplaçons les valeurs par défaut même si une valeur nulle est donnée.Corrigez ces deux problèmes.
- Premièrement, ne remplacez pas
size_mult
lorsque les options fournissent une valeur nulle.- Deuxièmement, arrêtez de créer un
split_opts
dans le builtin fetch.
Notez que git log
a été cassé entre Git 2.22 (mai 2019) et Git 2.27 (Q2 2020), lors de l'utilisation de magic pathspec.
L'analyse syntaxique de la ligne de commande de "git log :/a/b/
" a été cassé pendant environ une année complète sans que personne ne le remarque, ce qui a été corrigé.
Voir le commit 0220461 (10 Apr 2020) par Jeff King (peff
).
Voir le commit 5ff4b92 (10 Avr 2020) par Junio C Hamano (gitster
).
(Fusionné par Junio C Hamano -- gitster
-- dans le commit 95ca489, 22 Apr 2020)
sha1-name
: ne pas supposer que le magasin de ref est initialisé.Signalé par : Érico Rolim
c931ba4e ("
sha1
-name.c`` : supprimerthe_repo
dehandle_one_ref()
", 2019-04-16, Git v2.22.0-rc0 -- la fusion listée dans le lot n°8) a remplacé l'utilisation de la fonctionfor_each_ref()
helper, qui fonctionne avec le magasin de ref principal de l'instance de référentiel par défaut, parrefs_for_each_ref()
, qui peut fonctionner sur n'importe quelle instance de ref store, en supposant que l'instance de référentiel donnée à la fonction a son ref store déjà initialisé.Mais il est possible que personne ne l'ait initialisé, auquel cas, le code finit par déréférencer un fichier
NULL
pointeur.
Et :
repository
: marquer le pointeur "refs" comme privé.Signé par : Jeff King
Le pointeur "refs" d'un dépôt de structure commence sa vie comme suit .
NULL
mais il est ensuite initialisé paresseusement lorsqu'on y accède via la fonctionget_main_ref_store()
.
Cependant, il est facile pour le code appelant d'oublier cela et d'y accéder directement, ce qui conduit à un code qui fonctionne... un peu de du temps, mais échoue s'il est appelé avant que quelqu'un d'autre accède aux refs.C'est la cause du bogue corrigé par 5ff4b920eb ("
sha1-name
: ne pas supposer que le magasin de refs est initialisé", 2020-04-09, Git v2.27.0 -- fusion listée dans le lot #3). Afin d'éviter des bugs similaires, marquons plus clairement le champ "refs" comme privé.
Ma première pensée était d'améliorer votre IO, mais j'ai testé contre le dépôt rails en utilisant un SSD et j'ai obtenu un résultat similaire : 30 secondes.
--numstat
est ce qui ralentit tout, sinon... git-log
peut se terminer en 1 seconde même avec le formatage. Faire un diff est coûteux, donc si vous pouvez supprimer cela de votre processus, cela accélérera énormément les choses. Peut-être le faire après coup.
Sinon, si vous filtrez les entrées du journal en utilisant git-log
's own search facilities that will reduce the number of entries which need to do a diff. Par exemple, git log --grep=foo --numstat
Ils sont dans la docs sous "Commit Limiting". Cela peut réduire considérablement le nombre d'entrées que git doit formater. Les plages de révision, les filtres de date, les filtres d'auteur, l'extraction des messages du journal... tout cela peut améliorer les performances de git-log
sur un grand référentiel tout en effectuant une opération coûteuse.
Vous avez raison, il faut quelque part entre 20 et 35 secondes pour générer le rapport sur 56'000 commits générant 224'000 lignes (15MiB) de sortie. En fait, je pense que c'est une performance assez décente mais vous ne le faites pas ; ok.
Parce que vous générez un rapport en utilisant un format constant à partir d'une base de données immuable, vous ne devez le faire qu'une seule fois. Après, vous pouvez utiliser le résultat mis en cache de git log
et sauter la génération qui prend du temps. Par exemple :
git log --pretty=format:%Ht%aet%ant%att%s --numstat > log-pretty.txt
Vous pourriez vous demander combien de temps il faut pour rechercher dans tout ce rapport les données qui vous intéressent. C'est une question digne d'intérêt :
$ tail -1 log-pretty.txt
30 0 railties/test/webrick_dispatcher_test.rb
$ time grep railties/test/webrick_dispatcher_test.rb log-pretty.txt
…
30 0 railties/test/webrick_dispatcher_test.rb
real 0m0.012s
…
Pas mal, l'introduction d'un "cache" a réduit le temps nécessaire de 35+ secondes à une douzaine de millisecondes. C'est presque 3000 fois plus rapide.