Caso você esteja entrando nisso agora, acabei de passar por isso hoje e posso resumir onde isso está. Se você ainda não tentou fazer isso, alguns detalhes aqui podem ajudar.
Acho que a abordagem de @Omid Ariyan é a melhor maneira. Adicione os scripts de pré-confirmação e pós-checkout. NÃO se esqueça de nomeá-los exatamente como o Omid faz e NÃO se esqueça de torná-los executáveis. Se você esquecer qualquer um deles, eles não terão efeito e você executará "git commit" repetidamente se perguntando por que nada acontece :) Além disso, se você recortar e colar do navegador da web, tome cuidado para que as aspas e tiques não sejam alterado.
Se você executar o script pre-commit uma vez (executando um git commit), o arquivo .permissions será criado. Você pode adicioná-lo ao repositório e acho que é desnecessário adicioná-lo repetidamente no final do script de pré-confirmação. Mas não dói, eu acho (espero).
Existem alguns pequenos problemas sobre o nome do diretório e a existência de espaços nos nomes dos arquivos nos scripts do Omid. Os espaços eram um problema aqui e eu tive alguns problemas com a correção do IFS. Para registro, este script de pré-confirmação funcionou corretamente para mim:
#!/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"
Agora, o que ganhamos com isso?
O arquivo .permissions está no nível superior do repositório git. Tem uma linha por arquivo, aqui está o topo do meu exemplo:
$ cat .permissions
.gitignore;660;pauljohn;pauljohn
05.WhatToReport/05.WhatToReport.doc;664;pauljohn;pauljohn
05.WhatToReport/05.WhatToReport.pdf;664;pauljohn;pauljohn
Como você pode ver, nós temos
filepath;perms;owner;group
Nos comentários sobre essa abordagem, um dos postadores reclama que só funciona com o mesmo nome de usuário, o que é tecnicamente verdade, mas é muito fácil de corrigir. Observe que o script pós-checkout tem 2 ações,
# Set the file permissions
chmod $PERMISSIONS $FILE
# Set the file owner and groups
chown $USER:$GROUP $FILE
Então, estou ficando apenas com o primeiro, é tudo de que preciso. Meu nome de usuário no servidor Web é realmente diferente, mas o mais importante é que você não pode executar o chown a menos que seja root. Pode executar "chgrp", no entanto. É bastante claro como colocar isso em prática.
Na primeira resposta neste post, a que é mais amplamente aceita, a sugestão é usar git-cache-meta, um script que está fazendo o mesmo trabalho que os scripts de pré / pós-gancho aqui estão fazendo (analisando a saída de git ls-files
) . Esses scripts são mais fáceis de entender, o código git-cache-meta é um pouco mais elaborado. É possível manter git-cache-meta no caminho e escrever scripts de pré-confirmação e pós-checkout que o usariam.
Os espaços nos nomes dos arquivos são um problema com os dois scripts do Omid. No script pós-checkout, você saberá que tem espaços nos nomes de arquivo se vir erros como este
$ 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
Estou verificando soluções para isso. Aqui está algo que parece funcionar, mas eu só testei em um 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
Uma vez que as informações de permissões são uma linha de cada vez, eu defino IFS como $, então apenas as quebras de linha são vistas como coisas novas.
Eu li que é MUITO IMPORTANTE definir a variável de ambiente IFS de volta do jeito que estava! Você pode ver porque uma sessão de shell pode dar errado se você deixar $ como o único separador.