roselletabuena/git-atomic-commit

Divisez les modifications de l'arbre de travail en commits git atomiques et ciblés : examinez ce qui a changé, regroupez en unités logiques, ordonnez-les pour que chaque commit construise, et rédigez des messages qui correspondent au style existant du dépôt.

Qu'est-ce que git-atomic-commit ?

Cette compétence permet de transformer un ensemble de modifications non triées dans l'arbre de travail en une série de commits git atomiques, chacun contenant exactement un changement logique. Elle met en avant trois bénéfices concrets : la revue de code facilitée (un seul concept à juger), la réversibilité propre (annuler un mauvais changement sans perdre les bons), et le `git bisect` fiable (chaque commit construit et peut être pointé comme source d'un bug). Le workflow guide l'utilisateur en six étapes : (1) inspecter l'arbre complet avec `git status` et `git diff`, (2) regrouper les changements en unités logiques (en évitant le mot « et » dans le sujet du commit), (3) ordonner les commits pour que chacun laisse l'arbre fonctionnel, (4) staging chaque groupe avec la technique la moins invasive (fichiers entiers, stash, ou découpage intra-fichier via un fichier de référence spécifique), (5) rédiger les messages dans le style local (Conventional Commits, préfixes de ticket, capitalisation, etc.) sans inventer d'identifiants, et (6) vérifier le résultat avec `git log` et `git diff --cached`. Elle inclut des garde-fous importants : ne pas commiter si l'utilisateur ne l'a pas demandé, ne jamais jeter du travail non commité (`git checkout -- <file>` est interdit sans sauvegarde), ne pas réécrire l'historique publié sans autorisation, ne pas trop découper au point de casser la construction, et reconnaître quand un seul commit suffit. La compétence est conçue pour les environnements non interactifs où `git add -p` échoue silencieusement, et fournit des alternatives robustes.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/roselletabuena/skills/tree/HEAD/plugins/git-workflows/skills/git-atomic-commit

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Commits atomiques

Un commit atomique contient exactement un changement logique. Il ne s'agit pas de propreté pour la propreté — il s'agit de trois capacités concrètes que l'équipe perd lorsque les commits sont mélangés :

  • Revue : un relecteur peut garder une seule idée en tête et la juger.
  • Réversion : un mauvais changement peut être annulé sans emporter les bons changements avec lui.
  • Bisect : git bisect peut nommer le commit qui a introduit un bogue, ce qui ne fonctionne que si chaque commit est un changement et que chaque commit construit.

Cette dernière clause est la plus souvent oubliée. Atomique ne signifie pas « aussi petit que possible » — cela signifie « un changement complet ». Un commit qui sépare une fonction du site d'appel qu'elle nécessite est plus petit mais pas atomique, car il laisse l'arbre cassé.

Le workflow

1. Examiner avant de staging quoi que ce soit

Comprendre l'arbre entier avant de décider comment le diviser :

git status --porcelain      # chaque chemin, y compris les non suivis
git diff                    # modifications non stagées
git diff --cached           # tout ce qui est déjà stagé
git log --oneline -15       # où se trouve HEAD, et le style local

Résistez à git add -A et git commit -a comme premier geste. Ils sont la façon dont un arbre mélangé devient un commit mélangé, et une fois commité, le diviser est strictement plus de travail que de le diviser avant. Vérifiez également les modifications qui ne devraient pas du tout être commitées — sortie de build, fichiers .env, instructions de débogage, un fichier de configuration d'éditeur égaré.

2. Regrouper les modifications en unités logiques

Le test le plus fiable est linguistique : rédigez le sujet du commit, et s'il a besoin d'un « et » pour être exact, vous avez plus d'un commit. « Correction de la redirection de connexion et mise à jour de lodash » en fait deux. La question du relecteur est le deuxième test : devraient-ils comprendre le changement X pour juger le changement Y ? Si non, les modifications sont indépendantes et appartiennent à des commits séparés.

Séparer :

Garder séparéPourquoi
Formatage / espaces vs. logiqueUn reformatage enterre les trois vraies lignes dans 400 lignes de bruit. C'est la séparation la plus précieuse.
Renommages vs. changements de comportementMême raison — un renommage touche tout et cache la seule ligne qui compte.
Mises à jour de dépendances vs. codeChacune a besoin de sa propre histoire de réversion.
Corrections de bogues non liéesRéversions indépendantes, bisects indépendants.
Refactorisation vs. la fonctionnalité qui l'utilisePermet à un relecteur de confirmer que la refactorisation préserve le comportement.

Garder ensemble :

Garder dans un seul commitPourquoi
Un changement et ses testsIls forment une unité logique ; des tests pour du code non livré, ou du code sans tests, c'est chaque moitié d'un changement.
Un renommage et tous ses sites d'appelLa séparation laisse l'arbre cassé — le contraire d'atomique.
Un changement de signature et ses appelantsIdem.
Un changement et la documentation/changelog qui le décritIls décrivent la même décision et devraient être réversés ensemble.

3. Ordonner les commits pour que chacun construise

L'ordre compte car chaque commit doit laisser l'arbre fonctionnel. Placez les fondations avant les choses qui les utilisent : ajoutez l'assistant avant le code qui l'appelle, faites la refactorisation avant la fonctionnalité construite dessus, déposez le schéma avant la requête. Si deux groupes sont mutuellement dépendants, c'est le signe qu'ils ne forment en réalité qu'un seul commit.

