Jak przywrócić uprawnienia do plików i katalogów w git, jeśli zostały zmodyfikowane?


278

Mam kasę. Wszystkie uprawnienia do plików różnią się od tego, co git uważa, że ​​powinny być, dlatego wszystkie są wyświetlane jako zmodyfikowane.

Bez dotykania zawartości plików (po prostu chcę zmodyfikować uprawnienia) jak ustawić wszystkie uprawnienia do plików według tego, co według gita powinny być?


Odpowiedzi:


572

Git śledzi uprawnienia do plików i ujawnia zmiany uprawnień podczas tworzenia łatek przy użyciu git diff -p. Wszystko czego potrzebujemy to:

  1. utwórz odwrotną łatkę
  2. uwzględnij tylko zmiany uprawnień
  3. zastosuj łatkę do naszej kopii roboczej

Jako jedna linijka:

git diff -p -R --no-ext-diff --no-color \
    | grep -E "^(diff|(old|new) mode)" --color=never  \
    | git apply

możesz również dodać go jako alias do konfiguracji git ...

git config --global --add alias.permission-reset '!git diff -p -R --no-ext-diff --no-color | grep -E "^(diff|(old|new) mode)" --color=never | git apply'

... i możesz je wywołać za pomocą:

git permission-reset

Uwaga: jeśli używasz powłoki bash, upewnij się, że używasz 'zamiast "cudzysłowów wokół !git, w przeciwnym razie zostanie zastąpione ostatnim gituruchomionym poleceniem.

Dzięki @Mixologic za wskazanie, że po prostu używając -Ron git diff, kłopotliwe sedpolecenie nie jest już wymagane.


3
Jestem w OS X, to nie działa. Stwierdziłem, że problem dotyczy git. Nie stosuje zmian uprawnień do plików.
pepper_chico

15
Och, zadziałało, starałem się aplikować z katalogu innego niż katalog główny repozytorium. git Apply działa tylko tam.
pepper_chico

6
Czy jest jakiś powód, dla którego nie zrobiłbyś po prostu „git diff -p -R” zamiast robić sed, aby odwrócić?
Mixologic

6
@RobQuist moje lokalne zmiany nie zostały usunięte podczas korzystania z polecenia muhqu
logion

17
Dostajęfatal: unrecognized input
Tieme

120

Próbować git config core.fileMode false

Ze strony podręcznika git config:

core.fileMode

W przypadku wartości false różnice w wykonywalnych bitach między indeksem a kopią roboczą są ignorowane; przydatne na uszkodzonych systemach plików, takich jak FAT. Zobacz git-update-index (1) .

Domyślnie jest to prawda, z wyjątkiem tego, że git-clone (1) lub git-init (1) sondują i ustawią core.fileMode na false, jeśli to właściwe, podczas tworzenia repozytorium.


Dzięki, to właśnie skończyłem. Bardzo przyzwyczajony do cvs nie śledzących uprawnień, więc to działa.
Dale Forester

3
@shovas: Cieszę się, że to pomogło. Wystąpił podobny problem podczas udostępniania repozytoriów między Linuxem a Windows. BTW: jeśli to odpowiedziało na twoje pytanie, proszę zaznaczyć odpowiedź jako poprawną.
Tim Henigan,

Czy to możliwe, że git checkout origin/masterustawia uprawnienia do pliku przypisane do serwera do mojej lokalnej kopii roboczej? Ponieważ za każdym razem, gdy buduję V8 dla ArangoDB, uprawnienia do plików są zmieniane, tak że odmawia się dostępu do całego folderu kompilacji (nawet z podwyższonymi prawami; to znaczy Windows 7+). Przed kontynuowaniem procesu kompilacji muszę naprawić wszystkie lokalne uprawnienia do plików. Czy core.filemode falseto też można naprawić? Podejrzewam, że git ustawia uprawnienia Linuksa na moim komputerze z systemem Windows. Skrypty kompilacji mogą je po prostu zachować i zastosować te same uprawnienia do nowo utworzonych plików ...
CodeManX

Im zastanawiasz się, czy jest jakiś minusem do ustawiania filemodesię false!
kevoroid

11

Git nie przechowuje uprawnień do plików innych niż skrypty wykonywalne. Zastanów się nad użyciem czegoś takiego jak git-cache-meta, aby zapisać własność pliku i uprawnienia.

Git może przechowywać tylko dwa typy trybów: 755 (plik wykonywalny) i 644 (plik wykonywalny). Jeśli plik miał 444, git zapisałby, że ma 644.


