Si alguna vez hay que trabajar con un repositorio svn...
Comandos basicos
Clonar un repositorio svn (equivalente a git clone)
git svn clone [url]
Bajar últimos cambios del repositorio svn (equivalente a git fetch)
Bajar ultimos cambios e integrar con cambios propios (equivalente a git pull --rebase)
git svn rebase
Commitear cambios (equivalente a git push)
git svn dcommit
Mantener linealidad
Mientras git es un versionador diseñado para representar cambios no-lineales, la estructura de svn representa cambios lineales, esto en terminos de usar git con svn significa que siempre sin excepción los cambios que se hacen al master local deben ser lineales, es decir que no se permiten merge commits, en el workflow normal de git-git es frecuente que se generen merge commits cuando se hace pull de cambios que divergen, pero esa operacion se reemplaza por git svn rebase en el workflow de git-svn, la cual mantiene la linealidad re-aplicando los commits divergentes locales en la rama remota.
Eso quiere decir que si uno commitea B despues de A en la rama local, y otro commitea C despues de A, cuando el primero hace git svn rebase quedara lineal, asi:
A -C - B'
Mientras que en git queda la ramificacion de C y B y el merge commit que une ambas lineas divergentes.
Local Branches: De manera local se puede diverger
No hay ningun problema en hacer branches locales, el unico impedimento es que esos branches no se pueden publicar al servidor svn de una manera practica (existe una forma, pero es tan engorrosa que es mejor no utilizarla en un principio).
Lo que es muy importante tener en cuenta, es que si se necesita integrar esos branches a la rama principal con el objetivo de commitearlo a svn hay que hacerlo preservando la linealidad de la rama principal, esto se puede hacer con un squash merge (es la opcion q mas me gusta) o con rebase, rebase es mas complicado pero mantiene todo el historial del branch y yo en lo personal no lo considero conveniente por razones que voy a explicar mas adelante.
Local Merges al trunk: Mantener linealidad --squash
Suponiendo que hay que mergear un branch al master, hay que hacerlo de esta manera:
git merge --squash nombre_del_branch
Ese comando pone el resultado del merge en el indice y la working copy , posteriormente hayque commitear con el mensaje que se considere apropiado y por supuesto ese commit no rompera la linealidad. Esto mezcla todos los cambios del branch en un solo commit
Local Merges al trunk: Mantener linealidad con rebase
Rebasear el branch al master y despues mergearlo (debe ser fast-forward)
git checkout nombre_del_branch
git rebase master
git checkout master
git merge --ff-only nombre_del_branch
El primer comando cambia el branch actual a nombre_del_branch, el segundo lo rebasea a master (es decir, mueve todos los commits divergentes para que esten
linealmente a continuacion de master), vuelve a master otra vez y mergea el branch rebaseado, la opcion --ff-only es para indicar que solo haga el merge si es fast-forward
Remote branches: Mejor NO
Da problemas especialmente cuando se elimina un branch y tiende a ser complejo, podria servir como una herramienta para manipular branches de svn de manera mas facil pero generalmente trae complicaciones si uno no esta ducho con la combinacion git-svn
Hacer commit frecuente pero dcommit no tan frecuentes ni tan pesados
Normalmente en git no es un problema hacer push de varios commits, pero efectuar un dcommit que envie muchos commits a svn no conviene. La razon es que git svn dcommit convierte cada commit local de git en un commit de svn y lo envia, este proceso es muy costoso en terminos de network en comparacion del git push de siempre (esto sin contar posibles problemas de race condition mas probables en dcommits que tarden mucho).
Debo los links