¿Cómo fuerzo a git pull a sobrescribir todo en cada extracción?

203

Tengo un repositorio CENTRAL que tiene tres repositorios de desarrolladores que lo empujan y lo empujan normalmente.

También tengo otros dos repositorios que extraen del repositorio central: uno es el servidor en vivo y el otro es un servidor de prueba / etapa, cada uno extrayendo de su propia rama respectiva.

El escenario es este: tengo un post-updatescript de enlace en el repositorio CENTRAL que accede automáticamente a los repositorios de prueba y en vivo y ejecuta un comando de extracción en cada uno. Esto actualiza los servidores de prueba y en vivo, todo dependiendo de qué rama tiene nuevos commits. Todo esto funciona muy bien.

El problema es este: puede haber ocasiones en una emergencia en las que los archivos se actualicen directamente en el servidor (a través de ftp o lo que sea) y el script CENTRAL posterior a la actualización fallará, ya que se producirán conflictos de fusión / sobrescritura. No hay forma de evitar este escenario, y es inevitable.

Lo que me gustaría que sucediera es esto: quiero que la extracción de los sitios en vivo y de prueba siempre sobrescriba / combine en la extracción. Siempre. Estos repositorios serán solo de extracción ya que no son para el desarrollo.

En toda mi investigación, no puedo encontrar una buena solución para que una extracción siempre fuerce una sobrescritura de los archivos locales. ¿Es esto posible? Sería un gran escenario de desarrollo si es así.

bmilesp
fuente
1
Si bien he votado por la respuesta "restablecer a lo que acabas de obtener" a continuación, creo que la solución a tu problema real es no hacer cambios fuera de banda. Las modificaciones, por urgentes que sean, siempre deben pasar por el control de versiones. Nadie, excepto los operadores, debe tener acceso directo a los sitios en ejecución (por ejemplo, no a los desarrolladores). El uso del control de versiones consistentemente significa que tiene un registro de cuándo se hicieron los cambios, y quién los hizo, y mejores herramientas para trabajar con ellos. ¿Por qué subvertirlo, sin beneficio real?
Phil Miller
1
@Novelocrat, entiendo lo que dices. Desafortunadamente, hay una serie de escenarios en los que alguien puede cargar un archivo directamente al servidor. En ese caso, necesitaría ejecutar varios comandos para volver a sincronizar los repositorios. Anteriormente, utilizamos un script FTP para mover archivos del repositorio al servidor. El método propuesto anteriormente simplemente eliminaría el paso FTP, que ha funcionado muy bien en el pasado.
bmilesp
3
Por lo tanto, no permita que las personas accedan al servidor directamente. Bloquee el acceso FTP y SSH, o dígales que serán despedidos por hacer cambios inexplicables. Dejar que ese tipo de práctica continúe solo te perjudica a ti y a tu equipo a largo plazo.
Phil Miller

Respuestas:

510

Realmente la forma ideal de hacer esto es no usar pull en absoluto, pero en su lugar fetchy reset:

git fetch origin master
git reset --hard FETCH_HEAD
git clean -df

(Alterando mastercualquier rama que quiera seguir).

pullestá diseñado para fusionar cambios de alguna manera, mientras que resetestá diseñado simplemente para hacer que su copia local coincida con una confirmación específica.

Es posible que desee considerar opciones ligeramente diferentes cleansegún las necesidades de su sistema.

Ámbar
fuente
3
@ user730569 reset --hardes un comando que se utiliza para forzar el estado del directorio de trabajo (y la rama actual) a un estado que coincida con el de un commit particular.
Ámbar
25
FETCH_HEADes una referencia que se crea automáticamente fetchpara representar la referencia obtenida. No se fusiona, solo se sobrescribe directamente cada vez que realiza una búsqueda. cleanes un comando que elimina archivos que no son rastreados git, los -dfindicadores le dicen que elimine directorios ( -d) y que realmente elimine ( -f).
Ámbar
44
¿Por qué no hay una palabra clave para esto? Necesito esto mucho más a menudo que tirar.
Wolfgang Fahl
15
Es posible que desee usar git clean -dnantes de usar git clean -dfpara ver qué archivos / carpetas se eliminarán. git clean -dfsolo se puede revertir si tenía una copia de seguridad
Ibrahim Lawal
1
@NickMiddleweek Estaba preocupado de que git clean -dftambién elimine los archivos ignorados, pero resulta que no lo hará. git clean --helpdice "Normalmente, solo se eliminan los archivos desconocidos para Git, pero si se especifica la opción -x, también se eliminan los archivos ignorados. Esto puede, por ejemplo, ser útil para eliminar todos los productos de compilación".
nickang
6

No estoy seguro de cómo hacerlo con un comando, pero podría hacer algo como:

git reset --hard
git pull

o incluso

git stash
git pull
Matt Wolfe
fuente
Para ejecutar en un solo comando: git reset --hard && git pull. Alternativamente, pero no mejor git reset --hard; git pull,. El uso &&solo ejecutará el segundo comando si el primer comando fue exitoso. ;lo ejecutará independientemente del código de salida del primer comando.
mazunki
5

Para extraer una copia de la rama y forzar la sobrescritura de archivos locales desde el origen, use:

git reset --hard origin/current_branch

Todo el trabajo actual se perderá y será igual a la rama de origen.

Andrew Atkinson
fuente
5
git reset --hard HEAD
git fetch --all
git reset --hard origin/your_branch
Dzmitry
fuente
2

Puede cambiar el gancho para limpiar todo.

# Danger! Wipes local data!

# Remove all local changes to tracked files
git reset --hard HEAD

# Remove all untracked files and directories
git clean -dfx

git pull ...
Dietrich Epp
fuente
2
¿Qué hace x? explique los cambios
Steve K
2
Se supone que la x eliminará todos los archivos no rastreados, creo. Difícil de decir en la página de manual-hablar, por eso tenemos SO.
JosephK
2
@JosephK: Eso es incorrecto. El propósito básico de git cleanya es "Eliminar archivos no rastreados del árbol de trabajo" (parte superior de la página). Normalmente, esto no incluye los archivos ignorada, pero -xdice git cleanque incluya ficheros ignorados, así (salvo esto no afecta a los archivos ignorados por la -eopción).
Dietrich Epp
2

Si aún no ha confirmado los cambios locales desde la última extracción / clonación, puede usar:

git checkout *
git pull

checkoutborrará sus cambios locales con el último commit local y pulllo sincronizará con el repositorio remoto

Maviles
fuente