Aller au contenu
Sommaire

GitHealth Une application de bureau

Voir quelles branches comptent, sans toucher au dépôt.

Une application de bureau qui lit un dépôt Git en local, sans jamais l’écrire, et dit pour chaque branche ce qu’on peut en faire, avec la règle qui l’a décidé. Je l’ai conçue et développée seul, et je la publie en open source.

Un dépôt de démonstration de 17 branches : chaque ligne donne l’écart avec main, sa forme (en avance, divergée, fusionnée), l’activité et le verdict. Un clic agrandit l’écran.
Besoin
Savoir quelles branches d’un dépôt Git comptent encore, sans risquer de le modifier.
Ma part
J’ai conçu et développé seul l’application : le produit, l’architecture, l’interface, l’intégration continue et la distribution.
Rôle
Auteur et mainteneur
Période
Depuis août 2026
Équipe
Projet personnel, mené seul
Statut
Open source, version 0.2.0

Discutons de ce projet

Les verdicts

Un verdict par branche, et la règle qui l’a donné

L’application compare chaque branche à une base, ici main : les commits qu’elle a en plus et ceux qui lui manquent, ce qu’on appelle sa topologie, puis la date de son dernier commit. Elle en tire un verdict, et la fiche de la branche dit, règle par règle, comment elle l’a obtenu.

Pas de note globale : les faits d’un côté, leur lecture de l’autre. Et aucun verdict ne lance de commande Git : la suppression reste à copier, à la main.

Keep
elle porte des commits que la base n’a pas, n’a aucun retard sur elle, et n’est pas inactive.
Done
fusionnée ou au même commit que la base, dernier commit d’il y a 7 jours au plus : rien à faire pour l’instant.
Review
divergée, sans ancêtre commun, inactive, ou fusionnée (ou au même commit que la base) avec un dernier commit de 7 à 30 jours.
Cleanup possible
fusionnée ou au même commit que la base, sans commit depuis plus de 30 jours : la supprimer ne perd aucun commit.
Excluded
écartée par un motif protégé ou exclu de la politique.
Trois branches d’un même tronc, chacune avec son verdict : garder, revoir ou nettoyer. Trois branches d’un même tronc, chacune avec son verdict : garder, revoir ou nettoyer.
La fiche de la branche feature/advanced-search : verdict Review, puis les règles appliquées, de la divergence (+3 / −12) à l’âge du dernier commit.
Dernier commit il y a 55 jours, entre les seuils de 30 et 90 jours : la règle est écrite en clair, avec ses seuils.

La politique

Régler la politique, voir l’effet avant d’enregistrer

Chaque dépôt a sa politique : deux seuils d’activité, 30 et 90 jours par défaut, des motifs de branches protégées ou exclues, et jusqu’à huit bases de comparaison.

Avant d’enregistrer, un panneau projette la politique sur la dernière analyse, sans relancer Git. Enregistrer change la lecture, jamais les faits relevés.

Deux motifs ajoutés, pas encore enregistrés : trois branches passeraient de Review à Excluded.

L’analyse en direct

Regarder l’analyse lire le dépôt

Pendant l’analyse, l’écran montre chaque commande Git qu’elle lance, au moment où elle la lance.

Toutes sont des lectures : six commandes Git différentes suffisent à l’analyse entière, quel que soit le nombre d’appels, et aucune ne récupère ni n’écrit quoi que ce soit. C’est le but de cet écran : la lecture seule se vérifie, au lieu de se croire.

Une analyse en cours sur 169 branches, à mi-chemin : le registre se remplit, la carte des branches se dessine et la console liste les commandes git merge-base lancées.
Une analyse prise en cours, à 106 branches sur 169 : la loupe montre deux appels à git merge-base, chacun avec sa durée en millisecondes.

Les visualisations

Tout le dépôt d’un coup d’œil

L’onglet Visualisation lit une analyse de trois façons : une carte, un registre d’activité, et la dérive entre deux analyses.

La carte des branches : plus un trait est long, plus la branche s’est éloignée de main.
Le registre d’activité : deux curseurs déplacent les seuils et relisent chaque verdict, sans rien enregistrer.

Sous le capot

