Wie kann ich Git dazu bringen, Änderungen im Dateimodus (chmod) zu ignorieren?

2310

Ich habe ein Projekt, in dem ich den Dateimodus mit chmodwährend der Entwicklung auf 777 ändern muss, das sich aber im Haupt-Repo nicht ändern sollte.

Git nimmt chmod -R 777 .alle Dateien auf und markiert sie als geändert. Gibt es eine Möglichkeit, Git dazu zu bringen, Änderungen am Modus zu ignorieren, die an Dateien vorgenommen wurden?

Marcus Westin
quelle
17
Dies ist hilfreich, wenn Sie mit Git unter Windows + Bash unter Ubuntu unter Windows arbeiten
Elazar
4
Für alle , die nur Berechtigungsänderungen für einen bestimmten Aufruf ignorieren will git diff, und deshalb wollen ihre Git - Konfigurationsdateien nicht ändern: Sie verwenden können git diff -G.pro Zeds Antwort hier .
Sampablokuper

Antworten:

3822

Versuchen:

git config core.fileMode false

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

Mit dem -cFlag kann diese Option für einmalige Befehle festgelegt werden:

git -c core.fileMode=false diff

Das --globalFlag macht es zum Standardverhalten für den angemeldeten Benutzer.

git config --global core.fileMode false

Änderungen der globalen Einstellung werden nicht auf vorhandene Repositorys angewendet. Zusätzlich git cloneund git initexplizit core.fileModeauf trueConfig im Repo wie in diskutiert Git globalen core.fileMode falsch überschrieben lokal auf Klon

Warnung

core.fileModeist nicht die beste Vorgehensweise und sollte sorgfältig angewendet werden. Diese Einstellung deckt nur das ausführbare Bit des Modus und niemals die Lese- / Schreibbits ab. In vielen Fällen denken Sie, dass Sie diese Einstellung benötigen, weil Sie so etwas getan haben chmod -R 777, um alle Ihre Dateien ausführbar zu machen. In den meisten Projekten werden die meisten Dateien jedoch nicht benötigt und sollten aus Sicherheitsgründen nicht ausführbar sein .

Der richtige Weg, um diese Art von Situation zu lösen, besteht darin, Ordner- und Dateiberechtigungen getrennt zu behandeln.

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

Wenn Sie dies tun, müssen Sie es nie verwenden core.fileMode, außer in sehr seltenen Umgebungen.

Greg Hewgill
quelle
203
Wenn Sie dies tun git config --global core.filemode false, müssen Sie dies nur einmal für alle Repos tun.
Greg
13
Dies funktionierte nicht für mich, bis ich den Fall behoben habe, dass es FileMode anstelle von
Filemode sein
8
@tishma: Git-Konfigurationsabschnitt und Variablennamen unterscheiden gemäß der Dokumentation nicht zwischen Groß- und Kleinschreibung. Weitere Informationen finden Sie im Abschnitt KONFIGURATIONSDATEI. Wenn dies bei Ihnen nicht funktioniert hat, hat dies einen anderen Grund.
Greg Hewgill
11
@donquixote: Der git configBefehl schreibt die Einstellung in die richtige Konfigurationsdatei ( .git/confignur für das aktuelle Repository oder ~/.gitconfigbei Verwendung mit --global).
Greg Hewgill
8
@ zx1986: Es spielt keine Rolle. Von git config : "Die Variablennamen unterscheiden nicht zwischen Groß- und Kleinschreibung, ..."
Greg Hewgill
277

Modusänderung im Arbeitsbaum rückgängig machen:

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

Oder 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
Yoda
quelle
42
Lassen Sie unter OS X Lion den -d'\n'Teil weg, xargsda dies ein unzulässiges Argument ist (und nicht benötigt wird).
Pascal
9
Sie können alle Fehler über "chmod: fehlender Operand nach" + x "" ignorieren
Casey Watson
5
ist das aktuell? Ich bekomme 'chmod: zu wenige Argumente' in
mingw
7
@Pascal @pimlottc Das -d gibt das Trennzeichen als Zeilenumbruch anstelle eines Leerzeichens an. BSD xargs hat diese Option nicht, aber stattdessen können Sie die Ausgabe durchleiten tr '\n' '\0'und dann das -0Argument an xargs verwenden, um NUL als Trennzeichen zu verwenden.
Mark Aufflick
10
Cool, das trDing hat funktioniert! Hier ist der vollständige Befehl für OSX:git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7-|tr '\n' '\0'|xargs -0 chmod -x
K.-Michael Aye
135

