it-swarm-es.com

¿Cómo fuerzo "git pull" para sobrescribir los archivos locales?

¿Cómo fuerzo una sobrescritura de archivos locales en un git pull?

El escenario es el siguiente:

  • Un miembro del equipo está modificando las plantillas para un sitio web en el que estamos trabajando
  • Están agregando algunas imágenes al directorio de imágenes (pero olvida agregarlas bajo control de fuente)
  • Me envían las imágenes por correo, más tarde, a mí.
  • Estoy agregando las imágenes bajo el control de fuente y empujándolas a GitHub junto con otros cambios
  • No pueden obtener actualizaciones de GitHub porque Git no quiere sobrescribir sus archivos.

Este es el error que recibo:

error: el archivo de árbol de trabajo no rastreado 'public/images/icon.gif' se sobrescribirá por fusión

¿Cómo fuerzo a Git a sobrescribirlos? La persona es un diseñador; por lo general, resuelvo todos los conflictos a mano, por lo que el servidor tiene la versión más reciente que solo necesitan actualizar en su computadora.

6388
Jakub Troszok

Importante: Si tienes algún cambio local, se perderán. Con o sin la opción --hard, se perderán todas las confirmaciones locales que no se hayan enviado.[*]

Si tiene algún archivo que sea no seguido por Git (por ejemplo, contenido de usuario cargado), estos archivos no se verán afectados.


Creo que esta es la manera correcta:

git fetch --all

Entonces, tienes dos opciones:

git reset --hard Origin/master

O si estás en alguna otra rama:

git reset --hard Origin/<branch_name>

Explicación:

git fetch descarga lo último desde el control remoto sin intentar fusionar o volver a generar nada.

Luego, el git reset restablece la rama maestra a lo que acaba de recuperar. La opción --hard cambia todos los archivos en su árbol de trabajo para que coincidan con los archivos en Origin/master


Mantener los compromisos locales actuales.

[*]: Vale la pena señalar que es posible mantener las confirmaciones locales actuales creando una rama desde master antes de reiniciar:

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard Origin/master

Después de esto, todas las confirmaciones antiguas se mantendrán en new-branch-to-save-current-commits

Cambios no comprometidos

Sin embargo, los cambios no comprometidos (incluso en etapas) se perderán. Asegúrate de guardar y cometer todo lo que necesites. Para eso puedes ejecutar lo siguiente:

git stash

Y luego volver a aplicar estos cambios no comprometidos:

git stash pop
8139
RNA

Prueba esto:

git reset --hard HEAD
git pull

Debería hacer lo que quieras.

808
Travis Reeder

ADVERTENCIA: git clean elimina todos los archivos/directorios sin seguimiento y no se puede deshacer.


A veces, solo clean -f no ayuda. En caso de que tenga DIRECTORIOS sin seguimiento, la opción -d también es necesaria:

# WARNING: this can't be undone!

git reset --hard HEAD
git clean -f -d
git pull

ADVERTENCIA: git clean elimina todos los archivos/directorios sin seguimiento y no se puede deshacer.

Considere el uso de la marca -n (--dry-run) primero. Esto le mostrará lo que se eliminará sin eliminar realmente nada:

git clean -n -f -d

Ejemplo de salida:

Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...
409

Al igual que Hedgehog, creo que las respuestas son terribles. Pero aunque la respuesta de Hedgehog podría ser mejor, no creo que sea tan elegante como podría ser. La forma en que encontré que hacer esto es usando "fetch" y "fusionar" con una estrategia definida. Lo que debería permitir que los cambios locales se conserven siempre que no sean uno de los archivos con los que intenta forzar una sobrescritura. 

Primero haz una confirmación de tus cambios.

 git add *
 git commit -a -m "local file server commit message"

Luego recupera los cambios y sobrescribe si hay un conflicto

 git fetch Origin master
 git merge -s recursive -X theirs Origin/master

"-X" es un nombre de opción, y "suyo" es el valor de esa opción. Está eligiendo usar "sus" cambios, en lugar de "sus" cambios si hay un conflicto.

347
Richard Kersey

En lugar de hacer:

git fetch --all
git reset --hard Origin/master

Aconsejaría hacer lo siguiente:

git fetch Origin master
git reset --hard Origin/master

