libgit2 / libgit2/libgit2sharp
[RFC] Batched low level index operations
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- C#
- Estrellas
- 3.5k
- Forks
- 925
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Descripción
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?
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Lea primero PR #907 y los puntos de entrada existentes Index.Add() e Index.Remove(). Compare la API propuesta de Index.Update/IndexUpdater con el requisito de que el repositorio permanezca coherente entre llamadas; darlo por terminado requeriría un diseño aprobado por un maintainer y un alcance de implementación definido, algo que este RFC todavía no proporciona.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- csharp, git
- Área
- backend-api-design
- Tipo de issue
- Nueva funcionalidad
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Estado de actividad
- Estancado
- Claridad
- Necesita aclaración
- Aptitud para principiantes
- 25/100