<sect id="s-cvs-p">Criando projetos para serem usados no CVS
 <p>
Esta seção descreve todos os passos necessários para colocação de 
um projeto para ser desenvolvido através do CVS, os comandos do 
cvs, considerações a respeito dos comandos e sua utilização através 
de exemplos didáticos. 


<sect1 id="s-cvs-p-repos">Repositório
 <p>
Um repositório CVS é o local que armazena módulos e também os 
arquivos administrativos (que contém permissões, etc) são armazenados em 
um subdiretório chamado <file>CVSROOT</file>.
 <p>
O acesso a um repositório é feito através de parâmetros especificados na
variável <var>CVSROOT</var> ou pela opção <em>-d repositório</em> do 
cvs. Veja <ref id="s-cvs-d"> para ver exemplos de métodos de acesso. 
 <p>
O Repositório pode conter um ou mais módulos, cada módulo representa um 
projeto no servidor, criado após o uso do comando <tt>import</tt>. Segue 
um exemplo da estrutura de um repositório CVS:
<example>
var/lib
     |
     +- cvs
         |- CVSROOT
         |- projeto1
         +- projeto2

</example>
O subdiretório <file>cvs</file> é o repositório (veja o subdiretório 
<file>CVSROOT</file> dentro dele) e os diretórios dentro dele 
<file>projeto1</file> e <file>projeto2</file> são os módulos criados 
através do comando <tt>cvs import ...</tt>(veja <ref id="s-cvs-p-import">).
 <p>
Para acessar o projeto do CVS, então é definido o repositório que tem permissões de 
acesso na variável <tt>CVSROOT</tt> e então é executado um comando (checkout, 
update, commit, etc) no módulo que desejamos utilizar:
<example>
export CVSROOT=:ext:anonymous@servidor.org.br:/var/lib/cvs (&lt;- Repositório "cvs")
cvs checkout projeto1 (&lt;- módulo que desejamos pegar do servidor)

</example>
Nas seções seguintes serão explicados cada um dos comandos usados para trabalhar com 
um projeto no <prgn>cvs</prgn>.


<sect1 id="s-cvs-p-mkrepos">Criando um repositório
 <p>
Para adicionar um novo repositório no sistema, edite o 
arquivo <file>/etc/cvs-pserver.conf</file> e defina o nome 
de cada repositório na variável <var>CVS_PSERV_REPOS</var> 
separados por ":" (exemplo: <tt>CVS_PSERV_REPOS="/var/lib/cvs:/var/lib/cvs2"</tt>).
 <p>
Feito isso execute o comando <prgn>cvs-makerepos</prgn> para 
que os diretórios especificados no arquivo 
<file>/etc/cvs-pserver.conf</file> sejam criados com as 
devidas permissões. 
 <p>
