HOWTO · Git

Résoudre les erreurs de correctif Git

Cet article explique comment résoudre certaines erreurs courantes associées à l'application de correctifs git.

Sur cette page

Un correctif Git échoue généralement lorsque la commande ne correspond pas à son format, que le dépôt repose sur une base différente de celle attendue par le correctif ou que le contexte de celui-ci a changé. Déterminez s’il s’agit d’un correctif au format courriel ou d’un diff, inspectez la branche cible et l’arbre de travail, puis vérifiez son applicabilité avant de choisir une méthode de récupération. git apply traite les correctifs diff ; git am traite ceux au format courriel et crée des commits.

Identifier le type de correctif et la commande Git à utiliser

Un correctif diff classique contient souvent des lignes diff --git et des blocs de modifications commençant par @@. Appliquez-le à l’arbre de travail avec git apply. Un correctif produit par git format-patch est un message électronique contenant des métadonnées de commit ; il s’applique généralement avec git am, qui préserve l’auteur et le message du commit en créant un commit. Ces commandes ne sont pas interchangeables. Si le format du fichier n’est pas clair, examinez ses premières lignes avec head et recherchez des en-têtes de courriel et des métadonnées de commit avant de l’appliquer.

Si une opération am est déjà en cours, consultez git status avant de continuer. git am --continue reprend après la résolution du correctif de courriel en cours ; git am --abort arrête l’opération et restaure l’état antérieur. git am --skip ignore le correctif de courriel en cours : utilisez cette commande uniquement si vous voulez délibérément l’abandonner. Elle n’ignore généralement pas une erreur d’index produite par git apply.

Vérifier le dépôt et le correctif avant de l’appliquer

Commencez par git status --short --branch et git branch --show-current. Vérifiez que la branche active est bien la cible prévue et repérez les modifications suivies, indexées et non suivies. Ne changez pas de branche si cela risque d’écraser des modifications locales ; décidez d’abord comment les préserver, par exemple en les validant ou en les mettant prudemment de côté. Un correctif créé à partir d’un autre commit peut ne pas s’appliquer à la branche active, même si les deux branches contiennent les mêmes fichiers.

Inspectez le correctif avant de l’exécuter. Pour un diff, git diff --stat -- my_patch.patch ne permet pas d’inspecter un fichier de correctif ; utilisez head, less ou git apply --stat my_patch.patch pour en voir le contenu ou les chemins concernés. Exécutez ensuite git apply --check my_patch.patch. Cette vérification indique si le diff peut être appliqué sans modifier de fichiers. Elle ne confirme ni que le changement est celui que vous souhaitez ni que les modifications ultérieures seront correctes. Pour un correctif au format courriel, examinez le message et suivez la procédure git am correspondante au lieu de le traiter comme un diff classique.

Exécutez cet exemple autonome dans un shell où Git est installé. Il crée un dépôt temporaire, génère un diff, restaure le fichier d’origine, puis applique le diff sur la même base :

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

set -eu
tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
repo="$tmp/repo"
mkdir "$repo"
git -C "$repo" init -q
git -C "$repo" config user.name Example
git -C "$repo" config user.email example@example.com
printf 'first line
' > "$repo/note.txt"
git -C "$repo" add note.txt
git -C "$repo" commit -qm 'Add note'
printf 'first line
second line
' > "$repo/note.txt"
git -C "$repo" diff > "$tmp/change.patch"
git -C "$repo" checkout -- note.txt
git -C "$repo" apply --check "$tmp/change.patch"
git -C "$repo" apply "$tmp/change.patch"
printf 'Applied content: '
cat "$repo/note.txt"

Dans cet exemple, git apply --check est une vérification préalable ; la commande git apply qui suit effectue la modification. Dans votre dépôt, remplacez le chemin du diff généré par celui du correctif fourni, puis vérifiez de nouveau git status avant d’indexer quoi que ce soit.

Diagnostiquer les erreurs courantes de correctif Git

