Files
gh-wasabeef-claude-code-coo…/commands/semantic-commit.md
2025-11-30 09:05:34 +08:00

32 KiB
Raw Permalink Blame History

Commit sémantique

Divise les gros changements en petits commits significatifs avec des messages appropriés. Utilise uniquement des commandes git standard.

Utilisation

/semantic-commit [options]

Options

  • --dry-run : Afficher les divisions de commits proposées sans réellement committer
  • --lang <langue> : Forcer la langue pour les messages de commit (en, fr)
  • --max-commits <nombre> : Spécifier le nombre maximum de commits (défaut : 10)

Exemples de base

# Analyser les changements actuels et committer en unités logiques
/semantic-commit

# Vérifier uniquement la proposition de division (pas de commit réel)
/semantic-commit --dry-run

# Générer les messages de commit en anglais
/semantic-commit --lang en

# Générer les messages de commit en français
/semantic-commit --lang fr

# Diviser en maximum 5 commits
/semantic-commit --max-commits 5

Comment ça fonctionne

  1. Analyser les changements : Vérifier ce qui a changé avec git diff HEAD
  2. Grouper les fichiers : Assembler les fichiers liés
  3. Créer les messages : Écrire des messages de commit sémantiques pour chaque groupe
  4. Committer étape par étape : Committer chaque groupe après votre approbation

Quand diviser les changements

Ce qui rend un changement "important"

Nous divisons quand nous voyons :

  1. Nombreux fichiers : 5+ fichiers modifiés
  2. Nombreuses lignes : 100+ lignes modifiées
  3. Multiples fonctionnalités : Changements dans 2+ zones
  4. Types mixtes : feat + fix + docs ensemble
# Analyser l'échelle du changement
CHANGED_FILES=$(git diff HEAD --name-only | wc -l)
CHANGED_LINES=$(git diff HEAD --stat | tail -1 | grep -o '[0-9]\+ insertions\|[0-9]\+ deletions' | awk '{sum+=$1} END {print sum}')

if [ $CHANGED_FILES -ge 5 ] || [ $CHANGED_LINES -ge 100 ]; then
  echo "Changement important détecté : division recommandée"
fi

Comment diviser en petits commits significatifs

1. Division par limites fonctionnelles
# Identifier les unités fonctionnelles à partir de la structure des répertoires
git diff HEAD --name-only | cut -d'/' -f1-2 | sort | uniq
# → src/auth, src/api, components/ui, etc.
2. Séparation par type de changement
# Nouveaux fichiers vs modifications de fichiers existants
git diff HEAD --name-status | grep '^A' # Nouveaux fichiers
git diff HEAD --name-status | grep '^M' # Fichiers modifiés
git diff HEAD --name-status | grep '^D' # Fichiers supprimés
3. Analyse des dépendances
# Détecter les changements de relations d'import
git diff HEAD | grep -E '^[+-].*import|^[+-].*require' | \
cut -d' ' -f2- | sort | uniq

Analyse détaillée des fichiers

# Obtenir la liste des fichiers modifiés
git diff HEAD --name-only

# Analyser les changements de chaque fichier individuellement
git diff HEAD -- <fichier>

# Déterminer le type de changement pour les fichiers
git diff HEAD --name-status | while read status file; do
  case $status in
    A) echo "$file: Nouvelle création" ;;
    M) echo "$file: Modification" ;;
    D) echo "$file: Suppression" ;;
    R*) echo "$file: Renommé" ;;
  esac
done

Comment grouper les fichiers

  1. Par fonctionnalité : Garder les fonctions liées ensemble

    • Fichiers src/auth/ → Authentification
    • Fichiers components/ → Composants UI
  2. Par type : Même type de changements

    • Tests uniquement → test:
    • Documentation uniquement → docs:
    • Configuration uniquement → chore:
  3. Par dépendances : Fichiers qui ont besoin les uns des autres

    • Modèle + Migration
    • Composant + Style
  4. Par taille : Garder les commits gérables

    • Max 10 fichiers par commit
    • Garder les fichiers liés ensemble

