Git изменить значение по умолчанию umask при обновлении файла

У меня проблема с Git. Я искал решение в Google и в StackOverflow, но ничего не помогает.

Проблема заключается в том, что каждый раз, когда git обновляет какой-либо файл в рабочем каталоге (когда я проверяю ветки или я соединяю ветку и т.д.), тогда права на файл изменяются так, что добавляется флаг "writeable to group", И мой apache показывает "Ошибка 500" для файла, если он доступен для записи.

Пример: У меня есть файл index.php. Разрешения: "-rwxr-xr-x". Текущей (активной) ветвью является мастер. Этот файл был изменен в ветке "develop". Я выполняю "git checkout develop", и файл index.php получает разрешения "-rwxrwxr-x" (добавляется запись в группу). И мой сайт перестает работать. Поскольку apache не разрешает этот флаг в php файлах (я не знаю, почему, но я не могу это изменить).

Каждый раз, когда я выполняю "git checkout develop", мне нужно выполнить также "chmod g-w index.php". Мне не нравится выполнять две команды (и иногда я забываю выполнить это, и мой сайт не работает).

Что я могу сделать для решения этой проблемы? Я думаю, что это связано с umask. Я сделал несколько трюков, которые я нашел в Интернете, но ничего не работает.

Спасибо.

Ответы

Ответ 1

Достаточно опасно разрешить выполнение файла как двоичного. В любом случае я решил проблему с umask. Мой post-receive script выглядит следующим образом:

!/bin/sh
umask 002
GIT_WORK_TREE=/var/www/site git checkout -f

Итак, file permission установите для 664 и directory permissions значение 775, что идеально подходит мне.

P.S. Установка umask в файле .profile пользователя git не влияет, и я не понимаю, почему, пожалуйста, закомментируйте, если вы знаете, почему это происходит.

Ответ 2

Быстрый ответ - это функция оболочки, которая будет помещена в ваш ~/.profile. Далее следует объяснение.

git(){(umask 0022; command git "[email protected]")}

A umask является свойством процесса. Он унаследован от родительского процесса и впоследствии может быть изменен изнутри. Команда для изменения umask обычно называется umask.

Git не имеет опции настройки для установки его umask, он не изменяет свой umask после его выполнения. Вы должны установить Git umask извне, пусть наследуется от родительского процесса (обычно это оболочка).

Ммм, вам, похоже, не нравится идея, что ничего, кроме Git, изменило umask. Поэтому давайте изменим его только при выполнении git.

Когда оболочка выполняет строку, она берет первое слово в строке и пытается найти функцию этого имени. Только если его нет, он пытается найти команду этого имени в PATH. Функция, которую я написал выше, называется git, поэтому любое прямое обращение git теперь выполняет ее вместо команды git.

Функция выполняет подоболочку, изменяет ее umask и выполняет команду git изнутри подоболочки. После того как Git закончит свою работу, подоболочка также выйдет, и исходный экземпляр оболочки по-прежнему будет иметь исходный umask.

Однако функция также показывает, как обойти себя. Если вы вызываете git через command git или даже /usr/bin/git, функция не будет вызываться. Для любого приличного использования это достаточно хорошо.

Ответ 3

Использование перехватчиков для изменения режима файла после проверки исправляет проблему после ее возникновения. У вас уже есть плохой файловый режим в файловой системе при выполнении hook. Если запрос поступит только между проверкой и выполнением крюка, сервер ответит с ошибкой 500. Но вы все равно можете быть заинтересованы в этом решении.

Для всех файлов необходимо использовать post-checkout hook chmod g-w. Крючок .git/hooks/post-checkout, должен быть исполняемым и получает текущий HEAD как второй параметр ($ 2 в оболочке). Крюк может выглядеть так:

#!/bin/bash
git ls-files -z --with-tree="$2" | xargs -0 chmod g-w --

Поскольку крючок не получает список извлеченных файлов, это может быть наилучшей возможной реализацией. Он изменяет режим всех файлов в текущем HEAD.