MILIN Jacques wrote:

> j'ai un pb lorque j'essaie d'ajouter un patch � un fichier source. je
> tape les commandes suivantes:
> 
> %patch < /"nom du fichier"
> Le systeme repond : "The next patch would create the file
> 'Makefile.in',which already exists! Assumes -R? [n].
> 
> Je reponds y mais il ne prend pas en compte le patch ... alors si
> quelqu'un peut me sortir de cette me..

Il faudrait regarder le source du patch pour pouvoir r�pondre � ton
probl�me de mani�re sp�cifique.  Comme je ne l'ai pas, je vais te
d�tailler le m�canisme usuel de la combinaison diff/patch.


Un patch est g�n�r� � partir de la commande `diff' entre la version
originale et la version corrig�e.  G�n�ralement, le diff est g�n�r� �
partir de deux arboressences, c'est un diff r�cursif (diff -r).

Pour �tre exploit� efficassement, le fichier diff doit contenir, en plus
des lignes modifi�es, le contexte de chaque modification.  Cel� permet
au programme patch de se resynchroniser si un fichier est d�ja modifi�
localement.  Pour g�n�rer un patch au format ``context diff'' il faut
utiliser l'option -c, mais il est pr�f�rable d'utiliser le format
``unified'' avec option -u, qui est tout aussi informatif mais plus
condens� et plus fa�ilement lisible par un humain.

Si tu as supprim� ou ajout� un fichier entre les deux versions, il
faudra que tu ajoutes l'option -N pour les prendre en compte.  Sans
cette option tu n'auras que `Only foo in directory bar', qui ne
permettra de supprimer ou de cr�er ces fichiers.


Voici un exemple partiel d'un diff -ru que je vais utilis� dans la suite
de mes explications:

    diff -ru id-utils-3.2d/libidu/id-lang.map 
id-utils-3.2d-egp2/libidu/id-lang.map
    --- id-utils-3.2d/libidu/id-lang.map        Fri Apr 18 08:43:30 1997
    +++ id-utils-3.2d-egp2/libidu/id-lang.map   Fri Jan 28 10:14:03 2000
    @@ -52,6 +52,8 @@
     *.cpp                      C++
     *.cxx                      C++
     
    +*.java                     Java
    +
     ChangeLog*         Cdoc
     
     *.[sS]                     asm --comment=;
    @@ -71,7 +73,10 @@
     # portable object (i18n)
     *.po                       po
     
    -*.el                       elisp
    +*.el                       lisp
    +*.elc                      lisp
    +*.lisp                     lisp
    +*.scm                      lisp
     
     *.am                       make
     Makefile           make

La premi�re ligne (qui n'est pas obligatoire, elle est d'ailleur
supprim�e par dpkg-source -b) reprend les options pass�es � la commande
diff, ici `-ru'.  Les lignes suivantes (--- et +++) indiquent le fichier
d'origine et le fichier corrig�.  Vient ensuite une d�finition de
paragraphe @@ -52,6 +52,8 @@ suivie par les modifications � appliquer et
une deuxi�me d�finition de paragraphe @@ -71,7 +73,10 @@ et ses
modifications.

En claire, le second paragraphe commence � la ligne 71 dans le fichier
original (---) et porte sur 7 lignes.  Dans le nouveau fichier (+++), il
commence � la ligne 73 et porte sur 10 lignes.  Ce paragraphe contient
des lignes non modifi�es (le premier caract�re de ces lignes est un
espace) elles servent de contexte, une ligne supprim�e (commence par -)
et quatres lignes ajout�es (introduites par +).  Ces informations sont
utiles pour r�soudre � la main un rejet.


Si j'applique simplement ce patch par `patch < exemple.diff' dans le
r�pertoire id-utils-3.2d, je vais avoir ce r�sulta:

    can't find file to patch at input line 1
    Perhaps you should have used the -p or --strip option?
    The text leading up to this was:
    --------------------------
    |diff -ru id-utils-3.2d/libidu/id-lang.map 
id-utils-3.2d-egp2/libidu/id-lang.map
    |--- id-utils-3.2d/libidu/id-lang.map   Fri Apr 18 08:43:30 1997
    |+++ id-utils-3.2d-egp2/libidu/id-lang.map      Fri Jan 28 10:14:03 2000
    --------------------------
    File to patch: 

Mais si je me place dans le r�pertoire libidu, le patch sera appliqu�
correctement.  En fait, il faut indiqu� le niveau de r�pertoire �
ignorer avec l'option -p num.  Sans cette option, le fichier id-lang.map
est sens� se trouver dans le r�pertoire courrant.  Ici, en me placant
dans le r�pertoire id-utils-3.2d, j'aurai d� utiliser `patch -p1'.

Passons maintenant � un patch contenant des modifications pour les
fichiers pkg/Makefile.in, pkg/foo/Makefile.in et pkg/bar/Makefile.in.
Sans l'option -p1, c'est le _m�me_ fichier Makefile.in du r�pertoire
courrant qui sera modifi�, je pense que c'est ce qui t'es arriv�.


En conclusion, pour cr�er mes fichiers patch, j'utilise `diff -ru' (ou
`diff -ruN' lorsque j'ai ajout� ou supprim� un fichier).

Et voici _la_ commande patch que j'utilise 99% du temps:

    $ patch -p1 -s -N -E < le-fichier-patch

J'utilise l'option -R en plus pour le 1% restant lorsque je souhaite
annuler un patch, ou pour appliquer un patch fait � l'envers.

Mais attention, il faut _toujours_ regarder le source du patch pour
choisir le bon niveau de r�pertoire � ignorer.


En fait, comme je suis faignant, je me suis �crit le script zpatch
suivant:

    #!/bin/sh
    patchfile="$1"; shift
    case "$patchfile" in
        *.gz) uncomp="gzip -dc";;
        *.bz2) uncomp="bzip2 -dc";;
        *) uncomp="cat";;
    esac
    $uncomp "$patchfile" | patch -p1 -s -N -E "$@"

Que j'utilise simplement par

    $ zpatch le-fichier-patch

ou par

    $ zpatch le-fichier-patch -p2


Voila, bon patch :-)
-- 
Edouard G. Parmelan
http://egp.free.fr


Répondre à