Exemple de sortie

$ /semantic-commit

Analyse des changements...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Changements détectés :
• src/auth/login.ts (modifié)
• src/auth/register.ts (nouveau)
• src/auth/types.ts (modifié)
• tests/auth.test.ts (nouveau)
• docs/authentication.md (nouveau)

Divisions de commits proposées :

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Commit 1/3
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Message : feat: implémenter système d'enregistrement et connexion utilisateur
Fichiers inclus :
  • src/auth/login.ts
  • src/auth/register.ts
  • src/auth/types.ts

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Commit 2/3
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Message : test: ajouter tests complets pour système d'authentification
Fichiers inclus :
  • tests/auth.test.ts

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Commit 3/3
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Message : docs: ajouter documentation du système d'authentification
Fichiers inclus :
  • docs/authentication.md

Exécuter le commit avec ce plan de division ? (y/n/edit):

Vos options

  • y : Procéder avec la division proposée
  • n : Tout annuler
  • edit : Changer les messages de commit
  • merge <numéro1> <numéro2> : Combiner les commits
  • split <numéro> : Diviser davantage un commit

Mode Dry Run

$ /semantic-commit --dry-run

Analyse des changements... (DRY RUN)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[Affichage de la proposition de division de commit]

  Mode DRY RUN : Aucun commit réel ne sera exécuté
💡 Pour exécuter, relancez sans l'option --dry-run

Fonctionnalités intelligentes

1. Comprend votre projet

  • Détecte le type de projet à partir des fichiers de configuration
  • Détermine les fonctionnalités à partir de la structure des dossiers

2. Reconnaissance de patterns de changement

# Détecter les patterns de correction de bugs
- Mots-clés comme "fix", "bug", "error"
- Ajout de gestion d'exceptions
- Corrections de branches de conditions

# Détecter les patterns de nouvelles fonctionnalités
- Création de nouveaux fichiers
- Ajouts de nouvelles méthodes
- Ajouts de points de terminaison API

3. Analyse des dépendances

  • Changements dans les déclarations d'import
  • Ajout/modification de définitions de types
  • Relation avec les fichiers de configuration

Comment c'est construit

Commits étape par étape avec Git

1. Préprocessing : Sauvegarder l'état actuel
# Réinitialiser les changements non stagés s'il y en a
git reset HEAD
git status --porcelain > /tmp/original_state.txt

# Vérifier la branche de travail
CURRENT_BRANCH=$(git branch --show-current)
echo "Branche de travail : $CURRENT_BRANCH"
2. Exécution séquentielle de commits par groupe
# Lire le plan de division
while IFS= read -r commit_plan; do
  group_num=$(echo "$commit_plan" | cut -d':' -f1)
  files=$(echo "$commit_plan" | cut -d':' -f2- | tr ' ' '\n')

  echo "=== Exécution du commit $group_num ==="

  # Stager uniquement les fichiers pertinents
  echo "$files" | while read file; do
    if [ -f "$file" ]; then
      git add "$file"
      echo "Stagé : $file"
    fi
  done

  # Vérifier le statut de staging
  staged_files=$(git diff --staged --name-only)
  if [ -z "$staged_files" ]; then
    echo "Attention : Aucun fichier stagé"
    continue
  fi

  # Générer le message de commit (analyse LLM)
  commit_msg=$(generate_commit_message_for_staged_files)

  # Confirmation utilisateur
  echo "Message de commit proposé : $commit_msg"
  echo "Fichiers stagés :"
  echo "$staged_files"
  read -p "Exécuter ce commit ? (y/n) : " confirm

  if [ "$confirm" = "y" ]; then
    # Exécuter le commit
    git commit -m "$commit_msg"
    echo "✅ Commit $group_num terminé"
  else
    # Annuler le staging
    git reset HEAD
    echo "❌ Commit $group_num ignoré"
  fi

