2012-03-06 8 views
159

Tengo un repositorio desnudo CENTRAL que tiene tres repositorios de desarrolladores tirando de él y empujándolo normalmente.¿Cómo fuerzo a Git Pull para sobrescribir todo en cada extracción?

También tengo otros dos repositorios que extraen del repositorio central 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 script de gancho post-update en el repositorio CENTRAL que automáticamente accede a los repos test y live y ejecuta un comando de extracción en cada uno. Esto actualiza los servidores de prueba y en vivo, todo depende de qué rama tenga nuevas confirmaciones. Todo esto funciona genial

El problema es este: puede haber ocasiones en una emergencia que los archivos pueden actualizarse 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 el tirón de los sitios en vivo y de prueba sea siempre sobreescribir/fusionar al tirar. Siempre. Estos repositorios serán de solo extracción ya que no son para desarrollo.

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

+1

Aunque he votado a favor de la 'reset a lo que acaba de descabellada' respuesta a continuación, creo que la solución su verdadero problema es no hacer cambios fuera de banda. Las modificaciones, sin importar la urgencia, deberían * siempre * pasar por el control de versiones. Nadie, excepto los operadores, debe tener acceso directo a los sitios en ejecución (por ejemplo, no desarrolladores). Usar el control de versiones consistentemente significa que tiene un registro de cuándo se realizaron los cambios y quién los hizo, y mejores herramientas para trabajar con ellos. ¿Por qué subvertirlo, sin ningún beneficio real? – Novelocrat

+1

@Novelocrat, entiendo lo que dices. Desafortunadamente, hay una serie de escenarios en los que alguien puede subir un archivo directamente al servidor. En ese caso, necesitaría ejecutar una serie de comandos para volver a sincronizar los repos. Anteriormente utilizamos un script FTP para mover archivos desde el repositorio al servidor. El método propuesto anteriormente eliminaría simplemente el paso de 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 realizar cambios que no se pueden explicar. Permitir que ese tipo de práctica continúe solo te lastima a ti y a tu equipo a largo plazo. – Novelocrat

Respuesta

411

realmente la forma ideal de hacerlo es no utilizar pull en absoluto, pero en lugar fetch y reset:

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

(Alterar master a cualquier rama que desea estar siguiendo.)

pull está diseñado para fusionar los cambios de alguna manera, mientras que reset está diseñado para hacer que su copia local coincida con una confirmación específica.

Puede que tenga que considerar opciones ligeramente diferentes a clean dependiendo de las necesidades de su sistema.

+4

guau, esto es increíble. ¿Como funciona? – user730569

+3

@ user730569 'reset --hard' es 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 una confirmación particular. – Amber

+0

@Amber derecho, he usado 'reset --hard' antes, pero nunca junto con' fetch'. Cuando llamas a fetch, ¿está fusionando los contenidos en master, o en 'FETCH_HEAD'. ¿Qué es 'FETCH_HEAD' y dónde está relacionado con master? Por último, ¿qué es 'clean -df'? – user730569

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 ... 
+1

¿Qué hace x? por favor explique los interruptores – nottinhill

+1

@SirBenBenji: lea la página de manual: http://git-scm.com/docs/git-clean –

+0

Se supone que la x elimina todos los archivos sin seguimiento. Difícil de decir en la página de manual, por eso tenemos SO. – JosephK

5

no estoy seguro de cómo hacerlo en un comando, pero se podía hacer algo como:

git reset --hard 
git pull 

o incluso

git stash 
git pull 
2

para tirar de una copia de la rama y fuerza de sobreescritura de archivos locales de la utilización origen:

git reset --hard origin/current_branch 

Todo el trabajo actual se pierde y entonces será la misma que la rama de origen

1

Si no ha confirmar los cambios locales sin embargo, desde el último tirón/clon, puede utilizar:

git checkout * 
git pull 

checkout borrará los cambios locales con el último local de confirmación, y pull se Sincroniza al repositorio remoto

3
git reset --hard HEAD 
git fetch --all 
git reset --hard origin/your_branch