web-dev-qa-db-fra.com

Comment appliquer un patch Git à un fichier avec un nom et un chemin différents?

J'ai deux référentiels. Dans l'un, je modifie le fichier ./hello.test. Je valide les modifications et crée un correctif à partir de celui-ci avec git format-patch -1 HEAD. Maintenant, j'ai un deuxième référentiel qui contient un fichier ayant le même contenu que hello.test mais qui est placé dans un répertoire différent sous un nom différent: ./blue/red/hi.test. Comment puis-je appliquer le correctif susmentionné au fichier hi.test? J'ai essayé git am --directory='blue/red' < patch_file mais cela se plaint bien sûr que les fichiers ne portent pas le même nom (ce qui, à mon avis, importait à Git?). Je sais que je pourrais probablement éditer le diff pour l'appliquer à ce fichier spécifique mais je cherche une solution de commande.

68
mart1n

Vous pouvez créer le correctif à l’aide de git diff puis l’appliquer à l’aide de l’utilitaire patch , qui vous permet de spécifier le fichier auquel vous souhaitez appliquer le diff.

Par exemple:

cd first-repo
git diff HEAD^ -- hello.test > ~/patch_file

cd ../second-repo
patch -p1 blue/red/hi.test ~/patch_file
70
georgebrock

Il existe une solution simple n'impliquant ni l'édition manuelle de correctifs ni un script externe. 

Dans le premier référentiel (cela peut également exporter une plage de validation, utilisez -1 si vous souhaitez sélectionner une seule validation):

git format-patch --relative <committish> --stdout > ~/patch

Dans le deuxième référentiel:

git am --directory blue/red/ ~/patch

Au lieu d'utiliser --relative dans git format-patch, une autre solution consiste à utiliser l'option -p<n> dans git am pour supprimer les répertoires n du chemin des correctifs, comme indiqué dans la réponse à une question similaire .

Il est également possible d'exécuter git format-patch --relative <committish> sans le --stdout, qui générera un ensemble de fichiers .patch. Ces fichiers peuvent ensuite être chargés directement dans git am avec git am --directory blue/red/ path/to/*.patch.

31
magiraud

Répondant à ma propre question avec un script qui fait justement cela: https://github.com/mprpic/apply-patch-to-file

Plutôt que de modifier manuellement le fichier de correctif, il invite l'utilisateur à entrer le fichier cible, modifie le correctif et l'applique au référentiel dans lequel vous vous trouvez actuellement.

8
mart1n

En s'appuyant sur la réponse de @georgebrock, voici une solution que j'ai utilisée:

Commencez par créer les fichiers de correctif comme d’habitude (par exemple, git format-patch commitA..commitB).

Assurez-vous ensuite que votre référentiel cible est propre (il ne devrait y avoir aucun fichier modifié ou non suivi) et appliquez les correctifs comme suit:

cd second-repo
git am ~/00*.patch

Une erreur du type "erreur: XYZ n'existe pas dans l'index" sera générée pour chaque fichier de correctif. Vous pouvez maintenant appliquer ce patch manuellement:

patch --directory blue/red < ~/0001-*.patch
git add -a
git am --continue

Vous devez suivre ces trois étapes pour chaque fichier de correctif.

Cela préservera le message de validation d'origine, etc., sans nécessiter de commande git format-patch ni éditer les fichiers de correctif.

1
oliver

Je comprends que les deux fichiers sont exactement les mêmes dans votre situation, donc le correctif est susceptible de réussir.

Cependant, si vous souhaitez appliquer un correctif à un fichier similaire, mais pas exactement le même, ou si vous souhaitez appliquer un correctif interactif, vous utiliserez la fusion à trois voies.

Supposons que vous ayez modifié le fichier A, notons A~1 comme la version précédente et que vous souhaitez appliquer le diff compris entre A~1 à A dans Fichier B.

Ouvrez un outil de fusion à trois voies, par exemple Au-delà de Comparer, le chemin du panneau de gauche est A, le panneau du milieu est l’ancêtre commun, le chemin est donc A~1, le chemin de droite est B. Ensuite, le panneau inférieur montre le résultat de l'application du diff entre A~1 à A à Fichier B.

La figure suivante illustre l'idée.

 enter image description here

0
Gqqnbig