done < /tmp/commit_plan.txt
3. Gestion d'erreurs et rollback
# Gérer les échecs de hooks pre-commit
commit_with_retry() {
  local commit_msg="$1"
  local max_retries=2
  local retry_count=0

  while [ $retry_count -lt $max_retries ]; do
    if git commit -m "$commit_msg"; then
      echo "✅ Commit réussi"
      return 0
    else
      echo "❌ Échec du commit (tentative $((retry_count + 1))/$max_retries)"

      # Incorporer les corrections automatiques des hooks pre-commit
      if git diff --staged --quiet; then
        echo "Changements automatiquement corrigés par le hook pre-commit"
        git add -u
      fi

      retry_count=$((retry_count + 1))
    fi
  done

  echo "❌ Échec du commit. Veuillez vérifier manuellement."
  return 1
}

# Récupérer des interruptions
resume_from_failure() {
  echo "Processus de commit interrompu détecté"
  echo "Statut de staging actuel :"
  git status --porcelain

  read -p "Continuer le traitement ? (y/n) : " resume
  if [ "$resume" = "y" ]; then
    # Reprendre depuis le dernier commit
    last_commit=$(git log --oneline -1 --pretty=format:"%s")
    echo "Dernier commit : $last_commit"
  else
    # Réinitialisation complète
    git reset HEAD
    echo "Processus réinitialisé"
  fi
}
4. Vérification post-complétion
# Vérifier que tous les changements ont été committés
remaining_changes=$(git status --porcelain | wc -l)
if [ $remaining_changes -eq 0 ]; then
  echo "✅ Tous les changements committés"
else
  echo "⚠️  Changements non committés restants :"
  git status --short
fi

# Afficher l'historique des commits
echo "Commits créés :"
git log --oneline -n 10 --graph
5. Supprimer le push automatique
# Note : Pas de push automatique
echo "📝 Note : Push automatique non effectué"
echo "Si nécessaire, pushez avec la commande suivante :"
echo "  git push origin $CURRENT_BRANCH"

Détails de l'algorithme de division

Étape 1 : Analyse initiale
# Obtenir et classifier tous les fichiers modifiés
git diff HEAD --name-status | while read status file; do
  echo "$status:$file"
done > /tmp/changes.txt

# Statistiques des changements par répertoire fonctionnel
git diff HEAD --name-only | cut -d'/' -f1-2 | sort | uniq -c
Étape 2 : Groupement initial par limites fonctionnelles
# Groupement basé sur les répertoires
GROUPS=$(git diff HEAD --name-only | cut -d'/' -f1-2 | sort | uniq)
for group in $GROUPS; do
  echo "=== Groupe : $group ==="
  git diff HEAD --name-only | grep "^$group" | head -10
done
Étape 3 : Analyser la similarité des changements
# Analyser le type de changement pour chaque fichier
git diff HEAD --name-only | while read file; do
  # Détecter les ajouts de nouvelles fonctions/classes
  NEW_FUNCTIONS=$(git diff HEAD -- "$file" | grep -c '^+.*function\|^+.*class\|^+.*def ')

  # Détecter les patterns de correction de bugs
  BUG_FIXES=$(git diff HEAD -- "$file" | grep -c '^+.*fix\|^+.*bug\|^-.*error')

  # Déterminer si c'est un fichier de test
  if [[ "$file" =~ test|spec ]]; then
    echo "$file: TEST"
  elif [ $NEW_FUNCTIONS -gt 0 ]; then
    echo "$file: FEAT"
  elif [ $BUG_FIXES -gt 0 ]; then
    echo "$file: FIX"
  else
    echo "$file: REFACTOR"
  fi
done
Étape 4 : Ajustements basés sur les dépendances
# Analyser les relations d'import
git diff HEAD | grep -E '^[+-].*import|^[+-].*from.*import' | \
while read line; do
  echo "$line" | sed 's/^[+-]//' | awk '{print $2}'
done | sort | uniq > /tmp/imports.txt

