libgit2 / libgit2/libgit2sharp

RewriteHistory extremely slow

Ouverte
#1,684 6 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Langage dominant
C#
Étoiles
3.5k
Forks
925
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

Reproduction steps

Find a repo with 3000+ commits
Run the below code against that repo to rewrite the repo history:

private static void RewriteHistory(string repoPath, ICollection<string> subFolders)
{
    using (var repo = new Repository(repoPath))
    {
        var refs = repo.Refs.Where(r => r.CanonicalName.EndsWith("develop")).OrderBy(r => r.CanonicalName).ToList();
        var commits = repo.Commits.QueryBy(new CommitFilter { IncludeReachableFrom = refs }).ToArray();
        var count = 0;
        var stopwatch = Stopwatch.StartNew();

        Logger.InfoFormat("Found {0} commits", commits.Length);
        Logger.InfoFormat("Rewrite history started");

        repo.Refs.RewriteHistory(new RewriteHistoryOptions
        {
            OnError = OnError,
            OnSucceeding = OnSucceeding,
            PruneEmptyCommits = true,
            CommitTreeRewriter = commit =>
            {
                Logger.InfoFormat("Commit {0}/{1}", ++count, commits.Length);

                var tree = TreeDefinition.From(commit);
                foreach (var treeEntry in commit.Tree)
                {
                    var match = subFolders.FirstOrDefault(s => treeEntry.Path.StartsWithIgnoreCase(s));

                    if (match == null)
                        tree.Remove(treeEntry.Path);
                }

                return tree;
            }
        }, commits);
        Logger.InfoFormat("Rewrite history ended. Took {0}", stopwatch.Elapsed);

        repo.Reset(ResetMode.Hard, repo.Head.Commits.First());
    }
}
Expected behavior

This should take a reasonable time. I expect it to take a few minutes for sure but not hours. For example when running something similar in git from the command like it takes minutes. I'm sorry I don't have specific times but I can try to provide more data to compare performance if necessary.

Actual behavior

This takes 1h 43 minutes of which 1h 40 to just start the rewrite and about a couple of minutes to go through all the commits.
INFO : Found 3486 commits
INFO : Rewrite history started
[between these two log messages there is a 1h 40m gap]
INFO : Commit 1/3486
INFO : Commit 2/3486
...
INFO : Rewrite history ended. Took 01:43:51.5536779

Version of LibGit2Sharp (release number or SHA1)

0.26.0 + 2.0.267 (native)

Operating system(s) tested; .NET runtime tested

.net 4.6.1 - Win 2012R2

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par reproduire le rapport avec un dépôt contenant plus de 3 000 commits et mesurez le délai entre « Rewrite history started » et le premier callback de CommitTreeRewriter. Inspectez l’appel à RewriteHistory et la configuration de CommitTreeRewriter présentés dans l’issue. Le travail est considéré comme terminé lorsque la même réécriture de l’historique s’achève en quelques minutes plutôt qu’en plusieurs heures, tout en conservant le comportement de pruning signalé.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
csharp, git
Domaine
devtools, performance
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.