Git-svn fusiona dos twigs SVN

He leído numerosas preguntas y blogs SO sobre git-svn y fusión. Algunos de ellos (en particular, la página de manual de git-svn ) advierten contra el uso de fusionar en cualquier lugar cerca de la sucursal que planeo dcommit .

Otros, como esta respuesta SO , afirman que la fusión está bien siempre que use twigs de características dcommitting que borre antes de realizar la dcommitting .

Tengo una configuration con dos twigs SVN (y git) de larga vida:

  • tronco (git-svn: svn/trunk , git: master ) – la twig estable
  • branches / devel (git-svn: svn/devel , git: devel ): la twig de desarrollo principal desde la que se bifurcan las twigs de característica (y puedo vivir con su rebase en devel en lugar de fusionar).

Instantánea del estado actual en el Árbol de fuentes

En la image de arriba, (1) muestra el historial pasado de SVN, donde branches/devel se ha fusionado en trunk .

(2) muestra que he dcommitted éxito mi desarrollo actual de nuevo en SVN.

La pregunta: ¿puedo usar git-svn para fusionar dos twigs SVN para que el historial muestre el punto de fusión (como lo hace SVN)? En otras palabras: ¿qué sucede si dcommit que dcommit con el master como se muestra en (3) ?

¿Esto arruinará mi historial de SVN (o git)? ¿O simplemente olvidará que devel se fusionó en master ?

EDITAR: Si git solo olvida que el devel se fusionó con el master , ¿hay alguna diferencia entre dcommiting punto (3) y aplicar todas las confirmaciones como un solo parche ?

Investigando un poco más sobre el asunto, descubrí que git soporta la configuration de la propiedad svn:mergeinfo en la twig SVN cuando se dcommit :

 git svn dcommit --mergeinfo "/branches/somebranch:1-3" 

¡NÓTESE BIEN! el svn:mergeinfo se sobrescribe con lo que se da en la command-line, así que tenga cuidado de include las fusiones anteriores también .

Mientras que la versión más reciente de Git agregó el parámetro de configuration para establecer automáticamente esta propiedad:

 config key: svn.pushmergeinfo 

Tuve algunos problemas con el mergeinfo automático, por una razón u otra, el GIT lo calculó mal y no pude hacerlo funcionar.

SOLUCIÓN: git-merge-svn

Para automatizar el process, escribí un script de shell git-merge-svn que se puede usar para fusionar dos twigs de SVN con el set de svn:mergeinfo correcto en el dcommit.

El script maneja ambas situaciones:

  • la twig no está fusionada en git – hará la git merge antemano
  • las twigs ya se han fusionado en git (pero no en SVN): se desplazarán hasta el ancestro anterior para las revisiones de compromiso fusionadas.

Con este script, pude producir estas fusiones únicamente en git-side y conservar la información de fusión para que el gráfico de GIT muestre el logging muy bien:

resultado de git-merge-svn

Ejemplo de uso:

  1. Hacer algunos commits en devel6
  2. dcommit devel6 a SVN ( requerido para get los numbers de revisión de SVN para las confirmaciones)
  3. echa un vistazo a testtunk6 – sí, sé que hice un error tipográfico en el nombre 😉
  4. git merge-svn devel6

Los últimos resultados commant:

 % git merge-svn devel6 About to do an SVN merge: devel6 -> testtunk6 * NEW MERGE COMMIT |\ | * devel6 [7b71187] (r102) * | testtunk6 [0682a45] (r101) \| * [273d6d6] (r100) STEP 1: GIT merge Executing: git merge devel6 Continue? (y/n) [n]: y Merge made by the 'recursive' strategy. testfile | 1 + 1 file changed, 1 insertion(+) STEP 2: SVN dcommit executing: git svn dcommit --mergeinfo /idp/branches/devel:9-32,35-41 /idp/branches/devel6:89 /idp/branches/devel6:94 /idp/branches/devel6:93 /idp/branches/devel6:96 /idp/branches/devel6:97 /idp/branches/devel6:99 /idp/branches/devel6:100 /idp/branches/devel6:102 Continue? (y/n) [n]: y Committing to https://my.svn.host/svn/auth/idp/branches/testtunk6 ... M testfile Committed r103 M testfile Found merge parent (svn:mergeinfo prop): 7b71187fc371d3f86658c5850009e63be88157ac r103 = 87759323cbadd38bac78087d57b6870a926287e7 (refs/remotes/svn/testtunk6) No changes between 3fb2168cfbbe605fbd810d76513443203a85a549 and refs/remotes/svn/testtunk6 Resetting to the latest refs/remotes/svn/testtunk6 

Git y Svn tienen una estructura de datos diferente para mantener una historia.

Svn usa un tree simple. Es decir, cada compromiso tiene solo un padre, pero un compromiso puede tener varios hijos (twigs). Entonces, Svn no admite fusiones. Lo que ellos llaman "fusión" es en realidad la migration de sets de cambios, la analogía más cercana en git es la rebase o tal vez cherry-pick . Desde la versión 1.5 Svn es compatible con una propiedad de metainfo svn:mergeinfo que ayuda de alguna manera a rastrear lo que se "fusionó", sin embargo, se ve principalmente como una solución alternativa, que explica por qué las twigs en Svn son tan difíciles de usar. El punto de fusión es un compromiso que aplasta todos los sets de cambios fusionados y la resolución de conflictos en un solo set de cambios, probablemente anotado con la propiedad svn:mergeinfo .

Git usa el gráfico acíclico Dirigido, que es una forma muy natural de describir la fusión y ramificación de la historia. Un punto de fusión es simplemente otro compromiso con dos (o más) padres. Por lo tanto, su (3) en la image es una fusión de compromiso. Entonces, toda la historia parece natural, tiene todos los compromisos alcanzables en un gráfico de historia desde el punto actual.

El puente de Git-Svn intenta hacer lo mejor para manejar el inconveniente de layout de Svn, antes de hacer un dcommit , por lo general rebase todas las dcommit fusionadas en la parte superior de la twig de Svn actual. Asof ~ Hace 2 años, git-svn no pudo suministrar svn:mergeinfo , por lo que lo que está preguntando es imposible. Además, cuando se dcommit , git crea una confirmación "gemela" "poco" vinculada a una confirmación svn, por lo que reescribe la confirmación original.