34 votes

Comment appliquer un patch git d'un dépôt à un autre ?

J'ai deux dépôts, l'un est le dépôt principal d'une bibliothèque, et l'autre est un projet utilisant cette bibliothèque.

Si j'apporte une correction au projet subordonné, j'aimerais avoir un moyen facile d'appliquer ce correctif en amont.

L'emplacement du fichier est différent dans chaque dépôt.

  • Repo principal : www.playdar.org/static/playdar.js
  • Projet : playlick.com/lib/playdar.js

J'ai essayé d'utiliser git format-patch -- lib/playdar.js sur le projet playlick, puis git am sur le repo principal de playdar, mais les différents emplacements des fichiers dans le fichier patch ont soulevé une erreur.

Existe-t-il un moyen simple d'appliquer le correctif d'un commit donné sur un fichier donné à un autre fichier arbitraire situé ailleurs ?

Pour les points bonus, que se passe-t-il si le fichier auquel vous voulez appliquer le correctif ne se trouve pas dans un dépôt git ?

50voto

vergenzt Points 2526

Si l'édition manuelle du fichier patch est hors de question ou infaisable, il est possible de le faire avec les options standard (disponibles dans la rubrique git apply , git format-patch et GNU patch ).

  1. -p<n> supprime n les répertoires principaux à partir des chemins d'accès du correctif.

  2. Après traitement -p , --directory=<root> Prépare root à chacun des chemins du patch avant de l'appliquer.

Ejemplo

Ainsi, pour votre exemple, si l'on prend un correctif qui se trouvait à l'origine sur static/playdar.js et l'appliquer à lib/playdar.js vous courriez :

$ cat patch_file | git am     \ 
          -p1                 \ # remove 1 leading directory ('static/')
         --directory='lib/'     # prepend 'lib/'

25voto

araqnid Points 33350

Le patch produit par git format-patch est simplement un fichier texte - vous pouvez éditer les en-têtes du diff pour qu'il modifie un chemin différent.

Ainsi, par exemple, il aurait produit quelque chose comme ceci :

diff --git a/lib/playdar.js b/lib/playdar.js
index 1234567..89abcde
-- a/lib/playdar.js
++ b/lib/playdar.js

Il vous suffit de changer lib/playdar.js a static/playdar.js puis faire passer le correctif par git am"

Le patch doit pouvoir être lu par l'utilitaire de patch standard de GNU pour les personnes qui ne disposent pas de git --- mais ne courez pas format-patch con el -M , -C etc. pour produire des correctifs de renommage dans ce cas, car leur prise en charge n'est pas universelle.

4voto

Henrik Paul Points 22787

En supposant que les deux projets soient des projets git, il semblerait que sous-modules vous conviendrait parfaitement. Cela permet à un projet git de se lier dynamiquement à un autre projet git, essentiellement en construisant un repo git à l'intérieur d'un autre repo git, les deux ayant leur propre vie distincte.

En d'autres termes, ajoutez "main repo" en tant que sous-module dans "project". A chaque fois que vous faites un commit/push de nouvelles choses dans "main repo", vous n'avez qu'à git pull les replacer dans le "projet".

2voto

VonC Points 414372

A compléter Réponse de Henrik et d'aller chercher le point de bonus

que faire si le fichier auquel vous voulez appliquer le correctif n'est pas dans un dépôt git ?

Si vous avez accès aux répertoires des fichiers candidats à un patch provenant d'un dépôt git, vous pouvez d'abord transformer cet arbre de répertoires/fichiers en un dépôt git lui-même ! (' git init ' : un dépôt git n'est qu'un .git dans un répertoire Root après tout).
Ensuite, vous devez définir ce dépôt comme un sous-module de votre projet principal.

2voto

nobar Points 5849

L'utilisation de la --relative à l'option format-patch peut améliorer l'abstraction (cacher les détails non pertinents concernant le dépôt à partir duquel le correctif a été généré).

[repository-with-changes]
git format-patch --relative=(path-to-library) (base-commit-for-patch) ## 'HEAD~1'

J'ai trouvé le --3way à exiger lors de l'application du correctif (afin d'éviter que l'option does not exist in index erreur) -- votre kilométrage peut varier. En utilisant --directory=(...) n'est probablement nécessaire que si votre chemin cible n'est pas la racine du référentiel.

[repository-to-update]
git am --3way --directory=(path-to-library) (patch-file)

  • format-patch créera un fichier patch par commit dans la branche courante depuis 'base'.

  • La documentation relative à la --relative semble être manquante dans certains cas mais cela semble fonctionner quand même (à partir de la version 2.7.4).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X