130 votos

¿Es git-svn dcommit después de combinar en git peligroso?

Mi motivación para probar git-svn es el esfuerzo de la fusión y la ramificación. Entonces me di cuenta de que el hombre git-svn(1) dice:

"Ejecuta git merge o git-pull NO es recomendable en una rama planea dcommit. Subversion no representan fusiona en cualquier razonable o útil de la moda; de modo que los usuarios utilizando Subversion no puede ver cualquier fusiona que usted ha hecho. Además, si se mezcla o tirar de una rama de git, que es un reflejo de una rama SVN, dcommit puede cometer el mal rama".

¿Significa esto que no puedo crear una rama local de svn/trunk (o una rama), hack de distancia, mezcla de nuevo en svn/trunk, entonces dcommit? Entiendo que svn, los usuarios podrán ver el mismo lío que se funde en el svn pre 1.5.x siempre han sido, pero hay otros inconvenientes? La última frase me preocupa demasiado. ¿La gente rutinariamente hacer este tipo de cosas?

161voto

Sebastien Varrette Puntos 2277

De hecho, he encontrado una mejor forma con el --no-ff opción en git merge. Todo esto de squash de la técnica que he usado antes de que ya no es necesaria.

Mi nuevo flujo de trabajo es la siguiente:

  • Tengo un "maestro" de la rama que es la única rama que me dcommit, y que clone el repositorio SVN (-s suponga que tiene un estándar de SVN en el diseño del repositorio trunk/, branches/y tags/):

    git svn clone [-s] <svn-url>
    
  • Yo trabajo en una sucursal local de la "obra" (-b crea la rama de "trabajo")

    git checkout -b work
    
  • comprometerse a nivel local en el "trabajo" de la rama (-s a firmar el mensaje de confirmación). En la secuela, supongo que te hizo 3 local se compromete

    ...
    (work)$> git commit -s -m "msg 1"
    ...
    (work)$> git commit -s -m "msg 2"
    ...
    (work)$> git commit -s -m "msg 3"
    

