tortoise subversion from con branches svn rebase svn-reintegrate

svn - subversion - tortoise branch to trunk



Subversion rebase? (5)

Desearía tener un truco ingenioso para decirte cómo lograr el rebasado en SVN, pero siempre he evitado la actualización manual de una rama con cambios en el tronco en SVN principalmente debido a las complicaciones que requieren la selección manual de cereza que menciona jdehaan.

Lo que generalmente hago en cambio es seguir la práctica de fusionar los cambios de una rama al tronco, eliminar la rama y luego volver a crear la rama desde el tronco. Esto me permite actualizar / volver a establecer la base de mi rama de características, pero con el desafortunado efecto secundario de que los cambios anteriores de esa rama ahora forman parte del tronco. Por este motivo, solo sigo esta práctica cuando una rama de características se encuentra en un punto estable y utilizable, pero aún así deseo continuar trabajando en esa característica para poder completar un objetivo más grande.

Lo que preferiría es que al actualizar una rama al fusionar los cambios de troncales en una rama no se produzcan fusiones de reintegración posteriores de esa rama para extraer esas revisiones reordenadas durante el proceso. Debería ser posible hacerlo en base a las propiedades de información combinada, pero de acuerdo con lo que jdehaan declara y lo que he temido es que hacer esto todavía requiere una recolección selectiva.

Tenga en cuenta que la implementación correcta de rebasado también debería ser capaz de tomar en consideración los ejemplos de la caja de escalera donde una rama se hace desde otra rama.

Actualización: según la documentación de Subversion, parece que al usar la opción --reintegrate que Subversion debería ser capaz de reintegrar correctamente el trabajo realizado en una sucursal de una manera que descarta cualquier fusión posible que se haya hecho para llevar los cambios de base al rama. Por supuesto, esto es técnicamente un poco diferente al rebasado, pero creo que es lo suficientemente similar en el uso que podría denominarse como rebase.

Me resulta más fácil fusionar ramas y menos conflictos:

Copie el tronco en una nueva rama, combínelo con la rama / s de características. Cuando haya terminado, combine la nueva rama con el tronco. Esta técnica es bastante similar a la modificación mercurial y git.

Solía ​​fusionar cualquier changs del tronco para presentar branche / s. Pero más tarde, cuando fusioné la rama de características con el tronco, algunas de las cosas del tronco se fusionaron nuevamente al tronco, lo que causó muchos conflictos. Hay una elección de fusión de reintegración, pero no pareció funcionar para mí.

¿Alguien hace similar rebase de subversión? Empecé a hacer esto recientemente y no he visto ningún efecto secundario. ¿Esto causaría algún problema imprevisto?


En mi empresa usamos el siguiente enfoque:

  1. para cada tarea NK- $ X en el rastreador de problemas, tenemos sucursales separadas / NK- $ X
  2. comenzamos a trabajar en una tarea por svn cp trunk branches / NK- $ X
  3. nunca realizamos cambios directamente al tronco. Para cada actualización programada UPDNK- $ X tenemos sucursales separadas / UPDNK- $ X. Lo creamos con svn cp trunk branches / UPDNK- $ X justo antes de la actualización.
  4. cuando la tarea NK- $ X está programada para una actualización UPDNK- $ Y fusionamos branches / NK- $ X inot UPDNK- $ Y. Eso es cd UPDNK- $ Y; svn merge -r start: HEAD branches / NK- $ X
  5. después de que UPDNK- $ Y esté listo, lo fusionamos en trunk. Eso es cd trunk; svn merge -r start: HEAD branches / UPDNK- $ Y

Si sucede que la tarea NK- $ X dura más de un ciclo de iteración y, por lo tanto, necesita una actualización, NUNCA, nunca, NUNCA fusionaremos troncal a NK- $ X. Tenemos una regla según la cual usted se compromete con su sucursal solo con las cosas que usted mismo escribió, lo cual hace que todo sea más fácil. En cambio, hacemos:

cd NK-$X svn log //let L = the number of the last changeset to this branch changeset //let F = the number of the first changeset to this branch svn rm branches/NK-$X svn cp trunk branches/NK-$X svn up svn merge -r F:L branches/NK-$X@L svn ci -m ''refereshed''

De esta forma, cada vez que mires el registro de cambios de las sucursales / NK- $ X, solo verás los cambios realizados por el desarrollador.

Actualización: Dado que el flujo de trabajo anterior se puede automatizar, he comenzado un proyecto en github: svn rebase .