4. Stager chaque groupe

Utilisez la technique la moins invasive qui fonctionne. Ne montez en puissance que lorsque la plus simple ne peut pas exprimer la séparation :

Niveau 1 — stager des fichiers entiers. Cela couvre la grande majorité des séparations réelles, car les changements logiques vivent généralement dans des fichiers différents :

git add src/auth.py tests/test_auth.py
git commit -m "..."

Niveau 2 — mettre de côté des fichiers entiers lorsque quelque chose dans l'arbre pourrait autrement être facilement commité par accident :

git stash push -- requirements.txt    # mettre de côté
# ... commiter le reste ...
git stash pop                         # le ramener

Niveau 3 — diviser les modifications à l'intérieur d'un seul fichier. Nécessaire seulement quand un fichier contient vraiment deux changements logiques. La mécanique est délicate et facile à mal faire subtilement, donc lisez references/splitting-one-file.md avant d'essayer.

git add -p ne fonctionne pas dans les environnements non interactifs, et échoue silencieusement. Il affiche la première section, atteint EOF sur stdin, ne stage rien, et se termine avec 0. Un code de sortie réussi signifie ici que rien ne s'est passé. La même chose s'applique à git add -i, git commit -p et git checkout -p. Parce que l'échec ressemble à un succès, le dégât est généralement un commit vide ou manquant le changement prévu — utilisez donc les techniques du fichier de référence à la place, et vérifiez l'index avec git diff --cached avant de commiter.

5. Rédiger chaque message dans la voix du dépôt

Adaptez-vous à l'historique environnant plutôt que d'importer une convention. Un préfixe feat: dans un journal de sujets en prose simple est du bruit, et donne l'impression que l'historique vient de deux projets. Lisez d'abord le style local :

git log --no-merges --format='%s' -n 30               # style des sujets
git log --no-merges -n 10 --format='%n---%n%s%n%b'    # si les corps sont utilisés

Cherchez : un préfixe type: ou type(scope): (Conventional Commits), un préfixe de ticket comme [PROJ-123], la capitalisation, l'impératif vs. le passé (« Ajouter » vs. « Ajouté »), la longueur typique du sujet, et si les corps sont normaux ou les sujets suffisent seuls. Adoptez ce que vous trouvez. Conventional Commits est un bon défaut seulement lorsque le journal l'utilise déjà, ou que le dépôt n'a pas encore d'historique et que l'utilisateur n'a pas de préférence.

Quel que soit le style local, le sujet doit dire ce qui a changé et le corps — lorsque l'historique utilise des corps — doit dire pourquoi, puisque le diff montre déjà le quoi. Si le dépôt a un fichier CONTRIBUTING.md ou un hook commit-msg, ceux-ci remplacent l'inférence à partir du journal.

Respecter une convention ne signifie jamais inventer les données qu'elle porte. Si le style local intègre une référence de ticket ou de problème — [PROJ-123], Fixes #456 — et que vous n'avez pas reçu l'identifiant réel, n'en inventez pas un et ne continuez pas la numérotation que vous voyez dans le journal. Un [PROJ-124] plausible est pire que pas de préfixe du tout : il est permanent, il donne l'impression d'une traçabilité réelle, et il pointe probablement vers un ticket non lié de quelqu'un d'autre. Omettez la référence, adaptez le reste du style, et dites dans votre réponse que l'ID manque pour que l'utilisateur puisse le fournir — le commit n'est toujours pas poussé et facile à amender. Demandez le numéro si l'utilisateur est là pour le donner.

6. Vérifier avant de rendre la main

git log --oneline -n <count>     # la forme de ce que vous avez construit
git status --porcelain           # ce qui reste, le cas échéant

Confirmez que chaque commit ne contient que son propre changement (git show --stat <sha>), et que rien n'a été laissé de côté. Si des modifications restent non commitées intentionnellement, dites-le explicitement — un arbre que l'utilisateur croyait propre mais qui ne l'est pas est le pire résultat ici, car il le découvrira plus tard et ne saura pas si c'était délibéré.

Garde-fous

  • Façonnez comment commiter, pas si commiter. Si l'utilisateur n'a pas demandé de commit, cette compétence ne rend pas approprié d'en créer un, et elle n'implique jamais de pousser.
  • Ne jetez jamais de travail pour faciliter une séparation. git checkout -- <file>, git reset --hard et git stash drop détruisent le travail non commité qu'aucun commit ne contient encore — il est irrécupérable. Si une technique nécessite l'un d'eux, sauvegardez d'abord le contenu et confirmez que la sauvegarde existe avant de l'exécuter.
  • Ne réécrivez pas l'historique publié pour le nettoyer. Diviser des commits déjà poussés signifie un force-push qui réécrit l'historique que d'autres ont pu tirer ; demandez d'abord.
  • Ne sur-divisez pas pour paraître minutieux. Trois commits qui cassent chacun la construction sont pires qu'un seul qui fonctionne. En cas de doute, préférez le regroupement qui maintient chaque commit fonctionnel.
  • Si l'arbre s'avère contenir un seul changement logique, commitez-le en un seul. Tous les arbres n'ont pas besoin d'être divisés, et le dire est un excellent résultat.

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

Skills associés