Comment ajouter des autorisations chmod au fichier dans GIT?

182

Je veux git commit un fichier .sh, mais je veux qu'il soit exécutable lorsque je récupère ce même fichier sur un autre serveur.

Existe-t-il un moyen de le faire sans chmod u + x manuellement ce fichier dans les serveurs qui extraient le fichier?

Henley Chiu
la source

Réponses:

291

Selon la documentation officielle , vous pouvez définir ou supprimer le drapeau "exécutable" sur n'importe quel fichier suivi en utilisant la update-indexsous-commande.

Pour définir l'indicateur, utilisez la commande suivante:

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

Pour le supprimer, utilisez:

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

Sous la capuche

Bien que cela ressemble au système normal d'autorisation des fichiers Unix, ce n'est pas le cas. Git maintient un "mode" spécial pour chaque fichier dans sa mémoire interne:

  • 100644 pour les fichiers normaux
  • 100755 pour les exécutables

Vous pouvez le visualiser à l'aide de la ls-filesous-commande, avec l' --stageoption:

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

Par défaut, lorsque vous ajoutez un fichier à un référentiel, Git essaiera d'honorer ses attributs de système de fichiers et de définir le mode de fichier correct en conséquence. Vous pouvez désactiver cela en définissant l' core.fileModeoption sur false:

git config core.fileMode false

Dépannage

Si à un moment donné le mode de fichier Git n'est pas défini mais que le fichier a le bon indicateur de système de fichiers, essayez de supprimer le mode et de le redéfinir:

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

Prime

À partir de Git 2.9, vous pouvez organiser un fichier ET définir le drapeau en une seule commande:

git add --chmod=+x path/to/file
Antwane
la source
Quand je fais cela pour tester.sh, git commit et push, et checkout dans un autre serveur, ce sont les perms de ce fichier: -rw-rw-r-- 1 utilisateur utilisateur 12 décembre 5 11:42 test.sh
Henley Chiu
Je viens d'effectuer le test sur l'un de mes référentiels et cela fonctionne comme prévu. Les autorisations ont été définies sur le fichier à l'aide de la commande fournie sous Windows. Sur l'un de mes serveurs (Debian), le fichier avait auparavant les autorisations -rw-r - r--, maintenant définies sur -rwxr-xr-x. Quelle version de git utilisez-vous sur les machines locales et distantes?
Antwane
git version 1.9.5 dans mon local, et git 1.7.1 dans le serveur effectuant la vérification.
Henley Chiu
Je viens d'essayer de cloner sur un autre serveur (plus ancien) avec git 1.7.10, cela fonctionne toujours bien, le fichier a x autorisations. Peut-être que vous avez fait une erreur à un moment donné, ou vous avez des problèmes d'autorisation avec l'utilisateur qui a cloné sur le serveur distant
Antwane
Notez que vous ne pouvez modifier (définir ou effacer) que l'autorisation d'exécution. Git ne suit aucune autre autorisation (telle que l'autorisation de lecture ou d'écriture).
Dan Anderson
25

La réponse d'Antwane est correcte, et cela devrait être un commentaire, mais les commentaires n'ont pas assez d'espace et ne permettent pas le formatage. :-) Je veux juste ajouter que dans Git, les permissions de fichiers sont enregistrées seulement 1 comme soit 644ou 755(orthographié ( 100644et 100755; la 100partie signifie "fichier normal"):

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

Le premier - 644 - signifie que le fichier ne doit pas être exécutable, et le second signifie qu'il doit être exécutable. La façon dont cela se transforme en modes de fichiers réels dans votre système de fichiers dépend quelque peu du système d'exploitation. Sur les systèmes de type Unix, les bits passent par votre umaskparamètre, ce qui serait normalement 022de supprimer l'autorisation d'écriture de «groupe» et «autre», ou 002de supprimer l'autorisation d'écriture uniquement de «autre». Cela peut également être le 077cas si vous êtes particulièrement préoccupé par la confidentialité et souhaitez supprimer les autorisations de lecture, d'écriture et d'exécution à la fois du "groupe" et de "l'autre".


1 Les versions extrêmement anciennes des autorisations de groupe enregistrées par Git, de sorte que certains référentiels contiennent des entrées d'arborescence avec mode 664. Ce n'est pas le cas de Git moderne, mais comme aucune partie d'un objet ne peut jamais être modifiée, ces anciens bits d'autorisations persistent dans les anciens objets d'arbre.

Le changement pour stocker uniquement 0644 ou 0755 était dans le commit e44794706eeb57f2 , qui est antérieur à Git v0.99 et daté du 16 avril 2005.

Torek
la source
"Les premières versions de Git" une idée des versions exactes affectées par cela?
user5359531
2
@ user5359531 versions avant validation e44794706eeb57f2ee38ed1604821aa38b8ad9d2, c'est-à-dire antérieures à la version 0.99 de Git.
torek