Ahora quieren comprometerse en el servidor SVN

  • [Eventualmente] alijo de las modificaciones que no quieren ver comprometido en el servidor SVN (a menudo se comentó algo de código en el archivo principal sólo porque usted quiere acelerar la compilación y se centran en una determinada característica)

    (work)$> git stash
    
  • reajuste de la rama principal con el repositorio SVN (para actualizar desde el servidor SVN)

    (work)$> git checkout master
    (master)$> git svn rebase
    
  • ir de nuevo a la labor de sucursal y sujetar con el maestro

    (master)$> git checkout work
    (work)$> git rebase master
    
  • Asegúrese de que todo está bien con, por ejemplo:

    (work)$> git log --graph --oneline --decorate
    
  • Ahora es el momento de combinar los tres se compromete a partir de la "obra" de rama en "maestro", usando esta maravillosa --no-ff opción

    (work)$> git checkout master
    (master)$> git merge --no-ff work
    
  • Se puede observar el estado de los registros:

    (master)$> git log --graph --oneline --decorate
    * 56a779b (work, master) Merge branch 'work'
    |\  
    | * af6f7ae msg 3
    | * 8750643 msg 2
    | * 08464ae msg 1
    |/  
    * 21e20fa (git-svn) last svn commit
    
  • Ahora usted probablemente desee editar (amend) del último commit para su SVN tíos (de lo contrario van a ver sólo una única confirmación con el mensaje "Merge de la rama 'trabajo'"

    (master)$> git commit --amend
    
  • Por último commit en el servidor SVN

    (master)$> git svn dcommit
    
  • Volver a trabajo y, eventualmente, recuperar su escondidos en los archivos:

    (master)$> git checkout work
    (work)$> git stash pop
    

48voto

Greg Hewgill Puntos 356191

La creación de sucursales locales es definitivamente posible con git-svn. Mientras usted está usando sólo las ramas locales por sí mismo, y no tratando de usar git para combinar entre aguas arriba ramas del svn, que debe estar bien.

Tengo un "maestro" de la rama que yo uso para seguir el servidor svn. Esta es la única rama que me dcommit. Si yo estoy haciendo algo de trabajo, puedo crear un tema de rama y trabajan en ella. Cuando quiero hacer el commit, hago lo siguiente:

  1. Cometer todo para el tema de la rama
  2. git svn de reajuste (resolver cualquier conflicto entre su trabajo y el svn)
  3. git checkout master
  4. git svn de reajuste (este hace que el siguiente paso de un avance rápido de mezcla, vea la vara de Aarón de comentarios abajo)
  5. git merge topic_branch
  6. resolver cualquier combinación de los conflictos (no hay ninguna en este momento)
  7. git svn dcommit

También tengo otra situación en la que necesito para mantener algunos cambios locales (para depuración), que nunca debe ser empujado hacia arriba a svn. Por eso, tengo la de arriba, la rama principal, sino también una rama llamada "trabajo" de donde yo normalmente trabajo. Tema ramas se separaron de trabajo. Cuando quiero dedicar a trabajar allí, me checkout master y el uso de cherry-pick para recoger la cometa desde el trabajo de la rama que quiero comprometer a svn. Esto es debido a que quiero evitar cometer los tres locales de cambio se compromete. Entonces, yo dcommit de la rama principal y reajustar todo.

Vale la pena correr git svn dcommit -n primero para asegurarse de que usted está a punto de cometer exactamente lo que va a cometer. A diferencia de git, la reescritura de la historia en el svn es duro!

Siento que debe haber una mejor manera de combinar el cambio en una rama mientras saltarse los locales de cambio compromete a que el uso de cherry-pick, así que si alguien tiene alguna idea de que sería bienvenido.

31voto

Yaakov Belch Puntos 2489

Solución Simple: Quitar 'obra' la sucursal después de la fusión de

Respuesta corta: puede usar git sin embargo, usted como (ver más abajo para un flujo de trabajo simple), incluyendo la correspondencia. Sólo asegúrese de seguir cada uno de los 'git merge trabajo"con"git branch-d' para eliminar el trabajo temporal de la rama.

Fondo explicación: La combinación/dcommit problema es que cada vez que 'git svn dcommit' una rama, la combinación de la historia de esa rama es 'aplanado': git se olvida de todas las operaciones de combinación de lo que pasó en esta rama: Sólo el contenido del archivo se conserva, pero el hecho de que este contenido (total o parcialmente) vino de un específico otra rama se pierde. Ver: ¿por Qué git svn dcommit perder la historia de la combinación se compromete para con ramas locales?

(Nota: no es mucho lo que git-svn podría hacer al respecto: svn simplemente no entiende mucho más potente git se funde. Así, el interior del repositorio svn de este combinar la información no puede ser representado en cualquier forma.)

Pero este es todo el problema. Si elimina la 'obra' la sucursal después de que se ha fusionado en el 'master', el repositorio de git es 100% limpio y se ve exactamente igual que su repositorio svn.

Mi flujo de trabajo: Por supuesto, la primera vez clonado el control remoto del repositorio svn en un local del repositorio de git (esto puede tomar algo de tiempo):

$> git svn clone <svn-repository-url> <local-directory>

Todo el trabajo, entonces, que sucede en el interior del local "directorio". Siempre que necesito para obtener actualizaciones desde el servidor (como " svn update'), debo hacer:

$> git checkout master
$> git svn rebase

Hago todo mi trabajo de desarrollo en una rama separada del 'trabajo' que se crea como este:

$> git checkout -b work

Por supuesto, usted puede crear tantas ramas para tu trabajo, como te gusta y combinar y reajuste entre ellos como quieras (sólo borrarlos cuando haya terminado con él, como se discute a continuación). En mi trabajo normal, yo me comprometo con mucha frecuencia:

$> git commit -am '-- finished a little piece of work'

El siguiente paso (git rebase-i) es opcional --- es sólo la limpieza de la historia antes de archivar en svn: una Vez que llegó a un estable milla de piedra que quiero compartir con los demás, me reescribir la historia de este 'trabajo' rama y limpiar los mensajes de confirmación (otros que los desarrolladores no necesitan ver a todos los pequeños pasos y de los errores que he hecho en el camino --- solo el resultado). Para esto, debo hacer

$> git log

y copiar el hash sha-1 de la ultima revisión que está disponible en el repositorio svn (como se indica por una git-svn-id). Entonces yo llamo

$> git rebase -i 74e4068360e34b2ccf0c5869703af458cde0cdcb

Sólo tienes que pegar el hash sha-1 de nuestra última svn commit en lugar de la mía. Es posible que desee leer la documentación con 'git ayuda de reajuste " para los detalles. En resumen: este comando abre por primera vez un editor de presentar su comete ---- acaba de cambiar 'recoger' a 'squash' para todos los commits que desea la calabaza con el anterior comete. Por supuesto, la primera línea debe permanecer como una 'selección'. De esta manera, usted puede condensar sus muchas pequeñas se compromete en una o más unidades significativas. Guardar y salir del editor. Usted conseguirá al otro editor pidiendo que reescribir los mensajes de registro de confirmación.

En resumen: Después de terminar de código 'hacking', doy masajes a mi 'trabajo' de la rama hasta que se ve cómo quiero que me presente a los demás programadores (o cómo quiero que para ver el trabajo en un par de semanas cuando me vaya de la historia).

Con el fin de impulsar los cambios al repositorio svn, debo hacer:

$> git checkout master
$> git svn rebase

Ahora estamos de vuelta en el viejo 'maestro' de la rama actualizado con todos los cambios que han ocurrido en el momento en el repositorio svn (los nuevos cambios están ocultos en la 'obra' la sucursal).

Si hay cambios que pueden entrar en conflicto con su nueva " obra " los cambios, usted tiene que resolver localmente antes de que usted puede empujar a tu nuevo trabajo (ver detalles más abajo). Entonces, podemos pushear los cambios al svn:

$> git checkout master
$> git merge work        # (1) merge your 'work' into 'master'
$> git branch -d work    # (2) remove the work branch immediately after merging
$> git svn dcommit       # (3) push your changes to the svn repository

Nota 1: El comando 'git branch-d' es bastante seguro: sólo permite eliminar las ramas que usted no necesita más (porque ya están fusionados en su rama actual). Si se ejecuta este comando, por error, antes de combinar su trabajo con el 'maestro' de la sucursal, usted obtiene un mensaje de error.

Nota 2: asegúrese de eliminar su rama con 'git branch-d' entre la fusión y la dcommit: Si intenta eliminar la rama después de dcommit, usted obtiene un mensaje de error: Al hacer 'git svn dcommit', git se olvida de que su filial ha sido fusionado con el 'maestro'. Usted tiene que quitar con " git branch-D', que no hace el chequeo de seguridad.

Ahora, yo inmediatamente crear una nueva " obra " de la rama para evitar que accidentalmente la piratería en el máster de la rama:

$> git checkout -b work
$> git branch            # show my branches:
  master
* work

La integración de su 'trabajo', con cambios en el svn: Aquí es lo que yo hago cuando 'git svn reajuste' revela que los demás cambiado el repositorio svn mientras yo estaba trabajando en mi 'trabajo' rama:

$> git checkout master
$> git svn rebase              # 'svn pull' changes
$> git checkout work           # go to my work
$> git checkout -b integration # make a copy of the branch
$> git merge master            # integrate my changes with theirs
$> ... check/fix/debug ...
$> ... rewrite history with rebase -i if needed

$> git checkout master         # try again to push my changes
$> git svn rebase              # hopefully no further changes to merge
$> git merge integration       # (1) merge your work with theirs
$> git branch -d work          # (2) remove branches that are merged
$> git branch -d integration   # (2) remove branches that are merged
$> git svn dcommit             # (3) push your changes to the svn repository

Soluciones más potentes que existen: El flujo de trabajo es simplista: utiliza los poderes de git sólo dentro de cada ronda de 'actualizar/hack/dcommit' --- pero deja el proyecto a largo plazo de la historia tan lineal como el repositorio svn. Esto está bien si sólo quieres empezar a usar git se funde en pequeños primeros pasos en un legado de svn del proyecto.

Cuando esté más familiarizado con git fusión, siéntase libre de explorar otros flujos de trabajo: Si usted sabe lo que está haciendo, usted puede mezclar git se fusiona con el svn se funde (Usando git-svn (o similares) para ayudar con svn merge?)

8voto

Marius K Puntos 272

Greg Hewgill respuesta en la parte superior no es seguro! Si cualquier se compromete nuevo apareció el tronco entre los dos "git svn rebase", la fusión no será avanzar rápidamente.

Se puede asegurar mediante el uso de la bandera "--ff - sólo" a la combinación de git, pero generalmente no corro "git svn rebase" en la rama, único "git rebase maestro" en él (suponiendo que es sólo una rama local). Luego luego un "git fusión thebranch" está garantizado que avance rápido.

6voto

luntain Puntos 1779

Una manera segura para combinar ramas svn en git es utilizar git fusión--squash. Esto creará un único commit y parada para que puede agregar un mensaje.

Digamos que tienes una rama svn tema, llamada svn-rama.

git svn fetch
git checkout remotes/trunk -b big-merge
git merge --squash svn-branch

en este punto tienes todos los cambios desde el svn-rama aplastó a uno cometer esperando en el índice

git commit

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X