libgit2 / libgit2/libgit2sharp

[RFC] Batched low level index operations

Abierto
#908 1 comentario 0 reacciones 0 asignados Ver en GitHub

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

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. 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

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.