¿Git format-patch será compatible con svn?

96

¿Hay alguna forma de hacer que un parche creado con git format-patch sea compatible con svn para poder enviarlo a un repositorio svn?

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

ACTUALIZACIÓN: aunque actualmente no existe un script o una forma nativa de git para hacer esto, logré encontrar una publicación de principios de este año sobre cómo lograr esto manualmente. Seguí las instrucciones y tuve éxito al hacer que mis parches de git funcionaran con svn.

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

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

rip747
fuente
No puedo hacer que funcione ... ¿podrías publicar todos los pasos necesarios? ¡Gracias!
Mauricio Scheffer
1
Hola Anthony. ¿Consideraría cambiar la respuesta aceptada por la de Nicholas?
Simon East
Apoyo la sugerencia de Simon, tener la respuesta de Nicholas Smith como la aceptada beneficiaría a todos, ya que es mucho más práctico.
Albireo

Respuestas:

90

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

  • Cree el parche con git diff --no-prefix master..branch > somefile.diff, la parte maestra y la rama son opcionales, depende de cómo desee obtener sus diferencias.
  • Envíalo a donde quieras y aplica con patch -p0 < somefile.diff.

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

Nicholas Smith
fuente
1
Esta es la forma canónica de generar un parche compatible con SVN con Git. Debe marcarse como la respuesta.
mloskot
--no-pagerya no es una opción para git diff.
naught101
Originalmente se publicó sin --no-pager, no estoy seguro de por qué se agregó en la edición. Siempre me ha funcionado bien sin de --no-pagertodos modos.
Nicholas Smith
2
Solo para una confirmación en particular: git diff --no-prefix 056a1ba5140 7d939289b80 >my.patchfuncionó para mí (donde 056a1ba5140y 7d939289b80son los sha-1 de la confirmación anterior y particular en git).
Ed Randall
@ Lilás esto es un problema con SVN. Las diferencias / parches en SVN nunca han podido manejar archivos eliminados
Toofy
17

Aquí hay un script de ayuda para hacer una diferencia con el último conjunto de cambios svn y la confirmación dada: 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
fuente
1
Descubrí que el valor REV es incorrecto si no está trabajando con la última revisión de svn. Lo corrigí para usarlo git svn infoasí: REV=`git svn info | grep 'Last Changed Rev:' | sed -E 's/^.*: ([[:digit:]]*)/\1/'`
Sebastien Martin
1
¡Esto es IMPRESIONANTE! Muchas gracias. Tuve que hacer un cambio para que funcionara para importar mis parches al crisol de Fisheye, y fue reemplazar los espacios antes de "(revisión" con una pestaña en su lugar.
Zugwalt
10

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

  1. Haz dos clones de tu repositorio
  2. En un clon, mira tus últimas novedades
  3. En el otro clon checkout, lo que sea equivalente al svn upstream. Si ha planeado 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 de git SHA1 que más se aproxime al estado de svn.
  4. Ahora calcule un parche real ejecutando diff -rlos dos clones.
Norman Ramsey
fuente
12
O simplemente siga el consejo de @ Nicholas-smith y ejecútelo git diff --no-prefix > somefile.diffen su repositorio de git y envíelo a cualquier usuario de svn para que aplique el parche patch -p0 < somefile.diffen la raíz del proyecto.
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 están en nuestra lista TODO.

Bert Huijben
fuente
4

De hecho, es una solicitud de función a principios de 2008

Linus Torvalds dijo en ese momento:

Así que yo diría que necesitas algo más fuerte para decir "no hagas un git diff", y eso también debería deshabilitar 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 no deberíamos deshabilitar la parte más trivial. Debemos asegurarnos de no habilitar ninguna de las extensiones bastante importantes:
incluso si ToirtoiseSVN las ignora, si ignorarlas significa que no entiende bien la diferencia, no debería permitirse en absoluto.

Puede ser por eso

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

se introdujo en Git1.5.6 en mayo / julio de 2008 (aunque no lo he probado)

VonC
fuente
0

Asegúrese de que sus cambios estén confirmados y basados ​​en la parte superior de su rama git local, desde git bash run:

git show --pretty >> myChangesFile.patch

Ismail Hawayel
fuente
0

La respuesta aceptada proporcionada por Nicholas funciona bien, excepto cuando a) existen archivos binarios en el diff ob) está trabajando en Windows Git y tiene directorios con espacios. Para resolverlo, tuve que agregar un comando git diff anidado para ignorar los binarios y el comando sed para escapar de los espacios. Es un poco complicado de escribir, así que creé 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 luego escribe:

git svnpatch Feature123

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

Leandro Gómez
fuente