Jak sprawić, by Git ignorował zmiany trybu plików (chmod)?

2308

Mam projekt, w którym muszę zmieniać tryb plików chmodna 777 podczas opracowywania, ale który nie powinien się zmieniać w głównym repozytorium.

Git podnosi chmod -R 777 .i zaznacza wszystkie pliki jako zmienione. Czy istnieje sposób, aby Git ignorował zmiany trybu, które zostały wprowadzone w plikach?

Marcus Westin
źródło
17
Jest to pomocne przy pracy z Git na Windows + Bash na Ubuntu na Windows
Elazar
4
Dla każdego, kto po prostu chce ignorować zmiany uprawnień dla określonego wezwaniem git diff, iw związku z tym nie chce zmieniać swoje pliki konfiguracyjne Git: można używać git diff -G.za Zed za odpowiedź tutaj .
sampablokuper

Odpowiedzi:

3818

Próbować:

git config core.fileMode false

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

Za pomocą -cflagi można ustawić tę opcję dla poleceń jednorazowych:

git -c core.fileMode=false diff

A --globalflaga sprawi, że będzie to domyślne zachowanie dla zalogowanego użytkownika.

git config --global core.fileMode false

Zmiany ustawienia globalnego nie zostaną zastosowane do istniejących repozytoriów. Dodatkowo, git clonei git initjawnie ustawić core.fileModeaby truew config repo jak omówiono w Git globalny core.fileMode FAŁSZ przesłonięte lokalnie na klonie

Ostrzeżenie

core.fileModenie jest najlepszą praktyką i należy ją stosować ostrożnie. To ustawienie obejmuje tylko wykonywalny bit trybu, a nigdy bity do odczytu / zapisu. W wielu przypadkach uważasz, że potrzebujesz tego ustawienia, ponieważ zrobiłeś coś podobnego chmod -R 777, czyniąc wszystkie swoje pliki wykonywalnymi. Jednak w większości projektów większość plików nie potrzebuje i nie powinna być wykonywalna ze względów bezpieczeństwa .

Właściwym sposobem rozwiązania tego rodzaju sytuacji jest osobne zarządzanie uprawnieniami do folderów i plików za pomocą:

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

Jeśli to zrobisz, nigdy nie będziesz musiał używać core.fileMode, z wyjątkiem bardzo rzadkiego środowiska.

Greg Hewgill
źródło
203
Jeśli to zrobisz git config --global core.filemode false, musisz to zrobić tylko raz dla wszystkich repozytoriów.
Greg
13
to nie działało dla mnie, dopóki nie naprawiłem skrzynki powinien to być fileMode zamiast filemode
tishma
8
@tishma: Zgodnie z dokumentacją sekcja konfiguracji Git i nazwy zmiennych nie rozróżniają wielkości liter, patrz sekcja PLIK KONFIGURACJI , więc jeśli powyższe nie działało dla Ciebie, to z innego powodu.
Greg Hewgill
11
@donquixote: git configKomenda zapisuje ustawienie do poprawnego pliku konfiguracyjnego ( .git/configtylko dla bieżącego repozytorium lub ~/.gitconfigjeśli jest używane z --global).
Greg Hewgill
8
@ zx1986: To nie ma znaczenia. Z git config : „Nazwy zmiennych nie rozróżniają wielkości liter, ...”
Greg Hewgill
277

zmiana trybu cofania w działającym drzewie:

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

