Si Git informa que un archivo se volvió ejecutable —o dejó de serlo— en su Mac, primero identifique qué capa cambió: el archivo de trabajo, el índice de preparación (staging) o una confirmación (commit). Compare esos estados antes de modificar permisos o la configuración de Git. Git registra los archivos normales con el modo 100644 (no ejecutable) o 100755 (ejecutable); un cambio aislado entre ellos suele indicar una modificación en el bit de ejecución, no en el contenido del archivo. Documentación de diff de Git

1. Compruebe si el cambio está preparado (staged)

En Terminal, vaya al repositorio e inspeccione su estado y ambos diffs:

git status --short
git diff --summary
git diff --cached --summary

git diff compara el árbol de trabajo con el índice; git diff --cached compara el índice con HEAD. Git status distingue estas mismas capas, por lo que un cambio preparado aparece separado de uno no preparado. Documentación de git status

Busque salidas como mode change 100644 => 100755 path/to/file. Si aparece únicamente en git diff --summary, el archivo de trabajo difiere del índice. Si aparece en git diff --cached --summary, el cambio de modo se ha preparado y podría confirmarse. Si ambos están vacíos pero un compañero de equipo informa de un cambio confirmado, inspeccione el historial a continuación.

2. Compare el índice con el archivo de Mac

Para una ruta bajo seguimiento, inspeccione el modo registrado en el índice y los permisos actuales del archivo:

git ls-files --stage -- "scripts/build.sh"
ls -l "scripts/build.sh"

Reemplace scripts/build.sh con la ruta exacta relativa al repositorio; escríbala entre comillas para que los espacios y los caracteres de la shell se traten literalmente. En la salida de git ls-files --stage, el primer campo es el modo almacenado en el índice: 100644 significa que Git no registra el archivo como ejecutable, mientras que 100755 significa que sí lo hace. La salida de ls -l muestra los bits de permiso locales; una x en un triplete de permisos indica permiso de ejecución para esa clase de usuario. La documentación de git ls-files y la guía de permisos de Apple explican ambas perspectivas.

Esta comparación acota la causa. Si el índice indica 100644, pero ls -l muestra permiso de ejecución, la discrepancia reside en el archivo de trabajo (o Git está configurado para ignorar diferencias en los modos de archivo). Si el índice indica 100755, Git ya ha preparado o extraído un modo ejecutable, independientemente de lo que pretendía que fuera el archivo.

3. Encuentre la confirmación (commit) que introdujo el modo

Si el cambio ya se encuentra en el historial, examine los resúmenes de confirmaciones del archivo relevante:

git log --summary -- "scripts/build.sh"

El formato de parche de Git imprime encabezados old mode y new mode separados cuando cambia el modo de un archivo. Revise la confirmación donde cambian esos valores, luego compare su padre y el flujo de trabajo circundante: ¿se hizo ejecutable el archivo deliberadamente?, ¿un editor o script modificó los permisos?, ¿o se utilizó el repositorio en otro sistema de archivos o sistema operativo? La confirmación identifica cuándo Git registró el cambio; no demuestra qué aplicación o persona lo causó. Documentación sobre el formato diff de Git

Un cambio de modo en varios archivos no relacionados puede indicar una operación masiva de configuración de permisos o una transición de sistema de archivos o entorno. Git documenta que algunos sistemas de archivos no conservan los bits de ejecución y que un repositorio trasladado entre diferentes entornos puede experimentar comportamientos distintos con los modos de archivo. Tome esto como una pista para investigar, no como una prueba concluyente de una causa específica. Documentación de configuración de Git

4. Verifique la configuración de modo de archivo de Git

Compruebe la configuración y de dónde proviene:

git config --show-origin --get core.filemode

core.filemode controla si Git respeta las diferencias del bit de ejecución en el árbol de trabajo. Git establece esta opción en true de forma predeterminada cuando no se especifica y puede sondear el comportamiento del sistema de archivos al inicializar o clonar un repositorio. Si el comando muestra false, Git podría ignorar los cambios locales en el bit de ejecución; esa configuración no explica un modo ya registrado en una confirmación. Si no muestra nada, es posible que la opción no esté establecida, en cuyo caso se aplica el valor predeterminado documentado por Git. Documentación de configuración de Git

Evite establecer esta opción en false solo para ocultar una diferencia inesperada. Primero confirme si el repositorio se encuentra en un sistema de archivos o en una configuración compartida que no conserve de manera fiable los bits de ejecución, y si los colaboradores dependen del seguimiento de modos. Modificar este ajuste cambia la forma en que Git gestiona las diferencias de modo; no repara un modo registrado incorrectamente en el índice o en una confirmación.

5. Repare únicamente después de identificar el modo previsto

Si el archivo no debe ser ejecutable y el cambio no está preparado, restablezca el permiso local con chmod:

chmod a-x "scripts/build.sh"
git diff --summary

Si el modo previsto es ejecutable, use chmod a+x "scripts/build.sh" en su lugar. En macOS, chmod cambia los permisos del elemento especificado; elija el modo previsto en función de la función del archivo y la convención del repositorio, no simplemente para hacer desaparecer el diff. Guía de permisos de Apple

Si se ha preparado un modo incorrecto, establezca el permiso local deseado, luego prepare esa ruta de nuevo y revise el resumen preparado:

chmod a-x "scripts/build.sh"
git add -- "scripts/build.sh"
git diff --cached --summary

Use a+x en lugar de a-x cuando el archivo deba ser ejecutable. Si el modo es incorrecto en una confirmación existente, una nueva confirmación correctiva suele ser más clara que reescribir el historial compartido; coordine con su equipo antes de reescribir confirmaciones que otros ya puedan estar utilizando. En cualquier caso, inspeccione git diff y git diff --cached posteriormente para no pasar por alto modificaciones de contenido junto con el cambio de permisos.

Fuentes