# Grouper les fichiers liés
git diff HEAD --name-only | while read file; do
  basename=$(basename "$file" .js .ts .py)
  related=$(git diff HEAD --name-only | grep "$basename" | grep -v "^$file$")
  if [ -n "$related" ]; then
    echo "Fichiers liés : $file <-> $related"
  fi
done
Étape 5 : Optimisation de la taille des commits
# Ajuster la taille des groupes
MAX_FILES_PER_COMMIT=8
current_group=1
file_count=0

git diff HEAD --name-only | while read file; do
  if [ $file_count -ge $MAX_FILES_PER_COMMIT ]; then
    current_group=$((current_group + 1))
    file_count=0
  fi
  echo "Commit $current_group: $file"
  file_count=$((file_count + 1))
done
Étape 6 : Déterminer les groupes finaux
# Vérifier les résultats de division
for group in $(seq 1 $current_group); do
  files=$(grep "Commit $group:" /tmp/commit_plan.txt | cut -d':' -f2-)
  lines=$(echo "$files" | xargs git diff HEAD -- | wc -l)
  echo "Commit $group: $(echo "$files" | wc -w) fichiers, $lines lignes modifiées"
done

Conformité Conventional Commits

Format de base

<type>[scope optionnel]: <description>

[corps optionnel]

[pied(s) optionnel(s)]

Types standard

