Якщо ви зараз вступаєте в цю справу, я щойно пережив це і можу підсумувати, де це стоїть. Якщо ви ще цього не пробували, деякі деталі тут можуть допомогти.
Я думаю, що підхід @Omid Ariyan - найкращий спосіб. Додайте сценарії до завершення та після оформлення замовлення. НЕ забудьте назвати їх саме так, як це робить Омід, і НЕ забудьте зробити їх виконаними. Якщо ви забудете будь-яке з них, вони не мають ефекту, і ви знову і знову запускаєте "git commit", цікаво, чому нічого не відбувається :) Крім того, якщо вирізати та вставити з веб-браузера, будьте уважні, щоб лапки та клітинки не були перероблений.
Якщо запустити скрипт перед фіксацією один раз (запустивши git commit), тоді файли .permissions будуть створені. Ви можете додати його до сховища, і я вважаю, що не потрібно додавати його знову і знову в кінці сценарію попереднього введення. Але це не шкодить, я думаю (сподіваюся).
Існує кілька невеликих проблем щодо імені каталогу та наявності пробілів у іменах файлів у сценаріях Omid. Пробіли тут були проблемою, і у мене виникли проблеми з виправленням IFS. Для запису цей сценарій перед фіксацією працював правильно для мене:
#!/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"
Тепер, що ми отримуємо з цього?
Файл .permissions знаходиться на найвищому рівні git repo. У ньому є один рядок у файлі, ось верхня частина мого прикладу:
$ cat .permissions
.gitignore;660;pauljohn;pauljohn
05.WhatToReport/05.WhatToReport.doc;664;pauljohn;pauljohn
05.WhatToReport/05.WhatToReport.pdf;664;pauljohn;pauljohn
Як бачите, у нас є
filepath;perms;owner;group
У коментарях щодо такого підходу один із плакатів скаржиться, що він працює лише з тим самим іменем користувача, і це технічно правда, але це дуже легко виправити. Зверніть увагу, що сценарій після оформлення замовлення містить 2 дії,
# Set the file permissions
chmod $PERMISSIONS $FILE
# Set the file owner and groups
chown $USER:$GROUP $FILE
Тож я зберігаю лише перший, це все, що мені потрібно. Моє ім’я користувача на веб-сервері дійсно різне, але що ще важливіше, ви не можете запускати chown, якщо ви не root. Однак можна запустити "chgrp". Досить зрозуміло, як це використовувати.
У першій відповіді в цій публікації, найбільш широко прийнятій, пропозиція полягає в тому, щоб використовувати git-cache-meta, скрипт, який виконує ту саму роботу, що і тут виконуються скрипти перед гаком до / після (аналіз результатів git ls-files
) . Ці сценарії мені легше зрозуміти, мета-код git-cache-мета є більш досконалим. Можна зберігати git-cache-meta у шляху та писати сценарії до завершення та після оформлення замовлення, які його використовуватимуть.
Простіри в іменах файлів є проблемою для обох сценаріїв Omid. У сценарії після оформлення замовлення ви дізнаєтесь, що у назві файлів є пробіли, якщо ви бачите подібні помилки
$ 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
Я перевіряю рішення для цього. Ось щось, здається, працює, але я протестував лише в одному випадку
#!/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
Оскільки інформація про дозволи є одним рядком, я встановлюю IFS на $, тому лише розриви рядків розглядаються як нові речі.
Я читав, що ДУЖЕ ВАЖЛИВО повертати змінну середовища IFS назад такою, якою вона була! Ви можете зрозуміти, чому сеанс оболонки може піти погано, якщо ви залишите $ як єдиний роздільник.