Mantenga el archivo en un repositorio de Git, pero no rastree los cambios

305

Tengo varios archivos en un sitio de CodeIgniter que querré tener en el repositorio pero no rastrear ningún cambio.

Por ejemplo, implemento una nueva instalación de este marco en un nuevo cliente, quiero que se descarguen los siguientes archivos (tienen los valores predeterminados CHANGEME) y solo tengo que hacer cambios específicos para este cliente (credenciales de la base de datos, información de la dirección de correo electrónico, CSS personalizado).

// the production config files i want the files but they need to be updated to specific client needs
application/config/production/config.php
application/config/production/database.php
application/config/production/tank_auth.php
// index page, defines the environment (production|development)
/index.php
// all of the css/js cache (keep the folder but not the contents)
/assets/cache/*
// production user based styling (color, fonts etc) needs to be updated specific to client needs
/assets/frontend/css/user/frontend-user.css

Actualmente si corro

git clone [email protected]:user123/myRepo.git httpdocs

y luego edita los archivos de arriba, todo es genial. Hasta que libero una revisión o parche y corro git pull. Todos mis cambios se sobrescriben.

gorelativo
fuente
¿Podría ignorar los archivos de configuración / credenciales del cliente y hacer que el programa cree los archivos predeterminados si faltan cuando se instala el repositorio?
MatthewG

Respuestas:

618

git tiene una solución diferente para hacer esto. Primero cambie el archivo que no desea que se rastree y use el siguiente comando:

git update-index --assume-unchanged FILE_NAME

y si desea seguir los cambios nuevamente, use este comando:

git update-index --no-assume-unchanged FILE_NAME

documentación de git-update-index

nasirkhan
fuente
Hice lo que dices, pero el estado de git sigue diciendo que el archivo está modificado
rraallvv
77
Sí, esta debería ser la "respuesta aceptada". Trabajó para mi.
joshmcode
34
Según Junio ​​Hamano (el mantenedor de Git): "No se debe abusar de asumir sin cambios por un mecanismo de ignorar. [...] Git no promete que Git siempre considerará que estos caminos no están modificados --- si Git puede determinar que una ruta que está marcada como asumir-sin cambios ha cambiado sin incurrir en un costo adicional de lstat (2), se reserva el derecho de informar que la ruta ha sido modificada (como resultado, "git commit -a" es libre de confirmar que cambio)." En otras palabras, asumir sin cambios es solo para problemas de rendimiento local. Si Git puede determinar que esos archivos cambiaron de una manera más ligera, lo hará.
Alejandro García Iglesias
41
Al leer la información, creo que la --skip-worktreeopción es más adecuada para este trabajo que --assume-unchanged.
PJSCopeland
26
--skip-worktree es de hecho la mejor opción. Más información: stackoverflow.com/questions/13630849/…
Personalizador
80

Para extraer una respuesta de los comentarios de otra respuesta:

$ git update-index --skip-worktree FILENAME

Parece ser una mejor opción que --assume-unchanged

Puede leer más sobre esto aquí: Git: diferencia entre 'asumir-sin cambios' y 'omitir-árbol de trabajo'

Antonio
fuente
Cuando hago esto y luego trato de cambiar las ramas, aparece "Los siguientes archivos de árbol de trabajo no rastreados se sobrescribirán al finalizar la compra ... Por favor, muévalos o elimínelos antes de cambiar de rama". ¿Alguna idea de cómo evitar?
Patrick Szalapski
El artículo al que hace referencia @aexl se trasladó a compiledsuccessfully.dev/git-skip-worktree
Andrew Keeton el
1
Los documentos dicen que es una mala idea. "Los usuarios a menudo intentan usar los bits de asumir-sin cambios y omitir-trabajo para decirle a Git que ignore los cambios en los archivos que se rastrean. Esto no funciona como se esperaba, ya que Git aún puede verificar los archivos de árbol de trabajo contra el índice al realizar ciertas operaciones. En general, Git no proporciona una forma de ignorar los cambios en los archivos rastreados, por lo que se recomiendan soluciones alternativas ".
Curtis Blackwell
58

Para mis proyectos de Code Igniter, mantengo database.php.example y config.php.example en el repositorio.

Luego agrego config.php y aplicaciones / config / database.php al archivo .gitignore .

Entonces, finalmente, cuando implemente, puedo copiar los archivos .example (a config.php y database.php), personalizarlos y GIT no los rastreará.

superiggy
fuente
12
Buena solución, pero creo que la respuesta de nasirkhan es la mejor.
wordsforthewise
Esta no es una buena solución. Si elimina su índice git, comenzará a rastrear los cambios cuando no lo desee. Consulte la respuesta de @nasirkhans para conocer la forma correcta de hacerlo.
Brian Melton-Grace - MSFT
3
No estoy de acuerdo con los dos comentarios anteriores. De esta manera, es mucho más fácil actualizar los valores "predeterminados" sin tener que pagarlos y copiar su configuración local en otro lugar solo para volver a colocarlos. Además, se aplica a todos los repositorios, por lo que no tiene que hacer ningún cambio de repositorio repetido.
OskarD90
1
si está en gitignore, ¿por qué comenzaría a rastrear cambios nuevamente
Shapeshifter
Resuelve el problema del OP pero realmente no responde la pregunta.
Travis Wilson
1

Los pondría en tu .gitignore archivo y los copiaría manualmente según sea necesario.

Entonces el nombre de archivo esqueleto estaría en git, los nombres de archivo ignorados no estarían en git (pero estarían en .gitignore). De esta forma, cuando se realiza el paso manual para copiarlos a 'real' desde 'plantilla' (tal vez mejor nombre que esqueleto), se ignoran de inmediato.

Michael Durrant
fuente
1
¿no hay forma de agregarlos primero al repositorio y luego agregarlos a .gitignore? Sería genial si hubiera una solución para esto para incluir los archivos pero no cualquier cambio después de una cierta confirmación o algo así.
Gorelativo
1
@mklauber Quiero mantenerlos indefinidamente hasta que corra git rm <file>. El propósito es IE: un archivo config.php. Quiero mantener el archivo de configuración, pero obviamente no quiero rastrear las credenciales de la base de datos de cliente a cliente, ya que son diferentes.
Gorelativo
1
Sí, tengo el problema con nuestro archivo database.yml de rails. Mantenemos un esqueleto y luego lo copiamos y cambiamos.
Michael Durrant
si creo estos archivos de configuración "Esqueleto", ¿los agregaría a una confirmación inicial? y luego modificando .gitignore para ignorar el archivo? En efecto, ¿mantener el archivo en el repositorio pero como un esqueleto?
gorelativo
10
Tiene estas dos opciones: Agregue el archivo git add file1y luego edítelo .gitignore. El archivo comprometido permanecerá allí y no se actualizará. O bien: puede agregar el archivo .gitignorey luego agregarlo git add --force file1para forzar el archivo. Puede usar la segunda opción siempre que tenga que sobrescribir el archivo
klaustopher
1

Las respuestas dadas están resolviendo el problema solo parcialmente, pero introduciendo aún más problemas.

Necesitaba preservar el archivo "Web.Local.config". La única solución que funcionó para mí fue:

1. Excluir el archivo del proyecto

2. Cree una copia separada del archivo como Web.LocalTemplate.config

Ahora que Git rastrea "Web.LocalTemplate.config", todos los desarrolladores pueden usarlo como punto de partida. Sin embargo, el "Web.Local.config", que no forma parte del proyecto, se ignorará automáticamente.

Hrvoje Matić
fuente
¿Cómo es git update-index --skip-worktree FILENAMEsolo resolver su problema parcialmente, o incluso agregar más problemas? Resuelve exactamente lo que estás tratando de hacer. ¿Lo intentaste?
Amir Asyraf