¿Cómo hago para que Git ignore los cambios en el modo de archivo (chmod)?

2311

Tengo un proyecto en el que tengo que cambiar el modo de los archivos chmoda 777 durante el desarrollo, pero que no debería cambiar en el repositorio principal.

Git recoge chmod -R 777 .y marca todos los archivos como modificados. ¿Hay alguna manera de hacer que Git ignore los cambios de modo que se han realizado en los archivos?

Marcus Westin
fuente
17
Esto es útil cuando se trabaja con git en Windows + Bash en Ubuntu en Windows
Elazar
44
Para cualquier persona que sólo quiere hacer caso omiso de los cambios de permisos para una invocación específica de git diff, y que por lo tanto no quiere alterar sus archivos de configuración de Git: se puede usar git diff -G.por Zed respuesta aquí .
sampablokuper

Respuestas:

3824

Tratar:

git config core.fileMode false

Desde git-config (1) :

core.fileMode
    Tells Git if the executable bit of files in the working tree
    is to be honored.

    Some filesystems lose the executable bit when a file that is
    marked as executable is checked out, or checks out a
    non-executable file with executable bit on. git-clone(1)
    or git-init(1) probe the filesystem to see if it handles the 
    executable bit correctly and this variable is automatically
    set as necessary.

    A repository, however, may be on a filesystem that handles
    the filemode correctly, and this variable is set to true when
    created, but later may be made accessible from another
    environment that loses the filemode (e.g. exporting ext4
    via CIFS mount, visiting a Cygwin created repository with Git
    for Windows or Eclipse). In such a case it may be necessary
    to set this variable to false. See git-update-index(1).

    The default is true (when core.filemode is not specified
    in the config file).

El -cindicador se puede usar para configurar esta opción para comandos únicos:

git -c core.fileMode=false diff

Y la --globalbandera hará que sea el comportamiento predeterminado para el usuario conectado.

git config --global core.fileMode false

Los cambios de la configuración global no se aplicarán a los repositorios existentes. Adicionalmente, git cloney git initestablecer explícitamente core.fileModeque trueen la configuración de recompra como se discutió en Git falsa mundial core.fileMode reemplazado de forma local en el clon

Advertencia

core.fileModeno es la mejor práctica y debe usarse con cuidado. Esta configuración solo cubre el bit de modo ejecutable y nunca los bits de lectura / escritura. En muchos casos, cree que necesita esta configuración porque hizo algo como chmod -R 777hacer que todos sus archivos sean ejecutables. Pero en la mayoría de los proyectos, la mayoría de los archivos no necesitan y no deben ser ejecutables por razones de seguridad .

La forma correcta de resolver este tipo de situación es manejar los permisos de carpetas y archivos por separado, con algo como:

find . -type d -exec chmod a+rwx {} \; # Make folders traversable and read/write
find . -type f -exec chmod a+rw {} \;  # Make files read/write

Si haces eso, nunca necesitarás usarlo core.fileMode, excepto en un entorno muy raro.

Greg Hewgill
fuente
203
Si lo hace git config --global core.filemode false, solo tendrá que hacer esto una vez para todos los repositorios.
Greg
13
esto no funcionó para mí hasta que haya solucionado el caso, debería ser fileMode en lugar de
filemode
8
@tishma: la sección de configuración de Git y los nombres de las variables no distinguen entre mayúsculas y minúsculas de acuerdo con la documentación, consulte la sección ARCHIVO DE CONFIGURACIÓN , por lo que si lo anterior no funcionó para usted, entonces fue por una razón diferente.
Greg Hewgill
11
@donquixote: el git configcomando escribe la configuración en el archivo de configuración correcto ( .git/configsolo para el repositorio actual, o ~/.gitconfigsi se usa con --global).
Greg Hewgill
8
@ zx1986: No importa. De git config : "Los nombres de las variables no distinguen entre mayúsculas y minúsculas, ..."
Greg Hewgill
277

cambio de modo de deshacer en el árbol de trabajo:

git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -d'\n' chmod +x
git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -d'\n' chmod -x

O en mingw-git

