Если вы подумываете об этом прямо сейчас, я только что прошел через это сегодня и могу резюмировать, где это стоит. Если вы еще не пробовали это сделать, некоторые подробности здесь могут помочь.
Я думаю, что подход @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. В нем одна строка на файл, вот верхняя часть моего примера:
$ 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
В комментариях к этому подходу один из плакатов жалуется, что он работает только с тем же именем пользователя, и это технически верно, но это очень легко исправить. Обратите внимание на то, что скрипт после оформления заказа состоит из двух частей:
# Set the file permissions
chmod $PERMISSIONS $FILE
# Set the file owner and groups
chown $USER:$GROUP $FILE
Так что я оставлю только первую, это все, что мне нужно. Мое имя пользователя на веб-сервере действительно другое, но, что более важно, вы не можете запускать chown, если не являетесь пользователем root. Однако может запускать "chgrp". Достаточно ясно, как это использовать.
В первом ответе в этом сообщении, наиболее широко принятом, предлагается использовать git-cache-meta, скрипт, который выполняет ту же работу, что и скрипты pre / post hook здесь (анализ вывода из git ls-files
) . Эти сценарии мне легче понять, код git-cache-meta более сложен. Можно сохранить git-cache-meta в пути и написать сценарии до фиксации и после проверки, которые будут его использовать.
Пробелы в именах файлов - проблема обоих скриптов Омида. В сценарии после оформления заказа вы будете знать, что у вас есть пробелы в именах файлов, если вы увидите такие ошибки
$ 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 в прежнее состояние! Вы можете понять, почему сеанс оболочки может закончиться неудачно, если вы оставите $ в качестве единственного разделителя.