Как восстановить права доступа к файлам и каталогам в git, если они были изменены? - PullRequest
246 голосов
/ 25 марта 2010

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

Не касаясь содержимого файлов (просто хочу изменить разрешения), как мне установить для всех разрешений на файлы то, что Git считает, что они должны быть?

Ответы [ 8 ]

501 голосов
/ 10 декабря 2010

Git отслеживает разрешение файлов и выставляет изменения разрешений при создании патчей с использованием git diff -p. Итак, все, что нам нужно, это:

  1. создать обратный патч
  2. включает только изменения прав доступа
  3. примените патч к нашей рабочей копии

как однострочный:

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

вы также можете добавить его в качестве псевдонима в ваш git config ...

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

... и вы можете вызвать его через:

git permission-reset

Обратите внимание, что если вы используете bash, то обязательно используйте ' вместо " кавычек вокруг !git, в противном случае он заменяется последней командой git, которую вы выполнили.

Спасибо @Mixologic за указание, что при простом использовании -R на git diff громоздкая команда sed больше не требуется.

101 голосов
/ 25 марта 2010

Попробуйте git config core.fileMode false

Примечание: core.fileMode чувствительно к регистру !

Из справочной страницы git config:

core.fileMode

Если false, различия в исполняемых битах между индексом и рабочей копией игнорируются; полезно на сломанных файловых системах, таких как FAT. См. git-update-index (1) .

Значение по умолчанию - true, за исключением того, что git-clone (1) или git-init (1) будут проверять и устанавливать core.fileMode false, если это необходимо, при создании хранилища.

8 голосов
/ 25 марта 2010

Git не хранит права доступа к файлам, кроме исполняемых скриптов. Попробуйте сохранить что-то вроде git-cache-meta , чтобы сохранить владельца файла и разрешения.

Git может хранить только два типа режимов: 755 (исполняемый) и 644 (не исполняемый). Если бы ваш файл был 444 git, то в нем было бы 644.

6 голосов
/ 30 апреля 2015
git diff -p \
| grep -E '^(diff|old mode|new mode)' \
| sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/' \
| git apply

будет работать в большинстве случаев, но если у вас установлены внешние инструменты сравнения, такие как meld, вы должны добавить --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

было необходимо в моей ситуации

0 голосов
/ 23 апреля 2016

git diff -p используется в ответ muhqu может показывать не все расхождения.

  • видел это в Cygwin для файлов, которые мне не принадлежали
  • изменения режима полностью игнорируются, если core.filemode равно false (по умолчанию для MSysGit)

Этот код читает метаданные напрямую:

(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)

Однострочник непроизводственного класса (полностью заменяет маски):

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

(Кредит для "$ '\ 0'" идет на http://transnum.blogspot.ru/2008/11/bashs-read-built-in-supports-0-as.html)

0 голосов
/ 14 января 2016

Инструмент etckeeper может обрабатывать разрешения и с:

etckeeper init -d /mydir

Вы можете использовать его для других директорий, кроме /etc.

Установите с помощью менеджера пакетов или воспользуйтесь ссылкой выше.

0 голосов
/ 03 декабря 2010

Вы также можете попробовать крюк до / после оформления заказа.

См .: Настройка Git - Git Hooks

0 голосов
/ 25 марта 2010

Самое простое, что нужно сделать, это просто поменять разрешения обратно. Как заметил @kroger, git отслеживает только исполняемые биты. Поэтому вам, вероятно, просто нужно запустить chmod -x filename, чтобы исправить это (или +x, если это то, что нужно.

...