git diff --summary | grep  'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -e'\n' chmod +x
git diff --summary | grep  'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -e'\n' chmod -x
yoda
fuente
42
En OS X Lion, omita la -d'\n'parte xargsya que este es un argumento ilegal (y no es necesario).
Pascal
99
Puede ignorar cualquier error sobre "chmod: operando faltante después de '+ x'"
Casey Watson
55
¿Está esto actualizado? Recibo 'chmod: muy pocos argumentos' en mingw
hammett el
77
@Pascal @pimlottc La -d especifica que el delimitador sea nueva línea en lugar de cualquier espacio en blanco. BSD xargs no tiene esa opción, pero en su lugar puede canalizar la salida tr '\n' '\0'y luego usar el -0argumento arg para xargs para usar NUL como delimitador.
Mark Aufflick
10
¡Genial, la trcosa funcionó! Aquí está el comando completo para OSX:git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7-|tr '\n' '\0'|xargs -0 chmod -x
K.-Michael Aye
135

Si desea establecer esta opción para todos sus repositorios, use la --globalopción.

git config --global core.filemode false

Si esto no funciona, probablemente esté utilizando una versión más nueva de git, así que pruebe la --addopción.

git config --add --global core.filemode false

Si lo ejecuta sin la opción --global y su directorio de trabajo no es un repositorio, obtendrá

error: could not lock config file .git/config: No such file or directory
adrien
fuente
55
Parece que los usos posteriores de GIT --add, como engit config --add --global core.filemode false
mgaert
14
Si la configuración local del repositorio ya tiene filemode = true, cambiar la configuración global no ayudará, ya que la configuración local anulará la configuración global. Tendrá que cambiar la configuración local de cada repositorio de la máquina una vez
Rakib
3
POR FAVOR: ¡Actualice esta respuesta con la advertencia de syedrakib! Todo me pareció una locura antes de encontrarlo, y tuvo mucho sentido después.
jerclarke
88

Si

git config --global core.filemode false

no funciona para usted, hágalo manualmente:

cd into yourLovelyProject folder

cd en la carpeta .git:

cd .git

edite el archivo de configuración:

nano config

cambiar de verdadero a falso

[core]
        repositoryformatversion = 0
        filemode = true

->

[core]
        repositoryformatversion = 0
        filemode = false

guardar, salir, ir a la carpeta superior:

cd ..

reiniciar el git

git init

¡estás listo!

Sinan Eldem
fuente
11
En lugar de editar .git/config, un simple git config core.fileMode falseen la raíz de su proyecto es suficiente. Si edita el archivo de configuración, es mejor que elimine la directiva por completo, de modo que se recoja el global.
Felix
66
-1 si git config --global no funciona, significa que no tienes los permisos para hacerlo a nivel del sistema, la globalopción de eliminación hace exactamente lo mismo que editar manualmente .git / config
CharlesB
@CharlesB incorrecto: la respuesta proporcionó una solución al poner la opción directamente en el proyecto, haciéndola específica del proyecto. Esto no funcionará con otros proyectos de git que realice / finalice en el futuro, pero sí funciona para el proyecto en el que está trabajando. ( ~/.gitconfig~/project/.git/config
asegurémonos de
Una vez que esto se haya ejecutado, git init¿deberíamos volver a establecer el modo de archivo en verdadero?
Jordan
53

Agregando a la respuesta de Greg Hewgill (de usar la core.fileModevariable de configuración):

Puede usar la --chmod=(-|+)xopción de git update-index (versión de bajo nivel de "git add") para cambiar los permisos de ejecución en el índice, desde donde se seleccionaría si usa "git commit" (y no "git commit -a ").

Jakub Narębski
fuente
2
Esto debería haberse editado en la respuesta de Greg Hewgill en lugar de agregarse como una respuesta separada, creando así una respuesta suprema con una única representación inequívoca.
Greg
66
@Greg: Uno necesita tener suficientes puntos para editar una respuesta no propia; Creo que no tenía suficiente para editar permisos en ese momento.
Jakub Narębski
1
@Jakub Creo que ahora tienes suficiente reputación :) ¿Cómo sería este comando para un archivo de ejemplo?
Alex Hall
38

Puede configurarlo globalmente:

git config --global core.filemode false