Para adicionar manualmente um repositório (/var/lib/cvs), execute os 
seguintes passos:
<enumlist compact>
 <item>Execute o comando <tt>cvs -d /var/lib/cvs init</tt> (para criar 
  o repositório e os arquivos administrativos que ficam armazenados 
  dentro de <file>CVSROOT</file>.
 <item>Mude as permissões do diretório para sgid com: <tt>chmod 2775 
  /var/lib/cvs</tt>.
 <item>Mude o dono/grupo com o comando: <tt>chown root.src /var/lib/cvs</tt>
 <item>Opcional: caso utilize o método de acesso <em>pserver</em> será 
  necessário adicionar a opção <tt>--allow-root=/var/lib/cvs</tt> na 
  linha que inicia o servidor pserver. Este parâmetro deve ser usada 
 para cada repositório adicionado no servidor.
</enumlist>
A partir de agora, seu repositório já está pronto para ser utilizado.


<sect1 id="s-cvs-p-login">Logando no servidor de CVS via pserver
 <p>
Quando é usado o método de acesso pserver (<ref id="s-cvs-d-metodos-pserver">), 
é necessário fazer para ter acesso ao repositório. Por exemplo, 
para acessar o repositório <file>/var/lib/cvs</file> no servidor <file>servidor.org.br</file>:
<example>
export CVSROOT=:pserver:anonymous@servidor.org.br:/var/lib/cvs
cvs login

ou 

cvs -d :pserver:anonymous@servidor.org.br:/var/lib/cvs login

</example>
Então será solicitada a senha para ter acesso ao sistema. Note que 
toda a seção de <prgn>cvs</prgn> ocorre por comandos interativos que 
logo após concluídos retornam para o interpretador de comandos. 
O restante desta seção descreverá estes comandos e como utiliza-los de 
maneira eficiente. 
<![ %OBS [ 
 <p>
<strong>OBS: </strong> O uso da variável <var>CVSROOT</var> torna 
a utilização bastante prática, assim não precisamos especificar o repositório, 
método de acesso, etc. toda vez que usar um comando do <prgn>cvs</prgn>. 
]]>


<sect1 id="s-cvs-p-logout">Encerrando uma seção de CVS
 <p>
Embora que não seja necessário, após o uso do cvs é recomendável 
executar o logout do servidor para encerrar sua conexão com a máquina 
remota. 
<example>
# (assumindo que a variável CVSROOT está definida)
cvs logout

ou 

cvs -d :pserver:anonymous@servidor.org.br:/var/lib/cvs logout

</example>
<![ %OBS [ 
 <p>
<strong>OBS: </strong> Para os paranóicos é importante encerrar uma seção
de CVS, pois ele possui alguns bugs e um spoofing pode tornar possível o 
uso de uma seção deixada aberta. 
]]>


<sect1 id="s-cvs-p-checkout">Baixando arquivos
 <p>
O comando <tt>checkout</tt> (ou "co") é usado para fazer isto. Para 
utilizá-lo seguindo os exemplos anteriores:
<example>
mkdir /tmp/cvs
cd /tmp/cvs
cvs checkout modulo
cvs -d :pserver:anonymous@servidor.org.br:/var/lib/cvs

</example>
Será criado um subdiretório chamado <file>modulo</file> que contém todos os 
arquivos do servidor de CVS remoto. É necessário apenas que tenha acesso de 
leitura ao servidor de CVS para executar este comando. Você pode usar a 
opção <tt>-z [num]</tt> para ativar a compactação na transferência dos arquivos, 
isso acelera bastante a transferência em conexões lentas: 
<tt>cvs -z 3 checkout modulo</tt>. 
 <p>
Também é possível especificar apenas subdiretórios de um módulo para baixa-lo
via CVS e a estrutura de diretórios criada localmente será idêntica ao do 
servidor remoto. 


<sect1 id="s-cvs-p-import">Adicionando um novo projeto
 <p>
Use o comando <tt>cvs import</tt> para adicionar um novo projeto ao CVS. 
As entradas nos arquivos administrativos serão criadas e o projeto 
estará disponível para utilização dos usuários. A sintaxe básica do 
comando <tt>import</tt> é a seguinte:
 <p>
<tt>cvs import [<em>opções</em>] [<em>dir_modulo</em>] [<em>tag</em>] start</tt>
 <p>
Para adicionar o projeto <tt>focalinux</tt> que reside em <file>/usr/src/focalinux</file> 
ao cvs:
<example>
# Primeiro exportamos o CVSROOT para dizer onde e qual repositório acessar
export CVSROOT=:ext:usuario@servidor.com.br:2401/var/lib/cvs

cd /usr/src/focalinux
cvs import documentos/focalinux tag_modulo start

</example>
Por padrão o <prgn>import</prgn> sempre utiliza a máscara
<em>*</em> para fazer a importação dos arquivos do diretório 
atual. O projeto <tt>focalinux</tt> será acessado 
através de $CVSROOT/documentos/focalinux (<tt>cvs checkout
documentos/focalinux</tt>), ou seja, <file>/var/lib/cvs/documentos/focalinux</file>
no servidor CVS terá a cópia do focalinux. <tt>tag_modulo</tt> 
define o nome que será usado como identificador nas operações com os 
arquivos do CVS (pode ser usado "focalinux" em nosso exemplo). 
O parâmetro "start" diz para criar o módulo.

<![ %OBS [
 <p>
<strong>OBS: </strong> Por segurança, o diretório que contém os 
arquivos deverá ser sempre um caminho relativo na estrutura de 
diretórios, ou seja, você precisará entrar no diretório pai 
(como <file>/usr/src/projeto</file>) para executar o <tt>cvs import</tt>. 
Não é permitido usar <tt>/</tt> ou <tt>..</tt>, isto proíbe a 
descida em diretórios de nível mais altos e sérios incidentes 
de segurança em servidores CVS mal configurados pelo 
Administrador. ]]>


<sect1 id="s-cvs-p-update">Sincronizando a cópia remota com a cópia local
 <p>
Este comando sincroniza a cópia remota do CVS (ou arquivo) com a cópia local 
que está trabalhando em sua máquina. 
Quando se trabalha nativamente no CVS em equipe é recomendado a utilização deste 
comando pois alguém pode ter modificado o arquivo antes de você, então uma 
incompatibilidade entre sua versão e a nova poderia causar problemas.
 <p>
Supondo que tenha acabado de modificar o arquivo <file>main.c</file> do módulo
<file>cvsproj</file>, então antes de fazer o commit (<ref id="s-cvs-p-commit">) 
use o update:
<example>
cvs update main.c

ou 

cvs -d :ext:usuario@servidor.com.br:2401/var/lib/cvs update main.c

</example>
Após alguns segundos, sua cópia local ficará sincronizada com a cópia remota. 
Caso ele mostre alguma mensagem de saída, verifique o arquivo para solucionar 
qualquer conflito e então envie o arquivo para o servidor remoto 
(<ref id="s-cvs-p-commit">).
 <p>
Você pode fazer o update de mais arquivos usando referências globais 
(<tt>*</tt>, <tt>?</tt> ou <tt>[]</tt>).


<sect1 id="s-cvs-p-commit">Enviando as mudanças para o servidor remoto
 <p>
O comando "commit" (ou "ci"), envia as mudanças feitas nos arquivos locais
para o servidor remoto. Um exemplo de commit no arquivo <file>main.c</file>:
<example>
cvs commit main.c

cvs commit main.?

cvs commit *
</example>
O editor padrão do sistema será aberto e pedirá uma descrição das modificações para 
o commit. Esta descrição será usada como referência sobre as atualizações feitas em 
cada etapa do desenvolvimento. A mensagem também pode ser especificada usando a 
opção "-m mensagem", principalmente quando o texto explicando as alterações é 
pequeno.
 <p>
Para mudar o editor de texto padrão que será usado pelo <prgn>cvs</prgn>, 
altere a variável de ambiente <var>EDITOR</var> ou especifique o editor 
que deseja usar na linha de comando com a opção "-e editor":
<example>
cvs commit -e vi main.c

</example>


<sect1 id="s-cvs-p-add">Adicionando um arquivo ao módulo CVS do servidor
 <p>
Após criar/copiar o arquivo para seu diretório de trabalho, use o comando 
<tt>add</tt> para fazer isto. O arquivo será enviado ao servidor, bastando 
apenas executa o <tt>commit</tt> para salvar o arquivo:
<example>
cvs add main.h
cvs commit main.h

</example>


<sect1 id="s-cvs-p-add-dir">Adicionando um diretório ao módulo CVS do servidor
 <p>
O método para adicionar um diretório com arquivos é semelhante ao de adicionar 
apenas arquivos ao cvs. O único ponto que deve se seguido é que primeiro 
deve ser adicionado o diretório (com o "cvs add") salvar no servidor 
remoto ("cvs commit") e depois adicionar os arquivos existentes dentro
dele (assim como descrito em <ref id="s-cvs-p-add">). Para adicionar o 
diretório <file>teste</file> e seus arquivos no servidor <prgn>cvs</prgn>
remoto:
<example>
cvs add teste
cvs commit -m "Adicionado" teste
cvs add teste/*
cd teste
cvs commit -m "Adicionados" .

</example>
Os dois primeiros comandos agendam o diretório <file>teste</file> e fazem o 
<tt>commit</tt> no diretório remoto. Os dois últimos, enviam os arquivos 
existentes dentro deste diretório para o servidor remoto.


<sect1 id="s-cvs-p-remove">Removendo um arquivo do módulo CVS remoto
 <p>
O comando para fazer isto é o "remove". Primeiro use o <prgn>rm</prgn> para 
remover o arquivo/diretório de sua cópia local, depois execute o 
<tt>remove</tt> seguido de commit para confirmar a remoção do arquivo:
<example>
cvs remove main.h
cvs commit main.h

</example>


<sect1 id="s-cvs-p-removed">Removendo um diretório do módulo CVS remoto
 <p>
Para remover um diretório, primeiro remova todos os arquivos existentes
dentro dele com o comando <prgn>rm</prgn> e salve para o servidor 
(seguindo os métodos descritos em <ref id="s-cvs-p-remove">). O CVS 
não remove diretamente diretórios vazios, uma maneira de contornar 
isto é usar o <tt>update</tt> ou <tt>commit</tt> seguido da opção 
<tt>-P</tt> para ignorar diretórios vazios. Então a cópia remota do diretório
será removida do servidor:
<example>
rm -f teste/*
cvs remove teste/.
cvs commit teste/.
cd ..
cvs checkout modulo

</example>
Depois do checkout, o subdiretório teste terá sido removido.



<sect1 id="s-cvs-p-release">Dizendo que o módulo atual não está mais em uso
 <p>
O comando "release" faz esta função. Ele não é requerido, mas caso você tenha 
feito modificações que ainda não foram salvas no servidor de cvs (<tt>commit</tt>), 
ele alertará de arquivos modificados e perguntará se deseja continuar. Registrando
também o abandono das modificações no histórico do <prgn>cvs</prgn>. O comando
pode ser acompanhado de "-d" para remover o módulo anteriormente baixado com o 
"commit":
<example>
cvs release modulo

cvs release -d modulo

</example>
O <tt>release</tt> retorna os seguintes códigos quando verifica que as duas 
cópias (local e remota) não estão sincronizadas:
<taglist compact>
 <tag>U ou P</tag>
  <item>
Existe uma versão nova do arquivo no repositório. Para corrigir isso, execute
o comando "update". 

 <tag>A</tag>
  <item>
O arquivo não foi adicionado ainda ao repositório remoto. Se apagar o 
repositório local, este arquivo não será adicionado. Para corrigir isto, 
executa o comando "add" do cvs. 

 <tag>R</tag>
  <item>
O arquivo foi removido localmente, mas não foi removido do servidor remoto.
Use os procedimentos em <ref id="s-cvs-p-remove"> para corrigir a situação.


 <tag>M</tag>
  <item>
O arquivo está modificado localmente e não foi salvo ainda no servidor. 
Use os procedimentos em <ref id="s-cvs-p-update"> e <ref id="s-cvs-p-commit">
para salvar o arquivo.

 <tag>?</tag>
  <item>
O arquivo está em seu diretório de trabalho mas não tem referências no 
repositório remoto e também não está na lista de arquivos ignorados do 
CVS. 

</taglist>


<sect1 id="s-cvs-p-diff">Visualizando diferenças entre versões de um arquivo
 <p>
Com o comando "diff" é possível visualizar que diferenças o arquivo que 
está sendo editado possui em relação ao arquivo do repositório remoto. 
Outra funcionalidade útil do "diff" é comparar 2 versões de arquivos do mesmo 
repositório CVS. Exemplos:
<taglist compact>
 <tag>cvs diff main.c</tag>
  <item>
 Verifica as diferenças entre o arquivo <file>main.c</file> local e remoto.

 <tag>cvs diff -u -r 1.1 -r 1.2 main.c</tag>
  <item>
Mostra as diferenças em formato unificado para mostrar as diferenças entre as 
versões 1.1 e 1.2 do arquivo <file>main.c</file>.
</taglist>


<sect1 id="s-cvs-p-status">Visualizando o status de versão de arquivos 
 <p>
O comando "status" permite verificar que versões do arquivo especificado
está disponível localmente, remotamente, qual a versão inicial do 
arquivo no repositório, sticky tag. Exemplos:
<taglist compact>
 <tag>cvs status main.c</tag>
  <item>
 Verifica o status do arquivo <file>main.c</file>.

 <tag>cvs status -v main.c</tag>
  <item>
 Mostra o status do arquivo <file>main.c</file>, 
 adicionalmente mostra também as tags existentes no arquivo 
 (versão inicial, versão do repositório).
</taglist>


<sect1 id="s-cvs-p-utils">Outros utilitários para trabalho no repositório
 <p>
Além dos comandos do <prgn>cvs</prgn> descritos aqui, existem comandos 
no pacote <package>cvsutils</package> que auxiliam desde quem está 
aprendendo a utilizar o CVS (com o comando <prgn>cvsdo</prgn> para 
simular algumas operações de adição/remoção de arquivos) até profissionais
que usam o programa no dia a dia (<prgn>cvsu</prgn>, <prgn>cvsco</prgn>, 
<prgn>cvschroot</prgn>). 