¿No es necesario recuperar todos los controles remotos y las sucursales si va a restablecer la rama Origin/master?

251
Johanneke

Parece que la mejor manera es hacer primero:

git clean

Para eliminar todos los archivos sin seguimiento y luego continuar con el git pull... habitual.

125
Jakub Troszok

Advertencia, hacer esto eliminará permanentemente sus archivos si tiene alguna entrada de directorio/* en su archivo gitignore.

Algunas respuestas parecen ser terribles. Terrible en el sentido de lo que le sucedió a @Lauri siguiendo la sugerencia de David Avsajanishvili.

Más bien (git> v1.7.6):

git stash --include-untracked
git pull

Más tarde podrás limpiar la historia del alijo.

Manualmente, uno por uno:

$ git stash list
[email protected]{0}: WIP on <branch>: ...
[email protected]{1}: WIP on <branch>: ...

$ git stash drop [email protected]{0}
$ git stash drop [email protected]{1}

Brutalmente, todos a la vez:

$ git stash clear

Por supuesto, si quieres volver a lo que escondiste:

$ git stash list
...
$ git stash apply [email protected]{5}
102
Hedgehog

Puede encontrar este comando útil para desechar cambios locales:

git checkout <your-branch> -f

Y luego haga una limpieza (elimina los archivos sin seguimiento del árbol de trabajo):

git clean -f

Si desea eliminar directorios sin seguimiento además de los archivos sin seguimiento:

git clean -fd
88
Vishal

En lugar de fusionarse con git pull, intente esto: 

git fetch --all

seguido por:

git reset --hard Origin/master.

82
Lloyd Moore

Lo único que me funcionó fue:

git reset --hard HEAD~5

Esto te hará retroceder cinco compromisos y luego con

git pull

Encontré que al buscar cómo deshacer una fusión de Git .

55
Chris BIllante

El problema con todas estas soluciones es que todas son demasiado complejas o, un problema aún mayor, es que eliminan todos los archivos no rastreados del servidor web, que no queremos, ya que siempre hay archivos de configuración necesarios que están en El servidor y no en el repositorio Git.

Aquí está la solución más limpia que estamos usando:

# Fetch the newest code
git fetch

# Delete all files which are being added, so there
# are no conflicts with untracked files
for file in `git diff HEAD..Origin/master --name-status | awk '/^A/ {print $2}'`
do
    rm -f -- "$file"
done

# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print $2}'`
do
    git checkout -- "$file"
done

# Finally pull all the changes
# (you could merge as well e.g. 'merge Origin/master')
git pull
  • El primer comando recupera los datos más recientes.

  • El segundo comando verifica si hay algún archivo que se esté agregando al repositorio y elimina esos archivos no rastreados del repositorio local que podrían causar conflictos.

  • El tercer comando verifica todos los archivos que se modificaron localmente.

  • Finalmente, hacemos un esfuerzo para actualizar a la versión más reciente, pero esta vez sin ningún conflicto, ya que los archivos sin seguimiento que están en el repositorio ya no existen y todos los archivos modificados localmente ya son los mismos que en el repositorio.

51

Yo tuve el mismo problema. Nadie me dio esta solución, pero funcionó para mí.

Lo resolví por:

  1. Eliminar todos los archivos. Deja solo el directorio .git.
  2. git reset --hard HEAD
  3. git pull
  4. git Push

Ahora funciona.

39
John John Pichler

En primer lugar, pruebe el modo estándar:

git reset HEAD --hard # To remove all not committed changes!
git clean -fd         # To remove all untracked (non-git) files and folders!

Advertencia : Los comandos anteriores pueden provocar la pérdida de datos/archivos solo si no los ha confirmado. Si no está seguro, haga primero la copia de seguridad de toda la carpeta del repositorio.

A continuación, tire de nuevo.

Si lo anterior no ayuda y no le importan sus archivos/directorios sin seguimiento (haga la copia de seguridad primero por si acaso), intente los siguientes pasos simples:

cd your_git_repo  # where 'your_git_repo' is your git repository folder
rm -rfv *         # WARNING: only run inside your git repository!
git pull          # pull the sources again

Esto RETIRARÁ todos los archivos git (exime .git/ dir, donde tiene todos los confirmaciones) y tire de nuevo.


¿Por qué git reset HEAD --hard podría fallar en algunos casos?

  1. Reglas personalizadas en .gitattributes file

    Tener la regla eol=lf en .gitattributes podría hacer que git modifique algunos cambios de archivo al convertir los finales de línea CRLF en LF en algunos archivos de texto.

    Si ese es el caso, debe confirmar estos cambios CRLF/LF (revisándolos en git status), o intente: git config core.autcrlf false para ignorarlos temporalmente.

  2. Incompatibilidad del sistema de archivos

    Cuando utiliza un sistema de archivos que no admite atributos de permiso. En el ejemplo, tiene dos repositorios, uno en Linux/Mac (ext3/hfs+) y otro en el sistema de archivos basado en FAT32/NTFS.

    Como puede observar, hay dos tipos diferentes de sistemas de archivos, por lo que el que no admite permisos de Unix básicamente no puede restablecer los permisos de archivos en el sistema que no admite ese tipo de permisos, por lo que no importa cómo --hard intente, git siempre detecta algunos "cambios".

34
kenorb

Prima:

Al hablar de extracción/recuperación/fusión en las respuestas anteriores, me gustaría compartir un truco interesante y productivo,

git pull --rebase

Este comando anterior es el comando más útil en mi vida Git que ahorró mucho tiempo.

Antes de enviar su nuevo compromiso al servidor, pruebe este comando, se sincronizarán automáticamente los últimos cambios del servidor (con fetch + merge) y colocará su compromiso en la parte superior del registro de Git. No hay necesidad de preocuparse por la extracción/fusión manual.

Encuentre detalles en ¿Qué hace "git pull --rebase"?.

33

Tuve un problema similar. Tuve que hacer esto:

git reset --hard HEAD
git clean -f
git pull
27
Ryan

Resumí otras respuestas. Puedes ejecutar git pull sin errores:

git fetch --all
git reset --hard Origin/master
git reset --hard HEAD
git clean -f -d
git pull

Advertencia : este script es muy poderoso, por lo que podría perder sus cambios.

27
Robert Moon

Basándome en mis experiencias similares, la solución ofrecida por Strahinja Kustudic es, con mucho, la mejor. Como otros lo han señalado, simplemente haciendo un restablecimiento completo eliminará todos los archivos sin seguimiento que podrían incluir muchas cosas que no desea eliminar, como los archivos de configuración. Lo que es más seguro es eliminar solo los archivos que están a punto de agregarse y, para el caso, es probable que también desee revisar los archivos modificados localmente que estén a punto de actualizarse.

Con eso en mente, actualicé el script de Kustudic para hacer precisamente eso. También arreglé un error tipográfico (falta) en el original.

#/bin/sh

# Fetch the newest code
git fetch

# Delete all files which are being added,
# so there are no conflicts with untracked files
for file in `git diff HEAD..Origin/master --name-status | awk '/^A/ {print $2}'`
do
    echo "Deleting untracked file $file..."
    rm -vf "$file"
done

# Checkout all files which have been locally modified
for file in `git diff HEAD..Origin/master --name-status | awk '/^M/ {print $2}'`
do
    echo "Checking out modified file $file..."
    git checkout $file
done

# Finally merge all the changes (you could use merge here as well)
git pull
26
Rolf Kaiser

Creo que hay dos posibles causas de conflicto, que deben resolverse por separado, y por lo que puedo decir, ninguna de las respuestas anteriores trata de ambas:

  • Los archivos locales que no están rastreados deben eliminarse, ya sea de forma manual (más segura) o como se sugiere en otras respuestas, por git clean -f -d

  • Las confirmaciones locales que no están en la rama remota también deben eliminarse. OMI, la forma más fácil de lograr esto es con: git reset --hard Origin/master (reemplace 'master' por cualquier rama en la que esté trabajando, y ejecute primero git fetch Origin)

23
tiho

Una forma más fácil sería:

git checkout --theirs /path/to/file.extension
git pull Origin master

Esto anulará su archivo local con el archivo en git

20
maximus 69

Parece que la mayoría de las respuestas aquí se centran en la rama master; sin embargo, hay ocasiones en las que estoy trabajando en la misma rama de función en dos lugares diferentes y quiero que una rebase en una se refleje en la otra sin tener que saltar mucho en los aros.

Basándome en una combinación de la respuesta del ARN y la respuesta de torek a una pregunta similar , he encontrado una que funciona de manera espléndida:

git fetch
git reset --hard @{u}

Ejecuta esto desde una rama y solo restablecerá tu rama local a la versión ascendente.

Esto también se puede incluir en un alias de git (git forcepull):

git config alias.forcepull "!git fetch ; git reset --hard @{u}"

O, en su archivo .gitconfig:

[alias]
  forcepull = "!git fetch ; git reset --hard @{u}"

¡Disfrutar!

20
JacobEvelyn

Tuve el mismo problema y por alguna razón, incluso un git clean -f -d no lo haría. He aquí por qué: por algún motivo, si Git ignora su archivo (a través de una entrada de .gitignore, supongo), todavía le preocupa sobrescribir esto con un pull posterior, pero un limpio no elimínelo, a menos que agregue -x.

19
Tierlieb

Acabo de resolver esto yo mismo por:

git checkout -b tmp # "tmp" or pick a better name for your local changes branch
git add -A
git commit -m 'tmp'
git pull
git checkout master # Or whatever branch you were on originally
git pull
git diff tmp

donde el último comando proporciona una lista de los cambios locales. Siga modificando la rama "tmp" hasta que sea aceptable y luego vuelva a combinar en el maestro con: 

git checkout master && git merge tmp

Para la próxima vez, probablemente pueda manejar esto de una manera más limpia buscando "rama de escondite de git", aunque es probable que el alijo le cause problemas en los primeros intentos, así que primero experimente en un proyecto no crítico ...

18
Simon B.

Tengo una situación extraña que ni git clean o git reset funciona. Tengo que eliminar el archivo conflictivo de git index usando el siguiente script en cada archivo sin seguimiento:

git rm [file]

Entonces puedo tirar bien.

17
Chen Zhang

Conozco un método mucho más fácil y menos doloroso:

$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp

¡Eso es!

16
ddmytrenko

Estos cuatro comandos funcionan para mí.

git reset --hard HEAD
git checkout Origin/master
git branch -D master
git checkout -b master

Para comprobar/jalar después de ejecutar estos comandos.

git pull Origin master

Intenté mucho, pero finalmente tuve éxito con estos comandos.

13
vishesh chandra

Solo haz

git fetch Origin branchname
git checkout -f Origin/branchname // This will overwrite ONLY new included files
git checkout branchname
git merge Origin/branchname

Por lo tanto, evita todos los efectos secundarios no deseados, como eliminar archivos o directorios que desea conservar, etc.

12
user2696128

A pesar de la pregunta original, las respuestas principales pueden causar problemas a las personas que tienen un problema similar, pero que no quieren perder sus archivos locales. Por ejemplo, vea los comentarios de Al-Punk y crizCraig. 

La siguiente versión confirma sus cambios locales en una rama temporal (tmp), verifica la rama original (que asumo que es master) y combina las actualizaciones. Podría hacer esto con stash, pero me parece que generalmente es más fácil usar el enfoque de ramificación/fusión.

git checkout -b tmp
git add *; git commit -am "my temporary files"
git checkout master

git fetch Origin master
git merge -s recursive -X theirs Origin master

donde asumimos que otro repositorio es Origin master.

12
Snowcrash

Restablezca el índice y la cabecera a Origin/master, pero no reinicie el árbol de trabajo:

git reset Origin/master
11
user811773

Requisitos:

  1. Rastrea los cambios locales para que nadie aquí los pierda.
  2. Haga que el repositorio local coincida con el repositorio de origen remoto.

Solución:

  1. Stash Los cambios locales.
  2. Fetch con un limpiar de archivos y directorios ignorando .gitignore y restablecimiento completo a Origen .

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard Origin/master
    
9
vezenkov

Leí todas las respuestas pero estaba buscando un solo comando para hacer esto. Aquí esta lo que hice. Añadido un alias de git a .gitconfig

[alias]
      fp = "!f(){ git fetch ${1} ${2} && git reset --hard ${1}/${2};};f"

Ejecute su comando como 

git fp Origin master

equivalente a

git fetch Origin master
git reset --hard Origin/master
9
Venkat Kotra

No uses git reset --hard. Eso borrará sus cambios que pueden ser completamente indeseables. En lugar:

git pull
git reset Origin/master
git checkout <file1> <file2> ...

Por supuesto, puede usar git fetch en lugar de git pull ya que claramente no se fusionará, pero si usualmente tira, tiene sentido continuar presionando aquí.

Entonces, lo que sucede aquí es que git pullactualiza su Origen/referencia maestra; git resetactualiza la referencia de su sucursal local para que sea el mismo que Origin/master sin actualizar ningún archivo, por lo que su estado de salida no cambia; luego git checkoutconvierte los archivos a su estado de índice de sucursal local según sea necesario. En los casos en los que se ha agregado exactamente el mismo archivo en vivo y en el maestro ascendente, el índice ya coincide con el archivo después del restablecimiento, por lo que en el caso común no necesita hacer git checkout en absoluto.

Si la rama ascendente también contiene confirmaciones que desea aplicar automáticamente, puede seguir una variación sutil en el proceso:

git pull
git merge <commit before problem commit>
git reset <problem commit>
git checkout <file1> <file2> ...
git pull
8
Jim Driscoll

Esta es la mejor práctica para revertir cambios:

  • git commit Confirma tus cambios en etapas para que se guarden en reflog (ver más abajo)
  • git fetch Obtener los últimos cambios en sentido ascendente
  • git reset --hard Origin/master Restablecimiento completo de la rama maestra de origen

El reflogregistra ramas y otras referencias que se actualizan en el repositorio local. O simplemente coloque - el reflog es el historial de sus cambios.

Así que siempre es una gran práctica comprometerse. Los compromisos se agregan al reflog, lo que garantiza que siempre tendrá una forma de recuperar el código eliminado.

7
Jordan Georgiev

Utilicé este comando para deshacerme de los archivos locales que me impedían realizar una extracción/fusión. ¡Pero ten cuidado! Ejecute git merge … primero para ver si solo hay esos archivos que realmente desea eliminar.

git merge Origin/master 2>&1 >/dev/null | grep ^[[:space:]] | sed s/^[[:space:]]//g | xargs -L1 rm
  • git merge enumera entre otras cosas todos esos archivos. Están precedidos por algunos espacios en blanco.
  • 2>&1 >/dev/null redirecciona la salida de error a la estándar para que sea recogida por grep.
  • grep ^[[:space:]] filtra solo las líneas con nombres de archivos.
  • sed s/^[[:space:]]//g recorta los espacios en blanco desde el principio.
  • xargs -L1 rm llama a rm en cada uno de esos archivos, eliminándolos.

Manéjese con cuidado: sea cual sea el resultado de git merge, la rm se llamará para cada línea comenzando con un espacio en blanco.

5
Glutexo

Estaba intentando usar la rama Material2 en Angular2-Webpack-Starter y lo pasé genial. Esta era la única forma en que podía descargar y usar esa rama.

git clone --depth 1 https://github.com/angularclass/angular2-webpack-starter.git

cd angular2-webpack-starter/

git checkout -b material2

Abra la carpeta del proyecto y elimine todos los archivos y carpetas no ocultos. Deja todos los escondidos.

git add .

git commit -m "pokemon go"

git reset --hard

git pull Origin material2

(Cuando aparezca el editor, presione ': wq' y luego presione Enter)

Ahora estás listo.

5
Helzgate

En Windows, haga este único comando:

git fetch --all & git reset --hard Origin/master
3
Luca C.

Podría ignorar ese archivo con un archivo en la carpeta base de su proyecto:

.gitignore

public/images/*

Luego tire de los cambios y luego elimine esa línea de su archivo gitignore.

3
Daniel Gaytán

git fetch --all && git reset --hard Origin/master && git pull

1
Suge

1: Restablecer a una confirmación anterior

git reset --hard HEAD

2: Eliminar archivos sin seguimiento

git clean -f

3: Tire de los compromisos

git pull

Fuentes:

0
abhijithvijayan

si desea restablecer la rama de seguimiento remoto de forma genérica, utilice:

git fetch
git reset --keep Origin/$(git rev-parse --abbrev-ref HEAD)

si desea restablecer sus cambios locales también:

git fetch
git reset --hard Origin/$(git rev-parse --abbrev-ref HEAD)
0
warch