Tengo cambios locales en un archivo que no quiero comprometer en mi repositorio. Es un archivo de configuración para compilar la aplicación en un servidor, pero quiero compilar localmente con diferentes configuraciones. Naturalmente, el archivo siempre aparece cuando hago 'git status' como algo para organizar. Me gustaría ocultar este cambio en particular y no comprometerlo. No haré ningún otro cambio en el archivo.
Después de investigar un poco, veo 2 opciones: 'asumir-sin cambios' y 'omitir-árbol de trabajo'. Una pregunta anterior aquí habla sobre ellos, pero en realidad no explica sus diferencias. Mi pregunta es esta: ¿en qué se diferencian los dos comandos? ¿Por qué alguien usaría uno u otro?
.gitignore
para fines similares. ¿Esta solución funcionaría para usted?Respuestas:
Que desea
skip-worktree
.assume-unchanged
está diseñado para casos en los que es costoso verificar si se ha modificado un grupo de archivos; cuando configura el bit,git
(por supuesto) supone que los archivos correspondientes a esa parte del índice no se han modificado en la copia de trabajo. Por lo tanto, evita un lío destat
llamadas. Este bit se pierde cada vez que cambia la entrada del archivo en el índice (por lo tanto, cuando el archivo se cambia en sentido ascendente).skip-worktree
es más que eso: incluso cuandogit
sabe que el archivo ha sido modificado (o necesita ser modificado por algoreset --hard
similar), fingirá que no lo ha sido, utilizando la versión del índice en su lugar. Esto persiste hasta que se descarta el índice.Hay un buen resumen de las ramificaciones de esta diferencia y los casos de uso típicos aquí: http://fallengamer.livejournal.com/93321.html .
De ese artículo:
--assume-unchanged
asume que un desarrollador no debería cambiar un archivo. Este indicador está destinado a mejorar el rendimiento de las carpetas que no cambian, como los SDK.--skip-worktree
es útil cuando le indica a git que no toque un archivo específico porque los desarrolladores deberían cambiarlo. Por ejemplo, si el repositorio principal en sentido ascendente aloja algunos archivos de configuración listos para producción y no desea confirmar accidentalmente los cambios en esos archivos,--skip-worktree
eso es exactamente lo que desea.fuente
--skip-worktree
efectos y desactivar la bandera hay una--no-skip-worktree
opción. Funciona exactamente de la misma manera. Esto es útil en caso de que una mano se haya deslizado y se hayan marcado archivos incorrectos, o si las circunstancias hubieran cambiado y los archivos previamente omitidos ya no se deben ignorar.--skip-worktree
y el.git/info/exclude
archivo es que el primero funcionará incluso para los archivos que se rastrean actualmente..git/info/exclude
, como.gitignore
, solo evitará agregar accidentalmente archivos no rastreados al índice, pero no realizará cambios en los archivos que ya están rastreados.git update-index --skip-worktree <file_name>
Nota: fallengamer hizo algunas pruebas en 2011 (por lo que pueden estar desactualizadas), y aquí están sus hallazgos :
Operaciones
git pull
:Git conserva los cambios locales de todos modos.
Por lo tanto, no perderá accidentalmente ningún dato que haya marcado con ninguna de las banderas.
assume-unchanged
bandera: Git no sobrescribiría el archivo local. En cambio, generaría conflictos y consejos sobre cómo resolverlosskip-worktree
bandera: Git no sobrescribiría el archivo local. En cambio, generaría conflictos y consejos sobre cómo resolverlosgit stash
git pull
skip-worktree
assume-unchanged
bandera: descarta todos los cambios locales sin posibilidad de restaurarlos. El efecto es como 'git reset --hard
'. 'git pull
' la llamada tendrá éxitoskip-worktree
bandera: Stash no funcionaría enskip-worktree
archivos. 'git pull
' fallará con el mismo error que el anterior. El desarrollador se ve obligado a restablecer manualmente elskip-worktree
indicador para poder ocultar y completar el errorpull
.git pull
assume-unchanged
assume-unchanged
bandera: el contenido se actualiza, la bandera se pierde.'
git ls-files -v
' mostraría que la bandera se modifica aH
(desdeh
).skip-worktree
bandera: el contenido se actualiza, la bandera se conserva.'
git ls-files -v
' mostraría la mismaS
bandera que antespull
.git reset --hard
skip-worktree
assume-unchanged
assume-unchanged
bandera: se revierte el contenido del archivo. La bandera se restablece aH
(desdeh
).skip-worktree
bandera: el contenido del archivo está intacto. La bandera sigue siendo la misma.Agrega el siguiente análisis:
Parece que se
skip-worktree
está esforzando mucho por preservar sus datos locales . Pero no le impide obtener cambios aguas arriba si es seguro. Además, git no restablece la banderapull
.Pero ignorar el
reset --hard
comando ' ' podría convertirse en una desagradable sorpresa para un desarrollador.Assume-unchanged
La bandera podría perderse en lapull
operación y los cambios locales dentro de dichos archivos no parecen ser importantes para git.Ver:
Comentario de Junio (actual mantenedor de git) sobre la intención de
assume-unchanged
,En particular, Junio señala que los cambios en los
assume-unchanged
archivos podrían cometerse accidentalmente: "si Git puede determinar una ruta marcada comoassume-unchanged
modificada 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 cometer ese cambio) ".diferencia entre
assume-unchanged
yskip-worktree
como se discutió en la lista de correo de git al agregar elskip-worktree
parche .Él concluye:
En realidad, ninguna de las banderas es lo suficientemente intuitiva .
assume-unchanged
asume que un desarrollador no debería cambiar un archivo. Si se modificó un archivo, ese cambio no es importante. Este indicador está destinado a mejorar el rendimiento de las carpetas que no cambian, como los SDK.Pero si la promesa se rompe y se cambia un archivo, git revierte la bandera para reflejar la realidad. Probablemente esté bien tener algunos indicadores inconsistentes en carpetas generalmente no destinadas a ser cambiadas.
Por otro lado,
skip-worktree
es útil cuando le indica a git que no toque nunca un archivo específico. Eso es útil para un archivo de configuración ya rastreado.El repositorio principal ascendente aloja algunas configuraciones listas para producción, pero le gustaría cambiar algunas configuraciones en la configuración para poder hacer algunas pruebas locales. Y no desea verificar accidentalmente los cambios en dicho archivo para afectar la configuración de producción. En ese caso
skip-worktree
hace escena perfecta.Con Git 2.25.1 (febrero de 2020), el "En realidad ninguna de las banderas es lo suficientemente intuitiva" mencionado anteriormente se aclara más:
Ver commit 7a2dc95 , commit 1b13e90 (22 de enero de 2020) por brian m. carlson (
bk2204
) .(Fusionada por Junio C Hamano -
gitster
- en commit 53a8329 , 30 de enero de 2020)( Lista de correo de Git )
La
git update-index
página del manual ahora incluye:La última parte es lo que describo como un controlador de filtro de contenido típico basado en scripts de borrones / limpieza .
fuente