112 votes

Conserver les permissions de fichier avec Git

Je veux contrôler la version de mon serveur web comme décrit dans Contrôle de version pour mon serveur web, en créant un dépôt git à partir de mon répertoire /var/www. Mon espoir était alors de pouvoir pousser le contenu web depuis notre serveur de développement vers github, le tirer vers notre serveur de production, et passer le reste de la journée à la piscine.

Apparemment, un hic dans mon plan est que Git ne respecte pas les permissions des fichiers (je ne l'ai pas encore essayé, je lis à ce sujet maintenant.) Je suppose que cela a du sens étant donné que différentes machines ont tendance à avoir différentes configurations utilisateurs/groupes. Mais si je voulais forcer les permissions à se propager, sachant que mes serveurs sont configurés de la même manière, ai-je des options ? Ou y a-t-il un moyen plus simple d'aborder ce que j'essaie de faire ?

1 votes

Ouais, je suppose, bien que la solution à laquelle ils font référence, franchement, je ne suis pas sûr de ce que je dois en faire. J'espérais une approche plus directe.

0 votes

Que dire de la situation où le code source provient de l'environnement de développement (par exemple Windows - XAMPP, etc.) qui n'a pas d'informations sur la propriété des fichiers? Les fichiers à la fin du processus git doivent correspondre à la propriété et aux autorisations de l'emplacement cible. Git-cache-meta peut-il gérer cela? D'accord avec Yarin ... sûrement il s'agit d'un cas d'utilisation assez classique, qui devrait avoir une solution assez simple?

1voto

Vladimir Botka Points 10170

En pré-engagement/post-checkout, une option serait d'utiliser l'utilitaire "mtree" (FreeBSD) ou "fmtree" (Ubuntu) qui "compare une hiérarchie de fichiers à une spécification, crée une spécification pour une hiérarchie de fichiers ou modifie une spécification".

Les jeux par défaut sont les indicateurs, gid, lien, mode, nlink, taille, heure, type et uid. Cela peut être ajusté à un but spécifique avec l'interrupteur -k.

1voto

Albaro Pereyra Points 29

Je tourne sur FreeBSD 11.1, le concept de virtualisation des prisons FreeBSD rend le système d'exploitation optimal. La version actuelle de Git que j'utilise est la 2.15.1, je préfère également exécuter tout sur des scripts shell. Avec cela à l'esprit, j'ai modifié les suggestions ci-dessus comme suit :

git push: .git/hooks/pre-commit

#! /bin/sh -
#
# Un script de crochet appelé par "git commit" sans arguments. Le hook doit
# sortir avec un statut différent de zéro après avoir émis un message approprié s'il veut
# arrêter le commit.

SELF_DIR=$(git rev-parse --show-toplevel);
DATABASE=$SELF_DIR/.permissions;

# Effacer le fichier de base de données de permissions
> $DATABASE;

printf "Sauvegarde des permissions de fichiers...\n";

OLDIFS=$IFS;
IFS=$'\n';
for FILE in $(git ls-files);
do
   # Enregistrer les autorisations de tous les fichiers dans l'index
    printf "%s;%s\n" $FILE $(stat -f "%Lp;%u;%g" $FILE) >> $DATABASE;
done
IFS=$OLDIFS;

# Ajouter le fichier de base de données de permissions à l'index
git add $DATABASE;

printf "OK\n";

git pull: .git/hooks/post-merge

#! /bin/sh -

SELF_DIR=$(git rev-parse --show-toplevel);
DATABASE=$SELF_DIR/.permissions;

printf "Restauration des permissions de fichiers...\n";

OLDIFS=$IFS;
IFS=$'\n';
while read -r LINE || [ -n "$LINE" ];
do
   FILE=$(printf "%s" $LINE | cut -d ";" -f 1);
   PERMISSIONS=$(printf "%s" $LINE | cut -d ";" -f 2);
   USER=$(printf "%s" $LINE | cut -d ";" -f 3);
   GROUP=$(printf "%s" $LINE | cut -d ";" -f 4);

   # Définir les permissions du fichier
   chmod $PERMISSIONS $FILE;

   # Définir le propriétaire et les groupes du fichier
   chown $USER:$GROUP $FILE;

done < $DATABASE
IFS=$OLDIFS

pritnf "OK\n";

exit 0;

Si pour une raison quelconque vous avez besoin de recréer le script, le fichier .permissions doit avoir le format suivant :

.gitignore;644;0;0

Pour un fichier .gitignore avec des autorisations 644 données à root:wheel

Remarquez que j'ai dû apporter quelques modifications aux options stat.

Profitez-en,

1voto

Peter Berbec Points 11

Une autre addition à la réponse de @Omid Ariyan est les permissions sur les répertoires. Ajoutez ceci après la boucle for dans son script pre-commit``done.

for DIR in $(find ./ -mindepth 1 -type d -not -path "./.git" -not -path "./.git/*" | sed 's@^\./@@')
do
    # Enregistrer les permissions de tous les fichiers dans l'index
    echo $DIR";"`stat -c "%a;%U;%G" $DIR` >> $DATABASE
done

Cela sauvegardera également les permissions des répertoires.

0voto

ishigoya Points 159

Une autre option est git-store-meta. Comme l'a décrit l'auteur dans cette réponse de superutilisateur:

git-store-meta est un script perl qui intègre les fonctionnalités intéressantes de git-cache-meta, metastore, setgitperms et mtimestore.

0voto

jsaak Points 29

Version améliorée de https://stackoverflow.com/users/9932792/tammer-saleh réponse :

  1. Il met à jour uniquement les autorisations des fichiers modifiés.
  2. Il gère les liens symboliques
  3. Il ignore les répertoires vides (git ne peut pas les gérer)

.git/hooks/pre-commit:

#!/usr/bin/env bash

echo -n "Sauvegarde des autorisations des fichiers... "
cd "$(git rev-parse --show-toplevel)"
find . -type d ! -empty -printf 'X="%p"; chmod %m "$X"; chown %U:%G "$X"\n' > .permissions
find . -type f -printf 'X="%p"; chmod %m "$X"; chown %U:%G "$X"\n' >> .permissions
find . -type l -printf 'chown -h %U:%G "%p"\n' >> .permissions
git add .permissions
echo fait.

.git/hooks/post-merge:

#!/usr/bin/env bash

echo -n "Restauration des autorisations des fichiers... "
cd "$(git rev-parse --show-toplevel)"
git diff -U0 .permissions | grep '^\+' | grep -Ev '^\+\+\+' | cut -c 2- | /usr/bin/bash
echo "fait."

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X