Nel caso tu stia entrando in questo in questo momento, l'ho appena passato oggi e posso riassumere dove si trova. Se non l'hai ancora provato, alcuni dettagli qui potrebbero aiutarti.
Penso che l'approccio di @Omid Ariyan sia il modo migliore. Aggiungi gli script di pre-commit e post-checkout. NON dimenticare di nominarli esattamente come fa Omid e NON dimenticare di renderli eseguibili. Se dimentichi uno di questi, non hanno effetto e esegui "git commit" più e più volte chiedendoti perché non succede nulla :) Inoltre, se tagli e incolli dal browser web, fai attenzione che le virgolette e le zecche non lo siano alterato.
Se esegui lo script pre-commit una volta (eseguendo un commit git), verrà creato il file .permissions. Puoi aggiungerlo al repository e penso che non sia necessario aggiungerlo più e più volte alla fine dello script di pre-commit. Ma non fa male, penso (spero).
Ci sono alcuni piccoli problemi sul nome della directory e l'esistenza di spazi nei nomi dei file negli script Omid. Gli spazi erano un problema qui e ho avuto qualche problema con la correzione IFS. Per la cronaca, questo script pre-commit ha funzionato correttamente per me:
#!/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"
Ora, cosa ne ricaviamo?
Il file .permissions si trova nel livello superiore del repository git. Ha una riga per file, ecco l'inizio del mio esempio:
$ cat .permissions
.gitignore;660;pauljohn;pauljohn
05.WhatToReport/05.WhatToReport.doc;664;pauljohn;pauljohn
05.WhatToReport/05.WhatToReport.pdf;664;pauljohn;pauljohn
Come puoi vedere, abbiamo
filepath;perms;owner;group
Nei commenti su questo approccio, uno dei poster si lamenta del fatto che funziona solo con lo stesso nome utente, e questo è tecnicamente vero, ma è molto facile risolverlo. Nota che lo script post-checkout ha 2 parti di azione,
# Set the file permissions
chmod $PERMISSIONS $FILE
# Set the file owner and groups
chown $USER:$GROUP $FILE
Quindi tengo solo il primo, è tutto ciò di cui ho bisogno. Il mio nome utente sul server Web è effettivamente diverso, ma soprattutto non puoi eseguire chown a meno che tu non sia root. Può eseguire "chgrp", tuttavia. È abbastanza chiaro come utilizzarlo.
Nella prima risposta in questo post, quella più ampiamente accettata, il suggerimento è quindi di usare git-cache-meta, uno script che sta facendo lo stesso lavoro che stanno facendo gli script pre / post hook qui (analizzare l'output da git ls-files
) . Questi script sono più facili da capire per me, il codice git-cache-meta è piuttosto più elaborato. È possibile mantenere git-cache-meta nel percorso e scrivere script pre-commit e post-checkout che lo utilizzerebbero.
Gli spazi nei nomi dei file sono un problema con entrambi gli script di Omid. Nello script post-checkout, saprai di avere gli spazi nei nomi dei file se vedi errori come questo
$ 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
Sto verificando le soluzioni per questo. Ecco qualcosa che sembra funzionare, ma l'ho testato solo in un caso
#!/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
Poiché le informazioni sui permessi sono una riga alla volta, ho impostato IFS su $, quindi solo le interruzioni di riga vengono viste come cose nuove.
Ho letto che è MOLTO IMPORTANTE riportare la variabile d'ambiente IFS nel modo in cui era! Puoi vedere perché una sessione di shell potrebbe andare male se lasci $ come unico separatore.