Quatre choix qui ne se voient pas à l’écran, et ce qu’ils garantissent ; chacun se déplie sur son extrait du code public.

  1. Git en lecture seule, sans réseau ni identifiants code
    Contrainte
    Un diagnostic ne doit jamais devenir une modification du dépôt observé.
    Choix
    Git en ligne de commande, lancé sans passer par un interpréteur de commandes et limité à six commandes de lecture différentes ; chaque appel coupe le réseau, les identifiants et la maintenance automatique.
    Effet
    Un test de bout en bout relève l’empreinte du dépôt avant et après tout le parcours : références, journaux, index et copie de travail restent identiques.
    Le test d’empreinte
    src/App.GitHealth.Api/Git/Process/GitProcessRunner.cs · C#
    arguments.Add("--no-pager");
    AddConfiguration(arguments, "color.ui=false");
    AddConfiguration(arguments, "protocol.allow=never");
    AddConfiguration(arguments, "protocol.file.allow=never");
    AddConfiguration(arguments, "credential.helper=");
    AddConfiguration(arguments, "core.fsmonitor=false");
    AddConfiguration(arguments, "mailmap.file=");
    AddConfiguration(arguments, "maintenance.auto=false");
    AddConfiguration(arguments, "gc.auto=0");
    AddConfiguration(arguments, "fetch.writeCommitGraph=false");
  2. Un seul processus, une seule adresse locale code
    Contrainte
    Livrer une application de bureau sur trois systèmes sans surveiller deux processus.
    Choix
    Le serveur sert l’API et l’interface à une seule adresse locale, et ouvre la fenêtre du système dans le même processus.
    Effet
    Un seul processus et une seule adresse locale ; l’installation se fait pour l’utilisateur, sans droits d’administrateur.
    Les choix de structure
    docs/ARCHITECTURE.md · Markdown
    | Host | ASP.NET Core serves the API and the Angular files | One process, one port and one origin |
    | Main execution | Self-contained .NET executable | Direct access to the machine's repositories |
    | Desktop shell | Photino inside the host process | No child process to supervise |
    | Distribution | Velopack, per-user installation | No UAC, data outside the installation |
  3. La position de toutes les branches en un appel code
    Contrainte
    Rester rapide sur un dépôt de plusieurs centaines de branches.
    Choix
    La position de toutes les branches par rapport à main se calcule en un seul appel à Git, avec un repli au parallélisme borné pour les versions anciennes ; un banc de mesure tient des budgets de durée.
    Effet
    La position de 1 000 branches par rapport à main se lit en 231 ms dans 95 % des mesures, pour un budget de 850 ms. Reste l’étape la plus longue, le relevé des auteurs de chaque branche : environ 26 ms par branche sur le même banc.
    Le banc de la version 0.2.0
    src/App.GitHealth.Api/Git/Scanning/GitTopologyReader.cs · C#
    var format = "%(refname)%00%(objectname)%00" +
        $"%(ahead-behind:{scan.Reference.Commit.Value})%00";
    return RunAsync(
        scan.Repository.Context,
        ["for-each-ref", "--sort=refname", $"--format={format}",
            "refs/heads", "refs/remotes"],
        cancellationToken);
  4. Un assistant IA facultatif, qui ne lit qu’une analyse code
    Contrainte
    Un agent IA peut aider à lire un diagnostic, sans toucher au dépôt ni recevoir de données sans accord.
    Choix
    Un accord par dépôt, vérifié par l’API. L’agent tourne dans un dossier vide, en lecture seule, et n’interroge qu’une analyse enregistrée, avec un jeton valable le temps d’une exécution.
    Effet
    C’est la seule fonction qui envoie des données du dépôt hors de la machine, et elle reste facultative ; la lecture seule tient même si l’agent est un programme tiers.
    L’architecture de l’assistant
    docs/ARCHITECTURE.md · Markdown
    | Agent input | A read-only tool bridge over a stored capture | The agent queries measurements; it never opens the repository |
    | Agent authorisation | One 256-bit token per run, closed when it settles | A capture is reachable only while its run is alive |
    | Agent sandbox | Empty scratch directory, the CLI's read-only mode | The read-only guarantee survives a foreign process |
    | Assistant consent | A moment stored on the project, checked by the API | The screen asks; the API is what refuses |

Aujourd’hui

La version 0.2.0, publiée le 14/09/2026, est livrée pour quatre cibles natives : Windows, macOS Intel et Apple Silicon, et Linux. Elle s’installe sous Windows et macOS, et tourne aussi sous Linux. La suite avance sur la branche de développement : l’analyse planifiée et une API locale y attendent leur version.

Sources et méthode : chiffres, dates, méthode et crédits

Chiffres. Le banc de la version 0.2.0, sur un serveur d’intégration Windows hébergé : 1 000 branches, topologie lue en 231 ms au 95e centile, pour un budget de 850 ms, et relevé des auteurs en 25,8 s, soit environ 26 ms par branche (rapport de la version 0.2.0). Les six commandes Git différentes de l’analyse (for-each-ref, rev-list, merge-base, log, cat-file et rev-parse) viennent des limites connues du dépôt, et les options de chaque appel, de son lanceur de processus. Les quatre cibles sont celles de la publication des versions. Relevés le 14/10/2026, aux révisions 4cd740d (version 0.2.0) et bd2e5c9.

Écrans. Six vues réelles de l’application, lancée en local le 14/10/2026 sur des dépôts Git de démonstration fabriqués pour l’occasion : auteurs fictifs, aucune donnée réelle, interface ni retouchée ni recomposée. L’application capturée vient de la branche de développement (révision bd2e5c9 du 16/09/2026) : le numéro de version affiché est 0.2.0, mais l’engrenage de la barre du haut et l’analyse planifiée, en bas de l’écran de politique, ne sont pas encore publiés. Tout le reste existe dans la 0.2.0.

Verdicts et politique. L’échelle des verdicts, dont l’échelle courte des branches fusionnées, vient du guide de l’utilisateur ; l’effet projeté de la politique, du même guide ; la séparation des faits et de leur lecture, de l’architecture. La console de l’analyse et l’onglet Visualisation sont décrits dans les notes de la 0.2.0 : la console, les visualisations. La topologie en un seul appel est dans le code.

Le projet. Dépôt public sous licence MIT, commencé le 28/08/2026 : 159 commits de ma main et 11 de Dependabot à la révision bd2e5c9. Versions 0.1.0 (31/08/2026) et 0.2.0 (14/09/2026). L’interface de l’application est en anglais.

Sous le capot. Extraits de la branche de développement, révision bd2e5c9, relus le 15/10/2026.