Come faccio a fare in modo che Git ignori le modifiche alla modalità file (chmod)?


2311

Ho un progetto in cui devo cambiare la modalità dei file con chmod777 durante lo sviluppo, ma che non dovrebbe cambiare nel repository principale.

Git riprende chmod -R 777 .e contrassegna tutti i file come modificati. C'è un modo per fare in modo che Git ignori le modifiche alla modalità che sono state apportate ai file?


17
Questo è utile quando si lavora con git su Windows + Bash su Ubuntu su Windows
Elazar

4
Per chi vuole solo ignorare le modifiche di autorizzazione per una specifica invocazione git diff, e che perciò non vuole alterare i loro file di configurazione git: è possibile utilizzare git diff -G.per Zed risposta qui .
sampablokuper,

Risposte:


3824

Provare:

git config core.fileMode false

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

Il -cflag può essere utilizzato per impostare questa opzione per i comandi una tantum:

git -c core.fileMode=false diff

E il --globalflag lo renderà il comportamento predefinito per l'utente che ha effettuato l'accesso.

git config --global core.fileMode false

Le modifiche alle impostazioni globali non verranno applicate ai repository esistenti. Inoltre, git clonee git initin modo esplicito impostare core.fileModeper truela configurazione dei pronti contro termine, come discusso in Git globale core.fileMode falsa override localmente sul clone

avvertimento

core.fileModenon è la migliore pratica e dovrebbe essere usato con attenzione. Questa impostazione copre solo il bit eseguibile della modalità e mai i bit di lettura / scrittura. In molti casi pensi di aver bisogno di questa impostazione perché hai fatto qualcosa di simile chmod -R 777, rendendo eseguibili tutti i tuoi file. Ma nella maggior parte dei progetti la maggior parte dei file non ha bisogno e non dovrebbe essere eseguibile per motivi di sicurezza .

Il modo corretto di risolvere questo tipo di situazione è gestire le autorizzazioni per cartelle e file separatamente, con qualcosa come:

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

Se lo fai, non dovrai mai usarlo core.fileMode, tranne in un ambiente molto raro.


203
Se lo fai git config --global core.filemode false, dovrai farlo una sola volta per tutti i repository.
Greg,

13
questo non ha funzionato per me fino a quando non avrò risolto il caso dovrebbe essere fileMode invece di filemode
tishma

8
@tishma: la sezione di configurazione di Git ei nomi delle variabili non fanno distinzione tra maiuscole e minuscole in base alla documentazione, vedere la sezione FILE DI CONFIGURAZIONE , quindi se quanto sopra non ha funzionato per te, lo è stato per un motivo diverso.
Greg Hewgill,

11
@donquixote: il git configcomando scrive l'impostazione nel file di configurazione corretto ( .git/configsolo per il repository corrente o ~/.gitconfigse utilizzato con --global).
Greg Hewgill,

8
@ zx1986: non importa. Da git config : "I nomi delle variabili non fanno distinzione tra maiuscole e minuscole, ..."
Greg Hewgill

277

annulla modifica della modalità nell'albero di lavoro:

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 in 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

42
Su OS X Lion, ometti la -d'\n'parte xargspoiché si tratta di un argomento illegale (e non necessario).
Pascal,

9
Puoi ignorare qualsiasi errore relativo a "chmod: operando mancante dopo` + x '"
Casey Watson,

5
è aggiornato? Ottengo "chmod: troppi argomenti" in mingw
hammett il

7
@Pascal @pimlottc Il -d specifica il delimitatore come newline invece di qualsiasi spazio bianco. BSD xargs non ha questa opzione, ma invece è possibile reindirizzare l'output tr '\n' '\0'e quindi utilizzare -0arg su xargs per utilizzare NUL come delimitatore.
Mark Aufflick,

10
Bene, la trcosa ha funzionato! Ecco il comando completo per OSX:git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7-|tr '\n' '\0'|xargs -0 chmod -x
K.-Michael Aye,

135

Se si desidera impostare questa opzione per tutti i repository, utilizzare l' --globalopzione.

git config --global core.filemode false

Se questo non funziona probabilmente stai usando una versione più recente di git quindi prova l' --addopzione.

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

Se lo esegui senza l'opzione --global e la tua directory di lavoro non è un repository, otterrai

error: could not lock config file .git/config: No such file or directory

5
Sembra che più tardi GIT usi --add, come ingit config --add --global core.filemode false
mgaert

14
Se la configurazione locale del repository ha già filemode = true, la modifica della configurazione globale non sarà utile in quanto la configurazione locale avrà la precedenza sulla configurazione globale. Dovrà cambiare una volta la configurazione locale di ciascun repository della macchina
Rakib,

3
PER FAVORE: Aggiorna questa risposta con l'avvertimento di syedrakib! Tutto sembrava folle prima che lo trovassi e dopo aveva perfettamente senso.
jerclarke,

88

Se

git config --global core.filemode false

non funziona per te, fallo manualmente:

cd into yourLovelyProject folder

cd nella cartella .git:

cd .git

modifica il file di configurazione:

nano config

cambia da vero a falso

[core]
        repositoryformatversion = 0
        filemode = true

->

[core]
        repositoryformatversion = 0
        filemode = false

salva, esci, vai alla cartella superiore:

cd ..

reiniziare il git

git init

hai fatto!


11
Invece di modificare .git/config, git config core.fileMode falseè sufficiente un semplice nella radice del progetto. Se modifichi il file di configurazione, è meglio rimuovere completamente la direttiva, in modo che venga prelevata quella globale.
Felix,