14
Przepraszam, ale to nieprawda. Git rzeczywiście śledzi uprawnienia.
Czy

4
Jest mniej więcej dokładny, zobacz git.wiki.kernel.org/index.php/ContentLimitations . Dokładne ustawione uprawnienia wydają się być oparte na serwerze i ewentualnie kliencie, umaska także na ustawieniach konfiguracyjnych, patrz stackoverflow.com/a/12735291/125150 .
Motti Strom

12
@ Nie, nie będzie. Nie mogę uwierzyć, że twój komentarz otrzymał tak wiele pozytywnych opinii.
eis

@Will, jest to mniej więcej poprawne. Per the docs ...a mode of 100644, which means it’s a normal file. Other options are 100755, which means it’s an executable file; and 120000, which specifies a symbolic link. The mode is taken from normal UNIX modes but is much less flexible — these three modes are the only ones that are valid for files (blobs) in Git (although other modes are used for directories and submodules).
esmail

9
git diff -p \
| grep -E '^(diff|old mode|new mode)' \
| sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/' \
| git apply

będzie działać w większości przypadków, ale jeśli masz zainstalowane zewnętrzne narzędzia porównywania, takie jak meld, musisz dodać --no-ext-diff

git diff --no-ext-diff -p \
    | grep -E '^(diff|old mode|new mode)' \
    | sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/' \
    | git apply

był potrzebny w mojej sytuacji



0

Używam git z cygwin w systemie Windows, git applyrozwiązanie nie działa dla mnie. Oto moje rozwiązanie, uruchom chmodna każdym pliku, aby zresetować uprawnienia.

#!/bin/bash
IFS=$'\n'
for c in `git diff -p |sed -n '/diff --git/{N;s/diff --git//g;s/\n/ /g;s# a/.* b/##g;s/old mode //g;s/\(.*\) 100\(.*\)/chmod \2 \1/g;p}'`
do
        eval $c
done
unset IFS


-1

git diff -pużyte w odpowiedzi muhqua mogą nie wykazywać wszystkich rozbieżności.

  • widziałem to w Cygwin dla plików, których nie posiadałem
  • zmiany trybu są całkowicie ignorowane, jeśli core.filemodejest false(co jest domyślnym ustawieniem MSysGit)

Zamiast tego kod odczytuje metadane bezpośrednio:

(set -o errexit pipefail nounset;
git ls-tree HEAD -z | while read -r -d $'\0' mask type blob path
do
    if [ "$type" != "blob" ]; then continue; fi;
    case "$mask" in
    #do not touch other bits
    100644) chmod a-x "$path";;
    100755) chmod a+x "$path";;
    *) echo "invalid: $mask $type $blob\t$path" >&2; false;;
    esac
done)

Jednowarstwowy materiał nieprodukcyjny (całkowicie zastępuje maski):

git ls-tree HEAD | perl -ne '/^10(0\d{3}) blob \S+\t(.+)$/ && { system "chmod",$1,$2 || die }'

(Kredyt za „$ '\ 0” trafia na http://transnum.blogspot.ru/2008/11/bashs-read-built-in-supports-0-as.html )


-2

Najłatwiej jest po prostu zmienić uprawnienia z powrotem. Jak zauważył @kroger, git śledzi tylko bity wykonywalne. Prawdopodobnie musisz po prostu uruchomić, chmod -x filenameaby to naprawić (lub +xjeśli to jest to potrzebne.


Oto przykład z git show: diff --git a / OpenWatch / src / org / ale / openwatch / fb / FBUtils.java b / OpenWatch / src / org / ale / openwatch / fb / FBUtils.java index cd6fa6a..e5b0935 100644 That nieco pogrubioną czcionką są uprawnienia do plików.
Conrado

To też wydawało mi się najłatwiejsze. Niestety napotkałem ten sam problem co Conrado - nie mogłem zmienić uprawnień z 100644na 100755. Nie sądzę, żebyś zasłużył sobie na głos; Git powinien zostać odrzucony. Jest tak zepsuty na wiele sposobów na tak różnych poziomach ...
jww

-2

etckeeperNarzędzie może obsłużyć uprawnienia oraz z:

etckeeper init -d /mydir

Możesz użyć go do innych katalogów niż /etc.

Zainstaluj za pomocą menedżera pakietów lub pobierz źródła z powyższego linku.


4
Do czego ustawia uprawnienia? Jeśli nie odczytuje metadanych Gita lub nie wywołuje Git, nie robi tego, czego zażądał PO.
ivan_pozdeev
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.