Wenn Sie diese Option für alle Ihre Repos festlegen möchten, verwenden Sie die --globalOption.

git config --global core.filemode false

Wenn dies nicht funktioniert, verwenden Sie wahrscheinlich eine neuere Version von git. Probieren Sie die --addOption aus.

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

Wenn Sie es ohne die Option --global ausführen und Ihr Arbeitsverzeichnis kein Repo ist, erhalten Sie

error: could not lock config file .git/config: No such file or directory
adrien
quelle
5
Sieht aus wie später GIT verwendet --add, wie ingit config --add --global core.filemode false
mgaert
14
Wenn die lokale Konfiguration des Repos bereits den Dateimodus = true hat, hilft das Ändern der globalen Konfiguration nicht, da die lokale Konfiguration die globale Konfiguration überschreibt. Muss die lokale Konfiguration jedes Repos der Maschine einmal ändern
Rakib
3
BITTE: Aktualisieren Sie diese Antwort mit der Warnung von Syedrakib! Alles fühlte sich verrückt an, bevor ich es fand, und machte danach vollkommen Sinn.
Jerclarke
88

Wenn

git config --global core.filemode false

funktioniert bei Ihnen nicht, machen Sie es manuell:

cd into yourLovelyProject folder

CD in .git Ordner:

cd .git

Bearbeiten Sie die Konfigurationsdatei:

nano config

Ändern Sie true in false

[core]
        repositoryformatversion = 0
        filemode = true

->

[core]
        repositoryformatversion = 0
        filemode = false

Speichern, beenden, in den oberen Ordner wechseln:

cd ..

Schalte den Git wieder ein

git init

du bist fertig!