Types requis :

  • feat : Nouvelle fonctionnalité (ajout de fonctionnalité visible par l'utilisateur)
  • fix : Correction de bug

Types optionnels :

  • build : Changements au système de build ou aux dépendances externes
  • chore : Autres changements (sans impact sur la release)
  • ci : Changements aux fichiers de configuration CI ou aux scripts
  • docs : Changements de documentation uniquement
  • style : Changements qui n'affectent pas la signification du code (espaces, formatage, points-virgules, etc.)
  • refactor : Changements de code sans corrections de bugs ou ajouts de fonctionnalités
  • perf : Améliorations de performance
  • test : Ajout ou modification de tests

Scope (Optionnel)

Indique la zone affectée par le changement :

feat(api): add user authentication endpoint
fix(ui): resolve button alignment issue
docs(readme): update installation instructions

Breaking Change

Quand il y a des changements d'API breaking :

feat!: change user API response format

ou

feat(api)!: change authentication flow

Détection automatique des conventions de projet

Important : Si des conventions spécifiques au projet existent, elles prennent la priorité.

1. Vérifier la configuration CommitLint

Détection automatique de la configuration à partir des fichiers suivants :

  • commitlint.config.js
  • commitlint.config.mjs
  • commitlint.config.cjs
  • commitlint.config.ts
  • .commitlintrc.js
  • .commitlintrc.json
  • .commitlintrc.yml
  • .commitlintrc.yaml
  • Section commitlint dans package.json
# Vérifier les fichiers de configuration exemple
cat commitlint.config.mjs
cat .commitlintrc.json
grep -A 10 '"commitlint"' package.json
2. Détecter les types personnalisés

Exemple de types spécifiques au projet :

// commitlint.config.mjs
export default {
  extends: ["@commitlint/config-conventional"],
  rules: {
    "type-enum": [
      2,
      "always",
      [
        "feat",
        "fix",
        "docs",
        "style",
        "refactor",
        "test",
        "chore",
        "wip", // Travail en cours
        "hotfix", // Correction d'urgence
        "release", // Release
        "deps", // Mise à jour de dépendance
        "config", // Changement de configuration
      ],
    ],
  },
};
3. Détecter les paramètres de langue
// Quand le projet utilise des messages en français
export default {
  rules: {
    "subject-case": [0], // Désactiver pour le support français (accents)
    "subject-max-length": [2, "always", 72], // Ajuster la limite de caractères pour le français
  },
};

Flux d'analyse automatique

  1. Recherche de fichiers de configuration

    find . -name "commitlint.config.*" -o -name ".commitlintrc.*" | head -1
    
  2. Analyse des commits existants

    git log --oneline -50 --pretty=format:"%s"
    
  3. Statistiques d'usage des types

    git log --oneline -100 --pretty=format:"%s" | \
    grep -oE '^[a-z]+(\([^)]+\))?' | \
    sort | uniq -c | sort -nr
    

Exemples de conventions de projet

Style Angular
feat(scope): add new feature
fix(scope): fix bug
docs(scope): update documentation
Style combiné Gitmoji
✨ feat: add user registration
🐛 fix: resolve login issue
📚 docs: update API docs
Projets français
feat: ajout de la fonctionnalité d'inscription utilisateur
fix: correction du bug du processus de connexion
docs: mise à jour de la documentation API

Détection de langue

Comment nous déterminons votre langue :

  1. Option explicite avec --lang

    # Forcer en français
    /semantic-commit --lang fr
    
    # Forcer en anglais
    /semantic-commit --lang en
    
  2. Analyse du git log pour la détermination automatique

    # Analyser la langue des 20 derniers commits
    git log --oneline -20 --pretty=format:"%s" | \
    grep -E '^[\x{00C0}-\x{017F}]' | wc -l
    # Mode français si détection de caractères accentués
    
  3. Fichiers de projet paramètres de langue

    # Vérifier la langue du README.md
    head -10 README.md | grep -E '^[\x{00C0}-\x{017F}]' | wc -l
    
    # Vérifier la description de package.json
    grep -E '"description".*[\x{00C0}-\x{017F}]' package.json
    
  4. Analyse des commentaires et chaînes dans les fichiers modifiés

    # Vérifier la langue des commentaires dans les fichiers modifiés
    git diff HEAD | grep -E '^[+-].*//.*[\x{3040}-\x{30ff}]|[\x{4e00}-\x{9fff}]' | wc -l
    

Algorithme de détermination

# Calcul du score de langue française
FRENCH_SCORE=0

# 1. Configurations CommitLint (+3 points)
if grep -q '"subject-case".*\[0\]' commitlint.config.* 2>/dev/null; then
  FRENCH_SCORE=$((FRENCH_SCORE + 3))
fi

# 2. Analyse de git log (max +2 points)
FRENCH_COMMITS=$(git log --oneline -20 --pretty=format:"%s" | \
  grep -cE '[àâäçéèêëïîôùûüÿæœÀÂÄÇÉÈÊËÏÎÔÙÛÜŸÆŒ]' 2>/dev/null || echo 0)
if [ $FRENCH_COMMITS -gt 10 ]; then
  FRENCH_SCORE=$((FRENCH_SCORE + 2))
elif [ $FRENCH_COMMITS -gt 5 ]; then
  FRENCH_SCORE=$((FRENCH_SCORE + 1))
fi

# 3. Vérification README.md (+1 point)
if head -5 README.md 2>/dev/null | grep -qE '[àâäçéèêëïîôùûüÿæœÀÂÄÇÉÈÊËÏÎÔÙÛÜŸÆŒ]'; then
  FRENCH_SCORE=$((FRENCH_SCORE + 1))
fi

# 4. Vérification du contenu des fichiers modifiés (+1 point)
if git diff HEAD 2>/dev/null | grep -qE '^[+-].*[àâäçéèêëïîôùûüÿæœÀÂÄÇÉÈÊËÏÎÔÙÛÜŸÆŒ]'; then
  FRENCH_SCORE=$((FRENCH_SCORE + 1))
fi

# Déterminer : mode français si score >= 3
if [ $FRENCH_SCORE -ge 3 ]; then
  LANGUAGE="fr"
else
  LANGUAGE="en"
fi

Chargement automatique de configuration

Ce qui se passe à l'exécution

Nous vérifions les fichiers de configuration dans cet ordre :

  1. Rechercher les fichiers de configuration CommitLint

    # Rechercher dans cet ordre, utiliser le premier fichier trouvé
    commitlint.config.mjs
    commitlint.config.js
    commitlint.config.cjs
    commitlint.config.ts
    .commitlintrc.js
    .commitlintrc.json
    .commitlintrc.yml
    .commitlintrc.yaml
    package.json (section commitlint)
    
  2. Parser le contenu de configuration

    • Extraire la liste des types disponibles
    • Vérifier les restrictions de scope
    • Obtenir les limites de longueur de message
    • Vérifier les paramètres de langue
  3. Analyser l'historique des commits existants

    # Apprendre les patterns d'usage à partir des commits récents
    git log --oneline -100 --pretty=format:"%s" | \
    head -20
    

Analyser les exemples de configuration

commitlint.config.mjs standard :

export default {
  extends: ["@commitlint/config-conventional"],
  rules: {
    "type-enum": [
      2,
      "always",
      ["feat", "fix", "docs", "style", "refactor", "perf", "test", "chore"],
    ],
    "scope-enum": [2, "always", ["api", "ui", "core", "auth", "db"]],
  },
};

Configuration compatible japonais :

export default {
  extends: ["@commitlint/config-conventional"],
  rules: {
    "subject-case": [0], // Désactiver pour le japonais
    "subject-max-length": [2, "always", 72],
    "type-enum": [
      2,
      "always",
      ["feat", "fix", "docs", "style", "refactor", "test", "chore"],
    ],
  },
};

Configuration avec types personnalisés :

export default {
  extends: ["@commitlint/config-conventional"],
  rules: {
    "type-enum": [
      2,
      "always",
      [
        "feat",
        "fix",
        "docs",
        "style",
        "refactor",
        "test",
        "chore",
        "wip", // Travail en cours
        "hotfix", // Correction d'urgence
        "release", // Préparation de release
        "deps", // Mise à jour de dépendance
        "config", // Changement de configuration
      ],
    ],
  },
};

Comportement de fallback

Si aucun fichier de configuration n'est trouvé :

  1. Inférence automatique par analyse du git log

    # Extraire les types des 100 derniers commits
    git log --oneline -100 --pretty=format:"%s" | \
    grep -oE '^[a-z]+(\([^)]+\))?' | \
    sort | uniq -c | sort -nr
    
  2. Par défaut au standard Conventional Commits

    feat, fix, docs, style, refactor, perf, test, chore, build, ci
    
  3. Détermination de langue

    • Mode français si détection de caractères accentués français
    • Mode anglais par défaut

Exigences

  • Doit être dans un dépôt Git
  • Besoin de changements non committés
  • Les changements stagés sont temporairement réinitialisés

Important

  • Ne pushera pas : Vous devez git push vous-même
  • Même branche : Les commits restent dans la branche actuelle
  • Sauvegardez d'abord : Considérez git stash pour la sécurité

Quelles règles gagnent

Lors de la création de messages de commit, nous suivons cet ordre :

  1. Paramètres CommitLint (priorité la plus élevée)

    • Paramètres dans les fichiers commitlint.config.*
    • Types personnalisés et restrictions de scope
    • Restrictions de longueur et de casse de message
  2. Historique des commits existants (deuxième priorité)

    • Statistiques des types réellement utilisés
    • Langue des messages (français/anglais)
    • Patterns d'usage des scopes
  3. Type de projet (troisième priorité)

    • package.json → Projet Node.js
    • Cargo.toml → Projet Rust
    • pom.xml → Projet Java
  4. Standard Conventional Commits (fallback)

    • Comportement standard quand aucun paramètre n'est trouvé

Exemples de détection de convention

Détection automatique de scope dans Monorepo :

# Inférer les scopes à partir du dossier packages/
ls packages/ | head -10
# → Proposer api, ui, core, auth, etc. comme scopes

Conventions spécifiques au framework :

// Pour les projets Angular
{
  'scope-enum': [2, 'always', [
    'animations', 'common', 'core', 'forms', 'http', 'platform-browser',
    'platform-server', 'router', 'service-worker', 'upgrade'
  ]]
}

// Pour les projets React
{
  'scope-enum': [2, 'always', [
    'components', 'hooks', 'utils', 'types', 'styles', 'api'
  ]]
}

Conventions spécifiques à l'entreprise/équipe :

// Pattern courant dans les équipes françaises
{
  'type-enum': [2, 'always', [
    'feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore',
    'wip',      // Travail en cours (pour les pull requests)
    'hotfix',   // Correction d'urgence
    'release'   // Préparation de release
  ]],
  'subject-case': [0],  // Support japonais
  'subject-max-length': [2, 'always', 72]  // Limite plus longue pour le japonais
}

Bonnes pratiques

  1. Suivre les règles : Utiliser les patterns existants
  2. Garder petit : Un changement logique par commit
  3. Être clair : Dire ce qui a changé
  4. Grouper intelligemment : Fichiers liés ensemble
  5. Tests séparés : Commits de tests seuls
  6. Utiliser les configurations : CommitLint aide les équipes à rester cohérentes

Exemples de division du monde réel (Avant/Après)

Exemple 1 : Ajout de système d'authentification volumineux

Avant (un commit massif) :

# Fichiers modifiés (15 fichiers, 850 lignes modifiées)
src/auth/login.js          # Nouveau
src/auth/register.js       # Nouveau
src/auth/password.js       # Nouveau
src/auth/types.js          # Nouveau
src/api/auth-routes.js     # Nouveau
src/middleware/auth.js     # Nouveau
src/database/migrations/001_users.sql  # Nouveau
src/database/models/user.js            # Nouveau
tests/auth/login.test.js   # Nouveau
tests/auth/register.test.js # Nouveau
tests/api/auth-routes.test.js # Nouveau
docs/authentication.md    # Nouveau
package.json              # Ajout de dépendance
README.md                 # Ajout d'usage
.env.example             # Exemple de variable d'environnement

# Commit conventionnel problématique
feat: implement complete user authentication system with login, registration, password reset, API routes, database models, tests and documentation

Après (divisé en 5 commits significatifs) :

# Commit 1 : Fondation base de données
feat(db): add user model and authentication schema

Fichiers inclus :
- src/database/migrations/001_users.sql
- src/database/models/user.js
- src/auth/types.js

Raison : La structure de base de données est la fondation pour les autres fonctionnalités, committée en premier

# Commit 2 : Logique d'authentification
feat(auth): implement core authentication functionality

Fichiers inclus :
- src/auth/login.js
- src/auth/register.js
- src/auth/password.js
- src/middleware/auth.js

Raison : Logique métier d'authentification centrale committée ensemble

# Commit 3 : Points de terminaison API
feat(api): add authentication API routes

Fichiers inclus :
- src/api/auth-routes.js

Raison : La couche API dépend de la logique d'authentification, committée plus tard

# Commit 4 : Tests complets
test(auth): add comprehensive authentication tests

Fichiers inclus :
- tests/auth/login.test.js
- tests/auth/register.test.js
- tests/api/auth-routes.test.js

Raison : Tests ajoutés après que l'implémentation soit complète

# Commit 5 : Documentation et configuration
docs(auth): add authentication documentation and configuration

Fichiers inclus :
- docs/authentication.md
- package.json
- README.md
- .env.example

Raison : Documentation et configuration committées ensemble à la fin

Exemple 2 : Corrections de bugs et refactorisation mixtes

Avant (commit mixte problématique) :

# Fichiers modifiés (8 fichiers, 320 lignes modifiées)
src/user/service.js       # Corrections de bugs + Refactorisation
src/user/validator.js     # Nouveau (refactorisation)
src/auth/middleware.js    # Correction de bug
src/api/user-routes.js    # Correction de bug + Amélioration de gestion d'erreurs
tests/user.test.js        # Ajout de test
tests/auth.test.js        # Ajout de test de correction de bug
docs/user-api.md          # Mise à jour de documentation
package.json              # Mise à jour de dépendance

# Commit problématique
fix: resolve user validation bugs and refactor validation logic with improved error handling

Après (divisé en 3 commits par type) :

# Commit 1 : Corrections de bugs critiques
fix: resolve user validation and authentication bugs

Fichiers inclus :
- src/user/service.js (portion correction de bug uniquement)
- src/auth/middleware.js
- tests/auth.test.js (tests de correction de bugs uniquement)

Raison : Bugs affectant la production corrigés avec la priorité la plus élevée

# Commit 2 : Refactorisation de logique de validation
refactor: extract and improve user validation logic

Fichiers inclus :
- src/user/service.js (portion refactorisation)
- src/user/validator.js
- src/api/user-routes.js
- tests/user.test.js

Raison : Améliorations structurelles committées comme unités fonctionnelles

# Commit 3 : Documentation et mise à jour de dépendance
chore: update documentation and dependencies

Fichiers inclus :
- docs/user-api.md
- package.json

Raison : Améliorations de l'environnement de développement committées ensemble à la fin

Exemple 3 : Développement simultané de multiples fonctionnalités

Avant (commit massif cross-fonctionnel) :

# Fichiers modifiés (12 fichiers, 600 lignes modifiées)
src/user/profile.js       # Nouvelle fonctionnalité A
src/user/avatar.js        # Nouvelle fonctionnalité A
src/notification/email.js # Nouvelle fonctionnalité B
src/notification/sms.js   # Nouvelle fonctionnalité B
src/api/profile-routes.js # API nouvelle fonctionnalité A
src/api/notification-routes.js # API nouvelle fonctionnalité B
src/dashboard/widgets.js  # Nouvelle fonctionnalité C
src/dashboard/charts.js   # Nouvelle fonctionnalité C
tests/profile.test.js     # Tests nouvelle fonctionnalité A
tests/notification.test.js # Tests nouvelle fonctionnalité B
tests/dashboard.test.js   # Tests nouvelle fonctionnalité C
package.json              # Dépendances de toutes les fonctionnalités

# Commit problématique
feat: add user profile management, notification system and dashboard widgets

Après (divisé en 4 commits par fonctionnalité) :

# Commit 1 : Fonctionnalité profil utilisateur
feat(profile): add user profile management

Fichiers inclus :
- src/user/profile.js
- src/user/avatar.js
- src/api/profile-routes.js
- tests/profile.test.js

Raison : La fonctionnalité profil est une unité fonctionnelle indépendante

# Commit 2 : Système de notification
feat(notification): implement email and SMS notifications

Fichiers inclus :
- src/notification/email.js
- src/notification/sms.js
- src/api/notification-routes.js
- tests/notification.test.js

Raison : La fonctionnalité notification est une unité fonctionnelle indépendante

# Commit 3 : Widgets de tableau de bord
feat(dashboard): add interactive widgets and charts

Fichiers inclus :
- src/dashboard/widgets.js
- src/dashboard/charts.js
- tests/dashboard.test.js

Raison : La fonctionnalité tableau de bord est une unité fonctionnelle indépendante

# Commit 4 : Mise à jour des dépendances et infrastructure
chore: update dependencies for new features

Fichiers inclus :
- package.json

Raison : Mises à jour de dépendances communes committées ensemble à la fin

Comparaison des effets de division

Élément Avant (Commit massif) Après (Division appropriée)
Reviewabilité Très difficile Chaque commit est petit et reviewable
Suivi de bugs Difficile d'identifier l'emplacement du problème Les commits problématiques peuvent être immédiatement identifiés
Revert Besoin de tout reverter Peut identifier et reverter uniquement les parties problématiques
Développement parallèle Sujet aux conflits Fusion basée sur les fonctionnalités est facile
Déploiement Toutes les fonctionnalités déployées en une fois Déploiement par étapes possible

Dépannage

Quand le commit échoue

  • Vérifier les hooks pre-commit
  • Résoudre les dépendances
  • Réessayer avec des fichiers individuels

Quand la division est inappropriée

  • Ajuster avec l'option --max-commits
  • Utiliser le mode manuel edit
  • Relancer avec une granularité plus fine