Se o Git relatar que um arquivo se tornou executável — ou deixou de ser executável — no seu Mac, primeiro descubra qual camada foi alterada: o arquivo de trabalho, o índice de preparação (staging) ou um commit. Compare esses estados antes de alterar permissões ou a configuração do Git. O Git registra arquivos comuns como modo 100644 (não executável) ou 100755 (executável); uma alteração isolada entre eles geralmente indica uma mudança no bit de execução, não no conteúdo do arquivo. Documentação do git-diff
1. Verifique se a alteração está na área de preparação (staged)
No Terminal, acesse o repositório e inspecione seu status e ambos os diffs:
git status --short
git diff --summary
git diff --cached --summary
git diff compara a árvore de trabalho com o índice; git diff --cached compara o índice com HEAD. O status do Git faz distinção entre essas mesmas camadas, de modo que uma alteração preparada (staged) aparece separadamente de uma não preparada. Documentação do git-status
Procure por saídas como mode change 100644 => 100755 path/to/file. Se aparecer apenas em git diff --summary, o arquivo de trabalho difere do índice. Se aparecer em git diff --cached --summary, a alteração de modo foi preparada e pode ser confirmada em um commit. Se ambos estiverem vazios, mas um colega de equipe relatar uma alteração confirmada em commit, inspecione o histórico a seguir.
2. Compare o índice com o arquivo no Mac
Para um caminho monitorado, inspecione o modo registrado no índice e as permissões atuais do arquivo:
git ls-files --stage -- "scripts/build.sh"
ls -l "scripts/build.sh"
Substitua scripts/build.sh pelo caminho exato relativo ao repositório; use aspas para que espaços e caracteres do shell sejam tratados literalmente. Na saída de git ls-files --stage, o primeiro campo é o modo armazenado no índice: 100644 significa que o Git não registra o arquivo como executável, enquanto 100755 significa que registra. A saída de ls -l mostra os bits de permissão locais; um x em uma trinca de permissões indica permissão de execução para essa classe de usuário. A documentação do git-ls-files e o guia de permissões da Apple explicam as duas visões.
Essa comparação restringe a causa. Se o índice indicar 100644, mas o ls -l mostrar permissão de execução, a discrepância está no arquivo de trabalho (ou o Git está configurado para ignorar diferenças de modo de arquivo). Se o índice indicar 100755, o Git já preparou ou fez o checkout de um modo executável, independentemente de como você pretendia que o arquivo fosse.
3. Encontre o commit que introduziu o modo
Se a alteração já estiver no histórico, examine os resumos de commit do arquivo relevante:
git log --summary -- "scripts/build.sh"
O formato de patch do Git exibe cabeçalhos separados de old mode e new mode quando o modo de um arquivo muda. Revise o commit onde esses valores mudam e, em seguida, compare o commit pai e o fluxo de trabalho ao redor: o arquivo foi tornado executável deliberadamente, um editor ou script alterou as permissões, ou o repositório foi usado em outro sistema de arquivos ou operacional? O commit identifica quando o Git registrou a alteração; ele não prova qual aplicativo ou pessoa a causou. Documentação do formato de diff do Git
Uma alteração de modo em vários arquivos não relacionados pode indicar uma operação abrangente de definição de permissões ou uma transição de sistema de arquivos/ambiente. O Git documenta que alguns sistemas de arquivos não preservam os bits de execução e que um repositório movido entre ambientes pode apresentar comportamentos diferentes em relação aos modos de arquivo. Trate isso como uma pista para investigar, não como prova de uma causa específica. Documentação de configuração do Git
4. Verifique a configuração de modo de arquivo do Git
Verifique a configuração e de onde ela vem:
git config --show-origin --get core.filemode
core.filemode controla se o Git respeita as diferenças de bit de execução na árvore de trabalho. O Git define isso como verdadeiro por padrão quando não especificado e pode testar o comportamento do sistema de arquivos quando um repositório é inicializado ou clonado. Se o comando imprimir false, o Git poderá ignorar as alterações locais no bit de execução; essa configuração não explica um modo que já foi registrado em um commit. Se não imprimir nada, a configuração pode não estar definida, caso em que o padrão documentado do Git se aplica. Documentação de configuração do Git
Evite definir essa opção como false apenas para ocultar um diff inesperado. Primeiro, confirme se o repositório está em um sistema de arquivos ou configuração compartilhada que não preserva os bits de execução de forma confiável e se os colaboradores dependem do rastreamento de modo. Mudar a configuração altera a forma como o Git lida com as diferenças de modo; isso não repara um modo registrado incorretamente no índice ou no commit.
5. Corrija apenas após identificar o modo pretendido
Se o arquivo não deve ser executável e a alteração não estiver preparada (unstaged), restaure a permissão local com chmod:
chmod a-x "scripts/build.sh"
git diff --summary
Se o modo pretendido for executável, use chmod a+x "scripts/build.sh". No macOS, chmod altera as permissões do item especificado; escolha o modo pretendido com base na função do arquivo e na convenção do repositório, não apenas para fazer o diff desaparecer. Guia de permissões da Apple
Se um modo incorreto for preparado (staged), defina a permissão local pretendida, prepare esse caminho novamente e revise o resumo preparado:
chmod a-x "scripts/build.sh"
git add -- "scripts/build.sh"
git diff --cached --summary
Use a+x no lugar de a-x quando o arquivo deve ser executável. Se o modo estiver incorreto em um commit existente, um novo commit corretivo geralmente é mais claro do que reescrever o histórico compartilhado; coordene com a equipe antes de reescrever commits que outros já possam estar usando. Em qualquer caso, inspecione git diff e git diff --cached depois para não ignorar edições de conteúdo que possam acompanhar a alteração de permissão.
Fontes
BSD Permissions and Ownership — Apple Developer