Как добавить права доступа chmod к файлу в GIT?

182

Я хочу сделать коммит в файле .sh, но хочу, чтобы он был исполняемым, когда я извлекаю тот же файл на другом сервере.

Есть ли способ сделать это без ручного chmod u + x этот файл на серверах, которые извлекают файл?

Хенли Чиу
источник

Ответы:

292

Согласно официальной документации , вы можете установить или удалить флаг «исполняемый» для любого отслеживаемого файла с помощью update-indexподкоманды.

Чтобы установить флаг, используйте следующую команду:

git update-index --chmod=+x path/to/file

Чтобы удалить его, используйте:

git update-index --chmod=-x path/to/file

Под капотом

Хотя это похоже на обычную систему разрешения файлов Unix, на самом деле это не так. Git поддерживает специальный «режим» для каждого файла во внутренней памяти:

  • 100644 для обычных файлов
  • 100755 для исполняемых

Вы можете визуализировать это, используя ls-fileподкоманду, с --stageопцией:

$ git ls-files --stage
100644 aee89ef43dc3b0ec6a7c6228f742377692b50484 0       .gitignore
100755 0ac339497485f7cc80d988561807906b2fd56172 0       my_executable_script.sh

По умолчанию, когда вы добавляете файл в репозиторий, Git будет пытаться учитывать атрибуты его файловой системы и соответственно устанавливать правильный режим файла. Вы можете отключить это, установив core.fileModeпараметр в false:

git config core.fileMode false

Исправление проблем

Если в какой-то момент файловый режим Git не установлен, но файл имеет правильный флаг файловой системы, попробуйте удалить режим и установить его снова:

git update-index --chmod=-x path/to/file
git update-index --chmod=+x path/to/file

бонус

Начиная с Git 2.9, вы можете создать файл И установить флаг одной командой:

git add --chmod=+x path/to/file
Antwane
источник
Когда я делаю это для test.sh, git commit and push и checkout на другом сервере, это перми этого файла: -rw-rw-r-- 1 пользователь user 12 дек. 5 11:42 test.sh
Henley Chiu
Я только что выполнил тест на одном из моих репозиториев, и он работает, как ожидалось. Разрешения были установлены для файла с помощью предоставленной команды под Windows. На одном из моих серверов (Debian) ранее у файла были права доступа -rw-r - r--, теперь они установлены на -rwxr-xr-x. Какую версию git вы используете на локальных и удаленных машинах?
Antwane
git версии 1.9.5 в моем локальном компьютере и git 1.7.1 на сервере, делающем проверку.
Хенли Чиу
Просто попытался клонировать на другом (более старом) сервере с git 1.7.10, он все еще работает хорошо, файл имеет x разрешений. Возможно, вы ошиблись в какой-то момент или у вас возникли проблемы с правами доступа пользователя, который клонировал на удаленном сервере
Antwane
Обратите внимание, что вы можете только изменить (установить или очистить) разрешение на выполнение. Git не отслеживает никаких других разрешений (таких как разрешение на чтение или запись).
Дэн Андерсон
25

Ответ Antwane является правильным, и это должен быть комментарий, но комментарии не имеют достаточно места и не позволяют форматирование. :-) Я просто хочу добавить, что в Git записываются только права доступа к файлам 1 или как 644или 755(пишется ( 100644и 100755, а 100часть средств «обычный файл»):

diff --git a/path b/path
new file mode 100644

Первый - 644 - означает, что файл должен не быть исполняемым, а второй означает, что он должен быть исполняемым. То, как это превращается в реальные файловые режимы в вашей файловой системе, зависит от ОС. В Unix-подобных системах биты передаются через ваш umaskпараметр, который обычно должен был 022бы удалить разрешение на запись из «группы» и «другого» или 002удалить разрешение на запись только из «другого». Это также может быть, 077если вы особенно обеспокоены конфиденциальностью и хотите удалить разрешения на чтение, запись и выполнение как из «группы», так и из «другого».


1 Чрезвычайно ранние версии Git сохранили групповые разрешения, поэтому в некоторых репозиториях есть записи дерева с режимом 664. Современный Git этого не делает, но, поскольку никакая часть какого-либо объекта не может быть изменена, эти старые биты прав доступа все еще сохраняются в старых объектах дерева.

Изменение для хранения только 0644 или 0755 было в коммите e44794706eeb57f2 , который был до Git v0.99 и датирован 16 апреля 2005 года.

Торек
источник
«Ранние версии Git» Есть идеи, на какие именно версии это влияет?
user5359531
2
@ user5359531 версии до коммита e44794706eeb57f2ee38ed1604821aa38b8ad9d2, т. е. до Git версии 0.99.
Торек