2009-04-02 14 views
85

¿Hay alguna manera de hacer que un parche creado con git format-patch sea compatible con svn para que pueda enviarlo a un svn repo?¿El parche de formato Git es compatible con svn?

Estoy trabajando en un svn repo en github y quiero volver a enviar mis cambios al repositorio principal. Necesito crear un parche para hacer esto, sin embargo, el parche no se puede aplicar ya que git formatea ese parche de manera diferente que svn. ¿Hay algún secreto que aún no haya descubierto?

ACTUALIZACIÓN: Aunque actualmente no existe una secuencia de comandos o una forma nativa de git para hacer esto, logré encontrar una publicación de este año acerca de cómo lograr esto manualmente. He seguido las instrucciones y tuve éxito al obtener mis parches de git para que funcionen con svn.

Si alguien pudiera intentar escribir un guión para lograr esto y contribuir al proyecto de git, todos serían muy apreciados.

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

+0

No puedo hacer que funcione ... ¿podría publicar todos los pasos necesarios? ¡Gracias! –

+1

Hola Anthony. ¿Consideraría cambiar la respuesta aceptada a la de Nicholas? –

+0

En segundo lugar la sugerencia de Simon, tener la respuesta de Nicholas Smith como la aceptada beneficiaría a todos, ya que es mucho más práctica. – Albireo

Respuesta

74

Siempre tengo que Google esto, pero la forma en que he encontrado que funciona perfectamente (para mí) es:

  • Crear el parche con git diff --no-prefix master..branch > somefile.diff, la parte maestra y de derivación son opcionales, depende de cómo desee obtener sus diferencias.
  • Enviarlo donde sea y aplicar con patch -p0 < somefile.diff.

Siempre parece funcionar bien para mí y parece ser el método más simple que he encontrado.

+0

Esto funcionó para mí, gracias –

+1

Esta es la manera canónica de generar un parche compatible con SVN con Git. Debe marcarse como la respuesta – mloskot

+0

'--no-pager' ya no es una opción para' git diff'. – naught101

3

hecho, es un feature request principios de 2008

Linus Torvalds dijo en ese momento:

Así que yo diría que se necesita algo más fuerte que decir "no hacer una git diff ", y eso también debería impedir la detección de cambio de nombre como mínimo.
Francamente, cualquier programa que sea tan estúpido como para no aceptar los parches de git actuales (es decir, TortoiseSVN), entonces condenadamente no deberíamos simplemente deshabilitar la parte más trivial. Deberíamos asegurarnos de no habilitar cualquier de las extensiones bastante importantes:
incluso si ToirtoiseSVN las ignoraría, si ignorarlas significa que no comprende la diferencia, no debe permitirse en absoluto.

Esa puede ser la razón

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

se ha introducido en Git1.5.6 en mayo/julio de 2008 (no he probado, aunque)

11

SVN probablemente no puede entender la salida de git diff -p, pero se puede recurrir a la fuerza bruta:

  1. Hacer dos clones de tu repositorio
  2. En un clon echa un vistazo a tus últimas novedades
  3. En el otro clon checkout todo lo que sea equivalente al svn upstream. Si ha planificado con anticipación, tiene una copia de svn upstream en su propia rama, o ha etiquetado la última versión de svn. Si no ha planeado con anticipación, use la fecha o gitk para encontrar el hash git SHA1 que más se aproxima al estado svn.
  4. Ahora calcule un parche real ejecutando diff -r sobre los dos clones.
+12

O simplemente siga la recomendación de @ Nicholas-smith y ejecute 'git diff --no-prefix> somefile.diff' en su repositorio de git y envíe eso a cualquier usuario de svn para que apliquen el parche con' patch -p0 DavidG

10

Subversion < 1.6 no tiene soporte para parches. Parece que Subversion 1.7 permitirá aplicar parches y las extensiones git/hg a diff unificado se encuentran en nuestra lista de TODO.

17

Aquí hay un script de ayuda para hacer un diff contra el último conjunto de cambios SVN y el commit dado: 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.*/===================================================================/" 
+0

Esto es muy útil, ¡gracias! – Avi

+1

Encontré que el valor de REV es incorrecto si no está trabajando con la última revisión de svn. Lo corregí para usar 'git svn info' en su lugar así: ' REV = \ 'git svn info | grep 'Última modificación Rev:' | sed -E 's /^.*: ([[: digit:]] *)/\ 1 /' \ '' –

+4

El origen de este fragmento parece provenir de: https://gist.github.com/44537 –

0

Asegúrese de que sus cambios están comprometidos y porcentualizada en la parte superior de la rama local de Git, de Git Bash plazo:

git show de --pretty >> myChangesFile.patch

0

La respuesta aceptada proporcionado por Nicholas funciona bien, excepto cuando a) existen archivos binarios en el diff ob) trabajas en Windows Git y tienes directorios con espacios. Para resolver esto, tuve que agregar un comando anidado git diff para ignorar los binarios y el comando sed para escapar de los espacios. Es un poco engorroso para escribir, por lo que crea 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 a continuación escribe:

git svnpatch Feature123 

... Feature123.patch un archivo de revisión se creará con las diferencias entre la fusión base de rama principal y rama Feature123.

Cuestiones relacionadas