DES:SvnWEB
Índice
Introdução
A partir de 22/06/2009, os Sistemas Web da Unioeste encontram-se em um controlador de versão, o SubVersion.
Isso significa que, para editar qualquer código correspondente da pasta /var/www/sistemas (e /var/www/ccm inclusive), não é possível fazê-lo através de acesso direto, somente através do svn.
Para garantir que algumas funcionalidades destes sistemas não sofram degradação ou funcionamento inesperado devido a diferenças entre servidor de produção e desenvolvimento, o serviço de svn foi implantado através da técnica de manter o código após a importação no próprio servidor de produção, ainda que na pasta pessoal do programador, garantindo assim que não haja disparidades relativas a pacotes, ferramentas e outros programas ou métodos de acesso, que possam influenciar negativamente o funcionamento da cópia de desenvolvimento.
Comandos
apache
htpasswd
O SubVersion utiliza um módulo do apache para autenticar-se, via navegador, no repositório.
Para adicionar um usuário para autenticar-se, utilizamos o seguinte comando:
Obs: caso estejamos criando o primeiro usuário, acrescentar a opção -c ao comando, para criar o arquivo.
htpasswd -m <arquivo> <usuário> exemplo: htpasswd -m /etc/svn-auth-file chris
SVN Admin
Novo Repositório
Para criar um novo repositório, é necessário criar a pasta na raiz do svn, setar as permissões corretas, criar os primeiros diretórios e, se necessário, o import inicial.
(como root) svnadmin create /var/svn/<novo repositório> chown -R www-data:www-data /var/svn/<novo repositório> svn mkdir http://localhost/svn/<novo repositório>/trunk \ http://localhost/svn/<novo repositório>/branch \ http://localhost/svn/<novo repositório>/tag \ -m "Layout do Repositório" (opcionalmente) svn import <diretório de origem> http://localhost/svn/<novo repositório>/trunk -m "import inicial"
Para permitir que o deploy dos arquivos sejam feitos na pasta de produção, é necessário adicionar ao arquivo /var/svn/<novo repositório>/hooks/post-commit o seguinte comando:
REPOS="$1" REV="$2" if (! ( svnlook log -r $REV $REPOS | grep "~~NODEPLOY~~" ) ) then /usr/local/bin/svn-deploy.sh $REPOS $REV "/var/www/sistemas/piad" fi #/usr/share/subversion/hook-scripts/commit-email.pl "$REPOS" "$REV" webmaster@unioeste.br
SVN
CheckOut
Para desenvolver através do SubVersion, devemos fazer uma cópia da última versão. Isto implica numa série de comandos, alguns somente uma vez, outros, a cada cópia.
É importante também salientar que usaremos como padrão a divisão trunk do projeto, onde trunk é o ramo principal de desenvolvimento. Qualquer alteração em tag ou branch necessita de comandos específicos, que não serão temas deste tutorial, ao menos por enquanto :)
O comando abaixo monta o diretório pessoal remoto na própria máquina, permitindo assim que usemos comandos como se fossem locais, isto é, como se estivéssemos copiando para a máquina cliente. Ao invés disso, estamos copiando-a no próprio servidor, mas na pasta do usuário.
sshfs 200.201.88.80:/home/<nome do usuário>/public_html <ponto de montagem> -o workaround=rename exemplo: sshfs 200.201.88.80:/home/chris/public_html /home/chris/svn -o workaround=rename
A seguir, entramos no diretório criado e montado e, para copiar os arquivos efetivamente, executamos o seguinte comando:
svn co http://cac-php.unioeste.br/svn/<sistema a ser trabalhado>/trunk <pasta destino> exemplo: svn co http://cac-php.unioeste.br/svn/ccm/trunk /home/chris/svn/ccm
CheckIn
Antes de realizarmos qualquer CheckIn no servidor, é salutar fazermos o update do código, para saber se não há alteração e, se necessário realizarmos o a resolução de conflito entre trechos de código.
Obs: é importante salientar que não é absolutamente necessário o update, assim como também são raras as ocasiões onde uma resolução de conflito se faz necessária, já que o svn é bem "esperto" e consegue resolver a grande maioria das diferenças de código, ainda que no mesmo arquivo (a excessão é a edição de um mesmo arquivo e em um mesmo trecho de código).
svn up http://cac-php.unioeste.br/svn/<sistema a ser comparado>/trunk exemplo: svn up http://cac-php.unioeste.br/svn/ccm/trunk
Para submeter o código trabalhado de volta ao servidor, existem duas opções:
Obs: ambas as opções necessitam que o prompt encontre-se na pasta onde encontra-se o código.
- o código é enviado e é feito um deploy automático
svn ci -m "<log de mudança>" exemplo: cd /home/chris/svn/ccm svn ci -m "alteração da mensagem de saudação"
- o código é enviado sem, no entanto, enviá-lo para o servidor de produção (sem deploy)
- Atenção: a posição no log da expressão ~~NODEPLOY~~ não importa, mas ela deve ser escrita exatamente desta maneira: toda maiúscula e usando os quatro ~, dois antes e dois depois.
svn ci -m "<log de mudança> ~~NODEPLOY~~" exemplo: svn ci -m "alteração de mensagem de saudação ~~NODEPLOY~~"
Merge
O svn merge nos permite juntar "ramos" de nosso código em um terceiro ramo ou em um dos já existente, fazendo a união de um ao outro.
Para realizarmos o merge de ramos, devemos estabelecer qual ramo será a versão final esperada. Por exemplo, trabalhando com um branch e um trunk, onde o branch é desenvolvimento e trunk é o principal, faremos um CheckOut inicial do trunk e depois o svn merge com o branch. Depois basta fazer o merge, sempre tomando CUIDADO para que o ramo destino esperado seja o primeiro parâmetro e o ramo que se juntará a ele, seja o segundo.
Obs: Há um caso especial, quando já estamos trabalhando com um dos ramos, mas é outro que será "commitado". Veja o item svn switch.
svn merge http://cac-php.unioeste.br/svn/<projeto>/<ramo destino> http://cac-php.unioeste.br/svn/<projeto>/<ramo que será unido ao destino> exemplo (juntando um branch com o trunk): svn merge http://cac-php.unioeste.br/svn/sgrf/trunk http://cac-php.unioeste.br/svn/sgrf/branches
undo
Outro uso para o merge é o retorno a uma revisão prévia, quando, por exemplo, algo foi desenvolvido entre duas versões e é necessário voltar àquela funcional.
svn merge -rHEAD:<versão> exemplo (Está na versão 127 e queremos voltar à 123. Nova versão é criada como 128, sendo esta exatamente igual a 123): svn merge -rHEAD:123
Obs: é necessário fazer um "CheckIn" após o processo para estabelecer a nova versão no servidor.
Outros
Existem mais alguns comandos importantes que devem ser conhecidos.
mkdir
Existem duas formas de usar o svn mkdir, que cria diretórios para a estrutura do svn:
- svn mkdir CAMINHO...
- Cada diretório especificado por um CAMINHO de cópia de trabalho é criado localmente e agendado para inclusão ao próximo commit.
- svn mkdir URL...
- Cada diretório especificado por URL é criado no repositório via um commit imediato.
Em ambos os casos, todos os diretórios intermediários devem já existir.
svn add
Se precisarmos adicionar um arquivo a estrutura do svn (a local, nossa cópia de desenvolvimento), copiar ou criar o arquivo no diretório não é o suficiente, precisamos também "informar" à estrutura svn que aquele arquivo foi adicionado. Assim, se copiarmos qualquer arquivo para a pasta local do svn mas não adicioná-lo com svn add, o arquivo não será "commitado" quando dermos o comando de CheckIn, não existindo na estrutura svn do servidor.
Para isso, usamos o comando svn add.
Obs: Para realizarmos a adição do arquivo a estrutura local do svn, precisamos, antes de mais nada, copiar o arquivo em questão para a pasta onde encontra-se o código. Todas estas alterações só terão efeito no servidor quando forem "commitadas", isto é, quando usarmos o comando de CheckIn.
cp <origem> <destino> svn add <destino> exemplo: cp /home/chris/teste/style.css /home/chris/svn/css.css svn add /home/chris/svn/css.css
Infelizmente o ADD do svn não eh recursivo ou seja se você precisa adicionar um número grande de arquivos ai complicou, pra facilitar um pouco a tarefa utilize o seguinte comando.
svn status | grep '^\?'' | sed -e 's/^? *\(.*\)/\1/;s/ /\\ /g' | xargs svn add
Eu sugiro converter isso ai em um script.sh pra nao ter que ficar digitando esse catatal de coisas
svn del
Da mesma forma que precisamos executar svn add para adicionar um arquivo a estrutura svn, também precisamos executar um comando para remover um arquivo da estrutura.
Obs: Assim como o svn add, o svn del manipula a relação do arquivo com a estrutura do svn. Mas, se removermos o arquivo fisicamente da estrutura (usando rm ou mv) sem, no entanto, usar o svn del, esta mudança NÃO se refletirá no servidor após o commit.
svn del <arquivo> exemplo: svn del /home/chris/svn/ccm/css.css
svn switch
Há um comando intermediário necessário, caso nossa cópia de trabalho não seja seu objetivo final, por exemplo, esteja trabalhando com o branch mas queira juntar esse com o trunk. Precisamos fazer primeiro um svn switch.
svn switch http://cac-php.unioeste.br/svn/<projeto>/<ramo destino> exemplo (onde o branch é minha cópia de trabalho, mas será unido ao trunk): svn switch http://cac-php.unioeste.br/svn/sgrf/trunk
Repositórios Externos
A propriedade svn:externals é útil para fazer checkout de diretórios a partir de outros repositórios. Desta forma é possível criar repositórios para partes de softwares comuns e adicioná-lo como referência externa em diversos projetos diferentes.
Após configurar uma propriedade deve-se utilizar os seguintes comandos:
svn ci -m "mensagem" svn update
Isto irá fazer com que a propriedade seja enviada para o controle de versão e depois os diretórios dos repositórios externos sejam obtidos.
É importante lembrar que antes de configurar as propriedades, caso exista um diretório com o mesmo nome do diretório que será obtido do repositório externo, deve-se excluir este diretório do repositório atual.
svn propget
Este comando serve para pegar as propriedades configuradas em um determinado diretório. A sua syntaxe é:
svn propget propriedade diretório
Para pegar a propriedade svn:externals do diretório corrente usa-se o comando:
svn propget svn:externals .
svn propset
Este comando serve para configurar uma propriedade em um determinado diretório. A sua syntaxe é:
svn propset propriedade diretório
Para configurar o diretório atual para conter um diretório que é obtido de um repositório externo utiliza-se o seguinte comando:
svn propset svn:externals 'dir repositório_externo' .
Caso deseje configurar diversos diretórios para serem obtidos de um repositório externo crie um arquivo texto contendo todos os diretórios e referências no seguinte formato:
dir1 repositório_externo1 dir2 repositório_externo2 dir3 repositório_externo3 . . .
Para configurar o diretório para conter as definições informadas neste arquivo deve-se utilizar o seguinte comando:
svn propset svn:externals -F nome_do_arquivo .