En términos generales, la rebase es el acto de incorporar cambios ascendentes en una rama de características, antes de fusionar la rama de características nuevamente en la rama ascendente.

En git, el proceso es aún más sofisticado, porque los cambios que se han realizado desde que se creó la bifurcación se quitan y se almacenan temporalmente, se aplican los cambios ascendentes y luego se aplican los cambios almacenados. La conclusión aquí es fusionar el enlace troncal en una rama característica, no es una rebase en términos git, hay mucho más. El enfoque git tiene una serie de ventajas, pero no se puede implementar muy limpiamente en svn, ya que todas las confirmaciones deben almacenarse en el servidor (svn no se distribuye), sin embargo, se puede hacer en svn.

Una ''svn rebase'' (la forma de Git) podría parecerse a esto

  1. svn cp trunk feature
  2. se compromete con la función y el tronco
  3. svn cp trunk feature-rebase
  4. svn co feature-rebase
  5. cd feature-rebase
  6. svn merge feature
  7. svn commit
  8. svn rm feature
  9. svn mv feature-rebase feature
  10. (de nuevo en el WC de feature-rebase) función svn switch feature

Luego, finalmente, en una copia de trabajo de trunk, svn merge --reintegrate feature

¿Ves la diferencia de simplemente fusionar el tronco con la rama de características? En este ejemplo, comienza con lo último de la línea de enlace ascendente, luego combina los cambios de la función en eso.

Imagine que algunas de las confirmaciones en el tronco podrían provenir de una combinación de otra rama de características en el tronco, por lo que no estoy abogando por comprometerse directamente con el tronco.


Estoy usando este enfoque:

Con el rebasamiento, debe tener cuidado de no tomar las revisiones nuevamente cuando vuelva a fusionar. En lo que respecta a la fusión, realice una selección al azar: seleccione solo las revisiones en la rama de características que implementan algo nuevo, no los conjuntos de cambios de rebase. Entonces debería funcionar bien. COMENTARIO: No recuerdo haber usado alguna vez la rama de reintegración. Creo que es solo para casos de uso muy simples.

En su nuevo enfoque, de la descripción no queda claro cómo maneja la rebase desde el troncal hasta sus ramas de características, si es necesario. ¿Quieres deshabilitar por completo el rebasamiento? Como la bifurcación en svn es una operación económica, esta podría ser una opción también.


Uso un script que hace un git como rebase para svn:

#!/bin/bash set_safe() { set -eo pipefail } validate_number() ( if (! [ "$1" -eq "$1" ] 2>/dev/null ) then { echo "$1 is not a number" return 1 } fi ) get_line() ( set_safe #head -n "$1" | tail -n 1 sed -n "${1}p;$(($1+1))q" ) split_trim() ( set_safe tr "$1" ''/n'' | sed -e ''s/^/s*//;'' -e ''s//s*$//'' ) run_svn() ( set +x #echo "svn $*" 1>&2 svn --non-interactive --password "$svn_password" "$@" ) rebase() ( set_safe url="$1" cur="$2" end="$3" validate_number "$cur" if ([ -z "$end" ] || [ "$end" = "HEAD" ]) then { end="$(run_svn info "$url" | grep "Last Changed Rev" | cut -d'' '' -f4)" echo "end: $end" } else { validate_number "$end"; } fi while (true) do { log="$(run_svn log "$url" -l1 -r "$cur:HEAD")" meta="$(echo -n "$log" | get_line 2 | split_trim ''|'')" next="$(echo -n "$meta" | get_line 1 | tail -c +2)" author="$(echo -n "$meta" | get_line 2)" date="$(echo -n "$meta" | get_line 3 | awk ''{print $1, $2, $3}'')" msg="$(echo -n "$log" | tail -n +4 | head -n -1)" cur=$next if ([ -z $cur ] || [ $cur -gt $end ]) then { break; } fi echo "$msg" > .msg echo "Merging revision $cur:" echo "========" cat .msg echo "========" run_svn merge "$url" -c $cur run_svn commit -F .msg rm -f .msg run_svn update echo "Success" echo cur=$(($cur + 1)) } done ) if ([ -z "$1" ]) then { echo "Usage:" echo " svn-rebase.sh <url> <begin revision> [end revision]" exit } fi echo -n "svn password: " read -s svn_password echo rebase "$1" "$2" "$3" err=$? if ([ $err -ne 0 ]) then { echo "rebase failed: $err"; } fi exit $err

Combina revisiones de otra rama una por una.