Como recuperar as permissions do arquivo para o que o git “pensa” que o arquivo deveria ser?

Eu tenho um checkout git. Todas as permissions de arquivo são diferentes do que o git acha que elas deveriam ser, portanto todas elas aparecem como modificadas.

Sem tocar no conteúdo dos arquivos (só quero modificar as permissions) como eu defino todas as permissions de arquivos para o que o git acha que elas deveriam ser?

O Git controla a permissão de arquivos e expõe as mudanças de permissão ao criar patches usando git diff -p . Então tudo que precisamos é:

  1. criar um patch reverso
  2. include apenas as alterações de permissão
  3. aplicar o patch para a nossa cópia de trabalho

Como um one-liner:

 git diff -p -R --no-color \ | grep -E "^(diff|(old|new) mode)" --color=never \ | git apply 

você também pode adicioná-lo como um alias para sua configuração do git …

 git config --global --add alias.permission-reset '!git diff -p -R --no-color | grep -E "^(diff|(old|new) mode)" --color=never | git apply' 

… e você pode invocá-lo via:

 git permission-reset 

Note que, se o shell for bash , certifique-se de usar aspas ' vez de " volta do !git , caso contrário, ele será substituído pelo último comando git você executou.

Thx to @Mixologic por apontar que simplesmente usando -R no git diff , o complicado comando sed não é mais necessário.

Tente git config core.fileMode false

Nota: core.fileMode é sensível a maiúsculas e minúsculas !

Na página man do git config :

core.fileMode

Se false, as diferenças de bit executável entre o índice e a cópia de trabalho são ignoradas; útil em filesystems quebrados como o FAT. Veja git-update-index (1) .

O padrão é true, exceto que git-clone (1) ou git-init (1) examinará e definirá core.fileMode false se apropriado quando o repository for criado.

O Git não armazena permissions de arquivos que não sejam scripts executáveis. Considere usar algo como git-cache-meta para salvar a propriedade e as permissions do arquivo.

O Git só pode armazenar dois tipos de modos: 755 (executável) e 644 (não executável). Se o seu arquivo foi 444 git iria armazenar ele tem 644.

 git diff -p \ | grep -E '^(diff|old mode|new mode)' \ | sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/' \ | git apply 

irá funcionar na maioria dos casos mas se você tiver ferramentas de diff externas como o meld instalado você tem que adicionar –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 

foi necessário na minha situação

Você também pode tentar um gancho de check-out pré / pós pode fazer o truque.

Veja: Personalizando Git – Git Hooks

O mais fácil é apenas alterar as permissions de volta. Como @kroger notou git, apenas rastreia bits executáveis. Então você provavelmente só precisa executar o chmod -x filename para consertá-lo (ou +x se for necessário).

git diff -p usado na resposta de muhqu pode não mostrar todas as discrepâncias.

  • vi isso no Cygwin para arquivos que eu não possuía
  • alterações de modo são ignoradas completamente se core.filemode é false (que é o padrão para MSysGit)

Este código lê os metadados diretamente em vez disso:

 (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 ax "$path";; 100755) chmod a+x "$path";; *) echo "invalid: $mask $type $blob\t$path" >&2; false;; esac done) 

Um one-liner de não produção (substitui totalmente as máscaras):

 git ls-tree HEAD | perl -ne '/^10(0\d{3}) blob \S+\t(.+)$/ && { system "chmod",$1,$2 || die }' 

(Crédito para “$ ‘\ 0′” vai para http://transnum.blogspot.ru/2008/11/bashs-read-built-in-supports-0-as.html )

A ferramenta etckeeper pode manipular permissions e com:

 etckeeper init -d /mydir 

Você pode usá-lo para outros diretórios que /etc

Instale usando seu gerenciador de pacotes ou obtenha fonts do link acima.