Quero controlar a versão do meu servidor web conforme descrito em Controle de versão do meu servidor web , criando um repositório git a partir do meu /var/www directory
. Minha esperança era poder enviar o conteúdo da web de nosso servidor de desenvolvimento para o github, colocá-lo em nosso servidor de produção e passar o resto do dia no pool.
Aparentemente, uma falha em meu plano é que o Git não respeitará as permissões de arquivo (não tentei, só estou lendo sobre isso agora). Acho que isso faz sentido, pois diferentes caixas podem ter configurações de usuário / grupo diferentes. Mas se eu quisesse forçar a propagação de permissões, sabendo que meus servidores estão configurados da mesma forma, tenho alguma opção? Ou existe uma maneira mais fácil de abordar o que estou tentando fazer?
fonte
Respostas:
A
git-cache-meta
mencionada na pergunta do SO " git - como recuperar as permissões do arquivo que o git acha que o arquivo deveria ser? " (E o FAQ do git ) é a abordagem mais direta.A ideia é armazenar em um
.git_cache_meta
arquivo as permissões dos arquivos e diretórios.É um arquivo separado sem versão diretamente no repositório Git.
É por isso que o uso dele é:
Então você:
fonte
git ls-files
.Git é um sistema de controle de versão, criado para o desenvolvimento de software, portanto, de todo o conjunto de modos e permissões, ele armazena apenas bits executáveis (para arquivos comuns) e bits de link simbólico. Se você deseja armazenar permissões completas, você precisa de uma ferramenta de terceiros, como
git-cache-meta
( mencionada por VonC ) ou Metastore (usada por etckeeper ). Ou você pode usar IsiSetup , que IIRC usa git como back-end.Consulte a página Interfaces, frontends e ferramentas no Git Wiki.
fonte
/usr/share/git-core/contrib/hooks/setgitperms.perl
em meugit-contrib
pacote - um script para um propósito semelhante. ("Este script pode ser usado para salvar / restaurar permissões completas e dados de propriedade em uma árvore de trabalho git.")É muito tarde, mas pode ajudar outras pessoas. Eu faço o que você quer, adicionando dois ganchos git ao meu repositório.
.git / hooks / pre-commit:
.git / hooks / post-checkout:
O primeiro gancho é chamado quando você "confirma" e lê a propriedade e as permissões de todos os arquivos no repositório e os armazena em um arquivo na raiz do repositório chamado .permissions e, em seguida, adiciona o arquivo .permissions ao commit.
O segundo gancho é chamado quando você faz "checkout" e percorre a lista de arquivos no arquivo .permissions e restaura a propriedade e as permissões desses arquivos.
fonte
$SELF_DIR/../../
não é necessariamente a raiz do repositório ... masgit rev-parse --show-toplevel
é. (Não sei por que você não usaria apenaspwd
para o diretório atual, mas isso é discutível de qualquer maneira.)IFS=$'\n'
antes dofor
loop para interromper isso (eunset IFS
depois para ser seguro).chmod 0600 .pgpass
empost-checkout
. Sim, terei que atualizá-lo manualmente sempre que tiver um arquivo que precise de permissões específicas, mas isso está quebrado.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:
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:
Como você pode ver, nós temos
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,
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
Estou verificando soluções para isso. Aqui está algo que parece funcionar, mas eu só testei em um caso
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.
fonte
Podemos melhorar as outras respostas alterando o formato do
.permissions
arquivo parachmod
instruções executáveis e fazendo uso do-printf
parâmetro parafind
. Aqui está o.git/hooks/pre-commit
arquivo mais simples :... e aqui está o
.git/hooks/post-checkout
arquivo simplificado :Lembre-se de que outras ferramentas podem já ter configurado esses scripts, portanto, pode ser necessário mesclá-los. Por exemplo, aqui está um
post-checkout
script que também inclui osgit-lfs
comandos:fonte
No pré-commit / post-checkout, uma opção seria usar o utilitário "mtree" (FreeBSD) ou "fmtree" (Ubuntu) que "compara uma hierarquia de arquivo com uma especificação, cria uma especificação para uma hierarquia de arquivo ou modifica um especificação."
O conjunto padrão é flags, gid, link, mode, nlink, size, time, type e uid. Isso pode ser ajustado para a finalidade específica com a chave -k.
fonte
Estou executando o FreeBSD 11.1, o conceito de virtualização freebsd jail torna o sistema operacional ideal. A versão atual do Git que estou usando é 2.15.1, também prefiro executar tudo em scripts de shell. Com isso em mente, modifiquei as sugestões acima da seguinte forma:
git push: .git / hooks / pre-commit
git pull: .git / hooks / post-merge
Se por algum motivo você precisar recriar o script, a saída do arquivo .permissions deve ter o seguinte formato:
Para um arquivo .gitignore com 644 permissões concedidas ao root: wheel
Observe que tive que fazer algumas alterações nas opções de estatísticas.
Aproveitar,
fonte
Uma adição à resposta de @Omid Ariyan são as permissões nos diretórios. Adicione isso após o
for
loopdone
em seupre-commit
script.Isso também salvará as permissões do diretório.
fonte