Como adicionar permissões chmod ao arquivo no GIT?

182

Eu quero o git confirmar um arquivo .sh, mas quero que ele seja executável quando eu fizer check-out do mesmo arquivo em outro servidor.

Existe uma maneira de fazer isso sem chmod u + x manualmente esse arquivo nos servidores que efetuam o checkout do arquivo?

Henley Chiu
fonte

Respostas:

291

De acordo com a documentação oficial , você pode definir ou remover o sinalizador "executável" em qualquer arquivo rastreado usando o update-indexsubcomando.

Para definir o sinalizador, use o seguinte comando:

git update-index --chmod=+x path/to/file

Para removê-lo, use:

git update-index --chmod=-x path/to/file

Sob o capô

Embora isso pareça o sistema de permissão de arquivos unix comum, na verdade não é. O Git mantém um "modo" especial para cada arquivo em seu armazenamento interno:

  • 100644 para arquivos regulares
  • 100755 para executáveis

Você pode visualizá-lo usando o ls-filesubcomando, com a --stageopção:

$ git ls-files --stage
100644 aee89ef43dc3b0ec6a7c6228f742377692b50484 0       .gitignore
100755 0ac339497485f7cc80d988561807906b2fd56172 0       my_executable_script.sh

Por padrão, quando você adiciona um arquivo a um repositório, o Git tenta honrar seus atributos do sistema de arquivos e define o modo de arquivo correto de acordo. Você pode desativar isso configurando a core.fileModeopção para false:

git config core.fileMode false

Solução de problemas

Se em algum momento o modo de arquivo Git não estiver definido, mas o arquivo tiver o sinalizador correto do sistema de arquivos, tente remover o modo e configure-o novamente:

git update-index --chmod=-x path/to/file
git update-index --chmod=+x path/to/file

Bônus

Começando com o Git 2.9, você pode preparar um arquivo E definir o sinalizador em um comando:

git add --chmod=+x path/to/file
Antwane
fonte
Quando faço isso para test.sh, git commit, push e checkout em outro servidor, estas são as permissões desse arquivo: -rw-rw-r-- 1 usuário user 12 Dec 5 11:42 test.sh
Henley Chiu
Acabei de executar o teste em um dos meus repositórios e funciona como esperado. As permissões foram definidas no arquivo usando o comando fornecido no Windows. Em um dos meus servidores (Debian), o arquivo tinha permissões -rw-r - r-- antes, agora definido como -rwxr-xr-x. Qual versão do git você usa em máquinas locais e remotas?
Antwane
git versão 1.9.5 no meu local e git 1.7.1 no servidor que faz o checkout.
Henley Chiu
Apenas tentei clonar em outro servidor (mais antigo) com o git 1.7.10, ele ainda funciona bem, o arquivo tem permissões x. Talvez você tenha cometido um erro em algum momento ou tenha problemas de permissão com o usuário que clonou no servidor remoto.
Antwane
Observe que você só pode alterar (definir ou limpar) a permissão de execução. O Git não rastreia nenhuma outra permissão (como permissão de leitura ou gravação).
Dan Anderson
25

A resposta de Antwane está correta, e isso deve ser um comentário, mas os comentários não têm espaço suficiente e não permitem a formatação. :-) Eu só quero acrescentar que no Git, as permissões de arquivo são registradas apenas 1 como 644ou 755(escritas ( 100644e 100755; a 100parte significa "arquivo regular"):

diff --git a/path b/path
new file mode 100644

O primeiro - 644 - significa que o arquivo não deve ser executável, e o último significa que ele deve ser executável. Como isso se transforma nos modos de arquivo reais no sistema de arquivos depende um pouco do sistema operacional. Em sistemas do tipo Unix, os bits são passados ​​pela sua umaskconfiguração, que normalmente seria 022remover a permissão de gravação de "grupo" e "outro" ou 002remover a permissão de gravação apenas de "outro". Pode ser também 077se você está especialmente preocupado com a privacidade e deseja remover a permissão de leitura, gravação e execução do "grupo" e do "outro".


1 Versões extremamente antigas do Git salvavam permissões de grupo, para que alguns repositórios tivessem entradas de árvore com o modo 664nelas. O Git moderno não, mas como nenhuma parte de qualquer objeto pode ser alterada, esses bits de permissão antigos ainda persistem em objetos de árvore antigos.

A alteração para armazenar apenas 0644 ou 0755 estava no commit e44794706eeb57f2 , anterior ao Git v0.99 e datado de 16 de abril de 2005.

torek
fonte
"Versões anteriores do Git", alguma idéia de quais versões exatas são afetadas por isso?
user5359531
2
@ user5359531 versões antes da confirmação e44794706eeb57f2ee38ed1604821aa38b8ad9d2, ou seja, anterior à versão 0.99 do Git.
torek 7/03/19