Na wypadek, gdybyś teraz wchodził w to, właśnie przez to przeszedłem dzisiaj i mogę podsumować, na czym to polega. Jeśli jeszcze tego nie próbowałeś, niektóre szczegóły mogą pomóc.
Myślę, że podejście @Omid Ariyan jest najlepszym sposobem. Dodaj skrypty pre-commit i post-checkout. NIE zapomnij nazwać ich dokładnie tak, jak robi to Omid i NIE zapomnij uczynić ich wykonywalnymi. Jeśli zapomnisz któregokolwiek z nich, nie przyniosą one żadnego efektu i w kółko uruchamiasz "git commit", zastanawiając się, dlaczego nic się nie dzieje :) Ponadto, jeśli wycinasz i wklejasz z przeglądarki internetowej, uważaj, aby cudzysłowy i znaczniki nie były zmieniony.
Jeśli raz uruchomisz skrypt pre-commit (przez uruchomienie git commit), to zostanie utworzony plik .permissions. Możesz dodać go do repozytorium i myślę, że nie jest konieczne ciągłe dodawanie go na końcu skryptu pre-commit. Ale myślę, że to nie boli (mam nadzieję).
Istnieje kilka drobnych problemów związanych z nazwą katalogu i istnieniem spacji w nazwach plików w skryptach Omid. Przestrzenie były tutaj problemem i miałem problem z poprawką IFS. Dla przypomnienia, ten skrypt przed zatwierdzeniem działał poprawnie dla mnie:
#!/bin/bash
SELF_DIR=`git rev-parse --show-toplevel`
DATABASE=$SELF_DIR/.permissions
# Clear the permissions database file
> $DATABASE
echo -n "Backing-up file permissions..."
IFSold=$IFS
IFS=$'\n'
for FILE in `git ls-files`
do
# Save the permissions of all the files in the index
echo $FILE";"`stat -c "%a;%U;%G" $FILE` >> $DATABASE
done
IFS=${IFSold}
# Add the permissions database file to the index
git add $DATABASE
echo "OK"
Co z tego mamy?
Plik .permissions znajduje się na najwyższym poziomie repozytorium git. Ma jedną linię na plik, oto początek mojego przykładu:
$ cat .permissions
.gitignore;660;pauljohn;pauljohn
05.WhatToReport/05.WhatToReport.doc;664;pauljohn;pauljohn
05.WhatToReport/05.WhatToReport.pdf;664;pauljohn;pauljohn
Jak widać, mamy
filepath;perms;owner;group
W komentarzach na temat tego podejścia jeden z plakatów narzeka, że działa tylko z tą samą nazwą użytkownika i jest to technicznie prawda, ale bardzo łatwo to naprawić. Zwróć uwagę, że skrypt po kasie ma 2 elementy akcji,
# Set the file permissions
chmod $PERMISSIONS $FILE
# Set the file owner and groups
chown $USER:$GROUP $FILE
Więc zatrzymuję tylko pierwszy, to wszystko, czego potrzebuję. Moja nazwa użytkownika na serwerze WWW jest rzeczywiście inna, ale co ważniejsze, nie możesz uruchomić chown, jeśli nie jesteś rootem. Może jednak uruchomić "chgrp". Jest wystarczająco jasne, jak to wykorzystać.
W pierwszej odpowiedzi w tym poście, tej, która jest najczęściej akceptowana, sugestia jest taka, aby użyć git-cache-meta, skryptu, który wykonuje tę samą pracę, którą wykonują skrypty przechwytujące przed / po (parsowanie danych wyjściowych z git ls-files
) . Te skrypty są dla mnie łatwiejsze do zrozumienia, kod git-cache-meta jest raczej bardziej rozbudowany. Możliwe jest zachowanie git-cache-meta w ścieżce i pisanie skryptów przed zatwierdzeniem i po pobraniu, które by go używały.
Spacje w nazwach plików są problemem w obu skryptach Omid. W skrypcie po zakupie będziesz wiedział, że masz spacje w nazwach plików, jeśli zobaczysz takie błędy
$ git checkout -- upload.sh
Restoring file permissions...chmod: cannot access '04.StartingValuesInLISREL/Open': No such file or directory
chmod: cannot access 'Notebook.onetoc2': No such file or directory
chown: cannot access '04.StartingValuesInLISREL/Open': No such file or directory
chown: cannot access 'Notebook.onetoc2': No such file or directory
Sprawdzam rozwiązania tego problemu. Oto coś, co wydaje się działać, ale przetestowałem tylko w jednym przypadku
#!/bin/bash
SELF_DIR=`git rev-parse --show-toplevel`
DATABASE=$SELF_DIR/.permissions
echo -n "Restoring file permissions..."
IFSold=${IFS}
IFS=$
while read -r LINE || [[ -n "$LINE" ]];
do
FILE=`echo $LINE | cut -d ";" -f 1`
PERMISSIONS=`echo $LINE | cut -d ";" -f 2`
USER=`echo $LINE | cut -d ";" -f 3`
GROUP=`echo $LINE | cut -d ";" -f 4`
# Set the file permissions
chmod $PERMISSIONS $FILE
# Set the file owner and groups
chown $USER:$GROUP $FILE
done < $DATABASE
IFS=${IFSold}
echo "OK"
exit 0
Ponieważ informacje o uprawnieniach są wyświetlane po jednym wierszu na raz, ustawiłem IFS na $, więc tylko podziały wierszy są postrzegane jako nowe rzeczy.
Czytałem, że BARDZO WAŻNE jest ustawienie zmiennej środowiskowej IFS z powrotem tak, jak było! Możesz zobaczyć, dlaczego sesja powłoki może pójść źle, jeśli zostawisz $ jako jedyny separator.