Sinan Eldem
quelle
11
Anstatt zu bearbeiten .git/config, reicht ein einfaches git config core.fileMode falseim Stammverzeichnis Ihres Projekts aus. Wenn Sie die Konfigurationsdatei bearbeiten, sollten Sie die Direktive besser vollständig entfernen, damit die globale übernommen wird.
Felix
6
-1 Wenn git config --global nicht funktioniert, bedeutet dies, dass Sie nicht über die Berechtigungen verfügen, dies auf Systemebene zu tun. Das Entfernen der globalOption entspricht genau der manuellen Bearbeitung von .git / config
CharlesB
@CharlesB falsch - Die Antwort lieferte eine Problemumgehung, indem die Option direkt in das Projekt eingefügt und projektspezifisch gemacht wurde. Dies funktioniert nicht mit anderen Git-Projekten, die Sie in Zukunft erstellen / auschecken, funktioniert jedoch für das Projekt, an dem Sie arbeiten. (Lassen Sie uns sicherstellen, dass wir ~/.gitconfig~/project/.git/config
eindeutig sind
Sobald dies ausgeführt wurde, git initsollten wir den Dateimodus wieder auf true setzen?
Jordanien
53

Hinzufügen zur Antwort von Greg Hewgill (Verwendung der core.fileModeKonfigurationsvariablen):

Sie können die --chmod=(-|+)xOption git update-index (Low-Level-Version von "git add") verwenden, um die Ausführungsberechtigungen im Index zu ändern. Dort wird sie abgerufen, wenn Sie "git commit" (und nicht "git commit -a" verwenden ").

Jakub Narębski
quelle
2
Dies sollte in Greg Hewgills Antwort bearbeitet und nicht als separate Antwort hinzugefügt worden sein, wodurch eine höchste Antwort mit einer einzigen eindeutigen Darstellung erstellt wurde.
Greg
6
@ Greg: Man muss genug Punkte haben, um keine eigene Antwort zu bearbeiten; Ich glaube, ich hatte damals nicht genug zum Bearbeiten von Berechtigungen.
Jakub Narębski
1
@Jakub Ich denke, Sie haben jetzt genug Ruf :) Wie würde dieser Befehl für eine Beispieldatei aussehen?
Alex Hall
38

Sie können es global konfigurieren:

git config --global core.filemode false

Wenn dies für Sie nicht funktioniert, liegt der Grund möglicherweise darin, dass Ihre lokale Konfiguration die globale Konfiguration überschreibt.

Entfernen Sie Ihre lokale Konfiguration, damit die globale Konfiguration wirksam wird:

git config --unset core.filemode

Alternativ können Sie Ihre lokale Konfiguration auf den richtigen Wert ändern:

git config core.filemode false

Tyler Long
quelle
4
Wenn Ihnen die Hauptantwort nicht hilft, probieren Sie diese aus. Wenn Sie Ihre lokale Konfiguration überprüfen möchten, ohne sie zu git config -l
ändern
23

Wenn Sie den Befehl chmod bereits verwendet haben, überprüfen Sie den Unterschied zwischen den Dateien. Er zeigt den vorherigen Dateimodus und den aktuellen Dateimodus an, z.

neuer Modus: 755

alter Modus: 644

Stellen Sie den alten Modus aller Dateien mit dem folgenden Befehl ein

sudo chmod 644 .

Setzen Sie jetzt core.fileMode in der Konfigurationsdatei entweder mit dem Befehl oder manuell auf false.

git config core.fileMode false

Wenden Sie dann den Befehl chmod an, um die Berechtigungen aller Dateien zu ändern, z

sudo chmod 755 .

und setzen Sie core.fileMode erneut auf true.

git config core.fileMode true

Für Best Practices halten Sie core.fileMode nicht immer auf false.

Kishor Vitekar
quelle
Wollen Sie damit sagen, dass ein ganzes Projekt (in Entwicklung, Inszenierung und Produktion) 755 sein sollte?
Daniel
@ Daniel Feb: Nein. Ändere nur den Modus der erforderlichen Dateien.
Kishor Vitekar
For best practises don't Keep core.fileMode false alwaysWas meinst du, das solltest du erklären.
bg17aw
For best practises don't Keep core.fileMode false always.Einige Dateisysteme (z. B. FAT) unterstützen keine Dateiberechtigungen, daher meldet das Betriebssystem einen Standardwert (766 auf meinem System sowieso). In diesem Fall core.filemodeist dies in der lokalen Konfiguration unbedingt erforderlich, es sei denn, Sie möchten den Commit-Verlauf mit unnötigen und unbeabsichtigten Berechtigungsänderungen aufblähen
KevinOrr
Warum wechseln Sie überhaupt die Dauerwellen? Wenn Sie festlegen core.filemode=false, ignoriert git Ausführungsbitänderungen, ohne dass lokale Berechtigungen geändert werden müssen. Sofern Sie dem Index noch keine Berechtigungsänderungen hinzugefügt haben, verpassen Sie in diesem Fall den Schritt, den Sie git addnach dem Ausschalten benötigen würden core.filemode.
KevinOrr
18

Durch Definieren des folgenden Alias ​​(in ~ / .gitconfig) können Sie den Befehl fileMode per git einfach vorübergehend deaktivieren:

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

Wenn diesem Alias ​​der Befehl git vorangestellt wird, werden die Änderungen im Dateimodus nicht mit Befehlen angezeigt, die sie sonst anzeigen würden. Zum Beispiel:

git nfm status
Ville
quelle
14

Wenn Sie den Dateimodus in Konfigurationsdateien rekursiv auf false setzen möchten (einschließlich Submodule): find -name config | xargs sed -i -e 's/filemode = true/filemode = false/'

Dryobs
quelle
4
Dies funktioniert nicht, wenn sich diese Zeile nicht in der Konfigurationsdatei befindet. Wenn Sie es für Submodule ändern möchten, versuchen Sie dies:git submodule foreach git config core.fileMode false
courtlandj
4

Einfache Lösung:

Klicken Sie auf diesen einfachen Befehl im Projektordner ( Ihre ursprünglichen Änderungen werden nicht entfernt) . Es werden nur Änderungen entfernt , die vorgenommen wurden , während Sie die Berechtigung für den Projektordner geändert haben

Befehl ist unten:

git config core.fileMode false

Warum diese alle unnötigen Dateien geändert werden: weil Sie die Projektordnerberechtigungen mit commend sudo chmod -R 777 ./yourProjectFolder geändert haben

Wann werden Sie Änderungen überprüfen, was Sie nicht getan haben? Sie fanden wie unten bei der Verwendung von Git Diff Dateiname

old mode 100644
new mode 100755
Shashwat Gupta
quelle
1

Das funktioniert bei mir:

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

oder umgekehrt, abhängig von Ihrem Betriebssystem

find . -type f -exec chmod a+x {} \;
Martin Volek
quelle
1
Dies würde die Berechtigungen der Datei ändern, aber nicht dazu führen, dass git die Dateiberechtigungen der Datei ignoriert.
Domdambrogia
Nun, Sie haben Recht, das löst nicht git ignorieren Sache.
Martin Volek