Saltar al contenido principal
InicioTutorialesInteligencia Artificial (IA)

Git pull force: Cómo sobrescribir una rama local con una remota

Aprende por qué git pull --force no es la mejor forma de sobrescribir una rama local con la versión remota, y descubre el método adecuado utilizando git fetch y git reset.
Actualizado ago 2024

En determinadas situaciones, puede que deseemos restablecer el estado de un local Git local para alinearla con el repositorio remoto, descartando así cualquier cambio local. Esto se conoce comúnmente comotirón forzado .

Esto crea la idea errónea de que la forma de archivarlo es utilizar la opción --force en el comando git pull. En este artículo aprendemos que son cosas distintas.

Podemos sobrescribir nuestro estado local con el estado remoto utilizando los comandos que se indican a continuación, sustituyendo por el nombre de tu rama. Esta acción borrará permanentemente todos tus cambios locales en esa rama.

git fetch
git reset --hard origin/<branch_name>

Este artículo profundizará en los detalles de cómo funcionan estos comandos. Vamos más allá de las soluciones rápidas para comprender la mecánica subyacente, aprendiendo así métodos más eficaces para lograr el resultado deseado sin riesgo de perder cambios importantes. También aclaramos el concepto erróneo y aprendemos qué hace realmente la opción --force de git pull.

Cuándo considerar la posibilidad de sobrescribir los cambios locales

En general, sobrescribir cambios locales de esta forma va en contra del uso previsto de Git. Para casi cualquier situación, existe un flujo de trabajo Git adecuado para resolverla. Sin embargo, algunas de ellas suelen requerir un conocimiento más profundo de Git y tardan más tiempo en ejecutarse. Aunque no sea la mejor práctica, sobrescribir los cambios locales a veces puede ser la forma más rápida de hacer el trabajo.

En mi caso, esto suele ocurrir cuando trabajo en una función con la que no estoy muy familiarizado. Empiezo creando una rama y haciendo algunos commits. Cuando me atasco, pido ayuda a un compañero. Empiezan desde un commit anterior, antes de que yo cometiera el error, resuelven el problema y empujan sus cambios. En este punto, necesito sustituir mi versión local por la versión remota actualizada, descartando mis cambios locales, para poder seguir trabajando en la función.

Otro ejemplo es cuando hay un conflicto, y creo que es más difícil o lleva más tiempo solucionar el conflicto que volver a implementar nuestros cambios en la última versión del código.

Independientemente del motivo, asegúrate siempre de que esos cambios realmente no son necesarios y pueden eliminarse con seguridad, o haz una copia de seguridad de tu rama para evitar perder trabajo importante.

Cómo sobrescribir correctamente los cambios locales

El primer paso es buscar (descargar) el contenido más reciente del repositorio remoto en nuestra máquina local. Esto se hace utilizando elcomando fetch de git:

git fetch

Por defecto, esto recuperará el contenido de la rama actual, que suele ser lo que necesitamos. Podemos especificar opcionalmente la rama que deseamos descargar (sustituyendo por el nombre de la rama que queremos obtener):

git fetch origin/<branch_name>

También podemos utilizar la opción --all para descargarlo todo:

git fetch –all

Obtener los cambios del repositorio remoto no afectará a los archivos de tu directorio de la rama de trabajo actual. El comando fetch descarga los cambios del repositorio remoto pero no los fusiona. El repositorio local mantiene una vista tanto de los archivos locales como de los archivos remotos, y la obtención actualiza la vista de los archivos remotos.

Tras descargar los cambios del repositorio remoto, podemos utilizar el comando reset de git para restablecer la rama de trabajo actual a un estado determinado:

git reset --hard origin/<branch_name>

La opción --hard es necesaria para asegurarse de que los cambios locales son sobrescritos por los cambios remotos. En el comando anterior, elegimos sustituir la rama de trabajo actual por origin/, que corresponde a la versión remota de esa rama que se acaba de obtener.

El comando git reset borrará los cambios locales, aunque estén confirmados. Por tanto, se recomienda crear una copia de seguridad local de la rama actual antes de ejecutar ese comando. Esto puede hacerse utilizando:

git branch <name_of_the_backup_branck>

Sustituye por el nombre que quieras que tenga la rama de copia de seguridad.

Poniéndolo todo junto, podemos anular todos los cambios locales de una rama determinada con la última versión remota haciendo lo siguiente:

git fetch
git branch <name_of_the_backup_branch>
git reset --hard origin/<branch_name>

