Trabajar con Git y Perforce: flujo de trabajo de integración
Imagina que tu equipo trabaja de forma independiente en un repositorio de Git, pero una parte de la organización sigue usando Perforce para gestionar partes del mismo código base. Los equipos de Perforce no tienen intención de migrar, pero tu equipo ya ha hecho la transición a Git (por muchas buenas razones). Es importante que puedas mantener un proceso de intercambio de código bidireccional continuado entre ambos códigos base para que las mejoras desarrolladas en cualquiera de las versiones se puedan compartir sin que cueste demasiado tiempo o retrase a tu equipo.
Aquí es donde entra en juego esta guía. En TomTom, esta operación de sincronización se realiza una vez con cada nueva publicación, es decir, una vez cada seis semanas.
-- Este artículo se ha escrito en colaboración con Andrea Carlevato, Adolfo Bulfoni y Krzysztof Karczewski, quienes tuvieron la amabilidad de compartir el proceso de Git que utiliza la unidad NavApps de TomTom. --
Supuestos de partida
Asumiremos que ya estás familiarizado con el uso básico de Git y con un flujo de trabajo de ramas de función. Si no es así, te recomendamos ver un tutorial o un seminario web. Regresa cuando lo hayas hecho, te esperamos.
Durante el proceso hay que tener en cuenta algunos detalles importantes, así que deberías extremar las precauciones al realizar estas integraciones. ¡Seguimos cuando lo tengas todo listo!
Instalación de git p4
El primer paso es instalar el puente. Escribe esto en la línea de comandos para comprobar si ya lo tienes:
git p4
Si el sistema avisa de que git p4
no está instalado, descarga git-p4.py y guárdalo en una carpeta en tu PATH
, por ejemplo, ~/bin
(obviamente, Python también deberá estar instalado para que funcione).
Hazlo ejecutable de esta forma:
chmod +x git-p4.py
Para modificar el archivo ~/.gitconfig
añade:
[alias]
p4 = !~/bin/bit-p4.py
A continuación, ejecuta git p4
de nuevo y no deberías recibir ningún error. Si es así, la herramienta está instalada.
Material relacionado
Cómo mover un repositorio de Git completo
VER LA SOLUCIÓN
Aprende a usar Git con Bitbucket Cloud
Resumen del flujo de trabajo
Clonado inicial
Los proyectos de P4
pueden generar historiales enormes, por lo que el equipo puede elegir un punto de corte desde el que sincronizar, lo que ahorra mucho espacio y tiempo. git p4
permite elegir la lista de cambios desde la que iniciar el seguimiento:
git p4 clone //depot/path/project@<earlier-cutoff-point>,<latest-changelist>
- Ahora podemos ejecutar una sincronización y verificar que hemos recibido todos los conjuntos de cambios localmente:
git p4 sync
El comando sync
busca nuevos cambios en P4
y los importa como confirmaciones de Git.
- Nombramos la rama que usaremos para interactuar directamente con Perforce
p4-integ
. En este punto, solo queremos bifurcarla a partir deremotes/p4/main
:
git checkout -b p4-integ origin/p4/main
Sincronización rápida de seguimiento ("bait and switch")
Una vez finalizada la primera importación, las sincronizaciones posteriores de git->p4
se pueden realizar con los siguientes comandos:
git checkout p4-integ
git p4 sync
Lo anterior funciona, pero puede ser lento. Una forma mucho más rápida de ejecutar la sincronización es recrear refs
idénticas a las utilizadas en la última integración. Esta también es una buena manera de asegurarse de que los desarrolladores nuevos que se encarguen de la integración comiencen en la lista correcta de confirmaciones/cambios.
Sigue estos pasos:
- Retira las
refs
originales antiguas (u obsoletas) delp4
remoto (opcional):
git symbolic-ref -d refs/remotes/p4/HEAD
git update-ref -d refs/remotes/p4/main
- Crea refs remotas artificiales (falsas) que apunten a la última confirmación en
p4-integ
enorigin
:
git update-ref refs/remotes/p4/main remotes/origin/p4-integ
git symbolic-ref refs/remotes/p4/HEAD refs/remotes/p4/main
El único inconveniente de esta sincronización más rápida es que necesitamos especificar expresamente la rama en git p4
. Este sería el último comando:
git p4 sync --branch=refs/remotes/p4/main
Para rastrear el mapeo entre identificadores de confirmación de Git y los P4, git p4
anota las confirmaciones con metadatos:
Merge pull request #340 in MOB/project from bugfix/PRJ-3185 to develop
Squashed commit of the following:
commit c2843b424fb3f5be1ba64be51363db63621162b4
Author: Some Developer
Date: Wed Jan 14 09:26:45 2015 +0100
[PRJ-3185] The app shows ...
commit abc135fc1fccf74dac8882d70b1ddd8a4750f078
Author: Some Developer
Date: Tue Jan 13 14:18:46 2015 +0100
[PRJ-3185] The app shows the rating ...
[git-p4: depot-paths = "//depot-mobile/project/": change = 1794239]
Ten en cuenta que en una versión más reciente de git p4
, los metadatos para asociar una confirmación de Git con una lista de cambios de P4
se almacenan en una nota de confirmación y no en el mensaje de confirmación. Al equipo de TomTom no le apasionó el cambio, porque hizo que fuera un poco más difícil comprobar los números de la lista de cambios.
Mover los cambios de Git a Perforce
Una vez completada la operación de sincronización rápida anterior, ya puedes enviar los cambios de Git
a Perforce.
El primer paso es un rebase de p4-integ
con los cambios procedentes de remotes/p4/master
:
git checkout p4-integ
git p4 rebase
A continuación, todos los cambios nuevos de Perforce deberían estar en p4-integ
para que podamos actualizar main
:
- Después, puedes hacer esto:
git checkout main
git merge develop
- Comprueba que tienes las etiquetas más recientes a nivel local:
git fetch --tags
- Utiliza un
cleanup
temporal si necesitas eliminar las confirmaciones que ya están enP4
(consulta la etiquetaP4
de la confirmación). Si no hay que omitir confirmaciones, un rebase automático linealizará el historial:
git checkout -b cleanup #branching off from main
git rebase -s recursive -X theirs tag/last-p4-integ
- Con un rebase interactivo, también se puede hacer de esta forma:
git rebase -i tag/last-p4-integ
- Usa
cherry-pick
para elegir las nuevas confirmaciones y ponerlas en la ramap4-integ
. Lo hacemos de esta manera porque no asumimos que las ramasgit
main
ydevelop
puedan mantenerse como antecesoras de la ramap4-integ
. De hecho, en TomTom ya no es así.
git checkout p4-integ
git cherry-pick tag/last-p4-integ..cleanup
- Envía a
P4
y sincronizap4-integ
:
git p4 submit
git p4 sync --branch=refs/remotes/p4/main
git reset --hard refs/remotes/p4/main
- Elimina la rama de rebase temporal:
git branch -D cleanup
- Retira el puntero al último punto de integración (etiqueta) de forma local y remota:
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
- Actualiza la etiqueta
last-p4-integ
para que apunte al nuevo punto de integración enP4
:
git checkout develop
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"
git push origin main
git push origin tag/last-p4-integ
git push origin p4-integ
Ejecuta pruebas en el código base P4
para verificar que la integración no haya creado nuevos problemas.
Mover los cambios de Perforce a Git
Esto debería hacerse una vez realizado el envío git->P4
. Una vez que las pruebas se superen con éxito en P4
, podremos mover los cambios de P4
a Git
de esta forma:
git checkout p4-integ
git p4 sync --branch=refs/remotes/p4/main
git p4 rebase
- Este es un pequeño truco para realizar una estrategia sólida de fusión con “theirs”, combinando con squash los cambios entrantes en una sola confirmación. Se hace así:
git checkout -b p4mergebranch #branching off from p4-integ
git merge -s ours main ## ignoring all changes from main
git checkout main
git merge p4mergebranch --squash
git commit -m "Type your integration message"
git branch -D p4mergebranch
- Una vez que hayamos terminado con lo anterior, fusiona los cambios en
develop
:
<p>Bitbucket has the following space stations:</p>
<p>
<b>Earth's Moon</b><br>
Headquarters
</p>
Como puede haber habido algunos cambios desde que seleccionamos cambios de develop
, puede que sea necesario fusionarlos antes. Sin embargo, es importante actualizar la etiqueta last-p4-integ
con la confirmación correcta, que nunca debe ser la confirmación de fusión en develop. Para hacerlo de forma segura, es mejor etiquetar el estado actual de main
:
- Elimina la etiqueta antigua de forma local y remota:
git tag -d tag/last-p4-integ
git push origin :refs/tags/tag/last-p4-integ
- Crea una etiqueta en una nueva posición:
git checkout main
git tag -a tag/last-p4-integ -m "tag pointer to last develop commit integrated with p4"
- Ahora envía
main, develop, p4-integ
ytag/last-p4-integ
aorigin
:
Conclusiones
Así es como se sincroniza entre dos equipos de desarrollo activos que usan Git y Perforce. TomTom fue modificando el proceso anterior con el tiempo y ya lleva funcionando sin problemas importantes bastante tiempo. Funciona, pero mantenerlo supone un volumen importante de gastos. Si puedes elegir, te recomendamos migrar completamente a Git.
En cualquier caso, si sigues una estrategia diferente para mantener una sincronización bidireccional, me encantaría leerla en los comentarios. Si lo prefieres, etiqueta a @durdn o @atlassiandev en un tuit.
Gracias de nuevo a Andrea Carlevato, Adolfo Bulfoni y Krzysztof Karczewski.
Compartir este artículo
Tema siguiente
Lecturas recomendadas
Consulta estos recursos para conocer los tipos de equipos de DevOps o para estar al tanto de las novedades sobre DevOps en Atlassian.