libgit2 / libgit2/libgit2sharp
[RFC] Batched low level index operations
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
In the light of https://github.com/libgit2/libgit2sharp/pull/907, I was wondering if we should take this approach one step further.
Each call to repo.Stage() will
- Perform a diff between the working directory and the Index in order to determine what additions/removals should be promoted to the staging area
- Perform additions/deletions in the in memory Index
- Eventually persist the in memory Index to the disk
Each call to repo.Index.Add() (or Remove()) will
- Perform an addition (or a deletion) in the in memory Index
- Persist the in memory Index to the disk
As such, invoking repo.Index.Add() or repo.Index.Remove() will be more efficient than a call to repo.Stage().
We want to allow the user to switch to the command line git.git, between each call to LibGit2Sharp, and find the repository in a coherent state. This is the requirement that compels us to persist the in-memory Index at the very end of each Index related method.
However, would clients of the library require to perform many sequential calls to the lower level methods repo.Index.Add()|Remove(), the Index would be persisted as part of each call. Which may not be very efficient.
Considering this above, would a need for an IndexUpdater exist?
We may expose something like in the Index type:
public virtual void Update(params Action<IndexUpdater>[] actions)
which would allow the client to write such code:
repo.Index.Update(i => i.Add(path), i => i.Remove(otherPath))
Or even some more elaborate custom thingies such as
private void StageAllAdditionsRemovalsAndModifications(IRepository repo)
{
// Compare the Workdir against the Index without attempting at detecting Copies/Renames
var changes = repo.Diff.Compare<TreeChanges>(null, true,
compareOptions: new CompareOptions { Similarity = SimilarityOptions.None });
repo.Index.Update(i =>
{
// We first clean the Index from unwanted entries...
foreach (TreeEntryChanges treeEntryChanges in changes
.Where(tec => tec.Status == ChangeKind.Deleted))
{
i.Remove(treeEntryChanges.Path);
}
// ...then insert in the Index the additions/modifications.
foreach (TreeEntryChanges treeEntryChanges in changes
.Where(tec => tec.Status == ChangeKind.Added || tec.Status == ChangeKind.Modified))
{
i.Add(treeEntryChanges.Path);
}
});
}
And allow us to only persist the Index only once, when all the actions have been performed by the IndexUpdater.
Thoughts?
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Lisez d’abord PR #907 ainsi que les points d’entrée existants Index.Add() et Index.Remove(). Comparez l’API proposée de Index.Update/IndexUpdater avec l’exigence que le dépôt reste cohérent entre les appels ; considérer cela comme terminé nécessiterait une conception approuvée par un maintainer et un périmètre d’implémentation défini, ce que ce RFC ne fournit pas encore.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- csharp, git
- Domaine
- backend-api-design
- Type d'issue
- Fonctionnalité
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- À l'abandon
- Clarté
- À clarifier
- Accessibilité débutants
- 25/100