¿Cómo recuperar los permisos de archivo a lo que git "piensa" que debería ser el archivo?
file file-permissions (8)
Git no almacena permisos de archivo que no sean scripts ejecutables. Considere usar algo como git-cache-meta para guardar la propiedad y los permisos de los archivos.
Git solo puede almacenar dos tipos de modos: 755 (ejecutable) y 644 (no ejecutable). Si su archivo fuera 444 git lo almacenaría tiene 644.
Tengo un pago de git. Todos los permisos de archivo son diferentes de lo que git cree que deberían ser, por lo tanto, todos aparecen como modificados.
Sin tocar el contenido de los archivos (solo quiero modificar los permisos), ¿cómo configuro todos los permisos de los archivos según lo que git cree que deberían ser?
La herramienta etckeeper
puede manejar permisos y con:
etckeeper init -d /mydir
Puedes usarlo para otras direcciones que no sean /etc
Instale usando su administrador de paquetes u obtenga fuentes desde el enlace anterior.
Lo más fácil es volver a cambiar los permisos. Como @kroger señaló, git solo rastrea los bits ejecutables. Entonces, probablemente solo necesite ejecutar chmod -x filename
para solucionarlo (o +x
si eso es lo que necesita.
Prueba git config core.fileMode false
Nota: ¡ core.fileMode
mayúsculas y minúsculas !
Desde la página del manual de git config
:
core.fileMode
Si es falso, las diferencias de bits ejecutables entre el índice y la copia de trabajo se ignoran; Útil en sistemas de archivos rotos como FAT. Ver git-update-index(1) .
El valor predeterminado es true, excepto que git-clone (1) o git-init (1) sondearán y establecerán core.fileMode falso si es apropiado cuando se crea el repositorio.
También puedes probar con un gancho pre / post checkout que podría hacer el truco.
git diff -p
utilizado en la respuesta de muhqu puede no mostrar todas las discrepancias.
- Vi esto en Cygwin para archivos que no poseía
- los cambios de modo se ignoran completamente si
core.filemode
esfalse
(que es el valor predeterminado para MSysGit)
Este código lee los metadatos directamente en su lugar:
(set -o errexit pipefail nounset;
git ls-tree HEAD -z | while read -r -d $''/0'' mask type blob path
do
if [ "$type" != "blob" ]; then continue; fi;
case "$mask" in
#do not touch other bits
100644) chmod a-x "$path";;
100755) chmod a+x "$path";;
*) echo "invalid: $mask $type $blob/t$path" >&2; false;;
esac
done)
Una sola línea de calidad no productiva (reemplaza completamente las máscaras):
git ls-tree HEAD | perl -ne ''/^10(0/d{3}) blob /S+/t(.+)$/ && { system "chmod",$1,$2 || die }''
(El crédito para "$ ''/ 0''" va a http://transnum.blogspot.ru/2008/11/bashs-read-built-in-supports-0-as.html )
Git realiza un seguimiento de la emisión de archivos y expone los cambios de permisos al crear parches utilizando git diff -p
. Así que todo lo que necesitamos es:
- crear un parche inverso
- incluir solo los cambios de permiso
- aplicar el parche a nuestra copia de trabajo
Como una sola línea:
git diff -p -R --no-color /
| grep -E "^(diff|(old|new) mode)" --color=never /
| git apply
También puedes agregarlo como un alias a tu configuración de git ...
git config --global --add alias.permission-reset ''!git diff -p -R --no-color | grep -E "^(diff|(old|new) mode)" --color=never | git apply''
... y puedes invocarlo a través de:
git permission-reset
Tenga en cuenta que si su shell es bash
, asegúrese de usar ''
lugar de "
comillas alrededor del !git
, de lo contrario, se sustituye con el último comando de git
que ejecutó.
Gracias a @Mixologic por señalar que simplemente usando -R
en git diff
, ya no se requiere el comando engorroso sed
.
git diff -p /
| grep -E ''^(diff|old mode|new mode)'' /
| sed -e ''s/^old/NEW/;s/^new/old/;s/^NEW/new/'' /
| git apply
funcionará en la mayoría de los casos, pero si tiene herramientas de diferencias externas como meld instalada, debe agregar --no-ext-diff
git diff --no-ext-diff -p /
| grep -E ''^(diff|old mode|new mode)'' /
| sed -e ''s/^old/NEW/;s/^new/old/;s/^NEW/new/'' /
| git apply
era necesario en mi situación