Close

Bifurcaciones y repositorios upstream: instrucciones y consejo interesante

Primer plano de Nicola Paolucci
Nicola Paolucci

Experto en desarrollo


Si bifurcas proyectos para hacer tus propios cambios, podrás integrar fácilmente tus contribuciones. Sin embargo, si no envías esos cambios en sentido ascendente —es decir, de vuelta al repositorio principal—, corres el riesgo de perderlos de vista, lo que puede provocar líneas divergentes en tu repositorio. Para asegurarte de que todos los colaboradores partan del mismo punto, necesitarás conocer algunos principios de cómo interactúa git fork con git upstream. En esta entrada, te presentaré los conceptos básicos, los trucos e incluso te daré un consejo genial para tomar la delantera.

git upstream: actualizar y contribuir


Vamos a comenzar detallando una configuración común y el flujo de trabajo más básico para interactuar con los repositorios upstream.

En una configuración estándar, generalmente tienes un origin y un remote upstream; este último es el "guardián" del proyecto o la fuente de información a la que quieres contribuir.

Para empezar, comprueba que has configurado un remoto para el repositorio upstream (y confío en que también un origin):

git remote -v

origin  git@bitbucket.org:my-user/some-project.git (fetch)
origin  git@bitbucket.org:my-user/some-project.git (push)

Si no tienes un upstream, puedes añadirlo fácilmente con el comando remote:

git remote add upstream git@bitbucket.org:some-gatekeeper-maintainer/some-project.git
bases de datos
Material relacionado

Cómo mover un repositorio de Git completo

Logotipo de Bitbucket
VER LA SOLUCIÓN

Aprende a usar Git con Bitbucket Cloud

Comprueba que el remoto se ha añadido correctamente:

git remote -v

origin    git@bitbucket.org:my-user/some-project.git (fetch)
origin    git@bitbucket.org:my-user/some-project.git (push)
upstream  git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (fetch)
upstream  git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (push)

Ahora puedes recopilar los últimos cambios del repositorio upstream con fetch. Repite esto cada vez que quieras recibir actualizaciones:

Si el proyecto tiene etiquetas que no se han fusionado en la main, también debes hacer: git fetch upstream --tags.

git fetch upstream

Por lo general, conviene que la rama main local sea lo más parecida posible a la main de upstream y ejecutar el trabajo en las ramas de función, ya que más adelante podrían convertirse en solicitudes de incorporación de cambios.

En este punto, no importa si usas merge o rebase, ya que el resultado será normalmente el mismo. En este ejemplo, vamos a usar merge:

git checkout main
git merge upstream/main

Cuando quieras compartir algo de trabajo con los mantenedores upstream que ramificas desde main, crea una rama de función. Cuando la tengas lista, envíala a tu repositorio remoto.

También puedes usar rebase en su lugar y luego merge para que el upstream tenga un conjunto limpio de confirmaciones (lo ideal sería una) para evaluar:

git checkout -b feature-x

#some work and some commits happen
#some time passes

git fetch upstream
git rebase upstream/main

Publica con git fork


Una vez seguidos todos los pasos anteriores, publica tu trabajo en la bifurcación remota con un simple push:

git push origin feature-x
git push -f origin feature-x

Personalmente, prefiero mantener el historial lo más limpio posible y optar por la tercera opción, pero cada equipo tiene su propio flujo de trabajo. Nota: Solo deberías hacer esto cuando trabajes con tu propia bifurcación. NUNCA deberías reescribir el historial de repositorios y ramas compartidos.

Consejo del día: indicación del número de confirmaciones por delante/detrás


Después de un fetch, git status muestra cuántas confirmaciones estás por delante o por detrás de la rama remote sincronizada. ¿No estaría genial ver esta información en el símbolo del sistema? A mí también me lo pareció, así que empecé a toquetear bash y lo conseguí.

Así es cómo se verá en el mensaje cuando lo hayas configurado:

nick-macbook-air:~/dev/projects/stash[1|94]$

Solo tendrías que añadir una función (una sola) a tu .bashrc o equivalente:

function ahead_behind {
    curr_branch=$(git rev-parse --abbrev-ref HEAD);
    curr_remote=$(git config branch.$curr_branch.remote);
    curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);
    git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';
}
export PS1="\h:\w[\$(ahead_behind)]$"

Funcionamiento interno

Si te gusta tener todos los detalles, así es cómo funciona:

Obtenemos el nombre simbólico del HEAD actual, es decir, la rama actual:

curr_branch=$(git rev-parse --abbrev-ref HEAD);

Obtenemos el remoto al que apunta la rama actual:

curr_remote=$(git config branch.$curr_branch.remote);

Obtenemos la rama en la que se debe fusionar este remoto (con un truco de Unix para descartar todo hasta la última barra inclinada [ / ], inclusive):

curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);

Ahora tenemos lo que necesitamos para recopilar el número de confirmaciones que estamos por delante o por detrás:

git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';

Usamos el antiguo tr Unix para convertir el TAB en un separador |.

Primeros pasos con git upstream


Este es un recorrido básico por git upstream: cómo configurar un git upstream, crear una nueva rama, recopilar cambios, publicar con git fork y un consejo para saber a cuántas confirmaciones estás por delante o por detrás de la rama remota.

Bitbucket Server incluye sincronización de bifurcaciones que básicamente libera al desarrollador de la carga de actualizar las bifurcaciones. Además, Bitbucket Cloud tiene una sencilla sincronización en un solo paso, ¡échale un vistazo!

Sígueme (@durdn) y sigue al increíble equipo de @Bitbucket para saberlo todo sobre DVCS.

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


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.

Gente que colabora utilizando un muro lleno de herramientas

Blog de Bitbucket

Ilustración de Devops

Ruta de aprendizaje de DevOps

Demostraciones de funciones con expertos de Atlassian del Centro de demostraciones

Cómo funciona Bitbucket Cloud con Atlassian Open DevOps

Suscríbete para recibir el boletín de DevOps

Thank you for signing up