Limpieza completa borrando los archivos no rastreados

Git no tocará los archivos no rastreados (archivos que nunca utilizaron git add). Si además queremos borrar estos archivos, podemos hacerlo utilizando:

git clean -fdx

Este es un comando peligroso que se utiliza para eliminar archivos no rastreados del directorio de trabajo. Es esencial utilizar este comando con precaución, ya que borra permanentemente estos archivos, haciendo imposible recuperarlos mediante Git. Aquí tienes un desglose de las opciones del comando:

  • -f: Esta opción obliga a realizar la operación de limpieza. Git se negará a borrar los archivos no rastreados del directorio de trabajo sin esta bandera como medida de seguridad para evitar la pérdida accidental de datos.
  • -d: Esto indica a git clean que elimine no sólo los archivos no rastreados, sino también los directorios no rastreados. Por defecto, git clean sólo se dirige a archivos sin seguimiento e ignora los directorios.
  • -x: Por defecto, git clean respetará las reglas de .gitignore y no eliminará los archivos o directorios que coincidan con estos patrones. Incluir -x anula este comportamiento, indicando a Git que elimine también los archivos/directorios ignorados por .gitignore u otras reglas de ignorar. Esto da lugar a una limpieza muy exhaustiva, eliminando todos los archivos no rastreados del repositorio, incluidos los resultados de la compilación, los archivos de registro y otros artefactos generados que normalmente se ignoran.

Comprender Git Pull

La forma habitual de actualizar nuestro repositorio local con los cambios remotos es utilizando el comando git pull . Sin embargo, este comando no puede utilizarse para anular nuestros cambios locales porque git pull intentará fusionar nuestra versión local con la remota.

Bajo el capó, git pull realiza los siguientes pasos:

  1. Utiliza git fetch para descargar la última versión del repositorio remoto.
  2. Utiliza git merge para fusionar las ramas local y remota.

Debido al paso de fusión, git pull no es un comando adecuado en situaciones en las que queramos ignorar y descartar los cambios locales.

<code data-mce-selected=

¿Qué te parece el git pull --force?

Consultando la documentación del comando git pull vemos que ofrece la opción --force. Es un error común pensar que esta opción forzará la ejecución del comando git pull borrando los cambios locales con los remotos.

Cuando proporcionamos la opción --force a git pull, esta opción se transmite a git fetch. Así, git pull --force realiza los siguientes pasos:

  1. git fetch --force
  2. git merge

 <código data-mce-selected=

Hemos aprendido que fetch se utiliza para actualizar la vista local del repositorio remoto. Si la única diferencia entre tu repositorio local actual y el repositorio remoto son algunos commits que faltan (la rama local está por detrás de la versión remota), entonces git fetch simplemente actualizará la vista local añadiendo esos nuevos commits al historial.

Git fetch sincroniza el repositorio local con el repositorio remoto si el historial de ramas coincide

Sin embargo, podría darse el caso de que alguien reescribiera el historial de confirmaciones de la rama remota haciéndola incompatible con la vista local. En este caso, fetch no funcionará.

Git fetch fallará si el historial de la rama no coincide, a menos que utilicemos el <code data-mce-selected=

Podemos evitarlo utilizando la opción --force, que forzará a Git a ignorar el historial local y sobrescribirlo con el historial remoto. 

Vemos que la opción --force está relacionada con forzar la sobreescritura del historial de confirmaciones y no tiene nada que ver con ignorar los cambios locales en el directorio de la rama de trabajo.

Integrar los cambios locales

Sobrescribir los cambios locales con los remotos no es una práctica habitual de Git, pero puede ser útil en ciertos casos en los que no queremos lidiar con conflictos o no nos importan nuestros cambios locales.

Fusión

Normalmente, se retiraban los cambios y se solucionaban los conflictos. La gente tiende a tener miedo a enfrentarse a los conflictos. Algunos conflictos pueden ser abrumadores de tratar, pero no suele ser el caso. Se produce un conflicto cuando:

  1. Tanto la rama local como la rama remota tienen cambios en la misma parte de un archivo.
  2. Un archivo se borra por un lado y se modifica por otro.

En estos casos, Git no puede adivinar qué cambios queremos conservar, y tenemos que hacérselo saber manualmente. Git resaltará el conflicto en los archivos de la siguiente manera:

Ejemplo de conflictos Git

