2009-09-10 10 views
20

decir que tengo una rama de la característica, en la que fusionar los cambios aguas arriba antes de empujar mis cambios de nuevo:git checkout y combinar sin tocar árbol de trabajo

git branch feature1 
... [edit my code] 
... [commit] 
git fetch origin master 
git merge fetch_head [or rebase] 
... [resolve conflicts] 
... [build and test code] 

En este punto deseo de empujar mis cambios. La forma normal de hacer esto sería:

git checkout master [changes a bunch of working tree files] 
git merge feature1 [changes the same files right back] 

Esto funciona bien, pero hará que el (fecha de comprobación) compilador piensa que un montón de archivos están sucios y necesita una reconstrucción a pesar de que los contenidos son los mismos . ¿Hay alguna forma de verificar y fusionar que deje el árbol de trabajo sin cambios en este caso?

Algo así como:

git checkout master --merge-branch feature1 

EDIT:

sólo estoy hablando de avance rápido se fusiona que, por definición, no cambiaría el estado de los archivos.

+0

http://stackoverflow.com/questions/1282639/switch-git-branch-without-files-checkout –

+0

duplicado posible de [Merge, actualizar y tirar de las ramas de Git sin usar las cajas) (http://stackoverflow.com/questions/3216360/merge-update-and-pull-git-bit-branches-without-using-checkouts) –

Respuesta

7

[Editar] Esta es solo una solución/solución parcial. Ver la respuesta real por @djpohly a continuación.

En primer lugar, puede presionar desde cualquier lugar. No importa lo que hayas prestado, o si las confirmaciones que deseas enviar están en maestro.

git push REMOTE_REPO feature1:master 

ver git help push

Consejo: git push remoteRepo localRef:remoteRef

En cuanto a traer al maestro donde se encuentra ahora sin tocar el violín con su copia de trabajo ... Se puede forzar que de este modo:

# (while still on feature1 branch) 
git checkout -B master origin/master 

Pero esto hace un restablecimiento completo en el maestro. es decir, no verifica el avance rápido.

+0

Eso es cierto, y soluciona la mitad del problema. Aun así, no puedo permanecer en la rama de características una vez que se haya completado. Como me gustaría volver a dominar, todavía tendría este problema (bastante menor). –

+1

bueno, la otra parte de su pregunta (sobre querer que los tiempos de modificación de sus archivos de alguna manera cambien mágicamente a lo correcto) no es realmente solucionable. No hay forma de que git sepa qué archivos fueron compilados cuando. Entonces git siempre actualiza las marcas de tiempo cuando cambia los archivos. Esto da como resultado una nueva compilación adicional, pero eso es mucho mejor que no volver a compilar cuando debería. – JasonWoof

+2

tal vez le gustaría tener otro clon en su computadora, por lo que puede tener ambos desprotegidos a la vez? Si te preocupa el espacio, es posible tener dos clones locales que compartan el almacenamiento de repositorio. – JasonWoof

3

No hay forma de que merge (o rebase) funcione sin tocar el directorio de trabajo (y el índice), ya que puede haber conflictos de fusión que deben resolverse utilizando el directorio de trabajo (y/o índice).

Siempre puede tener otro clon (tal vez utilizando alternativas, o el directorio de enlaces simbólicos de objetos, para ahorrar espacio en el disco) u otro directorio de trabajo con contrib/workdir/git-new-workdir. O use una herramienta como ccache.

36

Una manera simple y segura de hacer esto, sin un empujón o una actualización forzada-es ir a buscar en feature1 principal:

(feature1)$ git fetch . feature1:master 
From . 
    4a6000d..8675309 feature1 -> master 

El truco está utilizando . para conseguir que el árbitro locales feature1. Esto es más seguro que la actualización forzosa de la rama maestra, ya que asegura que la actualización es un avance rápido. (Consulte el parámetro <refspec> en el git-fetch documentation para obtener más información.)

Ahora que feature1 y el maestro son los mismos, el cambio entre ellos no tocará los archivos:

(feature1)$ git checkout master 
Switched to branch 'master' 
(master)$ 
+0

Gracias, esto funcionó. Aunque, no entiendo qué está haciendo la parte 'fetch'. – towi

+1

@towi Efectivamente estás haciendo un 'git pull' sin actualizar la copia de trabajo (git pull es básicamente una combinación de' git fetch' y 'git merge'). – dlitz

+3

Esta debería ser la respuesta aceptada. Sigo volviendo a él en varios escenarios :) –

0

Si sólo se preocupan por un par de archivos, y está usando Unix, puede cambiar manualmente arregla el mtime después del hecho usando touch -d <timestamp>. Asegúrese de utilizar ls --full-time para obtener la marca de tiempo, ya que la pantalla predeterminada carece de precisión.

Por ejemplo, imagine que está utilizando Docker para crear una imagen para una aplicación web basada en Python. Si el archivo requirements.txt cambia, tarda mucho tiempo en reconstruirse, ya que tiene que descargar varias bibliotecas de terceros y compilarlas. Simplemente restablecer -mtime de ese archivo después de la fusión:

ls -og --full-time src/requirements.txt 
# -rw-r--r-- 1 282 2015-11-04 20:03:28.918979065 +0400 src/requirements.txt 

git checkout master 
git merge --no-ff feature-foo 

touch src/requirements.txt -d "2015-11-04 20:03:28.918979065 +0400" 
Cuestiones relacionadas