Pour patch does not apply ou un échec de bloc de modifications, Git n’a pas trouvé le contexte attendu dans le fichier cible. Le correctif peut provenir d’un autre commit, les lignes concernées peuvent avoir été modifiées ou les espaces peuvent différer. Comparez les lignes autour du bloc avec le fichier actuel et vérifiez la base prévue. Des options telles que --ignore-space-change ou --ignore-whitespace peuvent aider lorsque les différences portent uniquement sur les espaces ; elles ne résolvent ni une logique modifiée, ni des fichiers manquants, ni des conflits de contenu sans rapport.

Le message file already exists in index signale une collision de chemin ou d’index, mais ce texte ne suffit pas à en déterminer la cause. Vérifiez git status, examinez le chemin indiqué avec git ls-files --stage -- path/to/file et lisez le bloc du correctif. Déterminez si la modification est déjà indexée, si le correctif ajoute un chemin déjà suivi ou s’il a été créé pour une autre base de dépôt. Évitez de réinitialiser l’index ou de supprimer le fichier tant que vous ne savez pas quel état doit être conservé.

Le message error in file est lui aussi trop général pour identifier une cause à lui seul. Lisez les messages Git environnants, examinez le fichier indiqué et le bloc pertinent du correctif, puis vérifiez que le chemin existe avec la casse et l’orthographe attendues. Choisissez une correction en fonction des détails précis de l’échec au lieu de supposer que le correctif est corrompu.

Choisir une méthode de récupération après l’échec d’un correctif

Si git apply --check signale un écart de contexte, commencez par réévaluer la base cible. Il vous faudra peut-être la bonne branche ou le bon commit, ou adapter manuellement le correctif au fichier actuel. Ne changez pas de branche à l’aveugle : examinez et préservez vos modifications locales avant de changer de cible. Relancez la vérification une fois la base prévue préparée.

Si certains blocs sont indépendants et que vous souhaitez que Git applique ceux qu’il peut, git apply --reject my_patch.patch applique les blocs correspondants et écrit les blocs rejetés dans des fichiers .rej. L’application est partielle : examinez chaque fichier source modifié et chaque fichier .rej, puis incorporez ou écartez manuellement chaque modification rejetée. La commande ne résout pas le contenu rejeté et ne rend pas le correctif complet. Pour une tentative qui applique tout ou rien, utilisez plutôt git apply après une vérification réussie.

Pour les correctifs qui contiennent des informations de base exploitables, git apply --3way my_patch.patch demande à Git d’effectuer une fusion à trois voies. Les objets blob de base nécessaires doivent être disponibles ; sinon, la commande peut échouer. Même si la tentative aboutit, des marqueurs de conflit peuvent rester à résoudre manuellement. Cette option peut être utile lorsque le contexte a changé, mais ne constitue pas une solution universelle. Les options relatives aux espaces sont distinctes : utilisez-les uniquement si l’inspection montre que les différences d’espacement sont à l’origine du problème.

Résoudre les conflits et vérifier le résultat

Après toute récupération, examinez git status --short et git diff -- pour voir les fichiers modifiés et le contenu non indexé. Si le correctif a été appliqué avec --reject, repérez les fichiers .rej et comparez chaque bloc rejeté avec la source actuelle. Si une application à trois voies a laissé des conflits, recherchez les marqueurs de conflit, modifiez chaque fichier pour obtenir le contenu voulu, puis vérifiez qu’il ne reste aucun marqueur. Pour une opération de correctif au format courriel, suivez l’état de git am indiqué par git status, puis continuez ou annulez selon le cas.

Avant l’indexation, examinez le diff complet : git diff --check repère les problèmes d’espacement et git diff affiche les modifications. Inspectez également les modifications déjà indexées avec git diff --cached, le cas échéant. Vérifiez que les fichiers obtenus contiennent les changements prévus et que les modifications locales sans rapport sont toujours présentes. Après cet examen seulement, décidez si vous souhaitez indexer ou valider les changements. git log peut confirmer les nouveaux commits créés par git am, mais n’affiche pas toutes les modifications de l’arbre de travail ; utilisez donc aussi l’état et les diffs pour vérifier le résultat complet.