Comment faire pour que Git ignore les modifications du mode fichier (chmod)?

2311

J'ai un projet dans lequel je dois changer le mode des fichiers avec chmod777 lors du développement, mais qui ne devrait pas changer dans le référentiel principal.

Git reprend chmod -R 777 .et marque tous les fichiers comme modifiés. Existe-t-il un moyen de faire en sorte que Git ignore les modifications de mode qui ont été apportées aux fichiers?

Marcus Westin
la source
17
Ceci est utile lorsque vous travaillez avec git sur Windows + Bash sur Ubuntu sur Windows
Elazar
4
Pour tous ceux qui veulent tout simplement ignorer la permission des changements pour une invocation spécifique de git diff, et qui ne veut donc pas modifier leurs fichiers de configuration Git: vous pouvez utiliser git diff -G.par Zed réponse ici .
sampablokuper

Réponses:

3824

Essayer:

git config core.fileMode false

Depuis 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).

L' -cindicateur peut être utilisé pour définir cette option pour les commandes uniques:

git -c core.fileMode=false diff

Et l' --globalindicateur en fera le comportement par défaut pour l'utilisateur connecté.

git config --global core.fileMode false

Les modifications du paramètre global ne seront pas appliquées aux référentiels existants. En outre, git cloneet git initdéfinir explicitement core.fileModeà truela configuration des prises en pension comme indiqué dans faux core.fileMode global Git surchargée localement sur le clone

Attention

core.fileModen'est pas la meilleure pratique et doit être utilisée avec précaution. Ce paramètre ne couvre que le bit de mode exécutable et jamais les bits de lecture / écriture. Dans de nombreux cas, vous pensez que vous avez besoin de ce paramètre parce que vous avez fait quelque chose comme chmod -R 777, rendre tous vos fichiers exécutables. Mais dans la plupart des projets, la plupart des fichiers n'ont pas besoin et ne doivent pas être exécutables pour des raisons de sécurité .

La bonne façon de résoudre ce genre de situation est de gérer séparément les autorisations de dossier et de fichier, avec quelque chose comme:

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 vous faites cela, vous n'aurez jamais besoin de l'utiliser core.fileMode, sauf dans un environnement très rare.