Lub w 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
źródło
42
W systemie OS X Lion pomiń tę -d'\n'część, xargsponieważ jest to nielegalny argument (i nie jest potrzebny).
Pascal
9
Możesz zignorować wszelkie błędy dotyczące „chmod: brakujący operand po` + x '”
Casey Watson
5
czy to jest aktualne? Dostaję „chmod: za mało argumentów” w mingw
hammett
7
@Pascal @pimlottc -d określa separator jako znak nowej linii zamiast jakichkolwiek białych znaków. BSD xargs nie ma tej opcji, ale zamiast tego możesz przesłać dane wyjściowe, tr '\n' '\0'a następnie użyć -0arg do xargs, aby użyć NUL jako separatora.
Mark Aufflick
10
Fajnie, trrzecz zadziałała! Oto pełne polecenie dla OSX:git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7-|tr '\n' '\0'|xargs -0 chmod -x
K.-Michael Aye,
135

Jeśli chcesz ustawić tę opcję dla wszystkich swoich repozytoriów, użyj tej --globalopcji.

git config --global core.filemode false

Jeśli to nie zadziała, prawdopodobnie używasz nowszej wersji git, więc wypróbuj --addopcję.

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

Jeśli uruchomisz go bez opcji --global, a katalog roboczy nie jest repozytorium, otrzymasz

error: could not lock config file .git/config: No such file or directory
adrien
źródło
5
Wygląda późniejszych zastosowań GIT --add, jak wgit config --add --global core.filemode false
mgaert
14
Jeśli lokalna konfiguracja repo ma już filemode = true, to zmiana konfiguracji globalnej nie pomoże, ponieważ konfiguracja lokalna zastąpi konfigurację globalną. Będę musiał raz zmienić lokalną konfigurację każdego repozytorium maszyny
Rakib,
3
PROSZĘ: Zaktualizuj tę odpowiedź z ostrzeżeniem syedrakib! Wszystko wydawało się szalone, zanim je znalazłem, i po tym miało sens.
jerclarke
88

Gdyby

git config --global core.filemode false

nie działa dla Ciebie, zrób to ręcznie:

cd into yourLovelyProject folder

cd do folderu .git:

cd .git

edytuj plik konfiguracyjny:

nano config

zmień wartość true na false

[core]
        repositoryformatversion = 0
        filemode = true

->

[core]
        repositoryformatversion = 0
        filemode = false

zapisz, wyjdź, przejdź do górnego folderu:

cd ..

ponownie uruchom git

git init

gotowe!

Sinan Eldem
źródło
11
Zamiast edycji .git/configwystarczy prosty git config core.fileMode falseelement główny projektu. Jeśli edytujesz plik konfiguracyjny, lepiej całkowicie usunąć dyrektywę, aby pobrać globalny.
Felix
6
-1 jeśli git config --global nie działa oznacza to, że nie masz uprawnień, aby to zrobić na poziomie systemu, usunięcie globalopcji robi dokładnie to samo, co ręczne edytowanie .git / config
CharlesB
Niepoprawny @CharlesB - odpowiedzi zawierały obejście, umieszczając opcję bezpośrednio w projekcie, czyniąc ją specyficzną dla projektu. Nie będzie to działać z innymi projektami git, które tworzysz / realizujesz w przyszłości, ale działa z projektem, nad którym pracujesz. (upewnijmy się, że będziemy ~/.gitconfig~/project/.git/config
jednoznaczni
Czy po uruchomieniu tej funkcji git initnależy ponownie ustawić tryb pliku na true?
Jordan
53

Dodanie do odpowiedzi Grega Hewgilla (przy użyciu core.fileModezmiennej config):

Możesz użyć --chmod=(-|+)xopcji git update-index (niskopoziomowa wersja „git add”), aby zmienić uprawnienia do wykonywania w indeksie, skąd zostanie on odebrany, jeśli użyjesz „git commit” (a nie „git commit -a „).

Jakub Narębski
źródło
2
Powinno to zostać zredagowane w odpowiedzi Grega Hewgilla, a nie dodane jako osobna odpowiedź, tworząc w ten sposób jedną najwyższą odpowiedź z pojedynczą jednoznaczną reprezentacją.
Greg
6
@Greg: Trzeba mieć wystarczającą liczbę punktów do edycji, a nie własną odpowiedź; Myślę, że w tym czasie nie miałem dość uprawnień do edycji.
Jakub Narębski
1
@Jakub Myślę, że masz teraz dość reputacji :) Jak wyglądałoby to polecenie dla przykładowego pliku?
Alex Hall
38

Możesz to skonfigurować globalnie:

git config --global core.filemode false

Jeśli powyższe nie działa, przyczyną może być to, że konfiguracja lokalna zastępuje konfigurację globalną.

Usuń konfigurację lokalną, aby włączyć globalną konfigurację:

git config --unset core.filemode

Alternatywnie możesz zmienić konfigurację lokalną na odpowiednią wartość:

git config core.filemode false

Tyler Long
źródło
4
Jeśli główna odpowiedź ci nie pomoże - spróbuj tego. Jeśli chcesz sprawdzić konfigurację lokalną bez jej modyfikacji, zaznacz git config -l(wyświetl aktualną konfigurację - zarówno lokalną, jak i globalną)
Krzysztof Bociurko,
23

Jeśli używałeś już komendy chmod, sprawdź różnicę pliku, pokazuje poprzedni tryb pliku i bieżący tryb pliku, taki jak:

nowy tryb: 755

stary tryb: 644

ustaw stary tryb wszystkich plików za pomocą poniższego polecenia

sudo chmod 644 .

teraz ustaw core.fileMode na false w pliku konfiguracyjnym za pomocą polecenia lub ręcznie.

git config core.fileMode false

następnie zastosuj polecenie chmod, aby zmienić uprawnienia wszystkich plików, takich jak

sudo chmod 755 .

i ponownie ustaw core.fileMode na true.

git config core.fileMode true

W celu uzyskania najlepszych praktyk nie rób zawsze core.fileMode false.

Kishor Vitekar
źródło
Czy mówisz, że cały projekt (w fazie rozwoju, inscenizacji i produkcji) powinien wynosić 755?
Daniel
@Daniel Lut: Nie. Zmień tryb tylko niezbędnych plików.
Kishor Vitekar,
For best practises don't Keep core.fileMode false alwaysco masz na myśli, powinieneś to wyjaśnić.
bg17aw
For best practises don't Keep core.fileMode false always.Niektóre systemy plików (na przykład FAT) nie obsługują uprawnień do plików, więc system operacyjny zgłosi wartość domyślną (766 w moim systemie i tak). W takim przypadku core.filemodejest to absolutnie konieczne w konfiguracji lokalnej, chyba że chcesz
przesadzić
Ponadto, dlaczego w ogóle zawracasz sobie głowę zmianą permsów? Jeśli ustawisz, core.filemode=falsegit zignoruje zmiany bitów, nie musisz zmieniać lokalnych uprawnień. O ile nie dodałeś już zmian uprawnień do indeksu, w takim przypadku brakuje kroku, w którym musisz to zrobić git addpo wyłączeniu core.filemode.
KevinOrr,
18

Definiując następujący alias (w ~ / .gitconfig), możesz łatwo tymczasowo wyłączyć tryb fileMode dla polecenia git:

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

Gdy ten alias ma prefiks do komendy git, zmiany trybu plików nie pojawią się wraz z poleceniami, które w przeciwnym razie by je pokazały. Na przykład:

git nfm status
Ville
źródło
14

Jeśli chcesz ustawić tryb pliku na false w plikach konfiguracyjnych rekurencyjnie (w tym w podmodułach): find -name config | xargs sed -i -e 's/filemode = true/filemode = false/'

dryobs
źródło
4
To nie zadziała, jeśli tej linii nie ma w pliku konfiguracyjnym. Jeśli chcesz to zmienić dla submodułów, spróbuj tego:git submodule foreach git config core.fileMode false
courtlandj
4

Proste rozwiązanie:

Hit tego prostego polecenia w folderze projektu ( nie usunie oryginalne zmian) ... to będzie tylko usunąć zmiany , które zostały zrobione podczas zmienił uprawnienia folderu projektu

polecenie jest poniżej:

git config core.fileMode false

Dlaczego cały ten niepotrzebny plik jest modyfikowany: ponieważ zmieniłeś uprawnienia do folderu projektu poleceniem sudo chmod -R 777 ./yourProjectFolder

kiedy sprawdzisz zmiany, czego nie zrobiłeś? znalazłeś jak poniżej podczas używania nazwy pliku git diff

old mode 100644
new mode 100755
Shashwat Gupta
źródło
1

To działa dla mnie:

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

lub odwrotnie, w zależności od systemu operacyjnego

find . -type f -exec chmod a+x {} \;
Martin Volek
źródło
1
Spowoduje to zmianę uprawnień do pliku, ale nie spowoduje, że git zignoruje uprawnienia do pliku.
domdambrogia
Cóż, masz rację, to nie rozwiązuje problemu git ignoruj.
Martin Volek