Git format-patch pour être compatible svn?

96

Existe-t-il un moyen d'obtenir un patch créé avec git format-patch pour qu'il soit compatible svn afin que je puisse le soumettre à un dépôt svn?

Je travaille sur un repo svn sur github et je souhaite soumettre mes modifications au repo principal. J'ai besoin de créer un correctif pour ce faire, mais le correctif ne peut pas être appliqué car les formats git qui corrigent différemment de svn. Y a-t-il un secret que je n'ai pas encore découvert?

MISE À JOUR: Bien qu'il n'existe actuellement aucun script ou moyen git natif de le faire, j'ai réussi à trouver un article plus tôt cette année sur la façon de le faire manuellement. J'ai suivi les instructions et j'ai réussi à faire fonctionner mes correctifs git avec svn.

Si quelqu'un pouvait essayer d'écrire un script pour accomplir cela et contribuer au projet git, je serais tout le monde apprécié.

http://kerneltrap.org/mailarchive/git/2008/1/15/570308/thread#mid-570308

rip747
la source
Je n'arrive pas à le faire fonctionner ... pouvez-vous poster toutes les étapes nécessaires? Merci!
Mauricio Scheffer
1
Salut Anthony. Envisageriez-vous de changer la réponse acceptée par celle de Nicholas?
Simon East
J'appuie la suggestion de Simon, avoir la réponse de Nicholas Smith comme acceptée profiterait à tout le monde car c'est beaucoup plus pratique.
Albireo

Réponses:

90

Je dois toujours chercher sur Google, mais la façon dont j'ai trouvé que cela fonctionne parfaitement (pour moi) est:

  • Créez le patch avec git diff --no-prefix master..branch > somefile.diff, les parties master et branch sont facultatives, cela dépend de la façon dont vous souhaitez obtenir vos différences.
  • Envoyez-le partout et postulez avec patch -p0 < somefile.diff.

Cela semble toujours bien fonctionner pour moi et semble être la méthode la plus simple que j'ai rencontrée.

Nicholas Smith
la source
1
C'est la manière canonique de générer un patch compatible SVN avec Git. Il devrait être marqué comme la réponse.
mloskot
--no-pagern'est plus une option pour git diff.
naught101
Il a été initialement publié sans --no-pager, je ne sais pas pourquoi il a été ajouté dans l'édition. Cela a toujours bien fonctionné pour moi sans de --no-pagertoute façon.
Nicholas Smith
2
Pour un commit particulier uniquement: a git diff --no-prefix 056a1ba5140 7d939289b80 >my.patchfonctionné pour moi (où 056a1ba5140et 7d939289b80sont le sha-1 du commit précédent et particulier dans git).
Ed Randall du
@ Lilás c'est un problème avec SVN. Les différences / correctifs dans SVN n'ont jamais été en mesure de gérer les fichiers supprimés
Toofy
17

Voici un script d'aide pour faire une différence avec le dernier ensemble de modifications svn et le commit donné: http://www.mail-archive.com/[email protected]/msg00864.html

#!/bin/sh
#
# git-svn-diff
# Generate an SVN-compatible diff against the tip of the tracking branch
TRACKING_BRANCH=`git config --get svn-remote.svn.fetch | sed -e 's/.*:refs\/remotes\///'`
REV=`git svn find-rev $(git rev-list --date-order --max-count=1 $TRACKING_BRANCH)`
git diff --no-prefix $(git rev-list --date-order --max-count=1 $TRACKING_BRANCH) $* |
sed -e "s/^+++ .*/&    (working copy)/" -e "s/^--- .*/&    (revision $REV)/" \
-e "s/^diff --git [^[:space:]]*/Index:/" \
-e "s/^index.*/===================================================================/"
Christoph
la source
1
J'ai trouvé que la valeur REV est incorrecte si vous ne travaillez pas avec la dernière révision svn. Je l'ai corrigé pour l'utiliser à la git svn infoplace comme ceci: REV=`git svn info | grep 'Last Changed Rev:' | sed -E 's/^.*: ([[:digit:]]*)/\1/'`
Sebastien Martin
1
C'est génial! Merci beaucoup. J'ai dû faire une modification pour que cela fonctionne pour importer mes correctifs dans le creuset de Fisheye, et c'était de remplacer les espaces avant "(révision" par une tabulation à la place.
Zugwalt
10

SVN ne peut probablement pas comprendre la sortie de git diff -p, mais vous pouvez recourir à la force brute:

  1. Faites deux clones de votre repo
  2. En un seul clone, découvrez vos dernières informations
  3. Dans l'autre contrôle de clone, tout ce qui est équivalent au svn en amont. Si vous avez planifié à l'avance, vous avez une copie de svn en amont sur sa propre branche, ou vous avez marqué la dernière version de svn. Si vous n'avez pas planifié à l'avance, utilisez la date ou gitk pour trouver le hachage git SHA1 qui se rapproche le plus de l'état svn.
  4. Calculez maintenant un vrai patch en exécutant diff -rsur les deux clones.
Norman Ramsey
la source
12
Ou suivez simplement les conseils de @ Nicholas-smith et exécutez git diff --no-prefix > somefile.diffvotre dépôt git et envoyez-le à n'importe quel utilisateur svn pour qu'il applique le correctif patch -p0 < somefile.diffà la racine du projet.
DavidG
10

Subversion <1.6 ne prend pas en charge les correctifs. Il semble que Subversion 1.7 autorise l'application de correctifs et que les extensions git / hg aux différences unifiées figurent sur notre liste TODO.

Bert Huijben
la source
4

C'est en effet une demande de fonctionnalité début 2008

Linus Torvalds a déclaré à l'époque:

Donc, je dirais que vous avez besoin de quelque chose de plus fort pour dire "ne faites pas un git diff", et cela devrait également interdire au minimum la détection de changement de nom.
Franchement, tout programme qui est si stupide qu'il n'accepte pas les correctifs Git actuels (par exemple TortoiseSVN), alors nous ne devrions pas simplement désactiver la partie la plus triviale de celui-ci. Nous devons nous assurer de n'activer aucune des extensions assez importantes:
même si ToirtoiseSVN les ignorait, si les ignorer signifie qu'il comprend mal la différence, cela ne devrait pas être autorisé du tout.

C'est peut-être pourquoi

 git-format-patch: add --no-binary to omit binary changes in the patch.

a été introduit dans Git1.5.6 en mai / juillet 2008 (je ne l'ai pas testé cependant)

VonC
la source
0

Assurez-vous que vos modifications sont validées et rebasées au-dessus de votre branche git locale, à partir de git bash run:

git show --pretty >> myChangesFile.patch

Ismail Hawayel
la source
0

La réponse acceptée fournie par Nicholas fonctionne bien, sauf quand a) des fichiers binaires existent dans le diff ou b) vous travaillez dans Windows Git et avez des répertoires avec des espaces. Pour résoudre ce problème, j'ai dû ajouter une commande git diff imbriquée pour ignorer les binaires et une commande sed pour échapper aux espaces. C'est un peu lourd à écrire, j'ai donc créé un alias:

[alias]
svnpatch = "!f() { git diff --name-only --no-prefix master...$1 | grep -Ev \"\\.sdf|\\.Doc|\\.dll|\\.zip|\\.exe\" | sed 's_\\s_\\\\\\\\ _g'  | xargs git diff --no-prefix master...$1 > $1.patch; echo "Created $1.patch"; }; f"

Si vous tapez ensuite:

git svnpatch Feature123

... un fichier de correctif Feature123.patch sera créé avec les différences entre la base de fusion du maître de branche et de la branche Feature123.

Leandro Gomez
la source