Para resolver un conflicto, editamos el archivo borrando estas líneas excepto las que queremos conservar. Después de tratar todos los conflictos, podemos confirmar los cambios. Para una guía en profundidad, consulta este tutorial sobre cómo resolver conflictos de fusión en Git.

Seleccionando

Si realmente queremos hacer que nuestra versión local coincida primero con la versión remota y luego integrar eventualmente nuestros cambios, podemos traer los commits de la rama de copia de seguridad a la rama actual, así:

git cherry-pick <commit_hash>

Aquí, es el hash del commit que queremos integrar. Esto supone que antes de hacer git reset, creamos una rama de copia de seguridad con git branch y que los cambios locales habían sido confirmados.

Para encontrar el , podemos listar los hashes de commit en la rama de copia de seguridad utilizando el siguiente comando:

git log <name_of_the_backup_branck>

Guardando

Alternativamente, si no queremos confirmar nuestros cambios o crear una rama de copia de seguridad, podemos almacenar nuestros cambios antes de fusionarlos utilizando:

git stash

Este comando puede utilizarse para guardar temporalmente el trabajo actual sin confirmarlo en el historial de ramas. El almacenamiento aparta tus modificaciones, permitiéndote tener un directorio de trabajo limpio.

Después de reiniciar, podemos recuperar los cambios utilizando el siguiente comando:

git stash pop

Utilizando el almacenamiento, todo el flujo de trabajo sería más o menos así:

git fetch
git stash
git reset --hard origin/<branch_name>
git stash pop

Para saber más, consulta esta hoja de trucos con stash y otros comandos git.

Conclusión

A pesar de no ser una práctica recomendada, a veces nos encontramos en una situación en la que sólo queremos hacer que nuestra rama local coincida con el contenido de la rama remota, descartando al mismo tiempo nuestros cambios locales.

Existe la idea errónea de que esto se consigue utilizando git pull --force. Esto es incorrecto porque git pull --force combina git fetch --force y git merge. Por lo tanto, intenta fusionar los cambios locales con los remotos, sin sobrescribirlos.

La forma correcta de sobrescribir los cambios locales con el contenido del repositorio remoto es:

git fetch
git reset --hard origin/<branch_name>

El comando git reset debe utilizarse con precaución porque borrará los cambios locales, aunque se hayan confirmado. Si teníamos commits locales y creamos una rama de copia de seguridad, podemos traerlos de vuelta utilizando git cherry-pick. Si no confirmamos y queremos guardar temporalmente nuestro trabajo local, podemos utilizar git stash antes de restablecer y, a continuación, git stash pop para recuperar nuestros cambios.

Temas

¡Más información sobre Git!

Course

Introduction to Git

4 hr
37K
Familiarize yourself with Git for version control. Explore how to track, compare, modify, and revert files, as well as collaborate with colleagues using Git.
See DetailsRight Arrow
Start Course
Ver másRight Arrow
Relacionado

tutorial

Git rename branch: Cómo cambiar el nombre de una rama local o remota

Aprende a renombrar ramas Git locales y remotas utilizando el terminal o la interfaz gráfica de usuario (GUI) de clientes populares como GitHub.
François Aubry's photo

François Aubry

tutorial

Tutorial de GIT Push y Pull

Aprende a realizar solicitudes de Git PUSH y PULL con GitHub Desktop y la línea de comandos.

Olivia Smith

13 min

tutorial

Tutorial de Git Revert y Git Reset para principiantes

Una guía tutorial para principiantes que muestra cómo utilizar los comandos Git Revert y Reset.
Zoumana Keita 's photo

Zoumana Keita

10 min

tutorial

Tutorial de GitHub y Git para principiantes

Un tutorial para principiantes que muestra cómo funciona el control de versiones Git y por qué es crucial para los proyectos de ciencia de datos.
Abid Ali Awan's photo

Abid Ali Awan

17 min

tutorial

Guía de torchchat de PyTorch: Configuración local con Python

Aprende a configurar el torchat de PyTorch localmente con Python en este tutorial práctico, que proporciona orientación paso a paso y ejemplos.
François Aubry's photo

François Aubry

tutorial

Cómo ajustar GPT 3.5: Liberar todo el potencial de la IA

Explore GPT-3.5 Turbo y descubra el potencial transformador del ajuste fino. Aprenda a personalizar este modelo de lenguaje avanzado para aplicaciones especializadas, mejore su rendimiento y comprenda los costes asociados, la seguridad y las consideraciones de privacidad.
Moez Ali's photo

Moez Ali

11 min

See MoreSee More