Instalando e Configurando o Subversion e o WebSVN no Debian Squeeze
No mundo dos softwares open-source, o Concurrent Versions System (CVS) foi a ferramenta escolhida para controle de versão por muitos anos. E com razão. O próprio CVS é um software open-source também, e seu modus operandi não-restritivo e o suporte a operações de rede permitiram que diversos programadores distribuídos geograficamente compartilhassem seus trabalhos. Ele atende à natureza colaborativa do mundo open-source como um todo. O CVS e seu modelo de desenvolvimento semi- caótico se tornou um marco da cultura open-source.
Mas o CVS também tinha seus defeitos, e simplesmente corrigir estes defeitos prometia ser um enorme esforço. Chega o Subversion. Desenvolvido para ser um sucessor do CVS, os criadores do Subversion pretendiam ganhar a simpatia dos usuários CVS de duas maneiras—criando um sistema open-source com o projeto (e a “aparência”) semelhante ao do CVS, e tentando evitar muitos de seus conhecidos defeitos. Por mais que o resultado não seja necessariamente a próxima grande evolução no projeto de controle de versão, o Subversion é muito poderoso, muito usável, e muito flexível. E agora muitos projetos open-source, quase todos recém-iniciados, preferem agora o Subversion ao CVS.
Prepare o seu sistema com o seguinte script http://wiki.douglasqsantos.com.br/doku.php/confinicialsqueeze_en para que não falte nenhum pacote ou configuração.
Vamos instalar os pacotes necessários
aptitude install subversion libapache2-svn apache2 -y
Agora vamos criar o diretório home do svn
mkdir -p /home/svn
Agora vamos criar o primeiro projeto do svn
svnadmin create /home/svn/ShellScript --fs-type fsfs
Vamos acertar as permissões do diretório do svn
chown -R www-data:www-data /home/svn
Vamos carregar os módulos necessários para um bom funcionamento do SVN com o Apache
a2enmod ssl a2enmod dav a2enmod dav_svn a2enmod authz_svn
Agora vamos criar um virtual host para o nosso Subversion
vim /etc/apache2/sites-available/svn <VirtualHost *:80> ServerName svn.douglasqsantos.com.br Redirect / https://svn.douglasqsantos.com.br/ </VirtualHost> <VirtualHost *:443> ServerAdmin admin@douglasqsantos.com.br ServerName svn.douglasqsantos.com.br <Location /svn> DAV svn SVNParentPath /home/svn AuthType Basic AuthName "Subversion Repository" AuthUserFile /home/svn/passwd SVNListParentPath on AuthzSVNAccessFile /home/svn/authz Require valid-user SSLRequireSSL </Location> ErrorLog ${APACHE_LOG_DIR}/error_ssl.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined ServerSignature Off SSLEngine On SSLCertificateFile /etc/apache2/ssl/apache.pem SSLCertificateKeyFile /etc/apache2/ssl/apache.key </VirtualHost>
Para não precisar utilizar o dns para resolver o virtual host vamos acertar o /etc/hosts no cliente
vim /etc/hosts 127.0.0.1 localhost 127.0.1.1 douglas 10.0.0.22 svn.douglasqsantos.com.br svn
Agora vamos fazer um teste para verificarmos se estamos chegando no servidor pelo cliente
ping svn.douglasqsantos.com.br -c 3 PING svn.douglasqsantos.com.br (10.0.0.22) 56(84) bytes of data. 64 bytes from svn.douglasqsantos.com.br (10.0.0.22): icmp_req=1 ttl=64 time=0.292 ms 64 bytes from svn.douglasqsantos.com.br (10.0.0.22): icmp_req=2 ttl=64 time=0.345 ms 64 bytes from svn.douglasqsantos.com.br (10.0.0.22): icmp_req=3 ttl=64 time=0.314 ms --- svn.douglasqsantos.com.br ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 1998ms rtt min/avg/max/mdev = 0.292/0.317/0.345/0.021 ms
Vamos agora acertar as chaves para a conexão via https
Vamos criar o diretório para armazenar as chaves e vamos acessá-lo
mkdir /etc/apache2/ssl cd /etc/apache2/ssl
Agora vamos gerar as chaves
openssl req -new -x509 -days 365 -nodes -out apache.pem -keyout apache.key Generating a 1024 bit RSA private key ..............++++++ ...........................................++++++ writing new private key to 'apache.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:BR State or Province Name (full name) [Some-State]:Parana Locality Name (eg, city) []:Curitiba Organization Name (eg, company) [Internet Widgits Pty Ltd]:Douglas Organizational Unit Name (eg, section) []:Douglas Common Name (eg, YOUR name) []:Douglas Email Address []:douglas@douglasqsantos.com.br
Agora vamos criar um usuário para poder acessar os nossos projetos no Subversion com o htpasswd
htpasswd -cm /home/svn/passwd douglas New password: #senha Re-type new password: #senha Adding password for user douglas
Agora vamos acertar as permissões do Subversion para podermos acessar os nossos projetos
vim /home/svn/authz [ShellScript:/] douglas = rw
Aqui estou especificando que o usuário douglas vai ter acesso de leitura e escrita no projeto ShellScript porém poderíamos ter douglas = r o usuário douglas teria somente acesso de leitura ou ainda douglas = aqui o usuário não teria acesso algum no projeto ShellScript
Agora vamos carregar o nosso virtual host e desabilitar os hosts default e default-ssl
a2ensite svn a2dissite default a2dissite default-ssl
Agora vamos reiniciar o apache
/etc/init.d/apache2 restart
Para um teste simples acesse https://svn.douglasqsantos.com.br/svn/ShellScript/ vamos ter uma página com o seguinte conteúdo
ShellScript - Revision 0: /
Agora vamos instlar o WebSVN e suas dependências
aptitude install websvn -y
Responda as perguntas da seguinte forma
- Sim
- Deixe somente marcado apache2
- /home/svn
- /home/svn/ShellScript
Agora vamos fazer alguns acertos no WebSVN
Deixe o arquivo como abaixo
vim /etc/websvn/apache.conf # Configuration for websvn using php4. Alias /websvn /usr/share/websvn <Directory /usr/share/websvn> DirectoryIndex index.php Options FollowSymLinks Order allow,deny Allow from all AuthType Basic AuthName "Subversion Repository" AuthUserFile /home/svn/passwd Require valid-user <IfModule mod_php4.c> php_flag magic_quotes_gpc Off php_flag track_vars On </IfModule> </Directory>
Agora vamos acertar o WebSVN para efetuar a autenticação
vim /etc/websvn/config.php [...] // $config->useAuthenticationFile('/path/to/accessfile'); Global access file $config->useAuthenticationFile('/home/svn/authz');
Vamos fazer um ultimo acerto deixe o arquivo como abaixo.
vim /etc/websvn/svn_deb_conf.inc <?php // please edit /etc/websvn/config.php // or use dpkg-reconfigure websvn $config->parentPath("/home/svn/"); //$config->addRepository("repos 1", "file:/home/svn/ShellScript"); $config->setEnscriptPath("/usr/bin"); $config->setSedPath("/bin"); $config->useEnscript(); ?>
Agora vamos reiniciar o nosso apache
/etc/init.d/apache2 restart
Agora podemos testar em https://svn.douglasqsantos.com.br/websvn
Agora vamos criar mais um projeto para teste
Vamos no servidor criar um novo projeto
svnadmin create /home/svn/douglas --fs-type fsfs
Vamos acertar as permissões do nosso projeto
chown www-data:www-data -R /home/svn/douglas
Vamos acertar as permissões do acesso aos repositórios
vim /home/svn/authz [ShellScript:/] douglas = rw [douglas:/] douglas = rw
Agora vamos instalar em um cliente o Subversion para testar
aptitude install subversion subversion-tools -y
Agora vamos criar a estrutura de diretórios para os nossos projetos
mkdir -p /home/douglas/ShellScript/{trunk,tags,branches} mkdir -p /home/douglas/douglas/{trunk,tags,branches}
Agora vamos fazer um teste de importação de projeto
svn import /home/douglas/douglas https://svn.douglasqsantos.com.br/svn/douglas -m 'Importando o projeto inicial' Erro validando o certificado de servidor para 'https://svn.douglasqsantos.com.br:443': - O certificado não foi emitido por uma autoridade confiável. Use sua impressão digital para validar o certificado manualmente - O nome do servidor do certificado não bate. Informações do certificado: - Nome do servidor: Douglas - Validade: de Tue, 11 Oct 2011 18:02:28 GMT até Wed, 10 Oct 2012 18:02:28 GMT - Emissor: Douglas, Douglas , Curitiba, Parana, BR - Impressão digital: a7:47:2d:63:ae:ec:e3:28:1f:e7:0d:53:62:00:15:fe:0b:c9:26:2c (R)ejeitar, aceitar (t)emporariamente ou aceitar (p)permanente? p Área de autenticação: <https://svn.douglasqsantos.com.br:443> Subversion Repository Senha para 'root': #ENTER Área de autenticação: <https://svn.douglasqsantos.com.br:443> Subversion Repository Usuário: douglas Senha para 'douglas': Adicionando /home/douglas/douglas/trunk Adicionando /home/douglas/douglas/branches Adicionando /home/douglas/douglas/tags ----------------------------------------------------------------------- ATTENTION Your password for authentication realm: <https://svn.douglasqsantos.com.br:443> Subversion Repository can only be stored to disk unencrypted You are advised to configure your system so that Subversion can store passwords encrypted, if possible. See the documentation for details. You can avoid future appearances of this warning by setting the value of the 'store-plaintext-passwords' option to either 'yes' or 'no' in '/root/.subversion/servers'. ----------------------------------------------------------------------- Store password unencrypted (yes/no)? no Commit da revisão 1.
Agora vamos listar o nosso projeto no servidor
svn list https://svn.douglasqsantos.com.br/svn/douglas Área de autenticação: <https://svn.douglasqsantos.com.br:443> Subversion Repository Senha para 'douglas': ----------------------------------------------------------------------- ATTENTION Your password for authentication realm: <https://svn.douglasqsantos.com.br:443> Subversion Repository can only be stored to disk unencrypted You are advised to configure your system so that Subversion can store passwords encrypted, if possible. See the documentation for details. You can avoid future appearances of this warning by setting the value of the 'store-plaintext-passwords' option to either 'yes' or 'no' in '/root/.subversion/servers'. ----------------------------------------------------------------------- Store password unencrypted (yes/no)? no branches/ tags/ trunk/
Agora vamos voltar para o WebSVN para dar uma olhada em nosso projetos acesse https://svn.douglasqsantos.com.br/websvn
Agora selecione o projeto douglas, como pode ser notado temos a estrutura que importamos para o svn
Agora vamos efetuar algumas modificações
Primeiro temos que fazer um checkout do repositório no cliente
Vamos criar os diretórios para efetuar o checkout
mkdir /home/douglas/projeto1 cd /home/douglas/projeto1
Vamos fazer o checkout
svn co https://svn.douglasqsantos.com.br/svn/douglas Área de autenticação: <https://svn.douglasqsantos.com.br:443> Subversion Repository Senha para 'douglas': ----------------------------------------------------------------------- ATTENTION Your password for authentication realm: <https://svn.douglasqsantos.com.br:443> Subversion Repository can only be stored to disk unencrypted You are advised to configure your system so that Subversion can store passwords encrypted, if possible. See the documentation for details. You can avoid future appearances of this warning by setting the value of the 'store-plaintext-passwords' option to either 'yes' or 'no' in '/root/.subversion/servers'. ----------------------------------------------------------------------- Store password unencrypted (yes/no)? no A douglas/trunk A douglas/branches A douglas/tags Gerado cópia de trabalho para revisão 1.
Agora que já temos o checkout vamos fazer modificações no projeto
cd /home/douglas/projeto1/douglas/trunk
Agora vamos copiar alguns arquivos para o projeto para testarmos o SVN
cp -Rf /etc/network .
Vamos verificar o status do SVN
svn status ? network
Como pode ser notado o network está sem atributo então temos que marcar ele para ser atualizado no repositório
Agora vamos marcar o network para ser atualizado no repositório
svn add network A network A network/if-down.d A network/if-down.d/wpasupplicant A network/if-down.d/avahi-autoipd A network/if-down.d/upstart A network/if-down.d/postfix A network/if-pre-up.d A network/if-pre-up.d/wpasupplicant A network/if-pre-up.d/wireless-tools A network/if-post-down.d A network/if-post-down.d/wpasupplicant A network/if-post-down.d/wireless-tools A network/if-post-down.d/avahi-daemon A network/if-up.d A network/if-up.d/wpasupplicant A network/if-up.d/openssh-server A network/if-up.d/avahi-autoipd A network/if-up.d/upstart A network/if-up.d/ntpdate A network/if-up.d/postfix A network/if-up.d/avahi-daemon A network/interfaces
Vamos listar agora o status dos novos arquivos novamente
svn status A network A network/if-up.d A network/if-up.d/ntpdate A network/if-up.d/upstart A network/if-up.d/openssh-server A network/if-up.d/avahi-daemon A network/if-up.d/wpasupplicant A network/if-up.d/avahi-autoipd A network/if-up.d/postfix A network/interfaces A network/if-down.d A network/if-down.d/upstart A network/if-down.d/wpasupplicant A network/if-down.d/avahi-autoipd A network/if-down.d/postfix A network/if-pre-up.d A network/if-pre-up.d/wpasupplicant A network/if-pre-up.d/wireless-tools A network/if-post-down.d A network/if-post-down.d/avahi-daemon A network/if-post-down.d/wpasupplicant A network/if-post-down.d/wireless-tools
Como podemo ser notado temos o atributo A agora
- A item: O arquivo, diretório, ou link simbólico item está agendado para ser adicionado ao repositório.
- C item: O arquivo item está em um estado de conflito. Isto é, as modificações recebidas do servidor durante um update se sobrepõem às alterações locais feitas por você em sua cópia de trabalho. Você deve resolver este conflito antes de submeter suas alterações ao repositório.
- D item: O arquivo, diretório, ou link simbólico item está agendado para ser excluído do repositório.
- M item: O conteúdo do arquivo item foi modificado.
Agora vamos fazer o update do nosso repositório
svn commit -m 'Adicionado o diretorio network' Adicionando trunk/network Adicionando trunk/network/if-down.d Adicionando trunk/network/if-down.d/avahi-autoipd Adicionando trunk/network/if-down.d/postfix Adicionando trunk/network/if-down.d/upstart Adicionando trunk/network/if-down.d/wpasupplicant Adicionando trunk/network/if-post-down.d Adicionando trunk/network/if-post-down.d/avahi-daemon Adicionando trunk/network/if-post-down.d/wireless-tools Adicionando trunk/network/if-post-down.d/wpasupplicant Adicionando trunk/network/if-pre-up.d Adicionando trunk/network/if-pre-up.d/wireless-tools Adicionando trunk/network/if-pre-up.d/wpasupplicant Adicionando trunk/network/if-up.d Adicionando trunk/network/if-up.d/avahi-autoipd Adicionando trunk/network/if-up.d/avahi-daemon Adicionando trunk/network/if-up.d/ntpdate Adicionando trunk/network/if-up.d/openssh-server Adicionando trunk/network/if-up.d/postfix Adicionando trunk/network/if-up.d/upstart Adicionando trunk/network/if-up.d/wpasupplicant Adicionando trunk/network/interfaces Transmitindo dados do arquivo ................. Commit da revisão 2.
Vamos agora em https://svn.douglasqsantos.com.br/websvn para analisarmos o nosso repositório
Selecione douglas agora já notamos que estamos na revisão 2, agora navegue pelo seu projeto para analisar
Agora vamos deletar o diretório network do repositório pois ele não deve estar no repositório, no cliente
svn delete network/ D network/if-up.d/ntpdate D network/if-up.d/upstart D network/if-up.d/openssh-server D network/if-up.d/avahi-daemon D network/if-up.d/wpasupplicant D network/if-up.d/avahi-autoipd D network/if-up.d/postfix D network/if-up.d D network/interfaces D network/if-down.d/upstart D network/if-down.d/wpasupplicant D network/if-down.d/avahi-autoipd D network/if-down.d/postfix D network/if-down.d D network/if-pre-up.d/wpasupplicant D network/if-pre-up.d/wireless-tools D network/if-pre-up.d D network/if-post-down.d/avahi-daemon D network/if-post-down.d/wpasupplicant D network/if-post-down.d/wireless-tools D network/if-post-down.d D network
Como eu já estou no diretório /home/douglas/projeto1/douglas/trunk preciso somente passar o nome do diretório que quero remover caso contrário tem que passar a PATH do diretório a remover
Agora vamos atualizar no repositório
svn commit -m 'Removendo o diretorio network' Apagando trunk/network Commit da revisão 3.
Agora novamente no WebSVN verefique se o seu diretório network foi apagado do repositório
Agora vamos fazer um teste de modificação
vim /home/douglas/projeto1/douglas/trunk/ola.sh #!/bin/bash echo "Ola"
Agora vamos subir este arquivo para o repositório
Primeiro temos que marcar ele para ser atualizado
svn add ola.sh A ola.sh
Agora vamos mandar atualizar ele no repositório
svn commit -m 'Teste de modificacao' Adicionando trunk/ola.sh Transmitindo dados do arquivo . Commit da revisão 4.
Agora acesse novamente https://svn.douglasqsantos.com.br/websvn para verificar se o arquivo se encontra lá
Agora vamos efetuar uma modificação no arquivo
vim /home/douglas/projeto1/douglas/trunk/ola.sh #!/bin/bash #script para gerar um looping infinito while true; do echo "Ola"; done
Agora vamos verificar o atributo do arquivo
svn status M ola.sh
Agora vamos atualizar o arquivo
svn commit -m 'Teste de modificação' Enviando trunk/ola.sh Transmitindo dados do arquivo . Commit da revisão 5.
Agora vamos verificar a diferença dos arquivos em https://svn.douglasqsantos.com.br/websvn
Em douglas/trunk/ola.sh agora selecione Diferenças com a anterior
Agora vamos poder acompanhar a diferença entre as versões dos arquivos
Agora vamos modificar mais uma vez o arquivo para fazer um teste de diferença de arquivos
vim /home/douglas/projeto1/douglas/trunk/ola.sh #!/bin/bash #script para gerar um looping infinito while true; do echo "$(ls -lhaiR /)"; done
Agora vamos verificar a diferença do arquivo atual com o da ultima versão
svn diff /home/douglas/projeto1/douglas/trunk/ola.sh Index: /home/douglas/projeto1/douglas/trunk/ola.sh ====================================================================================================================================================================== --- /home/douglas/projeto1/douglas/trunk/ola.sh (revisão 5) +++ /home/douglas/projeto1/douglas/trunk/ola.sh (cópia de trabalho) @@ -3,5 +3,5 @@ while true; do -echo "Ola"; +echo "$(ls -lhaiR /)"; done
Como pode ser notado ele nos mostra todas as diferenças dos arquivos muito útil para a geração de patchs, vamos gerar um patch para teste
svn diff ola.sh > ola.patch
Vamos analisar agora o nosso patch
cat ola.patch Index: ola.sh ====================================================================================================================================================================== --- ola.sh (revisão 5) +++ ola.sh (cópia de trabalho) @@ -3,5 +3,5 @@ while true; do -echo "Ola"; +echo "$(ls -lhaiR /)"; done
Agora vamos fazer um chekcout em outro diretório para utilizar o patch
mkdir -p /tmp/douglas cd /tmp/douglas svn co https://svn.douglasqsantos.com.br/svn/douglas A douglas/trunk A douglas/trunk/ola.sh A douglas/branches A douglas/tags Gerado cópia de trabalho para revisão 5.
Vamos verificar o arquivo ola.sh
cat /tmp/douglas/douglas/trunk/ola.sh #!/bin/bash #script para gerar um looping infinito while true; do echo "Ola"; done
Como pode ser notado temos o arquivo sem as modificações que fizemos vamos aplicar o patch que obtemos com svn diff e vamos aplicar neste arquivo
cd /tmp/douglas/douglas/trunk cp /home/douglas/projeto1/douglas/trunk/ola.patch .
Agora vamos aplicar o patch
patch -p1 ola.sh ola.patch patching file ola.sh
Agora vamos confirmar a nossa alteração
cat ola.sh #!/bin/bash #script para gerar um looping infinito while true; do echo "$(ls -lhaiR /)"; done
Pronto temos o nosso arquivo modificado
Agora vamos verificar o status do nosso arquivo
cd /tmp/douglas/douglas/trunk/ svn status ola.sh M ola.sh
Agora eu quero reverter essa modificação, podemos efetuar da seguinte forma
svn revert ola.sh Revertido 'ola.sh'
Vamos verificar o nosso arquivo
cat ola.sh #!/bin/bash #script para gerar um looping infinito while true; do echo "Ola"; done
Como pode ser notado o nosso arquivo esta da mesma forma que no repositório
Para atualizar o repositório no cliente caso tenha sido feita alguma alteração no repositório podemos efetuar com o seguinte comando
svn update Na revisão 5.
Vamos verificar os logs do nosso projeto
svn log ------------------------------------------------------------------------ r5 | douglas | 2011-10-11 16:20:33 -0300 (Ter, 11 Out 2011) | 1 linha Teste de modificação ------------------------------------------------------------------------ r4 | douglas | 2011-10-11 16:14:23 -0300 (Ter, 11 Out 2011) | 1 linha Teste de modificacao ------------------------------------------------------------------------ r3 | douglas | 2011-10-11 16:09:42 -0300 (Ter, 11 Out 2011) | 1 linha Removendo o diretorio network ------------------------------------------------------------------------ r2 | douglas | 2011-10-11 16:05:33 -0300 (Ter, 11 Out 2011) | 1 linha Adicionado o diretorio network ------------------------------------------------------------------------ r1 | douglas | 2011-10-11 15:47:26 -0300 (Ter, 11 Out 2011) | 1 linha Importando o projeto inicial ------------------------------------------------------------------------
Agora se eu precisar saber somente os logs de uma determinada revisão por exemplo a 5 podemos consultar da seguinte forma
svn log -r 5 ------------------------------------------------------------------------ r5 | douglas | 2011-10-11 16:20:33 -0300 (Ter, 11 Out 2011) | 1 linha Teste de modificação ------------------------------------------------------------------------
Se quisermos de uma forma mais detalhada podemos utilizar da seguinte forma
svn log -r 5 -v ------------------------------------------------------------------------ r5 | douglas | 2011-10-11 16:20:33 -0300 (Ter, 11 Out 2011) | 1 linha Caminhos mudados: M /trunk/ola.sh Teste de modificação ------------------------------------------------------------------------
Agora vamos verificar como obtermos a diferença entre a versões de arquivos passando uma determinada revisão
svn diff -r 4 ola.sh Index: ola.sh ====================================================================================================================================================================== --- ola.sh (revisão 4) +++ ola.sh (cópia de trabalho) @@ -1,3 +1,7 @@ #!/bin/bash +#script para gerar um looping infinito -echo "Ola" +while true; +do +echo "Ola"; +done
Agora vamos comparar repositório com repositório, vamos comparar a versão 4 com a 5 do repositório.
svn diff -r 4:5 ola.sh Index: ola.sh ====================================================================================================================================================================== --- ola.sh (revisão 4) +++ ola.sh (revisão 5) @@ -1,3 +1,7 @@ #!/bin/bash +#script para gerar um looping infinito -echo "Ola" +while true; +do +echo "Ola"; +done
Vamos efetuar a visualização de uma versão de um arquivo no repositório sem comparar com outro arquivo, aqui eu vou visualizar a versão 4 de um arquivo
svn cat -r 4 ola.sh #!/bin/bash echo "Ola"
Listando o conteúdo de um repositório
svn list https://svn.douglasqsantos.com.br/svn/douglas branches/ tags/ trunk/
Vamos ver como obtemos uma versão do repositório de versões anteriores a que estamos, vamos fazer um checkout da versão 4 do nosso repositório
mkdir -p /tmp/v4 && cd /tmp/v4 svn checkout -r 4 https://svn.douglasqsantos.com.br/svn/douglas A douglas/trunk A douglas/trunk/ola.sh A douglas/branches A douglas/tags Gerado cópia de trabalho para revisão 4.
Agora vamos verificar como exportamos o nosso projeto finalizado sem precisar exportar os diretório .svn
svn export https://svn.douglasqsantos.com.br/svn/douglas -r 4 A douglas A douglas/trunk A douglas/trunk/ola.sh A douglas/branches A douglas/tags Exportada revisão 4.
Aqui eu passei a revisão 4 porém se eu não especificar a revisão ele vai pegar a última
Caso tenha alguma pane no sistema ou alguma pane na rede no momento da transmissão dos arquivos o Subversion pode travar os arquivos, com isso o arquivo fica com o status L de lock para voltar o arquivo ao normal temos que executar
svn cleanup
Após isso o seu arquivo volta ao normal
OBS: Em particular, cada diretório em sua cópia local contém um subdiretório chamado .svn, também conhecido como o diretório administrativo da cópia de local. Os arquivos em cada diretório administrativo ajudam o Subversion a reconhecer quais arquivos possuem alterações não-publicadas, e quais estão desatualizados em relação ao trabalho dos outros.