git_remotes()
#> $origin
#> [1] "https://github.com/YOU/REPO.git"
#>
#> $upstream
#> [1] "https://github.com/OWNER/repo.git"
32 Importar cambios de upstream en una bifurcación
Este flujo de trabajo es relevante si ha realizado bifurcación y clonación y ahora necesita incorporar los cambios posteriores del repositorio de origen a su copia. Estamos hablando tanto de tu bifurcación (tu copia remota del repositorio, en GitHub) como de tu copia local.
Esta es la situación inicial ideal:
Primero, verificaremos activamente la configuración anterior. Si su configuración no es óptima, discutiremos cómo solucionarlo.
32.1 Verifique la configuración de su repositorio local
Vocabulario: DUEÑO/REPO
se refiere a lo que llamamos el repositorio fuente, propiedad de DUEÑO
, que no eres tú. TU/REPO
se refiere a su bifurcación, es decir, su copia remota del repositorio fuente, en GitHub. Este es el mismo vocabulario utilizado en otros lugares, como el capítulo sobre configuraciones remotas comunes.
32.1.1 Lista tus controles remotos
Inspeccionemos los controles remotos actuales para su repositorio local.
Puedes comprobar esto con la línea de comando Git en el shell (Apéndice A):
git remote -v
Queremos ver algo como esto:
origin https://github.com/YOU/REPO.git (fetch)
origin https://github.com/YOU/REPO.git (push)
upstream https://github.com/OWNER/REPO.git (fetch)
upstream https://github.com/OWNER/REPO.git (push)
Información comparable está disponible en R con usethis::git_remotes()
:
Si solo tiene un control remoto, probablemente origin
, le recomiendo que modifique la configuración del control remoto. Pero primero comprobaremos otra cosa.
32.1.2 Ver la rama de seguimiento ascendente
Idealmente, su rama main
local tiene upstream/main
como su rama de seguimiento ascendente. Incluso si tiene un control remoto upstream
configurado correctamente, vale la pena comprobarlo. Si su rama predeterminada tiene una rama distinta a main
, sustitúyala según corresponda.
En el shell, con la rama predeterminada seleccionada, git branch -vv
debería revelar que upstream/main
es la rama de seguimiento ascendente:
~/some/repo/ % git branch -vv
* main 2739987 [upstream/main] Some commit message
Si, en cambio, ve origin/main
, le recomiendo que reconfigure la rama de seguimiento.
Toda esta información sobre controles remotos y sucursales también se incluye en la rica información reportada con usethis::git_sitrep()
.
32.1.3 Repara o completa la configuración de tu repositorio
Las instrucciones para agregar el control remoto upstream
y configurar el seguimiento ascendente para su rama predeterminada se proporcionan en Finalizar la configuración de bifurcación y clonación.
32.2 Verifica que tu “árbol de trabajo esté limpio”
Asumimos que su repositorio tiene esta configuración favorable:
Asegúrate de estar en la rama predeterminada, p. main
, y que su “árbol de trabajo esté limpio”. Primero, asegurémonos de que nuestra información en el control remoto upstream
esté actualizada:
git fetch upstream
git status
ahora debería mostrar algo como:
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
Si ha modificado archivos, debe descartar esos cambios o crear una nueva rama y confirmar los cambios allí para guardarlos.
También está bien si ves algo como esto:
Your branch is behind 'upstream/main' by 2 commits, and can be fast-forwarded.
Sin embargo, si ve algo como esto:
Your branch is ahead of 'upstream/main' by 1 commit.
o esto:
Your branch and 'upstream/main' have diverged,
and have 1 and 1 different commits each, respectively.
Esta es una señal de que ha tomado algunas decisiones lamentables.
Le recomiendo que nunca haga sus propias confirmaciones con la rama predeterminada de una bifurcación o con cualquier rama de la que no sea (co)propietario efectivamente. Sin embargo, si ya lo ha hecho, le explicamos cómo solucionar el problema en Um, ¿qué pasa si toco main
?.
32.3 Opción de sincronización 1: importe los cambios desde upstream
y luego envíelos a origin
Ahora estamos listos para incorporar los cambios que no tenemos del repositorio fuente DUEÑO/REPO
a nuestra copia local.
git pull upstream main --ff-only
Esto dice: “importe los cambios del control remoto conocido como upstream
a la rama main
de mi repositorio local”. Estoy siendo explícito sobre el control remoto (upstream
) y la rama (main
) en este caso, tanto para hacerlo más claro como para que este comando sea robusto para configuraciones de Git a nivel de repositorio y de usuario. Pero si ha seguido nuestras recomendaciones de configuración, no es necesario que sea tan explícito.
También recomiendo encarecidamente usar el indicador --ff-only
en este caso, para que también diga “si hice mis propias confirmaciones con main
, por favor oblígueme a enfrentar este problema AHORA”. Así es como se ve si no es posible realizar una combinación de avance rápido:
$ git pull upstream main --ff-only
From github.com:OWNER/REPO
* branch main -> FETCH_HEAD
fatal: Not possible to fast-forward, aborting.
Ver Um, ¿qué pasa si toco main
? para volver al camino feliz.
Suponiendo que haya tenido éxito con git pull
, el siguiente paso es opcional y muchas personas que tienen facilidad con Git no se molestan.
Si sigues mi consejo de nunca trabajar en main
de una bifurcación, entonces el estado de la rama main
en tu bifurcación TU/REPO
técnicamente no importa . Nunca realizará una solicitud de cambio desde main
y hay formas de establecer la base correcta para las ramas y solicitudes de cambio que cree.
Sin embargo, si su comprensión de todos estos conceptos de Git es, en el mejor de los casos, escasa, puede resultar útil intentar mantener las cosas simples, ordenadas y sincronizadas.
Siéntase libre de enviar el estado recientemente actualizado de main
local a su bifurcación TU/REPO
y disfrute de la satisfacción de estar “atrapado” con DUEÑO/REPO
, tanto en su bifurcación remota como en su repositorio local.
En el shell:
git push origin main
Si ha seguido nuestros consejos de configuración, realmente necesita ser así de explícito para poder enviar al origin
(no al upstream
).
32.4 Opción de sincronización 2: sincroniza tu bifurcación en GitHub, importe los cambios del origen
al repositorio local
Durante muchos años, esto no fue posible, aunque muchos usuarios de GitHub deseaban esta característica. Afortunadamente, ahora es posible sincronizar una bifurcación con su repositorio de origen en el navegador, es decir, realizar la sincronización entre los 2 repositorios de GitHub. La documentación oficial de GitHub para esto es Sincronizar una rama bifurcada desde la interfaz de usuario web.
Navegue a la página principal de su bifurcación TU/REPO
, es decir, su repositorio principal que está configurado como el control remoto origin
.
En la parte superior verá información sobre cómo se relaciona el estado de main
en su bifurcación con main
en el repositorio de origen, similar a lo que vemos con git status
en el enfoque alternativo anterior. Lo ideal es que veas algo como:
This branch is 2 commits behind DUEÑO:main.
lo que indica que puedes sincronizar en el sentido de avance rápido ideal.
Si ves algo como esto:
This branch is 1 commit ahead, 2 commits behind DUEÑO:main.
Esta es una señal de que ha tomado algunas decisiones lamentables.
Te recomiendo que nunca hagas tus propias confirmaciones en la rama predeterminada de una bifurcación o a cualquier sucursal de la que no sea (co)propietario efectivamente. Sin embargo, si ya lo ha hecho, le explicamos cómo solucionar el problema en Um, ¿qué pasa si toco main
?.
Una vez que esté listo para continuar, haga clic en “Sync fork” en la esquina superior derecha. Si tiene éxito, la página principal de TU/REPO
muestra algo como
Esta sucursal está actualizada con
PROPIETARIO/REPO:main
.
Si ha realizado confirmaciones en la rama predeterminada de su bifurcación, lo cual desaconsejamos encarecidamente, esto puede resultar en una confirmación de fusión (o incluso conflictos de fusión). Si está sufriendo debido a las confirmaciones que realizó en main
y está más allá de la ayuda que describimos a continuación, considere eliminar su bifurcación y repositorio local y comenzar de nuevo con Bifurcar y clonar. Vive y aprende.
Una vez que haya sincronizado exitosamente la rama predeterminada de TU/REPO
con la rama predeterminada de PROPIETARIO/REPO
, probablemente desee hacer lo mismo con su repositorio local. Dado que están sincronizados, puede importarlos desde upstream
u origin
.
En el shell, con la rama predeterminada desprotegida, ejecute uno de estos:
git pull upstream main --ff-only
git pull origin main --ff-only
Si ha seguido nuestros consejos de configuración, en realidad no necesita especificar el control remoto y la rama, porque esta rama está configurada para importar desde upstream
. Por las mismas razones que antes, es una buena idea incluir la opción --ff-only
. Si ha realizado confirmaciones locales con main
, esto hará surgir el problema, que se resuelve en la siguiente sección.
32.5 Um, ¿qué pasa si toco main
?
¡Te dije que no lo hicieras!
Pero bueno, aquí estamos.
Imaginemos que este es el estado de main
(o como se llame la rama predeterminada) en el repositorio fuente PROPIETARIO/REPO
:
... -- A -- B -- C -- D -- E -- F
y este es el estado de la rama main
en su copia local:
... -- A -- B -- C -- X -- Y -- Z
Las dos historias coinciden, hasta confirmar o indicar C
, luego divergen.
Si desea conservar el trabajo en las confirmaciones X
, Y
y Z
, cree una nueva rama ahora mismo, con la sugerencia en Z
, así, pero sustituyendo el nombre de su rama preferida:
git checkout -b my-great-innovations
Esto protege sus grandes innovaciones de las confirmaciones X
, Y
y Z
. Ahora revisa main
nuevamente:
git checkout main
Ahora supongo que has conservado el trabajo en X
, Y
y Z
(con una rama) o has decidido dejarlo ir.
Haga un restablecimiento completo de la rama main
para C
.
git reset --hard C
Tendrás que descubrir cómo transmitir C
en Git-speak. Especifíquelo en relación con HEAD
o proporcione el SHA. Consulte Capítulo 30 para obtener más ayuda.
El historial de su rama main
ahora es compatible con su historial en PROPIETARIO/REPO
. Las instrucciones anteriores para importar cambios desde upstream
ahora deberían funcionar. Un avance rápido debería tener éxito.
git pull upstream main --ff-only
Y ahora su historial local para main
debería coincidir con el del repositorio de origen:
... -- A -- B -- C -- D -- E -- F
Si eliges crear una sucursal con tu trabajo, también la tendrás localmente:
... -- A -- B -- C -- D -- E -- F (main)
\
-- X -- Y -- Z (my-great-innovations)
Si envió su historial alternativo (con confirmaciones X
, Y
y Z
) a su bifurcación TU/REPO
y le gusta mantener todo sincronizado, también necesitará forzar el envío de main
al control remoto origin
:
git push --force origin main
Sin embargo, realmente no nos gusta hablar de empujes forzados en Happy Git. Aquí solo lo hacemos porque estamos hablando de una bifurcación, que es bastante fácil de reemplazar si algo sale mal.