2009-08-10 17 views
25

Dadas varias confusiones git sin asentar, ¿es posible git-svn dcommit solo una de esas confirmaciones?git-svn dcommiting un commit de git simple

p. Ej. He confirmado foo, bar y baz, pero ahora solo quiero que la barra termine en el svn repo. es posible?

+0

son commits foo, bar y baz ya en la rama principal que está rastreando el svn repo? – Pradeep

+0

En mi caso, no. Pero es bueno mostrar cómo hacerlo en ambos sentidos. – baudtack

Respuesta

4

Tengo un tipo de respuesta crujiente. Puede crear una nueva bifurcación con out foo, bar y baz en ella y luego cherry-pick bar en la nueva bifurcación y luego git-svn dcommit que se bifurcan y eliminan cuando haya terminado. Aunque eso no parece muy elegante.

Suponiendo que foo, bar y baz están en la rama x y master no tiene ninguna de ellas.

git branch y master

git checkout y

git cherry-pick <sha1 of bar>

git svn dcommit

git checkout x

git svn rebase

git branch -d y

Si maestro tiene estas confirmaciones puede restablecer la cabeza como sugiere Sizzler.

+0

Me gustaría comprometer la rama principal y mantener esos otros bits separados. También puede usar el alijo aquí. –

+0

@Ben No estoy seguro de cómo comprometer la rama principal ayudaría. Ya tengo foo y bar y baz as commits en git. Simplemente aún no han llegado al repositorio svn. Si hago una nueva sucursal y escojo las que quiero, entonces solo obtengo esas confirmaciones. – baudtack

+0

si trabajas en master y aún quieres hacerlo de esta manera puedes usar: "git checkout trunk -by" - si eso no funciona para ti, mira en git svn docs y busca las opciones de diseño – haggi

13

git svn dcommit no puede confirmar la barra de forma selectiva. si has confirmado directamente foo, bar y baz en tu rama principal, entonces tienes que hacer lo siguiente para obtener solo la barra en svn.

Supongamos bar del sha cometen es algo así como 13abc ...

y master git log muestra todas las 3 comete foo, bar y baz.

  • es necesario crear una rama de maestro

    WIP git branch

la rama WIP tiene ahora foo, bar y baz

  • restablecer la cabeza del maestro a un commit antes de cualquiera de foo, bar o baz. que puede hacer que el uso de git reset (leer el manual, las diferencias entre las opciones duras, blandas y mixtos afecta cambios no confirmados en su árbol de trabajo)

    git restablecer --hard (COMMIT-identificación antes de foo, bar, baz)

    (o)

    git reset CABEZA --hard ~ 3 (Retroceder 3 revisiones)

ahora su rama principal tiene ninguno de foo, bar o Baz. verificar con git log.

  • ahora puedes seleccionar solo las confirmaciones que deseas comprometer a svn desde la rama wip en master. así que para obtener la barra

    git cherry-pick WIP 13abc (sha de la barra de cometer)

el maestro sólo se pone la barra de cometer solo.

  • ahora git svn dcommit should push bar alone.

sugerido el uso futuro

Así que para git-svn es preferible no hacer compromete directamente en la rama principal, que es el seguimiento de svn remoto. haga su trabajo en las sucursales locales y fusione selectivamente para dominar antes de comprometerse.

+0

I He escuchado opiniones diferentes sobre dónde debería ocurrir la fusión. La forma en que lo hago ahora es branch y dcommit y luego rebase master. Mantengo a master como la rama de seguimiento canónica y hago mi trabajo en otras ramas. Luego envío esos cambios a svn y los arrastro hacia master. Así es como se sugirió que lo haga en #git en freenode. Lo estaba haciendo de la forma en que sugieres antes, pero es un paso adicional ya que necesitas unir los cambios en maestros en lugar de simplemente presionarlos para convertirlos en svn y volverlos a bajar con rebase. – baudtack

26

(Lo siguiente asume su trabajo está en master.)

En primer lugar, cambiar el orden de sus últimos tres confirmaciones de manera que bar es primero.

git rebase -i HEAD~3 

Un editor aparecerá con algo como esto:

pick 498e4f4 foo 
pick 71547ae bar 
pick abf09c6 baz 

# Rebase 4d3fe72..abf09c6 onto 4d3fe72 
# 
# ... 

reordenarlos en el editor que aparece de manera que bar que ocurra primero.

pick 71547ae bar 
pick 498e4f4 foo 
pick abf09c6 baz 

# Rebase 4d3fe72..abf09c6 onto 4d3fe72 
# 
# ... 

Git girará durante unos segundos y eructar una confirmación:

Successfully rebased and updated refs/heads/master. 

Ahora puede rodar temporalmente a la bar commit (HEAD~2 significa dos confirmaciones de vuelta de HEAD) y dcommit que:

git checkout HEAD~2 
git svn dcommit 

Si usted es paranoico como yo, puede hacerlo git svn dcommit -n primero para asegurarse de que sólo está cometiendo lo usted quiere.

Ahora salta de nuevo a master:

git checkout master 

El último bit es rebase de manera que master se sincroniza con SVN:

git svn rebase 

Es un poco confuso para mí por qué esto es necesario, pero Supongo que comprometerse en un estado HEAD aislado tiene algo que ver con eso.

+0

Encuentro esta respuesta más fácil de entender que las otras. Perfect use-case para 'git svn dcommit -n' o' --dry-run'. – hdl

1

A veces solo quiero comprometer algunas confirmaciones de mi sucursal. P.ej.

A-----B-----C------D 
^    ^
|     | 
svn/trunk   trunk 

Si quiero cometer B y C pero no D creo una nueva rama, hacer un svn dcommit, volver a trunk y eliminar la rama.

Mientras estoy en la rama trunk hago

git checkout -b temp `C` 
git svn info // just to check that branch temp is properly connected to svn 
git svn dcommit 
git checkout trunk 
git branch -D temp 

EDITAR

Al igual que Stefan comentó:

con un adicional 'git svn rebase' funcionó bien para mí .

Esto es necesario, porque las confirmaciones que se confirman con svn se reescribirán. git-svn agrega el git-svn-id al mensaje de confirmación y, por lo tanto, el hash de confirmación cambia incluso si el contenido de la confirmación es el mismo. Pero dado que los contenidos son los mismos, la rebase no causará conflictos.

PS: Yo también a menudo se omite la nueva rama y justo la caja separada. P.ej.

git checkout --detach C 
git svn dcommit 
git checkout trunk 
git svn rebase 
+1

Con un 'git svn rebase' adicional funcionó bien para mí. – Stefan

+0

@Stefan sí, eso es cierto. Lo perdono y actualizaré mi respuesta. La rebase es necesaria, porque los commit serán reescritos por git-svn. Agrega el 'git-svn-id' al mensaje de confirmación. –