web-dev-qa-db-fra.com

Création d'un fichier de patch à partir d'un diff de 2 dossiers

J'ai apporté quelques modifications à un projet open source sans prendre le temps de créer des fichiers correctifs appropriés.

Maintenant, le responsable du projet a publié une nouvelle version, et parmi les fichiers nouveaux et modifiés, il y a un tas de fichiers renommés.

Quelle est la meilleure façon d'appliquer mes modifications à la nouvelle version?
Je suis complètement nouveau dans l'utilisation de diff/patch, et si je peux le faire avec git, ce serait mieux.

38
karatchov

Si vous avez deux répertoires a et b qui sont similaires et que vous souhaitez que b soit identique à a, vous pouvez créer et appliquer un correctif avec:

$ diff -ur b a > ba.diff
$ patch -i ba.diff

Supposons que vous ayez des répertoires local (contenant votre version locale de upstream1.0), upstream1.0, et upstream1.1. Pour créer et appliquer vos modifications à upstream1.1:

$ diff -ur upstream1.0 local > my.diff
$ cd upstream1.1
$ patch -i ../my.diff 

Consultez la documentation des correctifs et essayez de convaincre les responsables en amont d'utiliser git. Les choses seront beaucoup plus simples si vous pouvez utiliser des outils git pour travailler avec votre référentiel local.

54
William Pursell

Si le projet est sous git et que vous n'avez pas validé vos modifications localement, vous pouvez simplement faire git diff > file.patch pour obtenir des données de diff patchables. Si vous avez validé les modifications localement, vous pouvez faire git log pour trouver le commit avant vous et que git diff commit_string > file.patch.

Si le projet n'est pas sous git, ou si vous d/l source sans cloner le référentiel (comme le titre le suggère), vous pouvez utiliser diff -urN original_dir new_dir > file.patch pour créer le fichier de patch. Dans les deux cas, vous pouvez essayer d'utiliser le patch ultérieurement pour appliquer le patch.

Cependant, envisagez d'utiliser les outils git pour fusionner vos modifications avec la nouvelle version, car git est également capable de suivre les modifications de nom de fichier. Vous devrez en apprendre beaucoup sur git lui-même, et cela vous prendra un certain temps pour bien faire les choses - vous devriez probablement sauvegarder votre travail avant de commencer à jouer avec.

10
niry

Git prend en charge la détection du changement de nom des fichiers, donc si vous êtes chanceux, cela vous aidera. Ce qui suit est une ébauche approximative de ce que vous devez faire.

Importez la version originale:

tar zxvf open-source-project-0.1.tar.gz 
mv open-source-project-0.1 open-source-project
cd open-source-project
git init
git add .
git commit -m "Initial checkin of open-source-project-0.1"
git tag open-source-project-0.1

Vous pouvez maintenant appliquer vos modifications d'origine dans une branche distincte:

git checkout -b mychanges
cp /somewhere/where/your/changes/files/are/* .
git diff
git add .
git commit -m "My changes"
git tag my_changes_001

Ensuite, vous passez à la version la plus récente:

git checkout master
tar zxvf open-source-project-0.2.tar.gz 
mv open-source-project-0.2/* .
rmdir open-source-project-0.2
git add .
git commit -m "Update to open-source-project-0.2"
git tag open-source-project-0.2

Jusqu'à présent, tout est archivé dans le référentiel git, il est maintenant temps de commencer à essayer de fusionner vos modifications:

git checkout -b merge_test open-source-project-0.2
git pull . my_changes_001

Bonne chance...

Si vous souhaitez fusionner des fichiers manuellement, je recommande vraiment d'utiliser KDiff . En supposant que file1.c provient de open-source-project-0.1, file2.c de open-source-project-0.2 et file3.c de vos modifications, exécutez

kdiff3 -o merged_file.c file1.c file2.c file3.c
4
hlovdal

Vous pouvez essayer quelque chose qui m'a été suggéré ici auparavant, une solution intéressante "différente": d'abord cloner la dernière version du projet. Il ne devrait pas y avoir de changements locaux. Assurez-vous que le dossier .git est là. Copiez ensuite votre arborescence de travail, c'est-à-dire tous vos fichiers SAUF le dossier .git, dans le référentiel cloné. Maintenant, si vous tapez "git st", vous verrez tout ce qui a été changé. Vous devrez également trier l'espacement et les fins de ligne (git config core.autocrlf ...) si git st signale des fichiers qui n'ont pas vraiment de changements.

Maintenant, pour chaque fichier dans la liste git st, si vous tapez git diff, vous verrez vos modifications.

Ensuite, je modifierais les fichiers un par un, jusqu'à ce que git st ressemble à ce que je veux valider.

Je ne compterais pas sur la création de patchs car ils sont extrêmement pointilleux. Vous obtiendrez très probablement un "patch impossible à appliquer", tandis que la solution ci-dessus vous donne une liste des modifications non planifiées sur lesquelles vous pouvez travailler dans l'ordre que vous souhaitez.

1
user58777

Je n'ai pas pu commenter en raison de la mauvaise réputation. J'ajouterai donc une nouvelle réponse. J'ai essayé l'une des réponses ci-dessus qui avait encore des problèmes avec les lignes vides. Cependant, la méthode ci-dessous a fonctionné pour moi.

diff -uraBN upstream local > filename.patch
cd upstream
patch --dry-run -p1 -i filename.patch #highly recommended recommended
patch -p1 -i filename.patch
0
Aj700

Vous devriez probablement regarder git rebase. Peut-être même un simple git pull fera ce que vous voulez.

0
Tallak Tveide