2010-05-26 10 views
20

Trabajo con un equipo pequeño que usa git para la administración de código fuente. Recientemente, hemos estado haciendo ramas de temas para hacer un seguimiento de las características y luego fusionarlas en el maestro localmente y luego enviarlas a un repositorio central de git en un servidor remoto. Esto funciona muy bien cuando no se han realizado cambios en el maestro: creo mi rama de tema, la comprometo, la fusiono en maestro y luego la presiono. Hurra.git rebase en actualizaciones remotas

Sin embargo, si alguien ha enviado a origen antes que yo, mis confirmaciones no son rápidas. Por lo tanto, se produce un compromiso de fusión. Esto también ocurre cuando una rama de tema debe fusionarse con el maestro localmente para garantizar que mis cambios funcionen con el código a partir de ahora. Por lo tanto, terminamos con confluencias de fusión en todas partes y un registro de git que rivaliza con un brazalete de amistad.

Por lo tanto, el rebase es la opción obvia. Lo que me gustaría es:

  • crear ramas puntuales que sostiene varias entregas
  • checkout master y tire (avance rápido porque no he cometido para dominar)
  • ramas puntuales rebase en el nuevo jefe de dominar
  • rebase los temas contra el maestro (por lo que los temas a empezar por la cabeza maestros), con lo que amo a mi tema cabeza

mi forma de hacer esto actualmente se enumeran a continuación:

git checkout master 
git rebase master topic_1 
git rebase topic_1 topic_2 
git checkout master 
git rebase topic_2 
git branch -d topic_1 topic_2 

¿Hay una forma más rápida de hacerlo?

Respuesta

10

he encontrado, con el tiempo, mi solución favorita es:

git checkout topic 
# make [n] commits 
git rebase -i HEAD~[n] #clean up time 
git checkout master 
git pull --rebase 
git checkout topic 
git rebase master 
git checkout master 
git merge topic 
git push origin 
+0

Es la última fusión necesaria. Puedo imaginar la novedad de ver todas las horquillas de trabajo en el gráfico, pero el código ya está integrado en el maestro y no creo que sea irrazonable descartar el código de trabajo si no se convierte en una verdadera bifurcación. De lo contrario, en mi humilde opinión, esta respuesta es perfecta. –

2

Para nuestro equipo, configuramos algo que funciona muy bien y no utiliza rebase en absoluto.

Recortamos nuestro trabajo en las entradas de Jira que no tardan demasiado, por lo general 1-2 días de esfuerzo. Cada desarrollador crea una rama por boleto y trabaja en esta rama. Cuando esté listo para compartir esto, se envía al servidor central.

El servidor central es supervisado por un servidor hudson CI que extrae los cambios, fusiona todas las ramas actualizadas, reconstruye el software, ejecuta las pruebas y lo envía todo al repositorio principal central de git.

A partir de ahí lo llevamos de vuelta a nuestros repositorios. Hacemos regularmente (es decir, cada dos días) fusionar nuestras ramas de trabajo con el maestro central para mantenerlas "cerca".

Dado que nadie está trabajando en la máquina 'fusionando' y nadie más que el servidor de CI toca el maestro, tenemos problemas de fusión muy poco frecuentes (en aproximadamente el 1-2% de las confirmaciones). Y estos se resuelven rápidamente en el servidor de compilación al limpiar el espacio de trabajo. Descubrimos que podríamos haber evitado la mayoría de estas manteniendo cortas las ramas y fusionándonos con el maestro remoto antes de presionar.

También me gusta que la fusión sea mucho más robusta que el rebasado y requiera mucha menos repetición.

+0

Eso es genial para un desarrollo más lento, pero tenemos un entorno que requiere algunas confirmaciones para subir todas las noches, mientras que otras esperan una versión más grande. Supongo que una forma de manejar eso es configurar todas las noches y liberar ramas en el repositorio remoto ... pero parece que podría invitar incluso a más de estas asignaciones de fusión si no se respetan por completo. Aunque también creo que la fusión es más 'robusta', nuestro equipo es capaz de descifrar git-rebase y resolver problemas. Tener un historial de compromiso más legible es tan importante para mí. –

+0

Personalmente, creo que las horquillas fusionadas son feas/desordenadas en la historia, por lo que siempre vuelvo a establecer la base temporal/ramas de desarrollo en el origen remoto. Aún así, me parece interesante que su grupo haya implementado efectivamente un plan de fusión solamente con pocos problemas y beneficios medibles. ¿Refunda en su horario de extracción regular para mantener las cosas más cerca del maestro central? ¿Qué implica "limpiar el espacio de trabajo"? Y, ¿extraes y rebases para verificar conflictos antes de fusionarte con el repositorio central? –

+0

@EvanPlaice La limpieza del área de trabajo está borrando el directorio de trabajo en Jenkins. La próxima vez que se haga un clon nuevo. –

30

¿Conoce git pull --rebase? Se rebases en lugar de fusionarse cuando tiras, y evita que los commits de fusión contaminen tu historial.

También puede configurarlo como el comportamiento predeterminado para una rama con las opciones de configuración branch.<name>.rebase y branch.autosetuprebase.

+2

sí, y lo uso con frecuencia cuando actualizo una base de código compartido a la última desde remoto. Sin embargo, esta publicación fue más sobre las ramas de características una forma más simplificada de hacerlo y git pull rebase no es IMO. Sin embargo, la rebase automática de rama es una característica increíble y ya la he agregado a algunos repositorios. ¡Un gran consejo! :) –

1

También se puede simplemente rebase en contra de la puesta al día maestro

git checkout topic_1 
git rebase refs/remotes/origin/master 

que obvia la necesidad de que el tirón (al menos hasta el EOL de su rama de características). Nuestro proceso utiliza las solicitudes de extracción de GitHub, por lo que nunca tendré que hacerlo localmente.