git pull manteniendo cambios locales

132

¿Cómo puedo actualizar (extraer) de forma segura un proyecto git, manteniendo intactos archivos específicos, incluso si hay cambios ascendentes?

myrepo / config / config.php

¿Hay alguna forma de, incluso si este archivo se cambiara en remoto, cuando git pull, todo lo demás se actualiza, pero este archivo no cambia (ni siquiera se fusionó)?

PD. Necesito hacer lo que pido porque solo estoy escribiendo scripts de implementación basados ​​en git. No puedo cambiar los archivos de configuración a plantillas.

Por lo tanto, necesito una forma de escribir scripts de actualización que no pierdan lo que se cambió localmente. Esperaba algo tan simple como:

git assume-remote-unchanged file1
git assume-remote-unchanged file2

luego git pull

Johnny Everson
fuente
¿Se han config.phpcomprometido los cambios ?
Mark Longair
No está comprometido. Preferiría no tener que hacerlo
Johnny Everson
@JhonnyEverson: Es la misma clase general de un problema (Usted tiene un archivo de configuración y no desea comprometerse ajustes específicos, pero las necesidades de la estructura de archivo de configuración para realizar un seguimiento.)
Daenyth

Respuestas:

248

Hay una solución simple basada en el alijo Git. Guarda todo lo que has cambiado, saca todas las cosas nuevas, aplica tu alijo.

git stash
git pull
git stash pop

En stash pop puede haber conflictos. En el caso que describa, de hecho habría un conflicto config.php. Pero, resolver el conflicto es fácil porque sabes que lo que pones en el escondite es lo que quieres. Entonces haz esto:

git checkout --theirs -- config.php
GoZoner
fuente
55
ese git checkout: su comando es muy confuso. Hizo lo que quería una vez y algo realmente malo en otra ocasión. ¿Tienes alguna buena documentación al respecto?
Milimétrico
3
Sí, a veces 'suyo' y 'nuestro' pueden ser confusos. En un git merge'nuestro' es lo que está actualmente en el directorio de trabajo. Pero para un git rebase(o git rebase -onto) el significado puede intercambiarse.
GoZoner
1
git stash , git pull , git stash apply Puede soltar el alijo con: git stash dropUna vez que
combine
11
Lo que pasa con git es que tienes que entender lo que va a hacer. La otra cosa con git es que, incluso para las personas inteligentes, a menudo es muy difícil entender qué va a hacer git.
Brad Thomas
1
Debe verificar si realmente hay algo para esconder. De lo contrario, aparecería cambios ocultos de una anterior git stash.
Jörn Reimerdes
15

Si tiene un archivo en su repositorio que se supone que está personalizado por la mayoría de los extractores, cambie el nombre del archivo a algo como config.php.templatey agréguelo config.phpa su .gitignore.

KurzedMetal
fuente
55
compruebe esta respuesta también, puede usarla .gitattributespara mantener siempre sus cambios mientras se fusiona.
KurzedMetal
Eso es más de lo que necesitaba. Lo de la plantilla es la solución elegante, pero me temo que no puedo usar esto, ya que solo estoy escribiendo scripts de implementación.
Johnny Everson
6

Actualización: esto literalmente responde a la pregunta formulada, pero creo que la respuesta de KurzedMetal es realmente lo que quieres.

Asumiendo que:

  1. Estas en la rama master
  2. La rama aguas arriba está masterenorigin
  3. No tienes cambios no confirmados

.... Podrías hacerlo:

# Do a pull as usual, but don't commit the result:
git pull --no-commit

# Overwrite config/config.php with the version that was there before the merge
# and also stage that version:
git checkout HEAD config/config.php

# Create the commit:
git commit -F .git/MERGE_MSG

Puede crear un alias para eso si necesita hacerlo con frecuencia. Tenga en cuenta que si tiene cambios no confirmados config/config.php, esto los descartaría.

Mark Longair
fuente
4

También podemos probar git pull con rebase

git pull --rebase origin dev
Bhavesh Maniya
fuente
1

Para responder a la pregunta: si desea excluir ciertos archivos de un pago, puede usar el pago escaso

1) En .git/info/sparse-checkout, define lo que quieres conservar. Aquí, queremos todos (*) pero (observe el signo de exclamación) config.php:

 /*
 !/config.php

2) Dígale a git que desea tener en cuenta el pago escaso

 git config core.sparseCheckout true

3) Si ya tiene este archivo localmente, haga lo que git hace en un pago escaso (dígale que debe excluir este archivo configurando el indicador "skip-worktree" en él)

git update-index --skip-worktree config.php

4) Disfrute de un repositorio donde su archivo config.php es suyo, independientemente de los cambios que se realicen en el repositorio.


Tenga en cuenta que los valores de configuración NO DEBEN estar en el control de origen:

  • Es una posible violación de seguridad
  • Causa problemas como este para el despliegue

Esto significa que DEBE excluirlos (ponerlos en .gitignore antes de la primera confirmación) y crear el archivo apropiado en cada instancia en la que desproteja su aplicación (copiando y adaptando un archivo de "plantilla")

Tenga en cuenta que, una vez que git se hace cargo de un archivo, .gitignore no tendrá ningún efecto.

Dado que, una vez que el archivo está bajo el control de la fuente, solo tiene dos opciones (): - volver a basar todo su historial para eliminar el archivo (con git filter-branch) - crear una confirmación que elimine el archivo. Es como pelear una batalla perdida, pero, bueno, a veces tienes que vivir con eso.

Pierre-Olivier Vares
fuente