6
-1 se git config --global non funziona significa che non hai i permessi per farlo a livello di sistema, la rimozione globaldell'opzione fa esattamente la stessa cosa della modifica manuale di .git / config
CharlesB

@CharlesB errato: la risposta ha fornito una soluzione alternativa inserendo l'opzione direttamente nel progetto, rendendolo specifico per il progetto. Questo non funzionerà con altri progetti git che realizzerai / effettuerai il checkout in futuro, ma funzionerà per il progetto a cui stai lavorando. (assicuriamoci di chiarire le ambiguità ~/.gitconfige ~/project/.git/config)
ddavison il

Una volta eseguito git initquesto, dovremmo riportare filemode su true?
Giordania,

53

Aggiungendo alla risposta Greg Hewgill (dell'uso della core.fileModevariabile di configurazione):

È possibile utilizzare l' --chmod=(-|+)xopzione di git update-index (versione di basso livello di "git add") per modificare le autorizzazioni di esecuzione nell'indice, da dove verrebbe prelevato se si utilizzasse "git commit" (e non "git commit -a ").


2
Questo avrebbe dovuto essere modificato nella risposta di Greg Hewgill piuttosto che aggiunto come una risposta separata, creando così una risposta suprema con un'unica rappresentazione inequivocabile.
Greg,

6
@Greg: è necessario avere abbastanza punti per modificare la propria risposta; Penso di non avere abbastanza per le autorizzazioni di modifica in quel momento.
Jakub Narębski,

1
@Jakub Penso che tu abbia abbastanza reputazione ora :) Come sarebbe questo comando per un file di esempio?
Alex Hall,

38

Puoi configurarlo a livello globale:

git config --global core.filemode false

Se quanto sopra non funziona per te, il motivo potrebbe essere che la tua configurazione locale ha la precedenza sulla configurazione globale.

Rimuovere la configurazione locale per rendere effettiva la configurazione globale:

git config --unset core.filemode

In alternativa, è possibile modificare la configurazione locale sul valore corretto:

git config core.filemode false


4
Se la risposta principale non ti aiuta, prova questa. Se vuoi controllare la tua configurazione locale senza modificarla, controlla git config -l(elenca la configurazione corrente - sia locale che globale)
Krzysztof Bociurko

23

Se hai già usato il comando chmod quindi controlla la differenza del file, mostra la modalità file precedente e la modalità file corrente come:

nuova modalità: 755

modalità precedente: 644

imposta la vecchia modalità di tutti i file usando il comando seguente

sudo chmod 644 .

ora imposta core.fileMode su false nel file di configurazione usando il comando o manualmente.

git config core.fileMode false

quindi applicare il comando chmod per modificare le autorizzazioni di tutti i file come

sudo chmod 755 .

e imposta nuovamente core.fileMode su true.

git config core.fileMode true

Per le migliori pratiche non mantenere sempre core.fileMode falso.


Stai dicendo che un intero progetto (in sviluppo, messa in scena e produzione) dovrebbe essere 755?
Daniel,

@Daniel Feb: No. cambia solo la modalità dei file necessari.
Kishor Vitekar,

For best practises don't Keep core.fileMode false alwayscosa vuoi dire, dovresti spiegarlo.
bg17aw,

For best practises don't Keep core.fileMode false always.Alcuni filesystem (ad esempio FAT) non supportano i permessi dei file, quindi il sistema operativo riporterà un valore predefinito (766 sul mio sistema comunque). In questo caso, core.filemodeè assolutamente necessario nella configurazione locale, a meno che non si desideri gonfiare la cronologia di commit con modifiche di autorizzazione non necessarie e non intenzionali
KevinOrr

Inoltre, perché ti preoccupi di cambiare i permessi? Se impostato, core.filemode=falsegit ignorerà le modifiche ai bit di esecuzione, non è necessario modificare le autorizzazioni locali. A meno che tu non abbia già aggiunto modifiche all'autorizzazione all'indice, nel qual caso ti manca il passaggio in cui avresti bisogno git adddopo aver spento core.filemode.
KevinOrr,

18

Definendo il seguente alias (in ~ / .gitconfig) è possibile disabilitare temporaneamente temporaneamente il comando fileMode per git:

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

Quando questo alias è preceduto dal comando git, le modifiche alla modalità file non verranno visualizzate con comandi che altrimenti li mostrerebbero. Per esempio:

git nfm status

14

Se si desidera impostare filemode su false nei file di configurazione in modo ricorsivo (inclusi i sottomoduli): find -name config | xargs sed -i -e 's/filemode = true/filemode = false/'


5
Questo non funzionerà se quella linea non si trova nel file di configurazione. Se vuoi cambiarlo per i sottomoduli, prova questo:git submodule foreach git config core.fileMode false
courtlandj,

4

Soluzione semplice:

Hit questo comando semplice nella cartella del progetto ( non rimuoverà le modifiche originali) ... sarà solo rimuovere le modifiche che erano state fatte mentre si è modificato il permesso cartella del progetto

il comando è sotto:

git config core.fileMode false

Perché tutto questo file non necessario viene modificato: perché hai modificato le autorizzazioni della cartella del progetto con encom sudo chmod -R 777 ./yourProjectFolder

quando controllerai le modifiche cosa non hai fatto? hai trovato come sotto mentre usi git diff nomefile

old mode 100644
new mode 100755

1

Questo funziona per me:

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

o viceversa, a seconda del sistema operativo in uso

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

1
Questo cambierebbe le autorizzazioni del file, ma non farebbe in modo che git ignori le autorizzazioni del file.
domdambrogia,

Bene, hai ragione, questo non risolve git ignora cosa.
Martin Volek,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.