Si lo anterior no funciona para usted, la razón podría ser que su configuración local anule la configuración global.

Elimine su configuración local para que la configuración global surta efecto:

git config --unset core.filemode

Alternativamente, puede cambiar su configuración local al valor correcto:

git config core.filemode false

Tyler Long
fuente
44
Si la respuesta principal no te ayuda, prueba esta. Si desea verificar su configuración local sin modificarla, marque git config -l(enumere la configuración actual, tanto local como global)
Krzysztof Bociurko
23

Si ya ha utilizado el comando chmod , compruebe la diferencia de archivo, muestra el modo de archivo anterior y el modo de archivo actual, como:

nuevo modo: 755

modo antiguo: 644

establecer el modo antiguo de todos los archivos con el siguiente comando

sudo chmod 644 .

ahora establezca core.fileMode en falso en el archivo de configuración mediante el comando o manualmente.

git config core.fileMode false

luego aplique el comando chmod para cambiar los permisos de todos los archivos, como

sudo chmod 755 .

y nuevamente establezca core.fileMode en verdadero.

git config core.fileMode true

Para las mejores prácticas, no mantenga core.fileMode false siempre.

Kishor Vitekar
fuente
¿Estás diciendo que un proyecto completo (en desarrollo, puesta en escena y producción) debería ser 755?
Daniel
@Daniel Feb: No. solo cambia el modo de los archivos necesarios.
Kishor Vitekar
For best practises don't Keep core.fileMode false alwaysa qué te refieres, deberías explicar eso.
bg17aw
For best practises don't Keep core.fileMode false always.Algunos sistemas de archivos (FAT, por ejemplo) no admiten permisos de archivos, por lo que el sistema operativo informará un valor predeterminado (766 en mi sistema de todos modos). En este caso, core.filemodees absolutamente necesario en la configuración local, a menos que desee hinchar el historial de confirmaciones con cambios de permisos innecesarios e involuntarios
KevinOrr
Además, ¿por qué te molestas en cambiar las permanentes de nuevo? Si lo configura core.filemode=false, git ignorará los cambios de bits de ejecución, no es necesario cambiar los permisos locales. A menos que ya haya agregado cambios de permisos al índice, en cuyo caso se está perdiendo el paso que necesitaría git adddespués de apagarlo core.filemode.
KevinOrr
18

Al definir el siguiente alias (en ~ / .gitconfig) puede deshabilitar fácilmente temporalmente el comando fileMode per git:

[alias]
nfm = "!f(){ git -c core.fileMode=false $@; };f"

Cuando este alias tiene el prefijo del comando git, los cambios en el modo de archivo no se mostrarán con comandos que de otro modo los mostrarían. Por ejemplo:

git nfm status
Ville
fuente
14

Si desea establecer el modo de archivo en falso en los archivos de configuración de forma recursiva (incluidos los submódulos): find -name config | xargs sed -i -e 's/filemode = true/filemode = false/'

Dryobs
fuente
55
Esto no funcionará si esa línea no está en el archivo de configuración. Si desea cambiarlo por submódulos, intente esto:git submodule foreach git config core.fileMode false
courtlandj
4

Solución simple:

Presione este comando simple en la carpeta del proyecto ( no eliminará sus cambios originales) ... solo eliminará los cambios que se hayan realizado mientras cambió el permiso de la carpeta del proyecto

el comando está abajo:

git config core.fileMode false

Por qué se modifica todo este archivo innecesario: porque ha cambiado los permisos de la carpeta del proyecto con commend sudo chmod -R 777 ./yourProjectFolder

¿Cuándo verificará los cambios que no hizo? que encontraste como a continuación mientras usas el nombre de archivo git diff

old mode 100644
new mode 100755
Shashwat Gupta
fuente
1

Esto funciona para mi:

find . -type f -exec chmod a-x {} \;

o reversa, dependiendo de su sistema operativo

find . -type f -exec chmod a+x {} \;
Martin Volek
fuente
1
Esto cambiaría los permisos del archivo, pero no haría que git ignorara los permisos del archivo.
domdambrogia
Bueno, tienes razón, eso no resuelve git ignore cosa.
Martin Volek