Au cas où vous entreriez dans ce sujet maintenant, je viens de le traverser aujourd'hui et je peux résumer où cela en est. Si vous ne l'avez pas encore essayé, quelques détails ici pourraient vous aider.
Je pense que l'approche de @Omid Ariyan est le meilleur moyen. Ajoutez les scripts de pré-validation et de post-paiement. N'OUBLIEZ PAS de les nommer exactement comme le fait Omid et N'oubliez pas de les rendre exécutables. Si vous oubliez l'un ou l'autre, ils n'ont aucun effet et vous exécutez "git commit" encore et encore en vous demandant pourquoi rien ne se passe :) De plus, si vous coupez et collez hors du navigateur Web, faites attention à ce que les guillemets et les coches ne soient pas modifié.
Si vous exécutez le script de pré-validation une fois (en exécutant un commit git), le fichier .permissions sera créé. Vous pouvez l'ajouter au référentiel et je pense qu'il n'est pas nécessaire de l'ajouter encore et encore à la fin du script de pré-commit. Mais ça ne fait pas mal, je pense (espérer).
Il y a quelques petits problèmes concernant le nom du répertoire et l'existence d'espaces dans les noms de fichiers dans les scripts d'Omid. Les espaces étaient un problème ici et j'ai eu quelques problèmes avec le correctif IFS. Pour mémoire, ce script de pré-commit a fonctionné correctement pour moi:
#!/bin/bash
SELF_DIR=`git rev-parse --show-toplevel`
DATABASE=$SELF_DIR/.permissions
# Clear the permissions database file
> $DATABASE
echo -n "Backing-up file permissions..."
IFSold=$IFS
IFS=$'\n'
for FILE in `git ls-files`
do
# Save the permissions of all the files in the index
echo $FILE";"`stat -c "%a;%U;%G" $FILE` >> $DATABASE
done
IFS=${IFSold}
# Add the permissions database file to the index
git add $DATABASE
echo "OK"
Maintenant, que retirons-nous de cela?
Le fichier .permissions se trouve au niveau supérieur du dépôt git. Il a une ligne par fichier, voici le haut de mon exemple:
$ cat .permissions
.gitignore;660;pauljohn;pauljohn
05.WhatToReport/05.WhatToReport.doc;664;pauljohn;pauljohn
05.WhatToReport/05.WhatToReport.pdf;664;pauljohn;pauljohn
Comme vous pouvez le voir, nous avons
filepath;perms;owner;group
Dans les commentaires sur cette approche, l'une des affiches se plaint que cela ne fonctionne qu'avec le même nom d'utilisateur, et c'est techniquement vrai, mais il est très facile de le réparer. Notez que le script post-paiement comporte 2 actions,
# Set the file permissions
chmod $PERMISSIONS $FILE
# Set the file owner and groups
chown $USER:$GROUP $FILE
Donc je ne garde que le premier, c'est tout ce dont j'ai besoin. Mon nom d'utilisateur sur le serveur Web est en effet différent, mais plus important encore, vous ne pouvez exécuter chown que si vous êtes root. Peut cependant exécuter "chgrp". Il est assez clair comment mettre cela à profit.
Dans la première réponse de cet article, celle qui est la plus largement acceptée, la suggestion est donc d'utiliser git-cache-meta, un script qui fait le même travail que les scripts de pré / post hook ici (analyse de la sortie git ls-files
) . Ces scripts sont plus faciles à comprendre pour moi, le code git-cache-meta est un peu plus élaboré. Il est possible de garder git-cache-meta dans le chemin et d'écrire des scripts pré-commit et post-checkout qui l'utilisent.
Les espaces dans les noms de fichiers posent un problème avec les deux scripts d'Omid. Dans le script post-extraction, vous saurez que vous avez les espaces dans les noms de fichiers si vous voyez des erreurs comme celle-ci
$ git checkout -- upload.sh
Restoring file permissions...chmod: cannot access '04.StartingValuesInLISREL/Open': No such file or directory
chmod: cannot access 'Notebook.onetoc2': No such file or directory
chown: cannot access '04.StartingValuesInLISREL/Open': No such file or directory
chown: cannot access 'Notebook.onetoc2': No such file or directory
Je vérifie les solutions pour cela. Voici quelque chose qui semble fonctionner, mais je n'ai testé que dans un cas
#!/bin/bash
SELF_DIR=`git rev-parse --show-toplevel`
DATABASE=$SELF_DIR/.permissions
echo -n "Restoring file permissions..."
IFSold=${IFS}
IFS=$
while read -r LINE || [[ -n "$LINE" ]];
do
FILE=`echo $LINE | cut -d ";" -f 1`
PERMISSIONS=`echo $LINE | cut -d ";" -f 2`
USER=`echo $LINE | cut -d ";" -f 3`
GROUP=`echo $LINE | cut -d ";" -f 4`
# Set the file permissions
chmod $PERMISSIONS $FILE
# Set the file owner and groups
chown $USER:$GROUP $FILE
done < $DATABASE
IFS=${IFSold}
echo "OK"
exit 0
Étant donné que les informations sur les autorisations sont une ligne à la fois, j'ai défini IFS sur $, donc seuls les sauts de ligne sont considérés comme de nouvelles choses.
J'ai lu qu'il est TRÈS IMPORTANT de remettre la variable d'environnement IFS comme elle était! Vous pouvez voir pourquoi une session shell pourrait mal tourner si vous laissez $ comme seul séparateur.