Как восстановить права доступа к файлу для того, что git "думает", что файл должен быть?


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

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

8 223

8 ответов:

Git отслеживает filepermission и предоставляет изменения разрешений при создании патчей с помощью 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, в противном случае он будет заменен на последний вы сбежали.

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

попробовать git config core.fileMode false

Примечание: core.fileMode и регистр!

С git config на странице:

core.fileMode

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

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

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

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

git diff -p \
| grep -E '^(diff|old mode|new mode)' \
| sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/' \
| git apply

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

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

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

посмотреть: Настройка Git-Git Крючки

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

git diff -p в muhqu это могут отображаться не все расхождения.

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

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

(set -o errexit pipefail nounset;
git ls-tree HEAD -z | while read -r -d $'' 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",, || die }'

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

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

etckeeper init -d /mydir

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

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