¿Cómo recuperar los permisos de archivo a lo que git "piensa" que debe ser el archivo?


Tengo un git checkout. Todos los permisos de archivo son diferentes de lo que git piensa 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 a lo que git piensa que deberían ser?

Author: kenorb, 2010-03-25

8 answers

Git realiza un seguimiento de la emisión de archivos y expone los cambios de permisos al crear parches usando git diff -p. Todo lo que necesitamos es:

  1. crear un parche inverso
  2. incluir solo los cambios de permisos
  3. 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 se puede invocar a través de:

git permission-reset

Nota, si tu shell es bash, asegúrate de usar ' en lugar de " comillas alrededor del !git, de lo contrario se sustituye por el último comando git que ejecutó.

Thx a @Mixologic por señalar que simplemente usando -R en git diff, el engorroso comando sed ya no es necesario.

 447
Author: muhqu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-25 11:52:38

Intenta git config core.fileMode false

Nota: core.fileMode es sensible a mayúsculas y minúsculas!

De la git config página de manual:

core.fileMode

Si es false, las diferencias de bits ejecutables entre el índice y la copia de trabajo se ignoran; útil en sistemas de archivos rotos como FAT. Véase git-update-index(1).

El valor predeterminado es true, excepto que git-clone(1) o git-init(1) probarán y establecerán core.FileMode false si es apropiado cuando se crea el repositorio.

 91
Author: Tim Henigan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-16 05:21:22

Git no almacena permisos de archivo que no sean scripts ejecutables. Considere usar algo como git-cache-meta para guardar la propiedad del archivo y los permisos.

Git solo puede almacenar dos tipos de modos: 755 (ejecutable) y 644 (no ejecutable). Si tu archivo fuera 444 git almacenaría que tiene 644.

 8
Author: kroger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-18 15:15:15
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 instaladas herramientas de comparación externas como meld, 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

 4
Author: zainengineer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-30 07:58:55

También podría probar un gancho pre/post checkout podría hacer el truco.

Ver: Personalizar Git-Git Hooks

 0
Author: Doug,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-24 12:19:57

Lo más fácil de hacer es simplemente cambiar los permisos de nuevo. Como señaló @kroger, git solo rastrea bits ejecutables. Así que probablemente solo necesita ejecutar chmod -x filename para arreglarlo (o +x si eso es lo que se necesita.

 -1
Author: Pat Notz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-25 18:24:23

git diff -p usado en la respuesta de muhqu puede no mostrar todas las discrepancias.

  • vi esto en Cygwin para archivos que no tenía
  • los cambios de modo se ignoran completamente si core.filemode es false (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)

Un revestimiento único no apto para la producción (sustituye por completo a 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)

 -1
Author: ivan_pozdeev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:26:26

El etckeeper tool {[5] } puede manejar permisos y con:

etckeeper init -d /mydir

Puede usarlo para otros dirs además de /etc.

Instale usando su gestor de paquetes u obtenga fuentes desde el enlace anterior.

 -1
Author: MoreIT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-24 12:18:13