Greg Hewgill
la source
203
Si vous le faites, git config --global core.filemode falsevous n'aurez qu'à le faire une fois pour toutes les dépôts.
Greg
13
cela n'a pas fonctionné pour moi jusqu'à ce que j'ai corrigé le cas, il devrait être fileMode au lieu de filemode
tishma
8
@tishma: la section de configuration Git et les noms de variables ne respectent pas la casse selon la documentation, voir la section FICHIER DE CONFIGURATION , donc si ce qui précède ne fonctionnait pas pour vous, c'était pour une raison différente.
Greg Hewgill
11
@donquixote: La git configcommande écrit le paramètre dans le fichier de configuration correct ( .git/configuniquement pour le référentiel actuel ou ~/.gitconfigs'il est utilisé avec --global).
Greg Hewgill
8
@ zx1986: Peu importe. De git config : "Les noms de variables ne
respectent pas la
277

annuler le changement de mode dans l'arborescence de travail:

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

Ou 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
la source
42
Sous OS X Lion, omettez la -d'\n'partie xargscar il s'agit d'un argument illégal (et non nécessaire).
Pascal
9
Vous pouvez ignorer les erreurs concernant "chmod: opérande manquant après" + x ""
Casey Watson
5
est-ce à jour? Je reçois 'chmod: trop peu d'arguments' dans mingw
hammett
7
@Pascal @pimlottc Le -d spécifie que le délimiteur doit être une nouvelle ligne au lieu de n'importe quel espace. BSD xargs n'a pas cette option, mais à la place, vous pouvez diriger la sortie tr '\n' '\0'puis utiliser l' -0argument vers xargs pour utiliser NUL comme délimiteur.
Mark Aufflick
10
Cool, la trchose a fonctionné! Voici la commande complète pour 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 vous souhaitez définir cette option pour tous vos référentiels, utilisez l' --globaloption.

git config --global core.filemode false

Si cela ne fonctionne pas, vous utilisez probablement une version plus récente de git, essayez donc l' --addoption.

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

Si vous l'exécutez sans l'option --global et que votre répertoire de travail n'est pas un dépôt, vous obtiendrez

error: could not lock config file .git/config: No such file or directory
adrien
la source
5
On dirait que GIT utilisera plus tard --add, comme dansgit config --add --global core.filemode false
mgaert
14
Si la configuration locale du dépôt a déjà filemode = true, la modification de la configuration globale n'aidera pas car la configuration locale remplacera la configuration globale. Devra changer la configuration locale de chaque repo de la machine une fois
Rakib
3
S'IL VOUS PLAÎT: Mettez à jour cette réponse avec l'avertissement de syedrakib! Tout était fou avant que je ne le trouve, et avait un sens parfait après.
jerclarke
88

Si

git config --global core.filemode false

ne fonctionne pas pour vous, faites-le manuellement:

cd into yourLovelyProject folder

cd dans le dossier .git:

cd .git

éditez le fichier de configuration:

nano config

changer vrai en faux

[core]
        repositoryformatversion = 0
        filemode = true

->

[core]
        repositoryformatversion = 0
        filemode = false

enregistrer, quitter, aller dans le dossier supérieur:

cd ..

réinitialisez le git

git init

vous avez terminé!

Sinan Eldem
la source
11
Au lieu d'éditer .git/config, un simple git config core.fileMode falseà la racine de votre projet suffit. Si vous modifiez le fichier de configuration, vous feriez mieux de supprimer complètement la directive, de sorte que celle globale soit récupérée.
Felix
6
-1 si git config --global ne fonctionne pas, cela signifie que vous n'avez pas les autorisations pour le faire au niveau du système, la suppression de l' globaloption fait exactement la même chose que l'édition manuelle de .git / config
CharlesB
@CharlesB incorrect - la réponse a fourni une solution de contournement en plaçant l'option directement dans le projet, la rendant spécifique au projet. Cela ne fonctionnera pas avec d'autres projets git que vous réalisez / retirerez à l'avenir, mais cela fonctionne pour le projet sur lequel vous travaillez. (assurons-nous de ~/.gitconfig~/project/.git/config
lever l'ambiguïté
Une fois que cela s'est exécuté, git initdevons-nous remettre le mode de fichier à true?
Jordan
53

Ajout à la réponse de Greg Hewgill (à l'aide de la core.fileModevariable de configuration):

Vous pouvez utiliser l' --chmod=(-|+)xoption de git update-index (version de bas niveau de "git add") pour modifier les autorisations d'exécution dans l'index, d'où il serait récupéré si vous utilisez "git commit" (et non "git commit -a ").

Jakub Narębski
la source
2
Cela aurait dû être modifié dans la réponse de Greg Hewgill plutôt que ajouté comme réponse distincte, créant ainsi une réponse suprême avec une seule représentation non ambiguë.
Greg
6
@Greg: Il faut avoir suffisamment de points pour modifier sa propre réponse; Je pense que je n'avais pas assez pour modifier les autorisations à ce moment-là.
Jakub Narębski
1
@Jakub Je pense que vous avez assez de réputation maintenant :) À quoi ressemblerait cette commande pour un exemple de fichier?
Alex Hall
38

Vous pouvez le configurer globalement:

git config --global core.filemode false

Si ce qui précède ne fonctionne pas pour vous, la raison peut être que votre configuration locale remplace la configuration globale.

Supprimez votre configuration locale pour que la configuration globale prenne effet:

git config --unset core.filemode

Alternativement, vous pouvez changer votre configuration locale à la bonne valeur:

git config core.filemode false

Tyler Long
la source
4
Si la réponse principale ne vous aide pas, essayez celle-ci. Si vous souhaitez vérifier votre configuration locale sans la modifier, cochez git config -l(lister la configuration actuelle - locale et globale)
Krzysztof Bociurko
23

Si vous avez déjà utilisé la commande chmod, vérifiez la différence de fichier, il montre le mode de fichier précédent et le mode de fichier actuel tels que:

nouveau mode: 755

ancien mode: 644

définir l'ancien mode de tous les fichiers à l'aide de la commande ci-dessous

sudo chmod 644 .

définissez maintenant core.fileMode sur false dans le fichier de configuration à l'aide de la commande ou manuellement.

git config core.fileMode false

puis appliquez la commande chmod pour modifier les autorisations de tous les fichiers tels que

sudo chmod 755 .

et définissez à nouveau core.fileMode sur true.

git config core.fileMode true

Pour les meilleures pratiques, ne laissez pas toujours core.fileMode false.

Kishor Vitekar
la source
Êtes-vous en train de dire qu'un projet entier (en développement, mise en scène et production) devrait être 755?
Daniel
@Daniel Feb: Non. Modifiez uniquement le mode des fichiers nécessaires.
Kishor Vitekar
For best practises don't Keep core.fileMode false alwaysque voulez-vous dire, vous devez expliquer cela.
bg17aw
For best practises don't Keep core.fileMode false always.Certains systèmes de fichiers (FAT par exemple) ne prennent pas en charge les autorisations de fichiers, donc le système d'exploitation signalera une valeur par défaut (766 sur mon système de toute façon). Dans ce cas, core.filemodeest absolument nécessaire dans la configuration locale, sauf si vous voulez gonfler l'historique des validations avec des modifications d'autorisation inutiles et non intentionnelles
KevinOrr
Aussi, pourquoi vous dérangez-vous de changer les perms? Si vous définissez, core.filemode=falsegit ignorera les modifications des bits d'exécution, pas besoin de modifier les autorisations locales. À moins que vous n'ayez déjà ajouté des modifications de permission à l'index, auquel cas il vous manque l'étape à laquelle vous devez procéder git addaprès avoir désactivé core.filemode.
KevinOrr
18

En définissant l'alias suivant (dans ~ / .gitconfig), vous pouvez facilement désactiver temporairement la commande fileMode per git:

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

Lorsque cet alias est préfixé à la commande git, les changements de mode de fichier ne s'afficheront pas avec des commandes qui autrement les afficheraient. Par exemple:

git nfm status
Ville
la source
14

Si vous souhaitez définir le mode de fichier sur false dans les fichiers de configuration de manière récursive (y compris les sous-modules): find -name config | xargs sed -i -e 's/filemode = true/filemode = false/'

dryobs
la source
5
Cela ne fonctionnera pas si cette ligne n'est pas dans le fichier de configuration. Si vous voulez le changer pour les sous-modules, essayez ceci:git submodule foreach git config core.fileMode false
courtlandj
4

Solution simple:

Appuyez sur cette commande simple dans le dossier du projet ( elle ne supprimera pas vos modifications d'origine) ... elle supprimera uniquement les modifications qui ont été effectuées lorsque vous avez modifié l' autorisation du dossier de projet

la commande est ci-dessous:

git config core.fileMode false

Pourquoi tout ce fichier inutile est modifié: parce que vous avez modifié les autorisations du dossier de projet avec la commande sudo chmod -R 777 ./yourProjectFolder

quand vérifierez-vous les modifications que n'avez-vous pas faites? vous avez trouvé comme ci-dessous lors de l'utilisation de git diff filename

old mode 100644
new mode 100755
Shashwat Gupta
la source
1

Cela fonctionne pour moi:

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

ou inversé, selon votre système d'exploitation

find . -type f -exec chmod a+x {} \;
Martin Volek
la source
1
Cela modifierait les autorisations du fichier, mais ne ferait pas en sorte que git ignore les autorisations du fichier.
domdambrogia
Eh bien, vous avez raison, cela ne résout rien.
Martin Volek