Esta página manual ensina a como usar e administrar o CVS versão

Copyright © 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.

Portions
  Copyright © 1999, 2000, 2001, 2002, 2003 Derek R. Price,
  Copyright © 2002, 2003 Ximbiot http://ximbiot.com,
  Copyright © 1992, 1993, 1999 Signum Support AB,
  and Copyright © others.

Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.

Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.

Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions, except that this permission notice may be stated in a translation approved by the Free Software Foundation.

Visão Geral
***********

Este capítulo é para aqueles que nunca usaram o CVS antes, e talvez nunca tenham usado um programa de controle de versões antes.

Se você já conhece o CVS e está apenas tentando aprender sobre uma habilidade em particular ou lembrar um certo comando, você provavelmente pode pular tudo aqui.

O que é CVS?
============

CVS é um sistema de controle de versões.  Ao usá-lo, você pode registrar a história dos seus códigos fonte.

Por exemplo, às vezes aparecem erros quando um programa é modificado e você não detecta o problema até muito tempo depois de você ter feito a modificação.  Com CVS, você pode recuperar versões antigas para ver exatamente o que causou o erro.  Isto às vezes é de grande ajuda.

Você pode, é claro, salvar toda versão de todo arquivo que um dia você criou.  Mas isto vai consumir um enorme espaço no disco.  O CVS guarda todas as versões de um arquivo em um único arquivo em uma forma inteligente que guarda apenas as diferenças entre versões.

CVS também ajuda se você é parte de um grupo de pessoas trabalhando no mesmo projeto.  É muito fácil uns sobreescreverem as mudanças de outros se não forem extremamente cuidadosos.  Alguns editores, como o GNU Emacs, tentam se certificar de que o mesmo arquivo nunca seja modificado por duas pessoas ao mesmo tempo.  Infelizmente, se alguém estiver usando outro editor, está segurança não vai funcionar.  O CVS resolve este problema isolando os desenvolvedores uns dos outros.  Todo desenvolvedor trabalha em seu próprio diretório e o CVS mescla o trabalho quando cada desenvolvedor tiver terminado.

CVS começou como um monte de shell scripts escritos por Dick Grune, postados no newsgroup comp.sources.unix no volume 6, de Julho de 1986.  Na verdade, nenhum código daqueles scripts está presente na versão atual do CVS, mas muito dos algoritmos de resolução de conflitos do CVS vem deles.

Em abril de 1989, Brian Berliner projetou e codificou CVS.  Depois, Jeff Polk ajudou Brian com o projeto do módulo CVS e o suporte ao ramo do fornecedor.

Você pode conseguir o CVS de várias formas, inclusive baixando gratuitamente da internet.  Para maiores informações sobre baixar o CVS e para outros tópicos sobre CVS, veja:

     http://cvs.nongnu.org/

Existe uma lista de discussão, conhecida como info-cvs@nongnu.org, dedicada ao CVS.  Para se cadastrar ou descadastrar nela escreva para info-cvs-request@nongnu.org.  Se você preferir um grupo de usenet, existe um espelho de mão única (postagens para a lista de email são usualmente mandadas para o news group, mas não vice-versa) da lista info-cvs@nongnu.org em news:gnu.cvs.help.  O grupo usenet correto para postagens é o news:comp.software.config-mgmt que é para discussões sobre CVS (juntamente com outros sistemas de gerência de configuração).  No futuro, poderá ser criada uma comp.software.config-mgmt.cvs, mas apenas se houver bastante tráfego sobre o CVS na news:comp.software.config-mgmt.

Você também pode se cadastrar na lista de discussão bug-cvs@nongnu.org, descrita em maiores detalhes em Paus.  Para se cadastrar mande um e-mail para bug-cvs-request@nongnu.org.  Existe um espelho usenet de mão-dupla (postagens para o grupo usenet são usualmente mandadas para a lista e vice-versa) de bug-cvs@nongnu.org chamado news:gnu.cvs.bug.

O que CVS não é?
================

CVS pode fazer várias coisas para você, mas não tenta fazer tudo para todo mundo.

CVS não é um sistema de construção (build system).

     Embora a estrutura do seu repositório e arquivos de módulo interajam com seu sistema de construção (e.g. Makefiles), eles são essencialmente independentes.

     CVS não dita como você constroi nada.  Ele apenas guarda arquivos para recuperação numa estrutura de árvore que você concebeu.

     CVS não dita como usar o espaço em disco em diretórios de trabalho locais.  Se você escreve seus Makefiles ou scripts em cada diretório, eles têm que saber a posição relativa de todo o resto, logo você acaba tendo que pegar todo o repositório.

     Se você modularizar o seu trabalho e fizer um sistema de construção (build) que irá compartilhar arquivos (via links, mounts, VPATH em Makefiles, etc.), você pode organizar a sua utilização de disco de qualquer forma.

     Mas você tem que lembrar que qualquer sistema desse é muito trabalhoso para construir e manter.  O CVS não se importa com tais questões.

     Obviamente, você pode botar as ferramentas criadas para auxiliar tal sistema de construção (scripts, Makefiles, etc) dentro do CVS.

     Definir quais arquivos precisam ser reconstruídos quando algo muda é, novamente, algo para ser visto fora do escopo do CVS.  Uma abordagem tradicional é usar o make para construir, e usar alguma ferramenta automatizada para gerar as dependências que o make usa.

     See Builds, para mais informações sobre construção com CVS.

CVS não substitui gerenciamento.

     Espera-se que seus gerentes e líderes de projetos falem com você com a frequência suficiente para que você saiba de prazos, pontos de mescla, nomes de ramos e datas de lançamento (release).  Se eles não o fizerem, o CVS não pode ajudar.

     CVS é um instrumento para fazer o fonte dançar conforme a sua música.  Mas você é o maestro e o compositor.  Nenhum instrumento toca sozinho ou escreve sua própria música.

CVS não é um substituto para comunicação entre desenvolvedores.

     Quando se deparam com conflitos num único arquivo, a maioria dos desenvolvedores conseguem resolvê-los sem muito esforço.  Mas uma definição mais geral de ``conflito'' inclui problemas tão difíceis de resolver que é necessária a comunicação entre os desenvolvedores.

     CVS não pode determinar quando é que alterações simultâneas em um arquivo, ou vários, vão conflitar logicamente umas com as outras.  Seu conceito de conflito é puramente textual, surgindo quando duas alterações num mesmo arquivo base são próximas o suficiente para intimidar o comando de mescla (i.e. diff3).

     CVS não se propõe a dar qualquer ajuda quanto a localizar conflitos não-textuais ou distribuídos na lógica de programação.

     Por exemplo: Digamos que você altere os argumentos da função X definida no arquivo A.  Neste instante, alguem altera o arquivo B, adicionando novas chamadas à função X usando os argumentos antigos.  Vocês estão fora do escopo da competência do CVS.

     Adquira o hábito de ler documentação e conversar com seus parceiros.

CVS não tem controle de mudanças

     Controle de mudanças se refere a várias coisas.  Em primeiro lugar, pode significar bug-tracking (busca de erros), que é manter uma base de dados de erros relatados e o status de cada um (foi consertado? em qual lançamento? o submissor do erro concordou que o erro foi corrigido?).  Para fazer a interface do CVS com um sistema de bug-tracking externo, veja os arquivos rcsinfo e verifymsg (see Arquivos administrativos).

     Outra característica de controle de mudanças é manter um controle no fato de que mudanças em vários arquivos foram, de fato, uma única mudança lógica.  Se você devolve vários arquivos numa única operação com cvs commit (efetivar), CVS esquece que os arquivos foram devolvidos juntos, e o fato de eles terem a mesma mensagem de log é a única coisa que os une.  Manter um ChangeLog no estilo GNU pode de certa forma ajudar.

     Outro aspecto do controle de mudanças, em alguns sistemas, é a habilidade de se obter informação sobre o status de cada mudança.  Algumas mudanças foram escritas por um certo desenvolvedor, outras foram revisadas por um segundo desenvolvedor, e por aí vai.  Geralmente, a forma de fazer isto com o CVS é gerando um diff (usando cvs diff ou diff) e mandando por email para alguem que possa resolver as diferenças usando o utilitário patch.  Isto é muito flexível, mas depende de mecanismos externos ao CVS para garantir que nada dê problema.

CVS não é um programa de testes automático

     é possível reforçar o uso obrigatório de uma suíte de testes usando o arquivo commitinfo.  Eu nunca ouvi falar muito sobre projetos que tentam fazer isto, ou se existem armadilhas sutís nestes casos.

CVS não tem um modelo de processo inerente

     alguns sistemas fornecem formas de garantir que mudanças ou lançamentos sigam vários passos, com várias aprovações obrigatórias.  Geralmente, pode-se obter isto com o CVS, mas acarreta em um pouco mais de trabalho.  Em alguns casos você vai querer usar o arquivo commitinfo, loginfo, rcsinfo, ou verifymsg para exigir que certos passos sejam executados antes que o cvs permita uma devolução (checkin).  Também considere se características tais como ramos e etiquetas (tags) podem ser usadas para realizar tarefas como desenvolver numa árvore de desenvolvimento e então mesclar certas mudanças numa árvore estável apenas quando eles tenham sido confirmados.

Uma sessão de exemplo
=====================

Vamos apresentar o CVS usando numa sessão de trabalho típica.  A primeira coisa a saber é que CVS guarda todos os arquivos em um repository centralizado (see Repositório); esta sessão assume que um repositório esteja ativo.

Suponha que você esteja trabalhando num compilador simples.  O fonte é um monte de arquivos C e um Makefile.  O compilador é chamado tc (Trivial Compiler, ou Compilador trivial), e o repositório é feito de forma que exista um módulo chamado tc.

Obtendo os fontes
-----------------

A primeira coisa a fazer é pegar sua própria cópia de trabalho dos fontes de tc.  Para isto, use o comando checkout (pegar emprestado):

     $ cvs checkout tc

Isto vai criar um novo diretório chamado tc e povoa-lo com os fontes.

     $ cd tc
     $ ls
     CVS         Makefile    backend.c   driver.c    frontend.c  parser.c

O diretório CVS é usado internamente pelo CVS.  Normalmente, você não deve modificar ou remover quaisquer arquivos dele.

Você abre o seu editor favorito, trabalha no arquivo backend.c, e algumas horas depois você deixou o compilador mais otimizado.  Uma observação para usuários de RCS e SCCS: Não é necessário travar (lock) os arquivos que você quer editar.  See Múltiplos desenvolvedores, para uma explicação.

Efetivando suas alterações
--------------------------

Quando você se certificar que o compilador ainda é compilável você decide criar uma nova versão de backend.c.  Tal ato vai botar o seu novo backend.c no repositório e torná-lo disponível para qualquer outra pessoa que esteja usando o mesmo repositório.

     $ cvs commit backend.c

CVS inicia um editor, para que você possa digitar uma messagem de log.  Você digita ``Uma otimização adicionada.'', salva o arquivo temporário e sai do editor.

A variável de ambiente $CVSEDITOR determina qual editor vai ser aberto.  Se $CVSEDITOR não existe, e se a variável de ambiente $EDITOR existe, esta última é usada.  Se nenhuma das duas $CVSEDITOR e $EDITOR existem então o padrão vai variar dependendo do sistema operacional, por exemplo, vi para unix ou notepad para Windows NT/95.

Adicionalmente, CVS busca pela variável de ambiente $VISUAL.  Isto gera duas opiniões divergentes, se este é um comportamento desejável ou se releases futuras do CVS devem verificar $VISUAL ou ignorá-la.  Você vai estar OK se não tiver a variável $VISUAL ou se ela for igual à $EDITOR.

Quando o CVS inicia o editor, ele inclui uma lista de arquivos que foram modificados.  Para o CVS cliente, esta lista é baseada na comparação da data de modificação do arquivo com a data de modificação que o arquivo tinha da última vez que foi pego ou atualizado.  Entretanto, se a data de modificação de um arquivo mudou mas seu conteúdo não, ele vai ser considerado modificado.  A maneira mais fácil de lidar com isto é desconsidarando---se você seguir efetivando, o CVS vai notar que o conteúdo está intacto e vai tratar o arquivo como não-modificado.  O próximo update vai dar a dica para o CVS de que o arquivo está igual, e isto vai restaurar a data, fazendo com que o arquivo não apareça nas próximas aparições do editor.

Se você quer evitar o aparecimento de um editor, você pode especificar a mensagem de log na linha de comando usando a opção -m, desta forma:

     $ cvs commit -m "Uma otimização adicionada" backend.c

Limpando
--------

Antes de ir fazer outras tarefas, você decide remover sua cópia de trabalho de tc.  Uma forma aceitável de fazer isto é, obviamente:

     $ cd ..
     $ rm -r tc

mas uma forma melhor é usando o comando release (see release):

     $ cd ..
     $ cvs release -d tc
     M driver.c
     ? tc
     You have [1] altered files in this repository.
     Are you sure you want to release (and delete) directory `tc': n
     ** `release' aborted by user choice.

O comando release verifica se todas as suas modificações foram efetivadas.  Se o registro histórico (history log) está ativo ele também escreve uma observação no arquivo de histórico.  See arquivo history (histórico).

Quando você usa a opção -d com o release, ele também remove a sua cópia de trabalho local.

No exemplo acima, o comando release escreve poucas linhas de saída.  ? tc significa que o arquivo tc é desconhecido pelo CVS.  Não há nada com que se preocupar: tc é um compilador executável, e não deve ser guardado no repositório.  See cvsignore, para ver como fazer para sumir com este aviso.  See release output, para uma explicação geral de todas as possíveis saídas do release.

M driver.c é mais sério.  Significa que o arquivo driver.c foi modificado desde quando foi pego.

O comando release sempre termina dizendo quantos arquivos modificados você tem em sua cópia de trabalho dos fontes, e então pergunta por confirmação antes de apagar qualquer arquivo ou escrever qualquer coisa no arquivo de histórico.

Você decide que executar isto é seguro e responde n RET quando release pede uma confirmação.

Vendo diferenças
----------------

Você não lembra se modificou driver.c.  Logo, você precisa ver o que aconteceu com este arquivo.

     $ cd tc
     $ cvs diff driver.c

Este comando roda o diff para comparar a versão de driver.c que você pegou com a da sua cópia de trabalho.  Quando você vê a saída, você lembra de ter adicionado uma opção de linha de comando que permite a otimização.  Você devolve e lança (release) o módulo.

     $ cvs commit -m "Uma otimização adicionada" driver.c
     Checking in driver.c;
     /usr/local/cvsroot/tc/driver.c,v  <--  driver.c
     new revision: 1.2; previous revision: 1.1
     done
     $ cd ..
     $ cvs release -d tc
     ? tc
     You have [0] altered files in this repository.
     Are you sure you want to release (and delete) directory `tc': y

O Repositório
*************

O repositório do CVS guarda uma cópia completa de todos os arquivos e diretórios que estão sob controle de versão.

Normalmente, você nunca acessa qualquer dos arquivos do repositório diretamente.  Ao invés disso, você usa os comandos do CVS para pegar emprestada a sua cópia dos arquivos num diretório de trabalho, e então trabalhar nesta cópia.  Quando você termina um conjunto de mudanças, você as efetiva no repositório.  O repositório então passa a conter as mudanças que você fez, assim como gravar exatamente o que você fez, quando você fez e outras informações deste tipo.  Observe que o repositório não é um subdiretório do diretório de trabalho nem vice-versa; eles estão em locais diferentes.

CVS pode acessar um repositório de várias formas.  Ele pode estar no mesmo computador, ou num computador do outro lado da sala, ou do outro lado do mundo.  Para distinguir as várias formas de acessar um repositório o seu nome deve começar com um método de acesso.  Por exemplo, o método de acesso :local: significa acessar um diretório que é um repositório.  Logo, :local:/usr/local/cvsroot significa que o repositório está em /usr/local/cvsroot no computador rodando CVS.  Para informações sobre outros métodos de acesso, vá em Repositórios remotos.

Se o método de acesso é omitido e se o repositório começa com /, então assume-se :local:.  Se não começa com / então ou :ext: ou :server: é assumido.  Por exemplo, se você tem um repositório local em /usr/local/cvsroot, você pode usar /usr/local/cvsroot ao invés de :local:/usr/local/cvsroot.  Mas se (no Windows NT, por exemplo) seu repositório local é c:\src\cvsroot, então você deve especificar o método de acesso, como em :local:c:/src/cvsroot.

O repositório é separado em duas partes.  $CVSROOT/CVSROOT contém arquivos administrativos do CVS.  Os outros diretórios contém os módulos definidos pelo usuário.

Dizendo ao CVS onde está o seu repositório
==========================================

Existem várias formas de dizer ao CVS onde encontrar o repositório.  Você pode dar o nome do repositório explicitamente na linha de comando, com a opção -d (de "diretório"):

     cvs -d /usr/local/cvsroot checkout yoyodyne/tc

Ou você pode ajustar a variável de ambiente $CVSROOT para um caminho absoluto para a raiz (root) do repositório, /usr/local/cvsroot neste exemplo.  Para ajustar o $CVSROOT, usuário de csh e tcsh devem ter esta linha no seu arquivo .cshrc ou .tcshrc:

     setenv CVSROOT /usr/local/cvsroot

usuários de sh e bash devem, por sua vez, ter estas linhas nos seus .profile ou .bashrc:

     CVSROOT=/usr/local/cvsroot
     export CVSROOT

Um repositório especificado com -d se sobrepõe à variável de ambiente $CVSROOT.  Uma vez que você tenha pego emprestada uma cópia de trabalho do repositório, ela vai se lembrar onde está o seu repositório (a informação é registrada no arquivo CVS/Root na cópia de trabalho).

Tanto a opção -d quanto o arquivo CVS/Root sobreescrevem a variável de ambiente $CVSROOT.  Se a opção -d é diferente do CVS/Root, a primeira é usada.  Obviamente, para operações corretas, elas devem ser duas formas de referenciar o mesmo repositório.

Como os dados são guardados no repositório
==========================================

Para a maioria das aplicações, não importa como o CVS guarda as informações no repositório.  De fato, o formato mudou no passado, e provavelmente vai mudar no futuro.  Já que em quase todo os casos o acesso ao repositório é feito via comandos do CVS, tais mudanças não serão radicais.

Entretanto, em alguns casos pode ser necessário entender como o CVS guarda os dados no repositório.  Por exemplo, você pode precisar localizar travas do CVS (see Concorrência) ou você pode precisar lidar com permissões de arquivos apropriadas para o repositório.

Onde arquivos são guardados dentro do repositório
-------------------------------------------------

A estrutura geral do repositório é uma árvore de diretórios correspondendo aos diretórios no diretório de trabalho.  Por exemplo, suponha que o repositório está em

     /usr/local/cvsroot

Aqui está uma possível árvore de diretórios (mostrando apenas os diretórios):

     /usr
      |
      +--local
      |   |
      |   +--cvsroot
      |   |    |
      |   |    +--CVSROOT
               |      (arquivos administrativos)
               |
               +--gnu
               |   |
               |   +--diff
               |   |   (código fonte do GNU diff)
               |   |
               |   +--rcs
               |   |   (código fonte do RCS)
               |   |
               |   +--cvs
               |       (código fonte do CVS)
               |
               +--yoyodyne
                   |
                   +--tc
                   |    |
                   |    +--man
                   |    |
                   |    +--testing
                   |
                   +--(other Yoyodyne software)

Nos diretórios estão os arquivos de histórico para cada arquivo sob controle de versão.  O nome do arquivo de histórico é o nome do arquivo correspondente com um ,v no final.  Aqui está como o repositório do diretório yoyodyne/tc deve se parecer:

       $CVSROOT
         |
         +--yoyodyne
         |   |
         |   +--tc
         |   |   |
                 +--Makefile,v
                 +--backend.c,v
                 +--driver.c,v
                 +--frontend.c,v
                 +--parser.c,v
                 +--man
                 |    |
                 |    +--tc.1,v
                 |
                 +--testing
                      |
                      +--testpgm.t,v
                      +--test2.t,v

Os arquivos de histórico contém, entre outras coisas, informações suficientes para recriar qualquer revisão do arquivo, um log com todas as mensagens ???de commit??? e o usuário que efetivou (commit) a revisão.  Os arquivos de histórico são conhecidos como arquivos RCS (RCS files), pois o primeiro programa a guardar arquivos neste formato foi o sistema de controle de versões conhecido como RCS.  Para uma descrição completa do formato de arquivo, leia a página man rcsfile(5), distribuída com o RCS, ou o arquivo doc/RCSFILES na distribuição dos fontes do CVS.  Este formato de arquivo se tornou muito comum---muitos sistemas além do CVS e do RCS podem, pelo menos, importar arquivos de histórico neste formato.

Os arquivos RCS usados no CVS diferem em algumas poucas coisas do formato padrão.  A maior diferença são os ramos mágicos; para mais informações veja em Números de ramos mágicos.  Além disso, no CVS os nomes válidos de etiquetas (tags) é um subconjunto dos que são aceitos pelo RCS; para regras do CVS, leia em Etiquetas.

Permissões de arquivos
----------------------

Todos os arquivos ,v são criados somente-leitura, e você não deve mudar as permissões destes arquivos.  Os diretórios dentro do repositório devem dar permissão de escrita para as pessoas que tem permissão para modificar os arquivos em cada diretório. Isto normalmente significa que você deve criar um grupo do UNIX (veja em group(5)) consistindo nas pessoas que vão editar os arquivos num projeto, e ajustar o repositório tal que aquele grupo seja o dono do diretório.  (Em alguns sistemas, você também vai precisar ajustar o bit set-group-ID-on-execution nos diretórios do repositório (veja em chmod(1)) de forma que arquivos e diretório criados recebam o ID de grupo do diretório pai e não do processo atual.)

Isto significa que você pode apenas controlar o acesso aos arquivos por diretório.

Observe que os usuários devem ter direito de escrita para pegar arquivos emprestados, já que o CVS tem que criar arquivos de trava (see Concorrência).  Você pode usar LockDir (diretório de trava) no CVSROOT/config para botar os arquivos de trava num lugar fora do repositório se você quer permitir acesso somente-leitura a alguns diretórios (see config).

Observe também que os usuários devem ter permissão de escrita ao arquivo CVSROOT/val-tags.  O CVS usa tal arquivo para ter controle sobre quais etiquetas (tags) são nomes de etiquetas válidos (é às vezes atualizado quando etiquetas são usadas ou criadas).

Cada arquivo RCS vai pertencer ao usuário que o devolveu por último.  Isto tem pouco significado; o que realmente importa é quem possui os diretórios.

O CVS tenta ajustar de forma razoável as permissões para novos diretórios que vão sendo adicionados na árvore, mas você vai ter que mudar as permissões manualmente quando um novo diretório deve ter permissões diferentes das do seu diretório pai.  Se você ajusta a variável de ambiente CVSUMASK ela vai controlar as permissões que o CVS usa na criação de diretórios e/ou arquivos no repositório.  CVSUMASK não mexe nas permissões do diretório de trabalho; tais arquivos têm as permissões que são típicas para novos arquivos, exceto que algumas vezes o CVS cria os arquivos somente-leitura (veja as seções em ???watches???, Ajustando um ???watch???; -r, Opções globais; or CVSREAD, Variáveis de ambiente).

Observe que ao usar o CVS cliente/servidor (see Repositórios remotos), não há uma boa maneira de ajustar o CVSUMASK; o ajuste na máquina cliente não tem efeito.  Se você está se conectando com rsh, você pode ajustar o CVSUMASK em .bashrc ou .cshrc, como descrito na documentação de seu sistema operacional.  Este comportamento pode mudar em futuras versões do CVS; Não se basear na configuração do CVSUMASK no cliente não afeta nada.

Quando usar pserver, você deve ser, em geral, mais mais restritivo com permissões no diretório CVSROOT e nos diretórios abaixo dele na árvore; veja em Segurança com autenticação por senha.

alguns sistemas operacionais têm a habilidade de permitir que um programa execute com a habilidade de executar certas operações que quem chamou o programa não não tem.  Por exemplo, os set user ID (setuid) ou set group ID (setgid) do unix ou a caracteristica de installed image do VMS.  CVS não foi escrito para usar tais habilidades, logo, tentar instalar o CVS nesta forma vai gerar proteção apenas contra erros acidentais; qualquer um que esteja tentando driblar a segurança vai ser capaz de fazê-lo, e dependendo de como você configurou, o invasor pode ganhar acesso até a mais do que apenas o CVS.  Você pode estar considerando o uso do pserver.  Ele compartilha alguns dos mesmos atributos, em termos de possivelmente fornecer uma falsa sensação de segurança ou de abrir buracos de segurança ainda maiores dos que os que você quer fechar.  Portanto leia a documentação de segurança com pserver cuidadosamente se você está pensando nesta opção (Segurança com autenticação por senha).

Questões sobre permissões de arquivos específicas ao Windows
------------------------------------------------------------

Algumas questões sobre permissões de arquivos são específicas ao sistema operacional Windows (Windows 95, Windows NT e presumivelmente futuros sistemas operacionais nesta família.  Algumas coisas abaixo se aplicam ao OS/2 mas não estou bem certo).

Se você está usando um CVS local e o repositório está num sistema de arquivos em rede de um servidor Samba SMB, algumas pessoas relataram problemas com permissões.  Habilitando WRITE=YES na configuração do samba conserta/resolve.  ???Disclaimer:??? Eu não investiguei o suficiente as implicações de habilitar esta opção, nem sei se há algo que o CVS poderia fazer de diferente para evitar este problema.  Se você souber de algo, por favor nos ponha a par como descrito em Paus.

O attic
-------

Você deve ter notado que às vezes o CVS guarda um arquivo RCS no Attic.  Por exemplo, se o CVSROOT é /usr/local/cvsroot e nós estamos falando sobre o arquivo backend.c no diretório yoyodyne/tc, então o arquivo normalmente deve estar em

     /usr/local/cvsroot/yoyodyne/tc/backend.c,v

mas se ele vai para o attic, ele deve estar em

     /usr/local/cvsroot/yoyodyne/tc/Attic/backend.c,v

ao invés.  Não importa ao usuário onde, dentro do Attic, fica o arquivo; CVS mantém controle disto e busca no Attic quando é preciso.  Mas caso você queira saber, a regra é que o arquivo RCS é guardado no attic se e somente se a ???head revision??? no tronco está no estado morto (dead).  Um estado morto significa que o arquivo foi removido, ou nunca foi adicionado, naquela revisão.  Por exemplo, se você adiciona um arquivo num ramo, ele vai ter uma revisão de tronco num estado morto e uma revisão de ramo num estado não-morto.

O diretório CVS no repositório
------------------------------

O diretório CVS em cada diretório do repositório contém informações tais como atributos de arquivos (num arquivo chamado CVS/fileattr.  No futuro novos arquivos ficarão neste diretório, logo, implementações devem ignorar em silêncio arquivos adicionais.

Este comportamento é implementado apenas pelo CVS 1.7 e posteriores; para detalhes veja em Compatibilidade de ???Watches???.

O formato do arquivo fileattr é uma série de entradas da seguinte forma (onde { e } significam que o texto entre chaves pode ser repetido zero ou várias vezes):

ENT-TYPE FILENAME <tab> ATTRNAME = ATTRVAL {; ATTRNAME = ATTRVAL} <linefeed>

ENT-TYPE é F para arquivo, neste caso a entrada especifica os atributos para tal arquivo.

ENT-TYPE é D, e FILENAME vazio, para especificar atributos padrão para serem usados em novos arquivos adicionados.

Outros ENT-TYPE são reservados para futuras expansões.  CVS 1.9 e anteriores vão deletá-los a toda hora que ele escrever atributos de arquivos.  CVS 1.10 e posteriores vão preservá-los.

Observe que a ordem das linhas não é significante; um programa escrevendo o arquivo fileattr pode rearranjá-las de acordo com sua própria conveniência.

Não existe atualmente uma forma de tratar tabulações ou quebras de linha como caractere no nome do arquivo, = em ATTRNAME, ; em ATTRVAL, etc.  Obs.: algumas implementações também não manipulam o caractere NUL em nenhum dos campos, mas encorajamos implementações que permitam isto.

Por convenção, ATTRNAME começando com _ é para um atributo ao qual foi dado significado especial pelo CVS; outros ATTRNAMEs são para atributos definidos pelo usuário (ou que vão ser, já que implementações começaram suporte a atributos definidos pelo usuário).

Atributos internos:

_watched
     Quando presente significa que o arquivo está ???watched??? (watched) e deve ser emprestado como somente-leitura.

_watchers
     Usuários com ???watches??? para este arquivo.  O valor é WATCHER > TYPE { , WATCHER > TYPE } onde WATCHER é um nome de usuário, e TYPE é zero ou mais de edit,unedit,commit separados por + (isto é, deixe em branco para nenhum; não há palavras-chave para "nenhum" ou "todos").

_editors
     Usuários editando este arquivo.  O valor é EDITOR > VAL { , EDITOR > VAL } onde EDITOR é um username, e VAL é TIME+HOSTNAME+PATHNAME, onde TIME é quando o comando cvs edit (ou outro equivalente) aconteceu, e HOSTNAME e PATHNAME são do diretório de trabalho.

Example:

     Ffile1 _watched=;_watchers=joe>edit,mary>commit
     Ffile2 _watched=;_editors=sue>8 Jan 1975+workstn1+/home/sue/cvs
     D _watched=

significa que o arquivo file1 deve ser pego como somente-leitura.  Além disso, joe está ???watching??? edições e mary está ???watching??? ???commits???.  O arquivo file2 deve ser pego somente-leitura; sue comecou a edita-lo em 8 Jan 1975 no diretorio /home/sue/cvs na maquina workstn1.  Futuros arquivos que forem adicionados devem ser pegos somente-leitura.  Para representar este exemplo aqui, nós mostramos um espaco depois de D, Ffile1, e Ffile2, mas de fato existe um caractere de tab e nenhum espaco.

travas CVS no repositório
-------------------------

Para uma introdução às travas (locks) no CVS focando no comportamento visível ao usuário, veja em Concorrência.  A seção seguinte foi feita para para pessoas que escrevem ferramentas as quais precisam acessar um repositório CVS sem interferir com outras ferramentas acessando o mesmo repositório.  Se você se sentir confuso com os conceitos descritos aqui, como read lock, write lock e deadlock, você deve consultar a literatura de sistemas operacionais e bancos de dados.

Qualquer arquivo no repositório com um nome começando com #cvs.rfl. é uma trava de leitura.  Qualquer arquivo no repositório com um nome comçando com #cvs.pfl é uma trava de leitura ???promotable???.  Qualquer arquivo no repositório com um nome começando com #cvs.wfl é uma trava de escrita.  Versões antigas do CVS (antes do CVS 1.5) também criavam arquivos com nomes começando com #cvs.tfl, mas estes não são discutidos aqui.

O diretório #cvs.lock funciona como uma trava mestra.  Isto é, deve-se obter esta trava antes de criar qualquer das outras travas.

Para obter uma trava de leitura, primeiro crie o diretório #cvs.lock.  Esta operação deve ser atômica (o que deve ser verdade para a criação de um diretório na maioria dos sistemas operacionais).  Se isto falha por que o diretório já existe, espere um tempinho e tente de novo.  Depois de obter a trava #cvs.lock, crie um arquivo cujo nome seja #cvs.rfl. seguido pela informação de sua escolha (por exemplo, nome de host e nmero de identificaçao de processo).  Então remova o diretório #cvs.lock para ativar a trava mestra.  Então começe a ler o repositório.  Quando você terminar, remova o arquivo #cvs.rfl para liberar a trava de leitura.

Promotable read locks are a concept you may not find in other literature on concurrency.  They are used to allow a two (or more) pass process to only lock a file for read on the first (read) pass(es), then upgrade its read locks to write locks if necessary for a final pass, still assured that the files have not changed since they were first read.  CVS uses promotable read locks, for example, to prevent commit and tag verification passes from interfering with other reading processes.  It can then lock only a single directory at a time for write during the write pass.

To obtain a promotable read lock, first create the #cvs.lock directory, as with a non-promotable read lock.  Then check that there are no files that start with #cvs.pfl.  If there are, remove the master #cvs.lock directory, wait awhile (CVS waits 30 seconds between lock attempts), and try again.  If there are no other promotable locks, go ahead and create a file whose name is #cvs.pfl followed by information of your choice (for example, CVS uses its hostname and the process identification number of the CVS server process creating the lock).  If versions of CVS older than version 1.12.4 access your repository directly (not via a CVS server of version 1.12.4 or later), then you should also create a read lock since older versions of CVS will ignore the promotable lock when attempting to create their own write lock. Then remove the master #cvs.lock directory in order to allow other processes to obtain read locks.

Para obter uma trava de escrita, primeiro crie o diretório #cvs.lock, da mesma forma que com as travas de leitura.  Então verifique se não existem arquivos cujos nomes começam com #cvs.rfl. e se não existem arquivos cujo nome começa com #cvs.pfl que não tenha como dono o processo tentando ter a trava de escrita.  Se ???either??? existe, remova o #cvs.lock, espere um momento, e tente de novo.  Se não existem ???readers??? ou travas ???promotable??? de outros processos, então crie um arquivo cujo nome é #cvs.wfl seguido de informações da sua escolha (novamente, o CVS usa o hostname e o ???server process identification number??).  Remove your #cvs.pfl file if present.  Hang on to the #cvs.lock lock.  Escreva no repositório.  Quando tiver terminado, primeiro remova o arquivo #cvs.wfl e então o diretório #cvs.lock.  Observe que ao contrário do arquivo #cvs.rfl, o  arquivo #cvs.wfl é apenas informativo; ele não tem efeito na operação de trava além do que é feito pelo ato de manter a trava #cvs.lock.

Observe que cada trava (de escrita ou leitura) apenas trava um único diretório no repositório, inclusive no caso do Attic e do CVS sem incluir os subdiretórios que representam outros diretórios sob controle de versão.  Para travar uma árvore inteira, voc precisa travar cada diretório (observe que se você não conseguir obter alguma trava que você precise, você deve liberar a árvore toda antes para esperar e tentar novamente, para evitar ???deadlocks???).

Observe também que o CVS espera travas de escrita para controlar o acesso a arquivos foo,v individuais.  O RCS tem um esquema onde o arquivo ,foo, funciona como uma trava, mas o CVS não implementa isso.  Portanto, fazer uma trava de escrita no CVS é recomendado.  Veja os comentários no rcs_internal_lockfile no código fonte do CVS para mais discussões/explicações.

Como os arquivos são guardados no diretório CVSROOT
---------------------------------------------------

O diretório $CVSROOT/CVSROOT contém os vários arquivos administrativos.  Em alguns aspectos este diretório é igual a qualquer outro diretório no repositório; ele contém arquivos RCS cujos nomes terminam em ,v, e muitos dos comandos do CVS operam neles do mesmo jeito.  Entretanto, existem algumas poucas diferenças.

Para cada arquivo administrativo, além do arquivo RCS, existe também uma cópia de trabalho do arquivo.  Por exemplo, existe um arquivo RCS loginfo,v e um arquivo loginfo que contém a ultima revisão contida em loginfo,v.  Quando você devolve um arquivo administrativo, o CVS vai mostrar

     cvs commit: Rebuilding administrative file database

e atualizar a cópia de trabalho em $CVSROOT/CVSROOT.  Se não fizer, tem algo errado (see Paus).  Para adicionar os seus próprios arquivos aos arquivos a serem atualizados desta maneira, você pode adicioná-los ao arquivo administrativo  checkoutlist (see checkoutlist).

Por padrão o arquivo modules se comporta como descrito acima.  Se o arquivo modules é muito grande, guardar ele como um arquivo de texto normal faz a busca por módulos lenta (Não estou bem certo se isso importa tanto agora como quando o CVS primeiramente desenvolveu esta habilidade; não vi avaliações). Entretanto, fazendo edições apropriadas no código fonte do CVS pode-se guardar o arquivo modules num banco de dados que implementa a interface ndbm, tais como o Berkeley db ou GDBM.  Se esta opção está em uso, então o banco de dados modules será guardado nos arquivos modules.db, modules.pag, e/ou modules.dir.

Para informações sobre o significado dos vários arquivos administrativos, veja em Arquivos administrativos.

Como os dados são guardados no diretório de trabalho
====================================================

Assim como estamos conversando sobre as entranhas do CVS, que podem ficar visíveis de tempos em tempos, também devemos falar sobre o que o CVS bota nos diretórios CVS nos diretórios de trabalho. Assim como com o repositório, o CVS manipula esta informação e pode-se acessá-la normalmente via comandos CVS.  Mas em alguns casos pode ser útil dar uma olhada, e outros programas, como a interface de usuário gráfica jCVS ou o pacote para emacs VC, precisarem ver o que tem lá.  Tais programas devem seguir as recomendações nesta seção se eles querem interagir com outros programas que usam estes arquivos, inclusive versões futuras dos programas mencinados logo acima e o  cliente em linha-de-comando do CVS.

O diretório CVS contém vários arquivos.  Programas que estão lendo este diretório devem ignorar em silêncio arquivos que encontrem no diretório mas que não estejam documentados aqui, para permitir expansões futuras.

Os arquivos são guardados de acordo com a convenção de arquivo de texto do sistema em questão.  Isto significa que diretórios de trabalho não são portáveis entre sistemas com diferentes convenções para armazenar arquivos de texto.  Isto é de propósito, baseado na teoria de que os arquivos sendo gerenciados pelo CVS provavelmente também não seriam portáveis entre tais sistemas.

Root
     Este arquivo contém a raiz atual do CVS, como descrito em Especificando um repositório.

Repositório
     Este arquivo contém o diretório no qual está o repositório correspondente ao diretório atual.  Pode ser um caminho absoluto ou relativo; CVS adquiriu a habilidade de ler ambos os formatos desde a versão 1.3.  O caminho é relativo à raiz (root), e é a abordagem mais racional, mas o caminho absoluto é mais comum e ambos devem ser aceitos.  Por exemplo, depois do comando

          cvs -d :local:/usr/local/cvsroot checkout yoyodyne/tc

     o Root vai conter

          :local:/usr/local/cvsroot

     e o Repositório vai conter ou

          /usr/local/cvsroot/yoyodyne/tc

     ou

          yoyodyne/tc

     Se o diretório de trabalho particular não corresponde a um diretório no repositório, então o Repositório deve conter CVSROOT/Emptydir.

Entries
     Este arquivo relaciona os arquivos e diretórios no diretório de trabalho.  O primeiro caractere de cada linha indica de que tipo é a linha.  Se  caractere não for reconhecido, os programas lendo o arquivo devem pular de linha em silêncio, para permitir futuras expansões.

     Se o primeiro caractere é /, então o formato é:

          /NAME/REVISION/TIMESTAMP[+CONFLICT]/OPTIONS/TAGDATE

     Onde [ e ] não são partes da entrada, mas indicam que o + e o marcador de conflito são opcionais.  NAME é o nome do arquivo no diretório.  REVISION e a revisão da qual o arquivo no diretório de trabalho deriva, ou 0 para um arquivo adicionado, ou - seguido de uma revisão para um arquivo removido.  TIMESTAMP é o ???timestamp??? do arquivo quando o CVS o criou; se o timestamp difere da hora de modificação do arquivo, significa que o arquivo foi modificado.  É armazenado no formato usando pela função ISO C asctime() (por exemplo, Sun Apr  7 01:29:26 1996).  Pode-se escrever uma string que não esteja neste formato, por exemplo, Result of merge, para indicar que o arquivo deve ser sempre considerado como modificado.  Este não é um caso especial; para ver se um arquivo é modificado, um programa pode pegar o timestamp do arquivo e simplesmente criar uma string e comparar com TIMESTAMP.  Se existe um conflito, CONFLICT pode ser ajustada para o tempo de modificação do arquivo depois do arquivo ter sido escrito com marcações de conflito (see Exemplo de conflitos). Logo, se CONFLICT é posteriormente o mesmo que o tempo de modificação real do arquivo significa que o usuário obviamente não resolveu o conflito.  OPTIONS contém opções adesivas (por exemplo -kb para um arquivo binário).  TAGDATE contém T seguindo de um nome de etiqueta (tag), ou D para uma data, seguido de uma data ou etiqueta adesiva. Observe que se TIMESTAMP contém um par de timestamps separados por um espaço, ao invés de um único timestamp, você está lidando com uma versão do CVS anterior ao CVS 1.5 (sem documentação aqui).

     O fuso horário do timestamp no CVS/Entries (local ou universal) deve ser igual ao que o sistema operacional guarda para o timestamp do próprio arquivo. Por exemplo, no Unix o timestamp do arquivo está em tempo universal (universal time - UT).  Logo, o timestamp em CVS/Entries deve estar assim também.  No VMS, o timestamp do arquivo está em hora local, logo, o CVS no VMS deve usar hora local.  Esta regra é para que arquivos não pareçam estar modificados simplesmente por que o fuso horário mudou (por exemplo, saindo ou entrando no horário de verão).

     Se o primeiro caractere de uma linha em Entries é D, então ele indica um subdiretório.  D sozinho em uma linha indica que o programa que escreveu o arquivo Entries registra subdiretórios (portanto, se existe tal linha e nenhuma outra linha começando com D, conclui-se que não há subdiretórios).  Caso contrário, a linha vai se parecer com:

          D/NAME/FILLER1/FILLER2/FILLER3/FILLER4

     onde NAME é o nome do subdiretório, e todos os campos FILLER devem ser ignorados em silêncio, para expansões futuras.  Programas que modificam arquivos Entries devem manter estes campos.

     As linhas no arquivo Entries podem estar em qualquer ordem.

Entries.Log
     Este arquivo não registra qualquer informação a mais que no Entries, mas fornece um jeito de atualizar a informação sem ter que reescrever todo o arquivo Entries, incluindo a habilidade de preservar a informação mesmo se o programa que estava escrevendo o Entries e o Entries.Log aborta abruptamente.  Programas que estão lendo o arquivo Entries devem também verificar pelo Entries.Log.  Se este último existe, eles devem ler o Entries e então aplicar as mudanças mencionadas no Entries.Log.  Depois de aplicar as mudanças, a prática recomendada é reescrever o Entries e depois apagar o Entries.Log.  O formato de uma linha no Entries.Log é um comando de um caractere seguido de um espaço seguido por uma linha no formato especificado para uma linha no Entries.  O caractere de comando é A para indicar que a entrada está sendo adicionada, R para indicar que a entrada está sendo removida, ou qualquer outro caractere para indicar que a linha inteira em Entries.Log deve ser ignorada em silêncio (para expansão futura).  Se o segundo caractere da linha em Entries.Log não é um espaço, então foi escrito por uma versão antiga do CVS (não documentada aqui).

     Programas que estão escrevendo ao invés de lendo podem seguramente ignorar Entries.Log se assim escolherem.

Entries.Backup
     Este é um arquivo temporário.  O uso recomendado é escrever um novo arquivo entries para o Entries.Backup, e então renomeá-lo (atomicamente, quando possível) para Entries.

Entries.Static
     A única coisa relevante sobre este arquivo é se ele existe ou não.  Se ele existe, então quer dizer que apenas parte de um diretório foi pego e o CVS não vai criar arquivos adicionais neste diretório.  Para limpar isto, use o comando update com a opção -d, a qual vai pegar os arquivos adicionais e remover Entries.Static.

Tag (Etiqueta)
     Este arquivo contém as etiquetas (tags) ou datas adesivas por diretório.  O primeiro caractere é T para uma etiqueta de ramo, N para uma etiqueta que não é de ramo, ou D para uma data, ou outro caractere que quer dizer que o arquivo deve ser ignorado em silêncio, para expansão futura.  Este caractere é seguido de uma etiqueta ou data.  Observe que etiquetas ou data adesivas por diretório são usadas para coisas como ???applying to??? arquivos que acabaram de ser adicionados; ???they (the tags or the files)??? podem não ser os mesmos assim como as etiquetas adesivas ou datas em arquivos isolados.  Para informações gerais sobre etiquetas adesivas ou datas, veja em Etiquetas adesivas.

Notify
     Este arquivo guarda notificações (por exemplo, sobre edit ou unedit) que ainda não foram mandadas para o servidor.  Seu formato ainda não está documentado aqui.

Notify.tmp
     Este arquivo está para Notify como o Entries.Backup está para Entries.  Ou seja, para escrever em Notify, escreva o novo conteúdo primeiro em Notify.tmp e então (atomicamente, quando possível), renomeie-o para Notify.

Base
     Se os ???watches??? estão em uso, então um comando edit guarda a cópia original do arquivo no diretório Base.  Isto permite que o comando unedit opere mesmo se estiver sem comunicação com o servidor.

Baserev
     O arquivo lista a revisão de cada arquivo no diretório Base.  O formato é:

          BNAME/REV/EXPANSION

     Onde EXPANSION deve ser ignorada para permitir expansão futura.

Baserev.tmp
     Este arquivo está para Baserev assim como Entries.Backup está para Entries.  Ou seja, para escrever em Baserev, escreva o novo conteúdo primeiro em Baserev.tmp e então (atomicamente, quando possível), renomei-o para Baserev.

Template
     Este arquivo contém o modelo (template) especificado pelo arquivo rcsinfo (see rcsinfo).  Ele é usado apenas pelo cliente; o ???non-client/server??? CVS consulta o rcsinfo diretamente.

Os arquivos administrativos
===========================

O diretório $CVSROOT/CVSROOT contém alguns Arquivos administrativos.  See Arquivos administrativos, para uma descrição completa.  Você pode usar o CVS sem nenhum destes arquivos, mas alguns comandos funcionam melhor quando pelo menos o arquivo modules está bem configurado.

O mais importante destes arquivos é o arquivo modules.  Ele define todos os módulos no repositório.  Este é um exemplo de um arquivo modules.

     CVSROOT         CVSROOT
     modules         CVSROOT modules
     cvs             gnu/cvs
     rcs             gnu/rcs
     diff            gnu/diff
     tc              yoyodyne/tc

O arquivo modules é baseado em linha.  Na sua forma simples, cada linha contém o nome do módulo, um espaço e o diretório onde o módulo está.  O diretório é um caminho relativo em $CVSROOT.  As últimas quatro linhas no exemplo acima são exemplos de tais linhas.

A linha que define o módulo chamado modules usa funcionalidades que não são explicadas aqui. See modules, para uma explicação completa destas funcionalidades.

Editando arquivos administrativos
---------------------------------

Você edita os arquivos administrativos da mesma forma que você deve deve editar qualquer outro módulo.  Use cvs checkout CVSROOT para obter uma cópia de trabalho, edite-a e ???commit??? suas mudanças normalmente.

É possível ???commit??? um arquivo administrativo corrompido.  Em geral, você pode consertar o erro e devolvê-lo numa nova revisão, mas às vezes um erro particularmente ruim nos arquivos administrativos torna impossível ???commit??? novas revisões.

Repositórios múltiplos
======================

Em algumas situações é uma boa idéia ter mais de um repositório.  Por exemplo, se você tem duas equipes de desenvolvimento que trabalham em projetos separados sem compartilhar nenhum código.  Tudo que você tem que fazer para ter vários repositórios é especificar o repositório apropriado, usando a variável de ambiente CVSROOT ou a opção -d com o CVS, ou (depois de ter pego um diretório de trabalho) simplesmente deixando o CVS usar o repositório de onde veio o diretório de trabalho (see Especificando um repositório).

A grande vantagem de ter múltiplos repositórios é que eles podem residir em diferentes servidores.  Com o CVS versão 1.10, um comando não pode fazer recursão ???into??? diretórios ???from??? repositórios diferentes.  Com ???development versions??? do CVS, você pode obter código de múltiplos servidores para o seu diretório de trabalho.  CVS vai fazer a recursão e cuidar dos detalhes para fazer conexão em quantas máquinas quantas forem necessárias para executar o comando pedido.  Aqui está um exemplo de como preparar um diretório de trabalho:

     cvs -d server1:/cvs co dir1
     cd dir1
     cvs -d server2:/root co sdir
     cvs update

Os comandos cvs co acima preparam o diretório de trabalho.  Depois de feitos, o comando cvs update vai contactar o server2, para atualizar o subdiretório dir1/sdir e o server1, para atualizar o resto.

Criando um repositório
======================

Para preparar um repositório do CVS, escolha primeiramente a máquina e o disco onde você deseja armazenar o histórico de revisões dos fontes. requisitos de CPU e memória são modestos.  Portanto, muitas máquinas serão adequadas.  Para detalhes, veja em Requisitos do servidor.

Para estimar os requisitos de espaço em disco, se você estiver importando arquivos RCS de outro sistema, o tamanho destes arquivos vai ser o tamanho inicial do seu repositório, ou se você está começando sem nenhum histórico de versões, uma boa regra é reservar para o repositório do servidor três vezes o tamanho do código que estará sob os cuidados do CVS (Isto vai eventualmente estourar, mas não por enquanto). Nas máquinas dos desenvolvedores, você vai pracisar de aproximadamente o espaço em disco de um diretório de trabalho para cada desenvolvedor (ou a árvore inteira ou uma porção dela, dependendo do que o desenvolvedor usa).

O repositório deve estar acessível (diretamente ou através de um sistema de arquivos de rede) ???from??? todas as máquinas que queiram usar o CVS em modo servidor ou localmente; a máquina cliente só precisa ter acesso a ele através do protocolo do CVS.  Não é possível usar o CVS para ler de um repositório onde só se tem permissão de leitura, pois o CVS tem que ser capaz de criar arquivos de trava (see Concorrência).

Para criar um repositório, rode o comando cvs init.  Ele vai criar um repositório vazio no raiz do CVS especificado da forma usual (see Repositório).  For example,

     cvs -d /usr/local/cvsroot init

O cvs init tem o cuidado de nunca sobreescrever nenhum arquivo no repositório, logo, não há perigo em rodar o cvs init num repositório já criado.

cvs init pode guardar um registro histórico (history log); se você não quer guardar isto, remova o arquivo history depois de rodar o cvs init.  See arquivo history (histórico).

Fazendo backup de um repositório
================================

Não há nada particularmente mágico sobre os arquivos no repositório; Para a maior parte deles é possível fazer backup da mesma forma que com qualquer arquivo.  Entretanto, existem alguns fatos a considerar.

Primeiramente, para ser paranóico, alguem não deve nem sequer usar o CVS durante o backup, ou fazer o programa de backup travar o CVS enquanto estiver executando.  Para o CVS não ser usado, você deve proibir logins para máquinas que possam acessar o repositório ou desligar o seu servidor CVS or algum mecanismo similar.  Os detalhes vão depender do seu sistema operacional e de como você configurou o seu CVS.  Para travar o CVS, você deve criar travas #cvs.rfl em cada diretório do repositório.  Veja em Concorrência, para saber mais sobre travas no CVS.  ???Having said all this???, se você apenas fizer o backup sem nenhuma destas precauções, os resultados dificilmente vão ser catastróficos.  Ao recuperar do backup, o repositório pode estar em um estado inconsistente, mas isto não deve ser muito difícil de consertar manualmente.

Quando você recupera um repositório de um backup, supondo que mudanças no repositório foram feitas depois da criação do backup, diretório de trabalho que não foram afetados pela falha podem se referenciar a revisões que não mais existam no repositório.  Tentar rodar o CVS em tais diretórios vai gerar uma mensagem de erro.  uma forma de desfazer estas mudanças no repositório é dada a seguir:

  * Gere um novo diretório de trabalho.

  * Copie os arquivos do diretório de trabalho de antes da falha para o novo diretório de trabalho (não copie o conteúdo dos diretórios CVS, obviamente).

  * Mexa no novo diretório de trabalho, usando comandos como cvs update e cvs diff para descobrir o que mudou, e quando terminar, faça ???commit??? nas mudanças para o repositório.

Movendo um repositório
======================

Assim como fazer backup dos arquivos no repositório é muito parecido com fazer backup de quaisquer outros arquivos, se você precisar mover um repositório de um lugar para outro, é muito parecido com simplesmente mover uma coleção de arquivos.

O mais importante a se considerar é que diretórios de trabalho apontam para o repositório.  A forma mais simples de lidar com um repositório movido é simplesmente pegar um diretório de trabalho novo logo após da mudança.  É claro que você vai querer se certificar que o diretório de trabalho antigo foi devolvido antes da mudança, ou usar de qualquer outro artifício para se certificar de que não perderá nenhuma mudança.  Se você realmente quer reusar o antigo diretório de trabalho, é possível, desde que você faça uma operação manual nos arquivos CVS/Repository.  Você pode ver em Armazenamento do Diretório de trabalho, para informações sobre os arquivos CVS/Repository e CVS/Root, mas só se você quiser ter aborrecimentos, caso contrário esta opção não é boa.

Repositórios remotos
====================

Sua cópia de trabalho dos fontes pode estar em uma máquina diferente da do repositório.  Esta forma de usar o CVS é chamada operação client/server.  Você roda o CVS numa máquina que possa montar seu diretório de trabalho, conhecida como o cliente, e diz a ela para se comunicar com uma máquina que pode montar o repositório, chamada de servidor.  No geral, usar um repositório remoto é a mesma coisa que usar um local, exceto que o formato do nome do repositório é:

     [:METHOD:][[USER][:PASSWORD]@]HOSTNAME[:[PORT]]/path/to/repository

Colocar a senha no nome do repositório durante operações de checkout não é recomendado, já que isto vai fazer com que o CVS guarde uma cópia da senha em texto em cada diretório criado.  Dê um cvs login primeiro ao invés disto (see Cliente de autenticação por senha).

Os detalhes de exatamente o que precisa ser preparado depende de como você está conectado ao seu servidor.

Se METHOD não está especificado, e se o nome do repositório contém :, então o padrão é ext ou server, dependendo de sua plataforma; ambos estão descritos em Se conectando via rsh.

Requisitos do servidor
----------------------

A resposta rápida para que tipo de máquina é adequada para um servidor é que os requisitos são modestos---um servidor com 32M de memória ou até menos pode manipular uma árvore de fontes realmente grande com uma boa quantidade de atividade.

A resposta real, obviamente, é mais complicada.  Estimar as áreas conhecidas de grande consumo de memória deve ser suficiente para estimar os requisitos de memória.  Existem duas destas tais áreas documentadas aqui; Outros consumos de memória devem ser pequenos relativamente (se você notar que este não é o caso, nos faça saber, como descrito em Paus, assim poderemos atualizar este documento).

A primeira área de grande consumo de memória são os grandes checkouts, quando usando o servidor CVS. O servidor consiste de dois processos para cada cliente que está servindo.  O consumo de memória no processo filho deve permanecer pequeno.  O consumo de memória no processo pai, perticularmente se a conexão de rede com o cliente é pequena, pode crescer para algo um pouco maior que o tamanho dos fontes num diretório, ou dois megabytes, o que for maior.

Multiplicando o tamanho de cada servidor CVS pelo número de servidores que você espera ter ativos em cada momento deve dar uma idéia dos requisitos de memória para cada servidor.  Para a maior parte, a memória consumida pelo processo pai pode provavelmente ser espaço de troca ao invés de memória física.

A segunda área de grande consumo de memória é o diff, quando trazendo grandes arquivos.  Isto é preciso mesmo para arquivos binários.  A boa prática é permitir cerca de dez vezes o tamanho do maior arquivo que você vai devolver ao servidor, embora cinco vezes seja adequado.  Por exemplo, se você quer devolver um arquivo de 10 megabytes, você deve ter 100 megabytes of memory na máquina fazendo a devolução (o servidor para o caso cliente/servidor, ou a máquina rodando o CVS para não-cliente/servidor).  Esta memória pode ser espaço de troca ao invés de memória física.  Já que a memória é requerida apenas brevemente, não existe necessidade especial para fornecer memória para mais de uma devolução ao mesmo tempo.

O consumo de recursos no cliente é ainda mais modesto---qualquer máquina com capacidade suficiente para rodar o SO em questão não deve ter muitos problemas.

Para informações sobre requisitos de espaço em disco, veja em Criando um repositório.

Se conectando via rsh
---------------------

O CVS usa o protocolo rsh para realizar estas operações, logo, a máquina do usuário remoto tem que ter um arquivo .rhosts que dê acesso para o usuário local.  Observe que o programa que o CVS usa para este objetivo deve ser especificado usando a opção --with-rsh para configurar.

Por exemplo, suponha que você é o usuário mozart na máquina local toe.example.com, e a máquina servidora é faun.example.org.  Em faun, ponha a seguinte linha no arquivo .rhosts no diretório pessoal de bach:

     toe.example.com  mozart

E faça o teste para ver que o rsh está funcionando com

     rsh -l bach faun.example.org 'echo $PATH'

A seguir você vai ter que se certificar que o rsh vai ser capaz de acessar o servidor. Verifique se o caminho que o rsh mostrou no exemplo acima inclui o diretório contendo um programa chamado cvs que está no servidor.  Você precisa ajustar o caminho no .bashrc, .cshrc, etc., não no .login ou no .profile. Alternativamente, você pode ajustar a variável de ambiente CVS_SERVER na máquina cliente para o nome do arquivo do servidor que você quer usar, por exemplo /usr/local/bin/cvs-1.6.

Não há necessidade de se editar o inetd.conf ou iniciar um daemon (serviço) servidor de CVS.

Existem dois métodos de acesso que você pode usar no CVSROOT para rsh.  :server: especifica um cliente rsh interno, que é suportado apenas por alguns portes do CVS.  :ext: especifica um programa rsh externo.  Por padrão é o rsh (a menos que se especifique o contrário pela opção --with-rsh) mas você pode ajustar a variável de ambiente CVS_RSH para invocar outro programa que pode acessar o servidor remoto (por exemplo, remsh num HP-UX 9 já que o rsh é de certa forma diferente).  Deve ser um programa que transmita dados de e para o servidor sem modificar nada; por exemplo, o rsh do Windows NT não é adequado já que por padrão ele permuta CRLF com LF.  O porte do CVS para OS/2 tem um ???hack??? para passar -b para o rsh para contornar isso, mas já que isso pode potencialmente causar problemas para outros programas que não sejam o rsh padrão, isso deve mudar no futuro.  Se você ajustar o CVS_RSH para SSH ou algum outro substituto do rsh, as instruções no restante desta seção a respeito do arquivo .rhosts e outros provavelmente não se aplicarão; consulte a documentação do seu substituto do rsh.

Continuando nosso exemplo, supondo que você quer acessar o módulo foo no repositório /usr/local/cvsroot/, da máquina faun.example.org, você está pronto para seguir:

     cvs -d :ext:bach@faun.example.org:/usr/local/cvsroot checkout foo

(O bach@ pode ser omitido se o nome de usuário é o mesmo tanto no servidor como no cliente.)

Conexões diretas com autenticação por senha
-------------------------------------------

O cliente CVS também pode se conectar ao servidor usando um protocolo de senha.  Isto é particularmente útil se não se pode usar o rsh (por exemplo, se o servidor está atrás de um firewall), e o Kerberos também não está disponível.

Para usar este método é necessário fazer ajustes tanto do lado do cliente como no do servidor.

Ajustando o servidor para autenticação por senha
................................................

Antes de tudo, você provavelmente vai querer amarrar as permissões nos diretórios $CVSROOT e $CVSROOT/CVSROOT.  Veja em Segurança com autenticação por senha para mais informações.

No lado do servidor, o arquivo /etc/inetd.conf precisa ser editado para que o inetd saiba rodar o comando cvs pserver quando ele recebe uma conexão pela porta certa.  Por padrão, a porta de número 2401; entretanto, isto pode ser diferente se seu cliente foi compilado com CVS_AUTH_PORT definido para outra coisa.  Esta porta também pode ser especificada na variável CVSROOT (see Repositórios remotos) ou sobreescrita com a variável de ambiente CVS_CLIENT_PORT (see Variáveis de ambiente).

Se seu inetd permite ???raw port numbers??? no /etc/inetd.conf, então o seguinte (tudo na mesma linha do inetd.conf) deve ser suficiente:

     2401  stream  tcp  nowait  root  /usr/local/bin/cvs
     cvs -f --allow-root=/usr/cvsroot pserver

(Você pode usar também a opção -T para especificar um diretório temporário.)

A opção --allow-root especifica o diretório CVSROOT permitido.  Clientes que tentem usar um diretório CVSROOT diferente não conseguirão se conectar.  Se você quer permitir mais de um diretório CVSROOT, repita a opção. (Infelismente, muitas versões do inetd têm um limite muito baixo do número de argumentos e/ou do comprimento total do comando.  A solução usual para este problema é fazer o inetd rodar um script de shell que invoque o CVS com os argumentos necessários.)

Se seu inetd precisa de um nome simbólico de serviço ao invés de um número de porta, ponha em /etc/services:

     cvspserver      2401/tcp

e ponha cvspserver no lugar de 2401 no inetd.conf.

Se seu sistema usa xinetd no lugar de inetd, o procedimento é um pouco diferente.  Crie um arquivo chamado /etc/xinetd.d/cvspserver contendo o seguinte:

     service cvspserver
     {
        port        = 2401
        socket_type = stream
        protocol    = tcp
        wait        = no
        user        = root
        passenv     = PATH
        server      = /usr/local/bin/cvs
        server_args = -f --allow-root=/usr/cvsroot pserver
     }

(Se cvspserver é definido no /etc/services, você pode omitir a linha port.)

Uma vez que as instruções acima foram seguidas, reinicie seu inetd, ou faça o que for necessário para forçá-lo a reler seus arquivos de inicialização.

Se você enfrentar problemas, veja em Conexão.

Como o cliente guarda e transmite as senhas em texto simples (praticamente---veja Segurança com autenticação por senha para detalhes), um arquivo de senhas do CVS é geralmente usado, de forma que as pessoas nao comprometam suas senhas regulares quando acessam o repositório.  Este arquivo é o $CVSROOT/CVSROOT/passwd (see Intro aos arquivos administrativos).  Ele usa um formato separado por dois pontos, similar ao do /etc/passwd dos sistemas Unix, exceto que este tem menos campos: nome do usuário CVS, senha opcional, e um nome de usuário de sistema opcional para o CVS rodar como ele se ocorrer a autenticação. Aqui está um exemplo de arquivo passwd com cinco entradas:

     anonymous:
     bach:ULtgRLXo7NRxs
     spwang:1sOp854gDF3DY
     melissa:tGX1fS8sun6rY:pubcvs
     qproj:XR4EZcEs0szik:pubcvs

(As senhas são criptografadas de acordo com a função Unix crypt() padrão, portanto é possível copiar senhas diretamente de arquivos /etc/passwd normais do Unix.)

A primeira linha no exemplo vai dar acesso a qualquer cliente CVS que tente se autenticar como o usuário anonymous (anônimo), qualquer que seja a senha que ele esteja usando, até mesmo uma senha vazia. (Isto é típico de sítios que dão acesso somente-leitura anônimo; para informações sobre como fazer a parte "somente-leitura", veja em Acesso somente-leitura.)

As segunda e terceira linhas vão fornecer acesso a bach e spwang se eles fornecerem suas respectivas senhas em texto simples.

A quarta linha vai dar acesso a melissa, se ela fornecer a senha correta, mas suas opareções no CVS vão ser rodadas, na verdade, como o usuário de sistema pubcvs no lado do servidor.  Logo, não há a necessidade de haver qualquer usuário chamado melissa, mas tem que haver um chamado pubcvs.

A quinta linha mostra que identidades de usuários de sistema podem ser compartilhadas: qualquer cliente que se autentique com sucesso como qproj vai na verdade rodar como pubcvs, da mesma forma que melissa faz.  Desta forma você pode criar um único e compartilhado usuário de sistema para cada projeto no seu repositório, e dar a cada desenvolvedor sua própria linha no arquivo $CVSROOT/CVSROOT/passwd.  O nome de usuário do CVS em cada linha vai ser diferente, mas o usuário de sistema vai ser o mesmo.  A razão para se ter diferentes nomes de usuários do CVS é que o CVS vai registrar suas ações sob estes nomes: quando melissa submete (commit) uma mudança ao projeto, o checkin é gravado no histórico do projeto em nome de melissa, não de pubcvs.  E a razão para tê-los compartilhando um usuário de sistema é que você pode ajeitar as permissões da área relevante do repositório de forma que apenas aquela conta tenha permissão de leitura lá.

Se o campo do usuário de sistema está presente, todos os comandos do CVS com autenticação por senha rodarão como aquele usuário; se nenhum usuário é especificado, o CVS simplesmente vai usar o nome de usuário do CVS como o nome de usuário de sistema e rodar os comandos como este usuário.  Em qualquer caso, se não existir tal usuário no sistema, a operação do CVS vai falhar (independente do cliente ter fornecido uma senha válida).

Os campos de senha e usuário de sistema podem ser ambos omitidos (e se o campo de usuário de sistema for omitido, então a vírgula que o separava da senha criptografada também pode ser omitida).  Por exemplo, isto pode ser um arquivo $CVSROOT/CVSROOT/passwd válido:

     anonymous::pubcvs
     fish:rKa5jzULzmhOo:kfogel
     sussman:1sOp854gDF3DY

Quando o campo senha não existe ou é vazio, então uma tentativa de autenticação do cliente vai funcionar qualquer que seja a senha, inclusive a senha vazia. Entretanto, o dois pontos antes do nome de usuário do CVS é sempre necessário, mesmo se a senha for vazia.

O CVS também pode recorrer à autenticação do sistema.  Quando autenticando uma senha, o servidor primeiro procura pelo usuário no arquivo $CVSROOT/CVSROOT/passwd.  Se ele encontra o usuário, ele vai usar aquela entrada para autenticar como descrito acima.  Mas se o usuário não for encontrado, ou se o arquivo passwd do  CVS não existe, então o servidor pode tentar autenticar o nome de usuário e a senha usando as rotinas de ???user-lookup??? do sistema operacional (Este comportamento "alternativo" pode ser desabilitado ajustando o SystemAuth=no no arquivo config do CVS, see config).

O comportamento alternativo é procurar no /etc/passwd por este usuário de sistema a menos que seu sistema tenha PAM (Pluggable Authentication Modules) e seu servidor do CVS executável foi configurado para usar PAM em tempo de compilação (usando ./configure --enable-pam - veja no arquivo INSTALL para saber mais).  Neste caso, PAM é que vai autenticar.  Isto significa que o CVS pode ser configurado para usar qualquer fonte de autenticação por senha que PAM possa ser configurada para usar (as possibilidades incluem senha simples de UNIX, NIS, LDAP, e outras) no seu arquivo de configuração global (em geral /etc/pam.conf ou possivelmente /etc/pam.d/cvs).  Veja em sua documentação do PAM para mais detalhes sobre a configuração do PAM.

Observe que PAM é uma funcionalidade experimental no CVS e feedback é encorajado.  Por favor, mande e-mail para uma das listas do CVS (info-cvs@nongnu.org ou bug-cvs@nongnu.org) se você usa o suporte a PAM do CVS.  As listas são em inglês.

ATENÇÃO: Usar PAM dá ao administrador do sistema muito mais flexibilidade sobre como os usuários do CVS são autenticados mas não dá mais segurança que outros métodos.  Veja abaixo mais detalhes.

CVS precisa de um módulo "auth" e "account" no arquivo de configuração PAM.  Uma configuração PAM típica deve portanto ter as seguintes linhas no /etc/pam.conf para simular a autenticação /etc/passwd do sistema CVS padrão:

     cvs	auth	    required	pam_unix.so
     cvs	account	    required	pam_unix.so

O /etc/pam.d/cvs equivalente deve conter

     auth	    required	pam_unix.so
     account	    required	pam_unix.so

Alguns sistemas necessitam de um caminho completo para o módulo de forma que pam_unix.so (Linux) vai se tornar algo do tipo /usr/lib/security/$ISA/pam_unix.so.1 (Sun Solaris).  Veja o subdiretório contrib/pam da distribuição em código fonte do CVS para mais exemplos de configuração.

O nome de serviço PAM dado abaixo como "cvs" é apenas o nome do serviço na configuração padrão e pode ser mudado usando ./configure --with-hardcoded-pam-service-name=<pam-service-name> antes de compilar.  ??? CVS can also be configured to use whatever name it is invoked as as its PAM service name using ./configure --without-hardcoded-pam-service-name???, mas esta característica não deve ser usada se você não tiver controle do nome com o qual o CVS será chamado.

Esteja avisado, além disso, que recorrer a autenticação do sistema pode ser um risco de segurança: as operações do CVS deveram ser autenticadas com a senha do usuário regular, e a senha vai passar pela rede em texto plano.  Veja em Segurança com autenticação por senha para saber mais.  Isto pode ser um problema a mais com autenticação PAM por que é provável que a fonte do sistema de senhas é algum serviço de autenticação central como o LDAP, que é usado para autenticar outros serviços.

Por outro lado, PAM faz com que seja fácil mudar a senha regularmente.  Se os usuários têm um sistema de senha única, são mais fáceis de convencer a trocar de senha regularmente.

Numa configuração não-PAM, onde a senha é guardada no arquivo CVSROOT/passwd, é difícil mudar as senhas regularmente já que apenas usuários administradores (ou em alguns casos, processos que agem como usuários administradores) têm acesso de escrita ao arquivo.  ???Either there needs to be some hand-crafted web page or set-uid program to update the file, or the update needs to be done by submitting a request to an administrator to perform the duty by hand???.  No primeiro caso, ter que lembrar de uma senha a parte periodicamente pode ser difícil.  No segundo caso, a natureza manual da mudança vai significar que a senha não vai ser mudada até que seja absolutamente necessário.

Observe que os administradores do PAM vão evitar configurar one-time-passwords (OTP) para autenticação/autorização do CVS.  Se os OTPs são desejados, o administrador vai querer encorajar o uso de um dos outros métodos de acesso cliente/servidor. Veja a seção em see Repositórios remotos para uma lista de outros métodos.

Por agora, a única forma de botar uma senha no arquivo passwd do CVS é colar de algum outro lugar. Algum dia vai haver um comando cvs passwd.

Ao contrário da maioria dos arquivos no $CVSROOT/CVSROOT, é normal editar o arquivo passwd in loco, ao invés de pelo CVS.  Isto é devido a possíveis riscos de segurança ao se ter cópias do arquivo passwd baixadas para o diretório de trabalho das pessoas.  Se você quer incluir o arquivo passwd nos checkouts de $CVSROOT/CVSROOT, veja em checkoutlist.

Usando o cliente com autenticação por senha
...........................................

Para rodar um comando CVS num repositório remoto via servidor de autenticação por senha, deve-se espedificar o protocolo pserver, um nome de usuário opcional, a máquina do repositório, uma porta opcional, e o caminho para o repositório.  Por exemplo:

     cvs -d :pserver:faun.example.org:/usr/local/cvsroot checkout someproj

or

     CVSROOT=:pserver:bach@faun.example.org:2401/usr/local/cvsroot
     cvs checkout someproj

Entretanto, a menos que você esteja conectado a um repositório de acesso público (i.e., um daqueles que o usuário não precisa de senha), você vai precisar fornecer uma senha ou se logar antes.  Ao se logar, a sua senha é comparada com a do repositório e guardada num arquivo.  Isto é feito com o comando login, que vai pedir a sua senha interativamente se você não forneceu ela como parte do $CVSROOT:

     cvs -d :pserver:bach@faun.example.org:/usr/local/cvsroot login
     CVS password:

or

     cvs -d :pserver:bach:p4ss30rd@faun.example.org:/usr/local/cvsroot login

Depois de fornecer a senha, o CVS a verifica no servidor.   Se a verificação procede, então esta combinação de usuário, máquina, repositório e senha é gravada permanentemente de forma que futuras transações com este repositório não vão requerer a execução de cvs login.  (Se a verificação falhar, CVS vai sair avisando que a senha está incorreta e nada vai ser gravado.)

A gravação é feita, por padrão, no arquivo $HOME/.cvspass.  O arquivo tem formato legível, e num certo nível, editável, mas observe que as senhas não são guardadas em texto plano---elas são codificadas trivialmente para proteger contra ???compromise??? "inocente" (i.e., um administrador desavisado dar uma olhada ou outra pessoa sem segundas intenções).

Você pode  mudar o local padrão deste arquivo ajustando a variável de ambiente CVS_PASSFILE.  Se você usar esta variável, certifique-se de fazer isto antes de rodar cvs login.  Se você fizer isto depois de rodar o cvs login, então mais tarde os comandos do CVS vão ser incapazes de encontrar a senha para mandar para o servidor.

Uma vez que você esteja autenticado, todos os comandos do CVS que usam o repositório remoto e senha vão se autenticar com a senha armazenada.  Então, por exemplo

     cvs -d :pserver:bach@faun.example.org:/usr/local/cvsroot checkout foo

vai funcionar (a menos que a senha mude no servidor, onde neste caso você vai ter que rodar de novo cvs login).

Observe que se o :pserver: não estiver presente na especificação do repositório, o CVS vai assumir que deve usar o rsh para se conectar com o servidor, neste caso (see Se conectando via rsh).

É claro que, uma vez que você tenha uma cópia de trabalho baixada e está rodando comandos CVS de dentro dela, não existe mais a necessidade de explicitar o repositório, já que o CVS pode deduzir o repositório a partir do subdiretório CVS da cópia de trabalho.

A senha para um dado repositório remoto pode ser removida do CVS_PASSFILE usando o comando cvs logout.

Considerações de segurança com autenticação por senha
.....................................................

As senhas são guardadas no cliente com uma codificação trivial de texto, e transmitidas na mesma codificação. Esta codificação é feita apenas para prevenir uma quebra de segredo inadvertida (i.e., um administrador de sistema acidentalmente olhar o arquivo), e não evita nem mesmo que um atacante ingênuo consiga a senha.

O arquivo de senhas do CVS em separado (see Servidor de autenticação por senha) permite que as pessoas usem uma senha de acesso ao repositório deferente da senha de login.  Por outro lado, uma vez que um usuário tenha acesso maior que somente-leitura, ele pode executar programas no sistema do servidor de várias formas.  Então, o acesso ao repositório implica acesso ao sistema como um todo.  É possível modificar o CVS para evitar isto, mas até agora ninguem agiu neste sentido.

observe que já que o diretório $CVSROOT/CVSROOT contém o arquivo passwd e outros arquivos que são usados para verificações de segurança, você deve controlar as permissões neste diretório com o mesmo cuidado que tem com as permissões em /etc.  O mesmo se aplica ao próprio diretório $CVSROOT e qualquer diretório acima dele na árvore de diretórios. Qualquer pessoas que tenha permissão de escrita a algum destes diretórios vai ter a habilidade de se tornar qualquer usuário do sistema.  Observe que estas permissões são em geral mais rígidas que as que você usaria se você não estivesse usando o pserver.

Resumindo, qualquer um que consiga as senhas vai ter acesso ao repositório (que implica de certa forma acesso ao sistema em geral).  A senha está disponível para qualquer um que possa ???sniff??? pacotes de rede ou ler um arquivo protegido (i.e., somente-leitura para usuários).  Se você quer segurança real, use Kerberos.

Conexão direta com GSSAPI
-------------------------

GSSAPI é uma interface genérica para sistemas de segurança em rede como o Kerberos 5.  Se você tem uma biblioteca GSSAPI funcionando, você pode ter seu CVS conectado via uma conexão TCP direta, se autenticando com GSSAPI.

Para isto, o CVS precisa ter sido compilado com suporte a GSSAPI; quando você estiver configurando o CVS ele vai tentar detectar se as bibliotecas GSSAPI usando kerberos versão 5 estão presentes.  Você também pode configurar isto com opção --with-gssapi.

A conexão é autenticada usando GSSAPI, mas o fluxo de mensagem não é autenticado por padrão.  Você deve usar a opção global -a para pedir autenticação de fluxo.

Os dados transmitidos não são criptografados por padrão.  Suporte a criptografia deve ser compilado tanto no cliente quanto no servidor; use a opção de configuração --enable-encrypt para ativar isto. Com isto você deve usar a opção global -x para pedir criptografia.

Conexões GSSAPI são tratadas no lado servidor pelo mesmo servidor que cuida de autenticação por senha; veja em Servidor de autenticação por senha.  Se você está usando um mecanismo GSSAPI como o Kerberos, que fornece autenticação forte, você vai provavelmente querer impedir autenticação via senhas em texto plano. Para tal, crie um arquivo de senha CVSROOT/passwd vazio e faça SystemAuth=no no arquivo config (see config).

O servidor GSSAPI usa um nome principal de cvs/HOSTNAME, onde HOSTNAME é o nome canônico da máquina servidora.  Você vai ter que ajustar isto como é exigido pelo seu mecanismo GSSAPI.

Para se conectar usando GSSAPI, use :gserver:.  Por exemplo,

     cvs -d :gserver:faun.example.org:/usr/local/cvsroot checkout foo

Conexão direta com kerberos
---------------------------

A forma mais fácil de usar kerberos é usar o rsh kerberos, como descrito em Se conectando via rsh.  A principal desvantagem de usar rsh é que todos os dados precisam passar por outros programas, o que é mais lento.  Portanto, se você tem kerberos instalado, você pode se conectar via conexão TCP direta, autenticando com kerberos.

Esta seção diz respeito ao sistema de segurança de rede kerberos (kerberos network security system), versão 4. Kerberos versão 5 é suportado pela interface de segurança de rede genérica GSSAPI, como descrito na seção anterior.

Para isto, o CVS  precisa ter sido compilado com suporte a kerberos; quando você estiver configurando o CVS ele vai tentar detectar se as bibliotecas kerberos estão presentes ou você pode configurar isto com a opção --with-krb4.

Os dados transmitidos não são criptografados por padrão.  Suporte a criptografia deve ser compilado tanto no cliente quanto no servidor; use a opção de configuração --enable-encryption para ativar isto.  Você deve então usar a opção global -x para pedir criptografia.

Você precisa editar o inetd.conf no servidor para rodar cvs kserver.  O cliente usa a porta 1999 por padrão; se você quer usar outra porta especifique ela no CVSROOT (see Repositórios remotos) ou na variável de ambiente CVS_CLIENT_PORT (see Variáveis de ambiente) no cliente.

Quando você quiser usar o CVS, pegue um tíquete da forma usual (geralmente kinit); ele pode ser um tíquete que te permite se autenticar na máquina servidora.  Então você estará pronto para seguir:

     cvs -d :kserver:faun.example.org:/usr/local/cvsroot checkout foo

Versões anteriores do CVS podem recair numa conexão via rsh; esta versão não vai fazer isso.

Conectando via fork
-------------------

Este método de acesso permite a você conectar a um repositório no seu disco local via um protocolo remoto.  Em outras palavras, ele faz praticamente a mesma coisa que :local:, mas várias peduliaridades, paus e coisas do gênero são os mesmos do CVS remoto ao invés do CVS local.

Para trabalhar no dia-a-dia você vai preferir ou o :local: ou o :fork:, dependendo de suas preferências.  É claro que :fork: é bastante útil em testes ou depuração do cvs e o protocolo remoto.  Especificamente, nós evitamos todas as configurações/ajustes relacionados a redes, sessões expirando e autenticação inerentes de métodos de acesso remoto mas ainda assim criamos uma conexão que usa o protocolo remoto.

Para se conectar usando o método fork, use :fork: e o caminho para seu repositório local. Por exemplo:

     cvs -d :fork:/usr/local/cvsroot checkout foo

Assim como com :ext:, o servidor é chamado cvs por padrão, ou o valor da variável de ambiente CVS_SERVER.

Acesso somente-leitura ao repositório
=====================================

É possível permitir acesso somente-leitura ao repositório a pessoas usando o servidor de autenticação por senha (see Autenticação por senha).  (Os outros métodos de acesso não tem suporte explícito para somente-leitura de usuários, já que todos estes métodos assumem acesso por login à máquina do repositório de qualquer forma, e portanto o usuário pode fazer o que as permissões de arquivos locais permitirem.)

Um usuário que tem acesso somente-leitura pode realizar apenas as operações do CVS que não modificam o repositório, exceto alguns arquivos ``administrativos'' (tais como arquivos de trava e o arquivo history). Pode ser desejável usar esta habilidade em conjunto com ???``user-aliasing''??? (see Servidor de autenticação por senha).

Ao contrário de versões anteriores do CVS, usuários somente-leitura são capazes de simplesmente ler o repositório, e não de executar programas no servidor ou ainda conseguir níveis de acessos extras. Ou, para ser mais preciso, os papéis conhecidos foram ???plugged???.  Pelo fato de esta característica ser nova e ainda não ter recebido uma auditoria de segurança abrangente, você deve usar quaisquer níveis de precaução que pareçam seguros de acordo com a sua forma de agir com respeito a segurança.

Existem duas formas de estabelecer acesso somente-leitura para um usuário: por inclusão ou por exclusão.

"Inclusão" significa botar aquele usuário específico no arquivo $CVSROOT/CVSROOT/readers, que é simplesmente uma lista de usuários separados por quebra de linha.  Aqui está um exemplo do readers:

     melissa
     splotnik
     jrandom

(Não esqueça a quebra de linha depois do último usuário.)

"Exclusão" significa listar explicitamente todos que têm acesso de escrita---se o arquivo

     $CVSROOT/CVSROOT/writers

existe, então apenas os usuários que constam nele teram acesso de escrita, e qualquer outra pessoa acesso somente-leitura (obviamente, mesmo os usuários somente-leitura devem ainda ser listados no arquivo passwd do CVS).  O arquivo writers tem o mesmo formato do arquivo readers.

Observação: se seu arquivo passwd do CVS associa usuários do cvs com usuários do sistema (see Servidor de autenticação por senha), certifique-se de que você esteja negando ou fornecendo acesso somente-leitura usando os usuários do cvs, e não os do sistema.  Ou seja, os arquivos readers e writers contêm nomes de usuários do cvs, que não necessáriamente têm o mesmo nome que usuários do sistema.

Here is a complete description of the server's behavior in deciding whether to grant read-only or read-write access:

If readers exists, and this user is listed in it, then she gets read-only access.  Or if writers exists, and this user is NOT listed in it, then she also gets read-only access (this is true even if readers exists but she is not listed there).  Otherwise, she gets full read-write access.

Of course there is a conflict if the user is listed in both files.  This is resolved in the more conservative way, it being better to protect the repository too much than too little: such a user gets read-only access.

Temporary directories for the server
====================================

While running, the CVS server creates temporary directories.  They are named

     cvs-servPID

where PID is the process identification number of the server. They are located in the directory specified by the -T global option (see Opções globais), the TMPDIR environment variable (see Variáveis de ambiente), or, failing that, /tmp.

In most cases the server will remove the temporary directory when it is done, whether it finishes normally or abnormally.  However, there are a few cases in which the server does not or cannot remove the temporary directory, for example:

  * If the server aborts due to an internal server error, it may preserve the directory to aid in debugging

  * If the server is killed in a way that it has no way of cleaning up (most notably, kill -KILL on unix).

  * If the system shuts down without an orderly shutdown, which tells the server to clean up.

In cases such as this, you will need to manually remove the cvs-servPID directories.  As long as there is no server running with process identification number PID, it is safe to do so.

Começando um projeto com o CVS
******************************

Já que renomear e mover arquivos entre diretórios é um tanto quanto inconveniente, a primeira coisa a fazer quando você começa um novo projeto deve ser ponderar a respeito da organização dos arquivos.  Não é impossível renomear ou mover arquivos, mas isto aumenta as chances de erro e o CVS tem algumas idiossincrasias em especial quanto a renomear diretórios.  See Movendo arquivos.

O que fazer depende da situação em que você está.

Ajustando os arquivos
=====================

O primeiro passo é criar os arquivos dentro do repositório.  Isto pode ser feito de algumas maneiras diferentes.

Criando uma árvore de diretórios de uma quantidade de arquivos
--------------------------------------------------------------

Quando você começa a usar o CVS, provavelmente vai ter vários projetos que podem ser postos sob controle do CVS.  Nestes casos a forma mais fácil é usar o comando import.  Um exemplo é provavelmente a forma mais fácil de explicar como se usa o import.  Se os arquivos que você quer instalar no CVS estão em WDIR, e você quer que eles estejam no repositório $CVSROOT/yoyodyne/RDIR, você pode fazer isto:

     $ cd WDIR
     $ cvs import -m "Imported sources" yoyodyne/RDIR yoyo start

A menos que você forneca uma mensagem de log (registro) com a opção -m, o CVS vai iniciar um editor e esperar uma mensagem.  A string yoyo é uma etiqueta de fornecedor (vendor tag), e start é uma etiqueta de release (release tag).  Eles podem não fazer sentido neste contexto, mas já que o CVS exige, elas devem estar presentes. See Acompanhando fontes, para mais informações sobre isto.

Você agora pode verificar se está funcionando, e então apagar seu diretório do código fonte original.

     $ cd ..
     $ cvs checkout yoyodyne/RDIR       # Explanation below
     $ diff -r WDIR yoyodyne/RDIR
     $ rm -r WDIR

Erasing the original sources is a good idea, to make sure that you do not accidentally edit them in WDIR, bypassing CVS. Of course, it would be wise to make sure that you have a backup of the sources before you remove them.

The checkout command can either take a module name as argument (as it has done in all previous examples) or a path name relative to $CVSROOT, as it did in the example above.

It is a good idea to check that the permissions CVS sets on the directories inside $CVSROOT are reasonable, and that they belong to the proper groups.  See Permissões de arquivos.

If some of the files you want to import are binary, you may want to use the wrappers features to specify which files are binary and which are not.  See Wrappers.

Criando os Arquivos de Outros Sistemas de Controle de Versões
-------------------------------------------------------------

If you have a project which you are maintaining with another version control system, such as RCS, you may wish to put the files from that project into CVS, and preserve the revision history of the files.

From RCS

From RCS
     If you have been using RCS, find the RCS files---usually a file named foo.c will have its RCS file in RCS/foo.c,v (but it could be other places; consult the RCS documentation for details).  Then create the appropriate directories in CVS if they do not already exist.  Then copy the files into the appropriate directories in the CVS repository (the name in the repository must be the name of the source file with ,v added; the files go directly in the appropriate directory of the repository, not in an RCS subdirectory).  This is one of the few times when it is a good idea to access the CVS repository directly, rather than using CVS commands.  Then you are ready to check out a new working directory.

     The RCS file should not be locked when you move it into CVS; if it is, CVS will have trouble letting you operate on it.

From another version control system
     Many version control systems have the ability to export RCS files in the standard format.  If yours does, export the RCS files and then follow the above instructions.

     Failing that, probably your best bet is to write a script that will check out the files one revision at a time using the command line interface to the other system, and then check the revisions into CVS. The sccs2rcs script mentioned below may be a useful example to follow.

From SCCS
     There is a script in the contrib directory of the CVS source distribution called sccs2rcs which converts SCCS files to RCS files. Note: you must run it on a machine which has both SCCS and RCS installed, and like everything else in contrib it is unsupported (your mileage may vary).

From PVCS
     There is a script in the contrib directory of the CVS source distribution called pvcs_to_rcs which converts PVCS archives to RCS files. You must run it on a machine which has both PVCS and RCS installed, and like everything else in contrib it is unsupported (your mileage may vary).  See the comments in the script for details.

Criando uma árvore de diretórios do zero
----------------------------------------

For a new project, the easiest thing to do is probably to create an empty directory structure, like this:

     $ mkdir tc
     $ mkdir tc/man
     $ mkdir tc/testing

After that, you use the import command to create the corresponding (empty) directory structure inside the repository:

     $ cd tc
     $ cvs import -m "Created directory structure" yoyodyne/DIR yoyo start

Then, use add to add files (and new directories) as they appear.

Check that the permissions CVS sets on the directories inside $CVSROOT are reasonable.

Definindo o módulo
==================

The next step is to define the module in the modules file.  This is not strictly necessary, but modules can be convenient in grouping together related files and directories.

In simple cases these steps are sufficient to define a module.

 1. Get a working copy of the modules file.

          $ cvs checkout CVSROOT/modules
          $ cd CVSROOT

 2. Edit the file and insert a line that defines the module. See Intro aos arquivos administrativos, for an introduction.  See modules, for a full description of the modules file.  You can use the following line to define the module tc:

          tc   yoyodyne/tc

 3. Commit your changes to the modules file.

          $ cvs commit -m "Added the tc module." modules

 4. Release the modules module.

          $ cd ..
          $ cvs release -d CVSROOT

Revisões
********

Para muitos usos do CVS, não é necessário se preocupar com o número de revisões; o CVS atribui números tais como 1.1, 1.2 e por aí vai, e isto é tudo que se precisa saber.  Entretanto, Algumas pessoas preferem ter mais conhecimento e controle a respeito de como o CVS atribui números de revisão.

Se você quiser marcar um conjunto de revisões envolvendo mais de um arquivo, tais como as revisões que integram uma release, pode usar uma etiqueta (tag), que é uma revisão simbólica que pode ser associada a uma revisão numérica em cada um dos arquivos.

Números de revisão
==================

Cada versão de um arquivo tem um número de revisão único.  Números de revisão são coisas do tipo 1.1, 1.2, 1.3.2.2 ou até mesmo 1.3.2.2.4.5.  Um número de revisão sempre tem uma quantidade par de números inteiros na base dez separados por ponto.  Por padrão, a revisão 1.1 é a primeira revisão de um arquivo.  Cada revisão sucessiva ganha um novo número somando um ao número mais a direita.  A figura a seguir mostra mostra algumas revisões, com a revisão mais nova mais à direita.

            +-----+    +-----+    +-----+    +-----+    +-----+
            ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !
            +-----+    +-----+    +-----+    +-----+    +-----+

Também é possível ter números com mais de um ponto, por exemplo 1.3.2.2.  Tais revisões representam revisões em ramos (see Ramificando e mesclando); estes números de revisão são explicados em detalhes em Ramos e revisões.

Versões, revisões e releases
============================

Um arquivo pode ter várias versões, como descrito acima.  Da mesma forma, um produto de software também pode ter várias versões.  Frequentemente um produto de software recebe um número de versão, tal como 4.1.1.

Versões, neste documento são chamadas, principalmente, de revisões , e também de releases.  Para evitar confusão, o termo versão praticamente não é usado neste documento.

Atribuindo revisões
===================

Por padrão, CVS vai atribuir revisões numéricas mantendo o primeiro número e aumentando o segundo.  Por exemplo, 1.1, 1.2, 1.3, etc.

Quando um novo arquivo é adicionado, o segundo número vai ser sempre o um e o primeiro número vai ser igual ao maior primeiro número de qualquer arquivo no diretório.  Por exemplo, se o diretório atual contiver arquivos os quais o maior número de revisão seram 1.7, 3.1 e 4.12, então um arquivo adicionado vai receber a revisão numérica 4.1.

Normalmente não há razão para se preocupar com números de revisão---é melhor tratá-los como numeração interna que o CVS mantém, e etiquetas (tags) fornecem uma forma melhor de distinguir entre coisas tais como release 1 e release 2 de seu produto (see Etiquetas).  Entretando, se você quiser ajustar as revisões numéricas, a opção -r do cvs commit pode fazer isto.  A opção -r implica na opção -f, no sentido de que ela faz com que os arquivos sejam submetidos mesmo caso eles não estejam modificados.

Por exemplo, para subir todos os arquivos para a revisão 3.0 (inclusive os que não sofreram mudanças), você deve invocar:

     $ cvs commit -r 3.0

Observe que o número que você especificar com a opção -r deve ser maior que qualquer número de revisão existente.  Ou seja, se a revisão 3.0 existe, você não pode fazer cvs commit -r 1.3.  Se você quiser manter várias releases em paralelo, você deve usar um ramo (see Ramificando e mesclando).

Etiquetas (Tags)--Revisões simbólicas
=====================================

Os números de revisão tem uma vida a parte.  Eles não precisam ter nada a ver com os números de release de seu produto de software.  Dependendo de como você usa o CVS, os números de revisão podem mudar várias vezes entre duas releases.  Como um exemplo, alguns dos arquivos fonte do RCS 5.6 tinham os seguintes números de revisão:

     ci.c            5.21
     co.c            5.9
     ident.c         5.3
     rcs.c           5.12
     rcsbase.h       5.11
     rcsdiff.c       5.10
     rcsedit.c       5.11
     rcsfcmp.c       5.9
     rcsgen.c        5.10
     rcslex.c        5.11
     rcsmap.c        5.2
     rcsutil.c       5.10

Você pode usar o comando tag para dar um nome simbólico para uma certa revisão de um arquivo.  Você pode usar a opção -v com o comando status para ver todas as etiquetas que um arquivo possui, e que números de revisão elas representam.  Nomes de etiqueta devem começar com letra maiúscula ou minúscula e pode conter letras maiúsculas e minúsculas, dígitos, - e _.  Os dois nomes de etiqueta BASE e HEAD são reservados para o CVS.  É esperado que nomes futuros que sejam especiais para o CVS recebam nomes especiais, por exemplo começando com ., sendo então nomeados de forma análoga a BASE e HEAD, para evitar conflitos com os nomes de etiqueta atuais.

Você vai querer definir algumas convenções para nomear etiquetas, baseado em informações tais como nome do programa e número da versão da release.  Por exemplo, algume pode pegar o nome do programa, seguindo pelo número de versão com o . trocado por -, de forma que o CVS 1.9 seja etiquetado com o nome de cvs1-9.  Se você escolhe uma convenção consistente, você não vai precisar ficar constantemente adivinhando se a etiqueta é cvs-1-9 ou cvs1_9 ou sei lá o que.  Você pode até mesmo considerar reforçar esta convenção no arquivo taginfo (see taginfo).

O exemplo seguinte mostra como você pode adicionar uma etiqueta a um arquivo.  Os comandos devem ser executados de dentro do seu diretório de trabalho.  Ou seja, você deve executar o comando no diretório onde backend.c fica.

     $ cvs tag rel-0-4 backend.c
     T backend.c
     $ cvs status -v backend.c
     ===================================================================
     File: backend.c         Status: Up-to-date

         Version:            1.4     Tue Dec  1 14:39:01 1992
         RCS Version:        1.4     /u/cvsroot/yoyodyne/tc/backend.c,v
         Sticky Tag:         (none)
         Sticky Date:        (none)
         Sticky Options:     (none)

         Existing Tags:
             rel-0-4                     (revision: 1.4)

Para um resumo completo da sintaxe de cvs tag, incluindo as várias opções, veja em Chamando o CVS.

Existem poucas razões para etiquetar um arquivo em separado.  Um uso mais comum é etiquetar todos os arquivos que fazem parte de um módulo com a mesma etiqueta em momentos estratégicos do ciclo de vida do desenvolvimento, como por exemplo, quando fica pronta uma release.

     $ cvs tag rel-1-0 .
     cvs tag: Tagging .
     T Makefile
     T backend.c
     T driver.c
     T frontend.c
     T parser.c

(Quando você passa um diretório para o CVS como argumento, ele geralmente realiza a operação em todos os arquivos do diretório e (recursivamente) a todo subdiretório que ele contenha. See Comportamento recursivo.)

O comando checkout tem uma opção, -r, que permite pegar uma certa revisão de um módulo.  Esta opção torna fácil recuperar as ontes que fizeram parte da release 1.0 do módulo tc a qualquer momento no futuro:

     $ cvs checkout -r rel-1-0 tc

Isto pode ser útil, por exemplo, se alguem afirma que tem um pau naquela versão, mas você não acha o pau na cópia de trabalho mais recente.

Você também pode pegar um módulo do jeito que ele estava em qualquer data.  See checkout options. Quando usar -r em qualquer destes comandos, você vai precisar estar atento às etiquetas adesivas; veja em Etiquetas adesivas.

Quando você etiqueta mais de um arquivo com a mesma etiqueta você pode pensar na etiqueta como "uma curva desenhada ao longo da matriz de nomes de arquivo por números de revisão".  Digamos que temos 5 arquivos com as seguintes revisões:

             file1   file2   file3   file4   file5

             1.1     1.1     1.1     1.1  /--1.1*      <-*-  TAG
             1.2*-   1.2     1.2    -1.2*-
             1.3  \- 1.3*-   1.3   / 1.3
             1.4          \  1.4  /  1.4
                           \-1.5*-   1.5
                             1.6

Em algum momento no passado, as versões com * foram etiquetadas.  Você pode pensar na etiqueta como uma alça presa à curva que passa pelas revisões marcadas.  Quando você puxa a alça, vem as revisões etiquetadas.  outra maneira de perceber isto é ver através de um conjunto de revisões que foram alinhadas pelas revisões etiquetadas, como isto:

             file1   file2   file3   file4   file5

                             1.1
                             1.2
                     1.1     1.3                       _
             1.1     1.2     1.4     1.1              /
             1.2*----1.3*----1.5*----1.2*----1.1*    (--- <--- Look here
             1.3             1.6     1.3              \_
             1.4                     1.4
                                     1.5

Especificando o que etiquetar no diretório de trabalho
======================================================

O exemplo na seção anterior  demonstra uma das formas mais comuns de escolher que revisões etiquetar.  A saber, rodando o comando cvs tag sem argumentos faz com que o CVS selecione as revisões que estão presentes no diretório de trabalho atual.  Por exemplo, se a cópia do arquivo backend.c no diretório de trabalho foi pega da revisão 1.4, então o CVS vai etiquetar a revisão 1.4.  Observe que a etiqueta é aplicada na revisão 1.4 no repositório imediatamente; Etiquetar não funciona como modificar arquivos ou outras operações nas quais primeiros você modifica o diretório de trabalho e então roda o cvs commit para mandar as modificações para o repositório.

Um aspecto potencialmente confuso no fato de o comando cvs tag operar no repositório é que você está etiquetando revisões devolvidas, que podem diferir de arquivos localmente modificados no seu diretório de trabalho.  Se você quer evitar fazer isto por engano, use a opção -c no cvs tag.  Se existe qualquer arquivo localmente modificado, o CVS vai abortar com erro antes de etiquetar qualquer arquivo:

     $ cvs tag -c rel-0-4
     cvs tag: backend.c is locally modified
     cvs [tag aborted]: correct the above errors first!

Especificando o que etiquetar por data ou revisão
=================================================

O comando cvs rtag etiqueta o repositório em uma certa data ou hora (ou pode ser usado para etiquetar a última revisão).  rtag trabalha diretamente no repositório (não requer um checkout e não procura por um diretório de trabalho).

As seguintes opções especificam que data ou revisão etiquetar.  Veja em Opções comuns, para uma descrição completa delas.

-D DATA
     Etiqueta a revisão mais recente que seja anterior a DATA.

-f
     Útil apenas em conjunto com -D DATA ou -r ETIQUETA.  Se não encontrar uma revisã casando com o padrão, usar a revisão mais recente (ao invés de ignorar o arquivo).

-r ETIQUETA
     Etiqueta apenas os arquivos que contém a etiqueta ETIQUETA existente.

O comando cvs tag também permite que você especifique arquivos por revisão ou data, usando as mesmas opções -r, -D e -f. Entretanto, este característica não é provavelmente o que você quer.  A razão é que o cvs tag escolhe que arquivos etiquetar baseado nos arquivos que existem no diretório de trabalho, ao invés de arquivos que existem na dada etiqueta/data.  Portanto, você é geralmente ???better off??? usar cvs rtag.  As exceções devem ser casos como:

     cvs tag -r 1.4 stable backend.c

Apagando, movendo e renomeando etiquetas
========================================

Normalmente não se modificam etiquetas.  Elas existem para registrar o histórico do repositório e, portanto, apagá-las ou alterar o significado delas não é, em geral, o que você quer.

Entretanto, podem haver casos nos quais alguem usa a etiqueta temporariamente ou bota no lugar errado por acidente.  Logo, é possível apagar, mover, ou renomear uma etiqueta.

ATENÇÃO: os comandos nesta seção são perigosos; eles apagam permanentemente informações históricas e pode ser difícil ou impossível recuperar tais informações em caso de erro.  Se você é um administrador do CVS, você deve considerar restringir estes comandos com o arquivo taginfo (see taginfo).

Para apagar uma etiqueta, especifique a opção -d tanto para cvs tag quanto para cvs rtag.  Por exemplo:

     cvs rtag -d rel-0-4 tc

apaga a etiqueta ???non-branch??? rel-0-4 do módulo tc.  No caso de etiquetas de ramos serem encontradas no repositório com o nome dado, uma mensagem de aviso vai ser mostrada e a etiqueta de ramo não vai ser apagada.  Se você está absolutamente certo de que sabe o que está fazendo, a opção -B pode ser especificada para permitir que se apague as etiquetas de ramos.  Neste caso, qualquer etiqueta ???non-branch??? encontrada vai disparar avisos e não vai ser apagada.

ATENÇÃO: Mover etiquetas de ramos é muito perigoso!  Se você pensa que precisa da opção -B, pense duas vezes e pergunte a seu administrador do CVS sobre ela (se não for você). É quase certo que existe outra forma de alcançar o seu objetivo.

Quando falamos em mover uma etiqueta, queremos dizer fazer com que o mesmo nome aponte para diferentes revisões.  Por exemplo, a etiqueta stable pode atualmente apontar para a revisão 1.4 do arquivo backend.c e talvez nós queiramos fazé-la apontar para a revisão 1.6.  Para mover uma etiqueta ???non-branch???, Use a opção -F tanto com o cvs tag oquanto com o cvs rtag.  Por exemplo, esta mudança pode ser alcançada com:

     cvs tag -r 1.6 -F stable backend.c

Se alguma etiqueta de ramo for encontrada no repositório com o nome dado, um aviso é mostrado e a etiqueta de ramo não é alterada.  Se você está absolutamente certo de que você quer mover a etiquta de ramo, a opção -B pode ser especificada.  Neste caso, etiquetas ???non-branch??? encontradas com o nome dado serão ignoradas com uma mensagem de aviso.

ATENÇÃO: Mover etiquetas de ramos é muito perigoso!  Se você pensa que precisa da opção -B, pense duas vezes e pergunte a seu administrador do CVS sobre ela (se não for você). É quase certo que existe outra forma de alcançar o seu objetivo.

Quando falamos em renomear uma etiqueta, queremos dizer fazer com que um nome diferente aponte para para as mesmas revisões que a etiqueta antiga.  Por exemplo, alguem pode ter digitado errado o nome de uma etiqueta e quer corrigir isto (de preferência antes que outros caiam no mesmo erro).  Para renomear uma etiqueta, primeiro crie uma nova etiqueta usando a opção -r para o cvs rtag, e então apague o nome antigo.  (Cuidado: este método não vai funcionar com etiquetas de ramos).  Isto deixa a nova etiqueta exatamente nos mesmos arquivos que a etiqueta antiga. Por exemplo:

     cvs rtag -r old-name-0-4 rel-0-4 tc
     cvs rtag -d old-name-0-4 tc

Etiquetando e adicionando e removendo arquivos
==============================================

O tema a respeito de como exatamente etiquetas interagem com arquivos adicionados e removidos é de certa forma obscuro; Normalmente, o CVS vai verificar quais arquivos existem ou não sem muita confusão.  Por padrão, etiquetas são aplicadas apenas a arquivos que tenham uma revisão correspondendo ao que está sendo etiquetado.  Arquivos que ainda não existem, ou que já foram removidos, simplesmente omitem a etiqueta, e o CVS trata a ausência de uma etiqueta como significando que o arquivo não existia na criação da etiqueta.

Entretanto, Isto pode perder uma pequena quantidade de informação.  Por exemplo, suponha que um arquivo foi adicionado e então removido.  Então, se a etiqueta está faltando para aquele arquivo, não há como se descobrir se a data da etiqueta é posterior à adição ou anterior à remoção do arquivo.  Se você usa a opção -r para cvs rtag, então o CVS etiqueta os arquivos que foram removidos, e portanto remove este problema.  Por exemplo, alguem pode especificar -r HEAD para etiquetar a head.

A respeito de adicionar e remover arquivos, o comando cvs rtag tem a opção -a que significa limpar a etiqueta de arquivos removidos que ???would not otherwise be tagged???.  Por exemplo, alguem pode especificar esta opção em conjunto com -F quando mover uma etiqueta.  Se alguem mover uma etiqueta sem o -a, então a etiqueta nos arquivos removidos vai continuar fazendo referência à revisão antiga, Ao invés de refletir o fato de que o arquivo foi removido.  Eu não acho que isto seja necessário se -r é especificado, como falado acima.

Etiquetas adesivas
==================

Algumas vezes, um cópia de tabalho de uma revisão tem dados extra associados a ela, por exemplo, ela pode estar num ramo (see Ramificando e mesclando), ou restrita a uma versão anterior a uma certa data por checkout -D ou update -D.  Já que este dado persiste -- ou seja, ele se aplica a comandos subseqüentes na cópia de trabalho -- nós o chamamos de adesivos.

Na maioria das vezes, ser adesivo é um aspecto obscuro do CVS que você não precisa saber a respeito. Entretanto, mesmo se você não quiser usar esta habilidade, você  vai precisar saber alguma coisa sobre etiquetas adesivas (sticky tags) (por exemplo, como evitá-las!).

Você pode usar o comando status para ver se alguma etiqueta ou data adesiva estão ligadas:

     $ cvs status driver.c
     ===================================================================
     File: driver.c          Status: Up-to-date

         Version:            1.7.2.1 Sat Dec  5 19:35:03 1992
         RCS Version:        1.7.2.1 /u/cvsroot/yoyodyne/tc/driver.c,v
         Sticky Tag:         rel-1-0-patches (branch: 1.7.2)
         Sticky Date:        (none)
         Sticky Options:     (none)

As etiquetas adesivas vão permanecer nos seus arquivos de trabalho até que você apague elas com cvs update -A.  A opção -A mescla as alterações locais na versão do arquivo na cabeça (head) do tronco, removendo qualquer etiqueta, data ou opção adesiva. Veja em update para mais a respeito desta operação do cvs update.

O uso mais comum de etiquetas adesivas é identificar em que ramo se está trabalhando, como descrito em Acessando ramos.  Entretanto, etiquetas adesivas em ???non-branch??? também têm seu uso.  Por exemplo, suponha que você quer evitar atualizar seu diretório de trabalho, para se isolar de mudanças que outras pessoas estão fazendo que possam que possam desestabilizar seu trabalho.  Você pode, claro, simplesmente não rodar o cvs update.  Mas se você quer evitar atualizar (fazer update) apenas uma parte de uma grande árvore, então etiquetas adesivas podem ajudar.  Se você pega uma certa revsão (como a 1.4) ela vai se tornar adesiva. comandos cvs update subsequentes não vão trazer a revisão mais nova até que você limpe a etiqueta com os comandos cvs update -A.  Da mesma forma, o uso da opção -D em update ou checkout define uma data adesiva, que, similarmente, faz com que a data seja usada para futuras ???retrievals???.

É normal as pessoas quererem recuperar uma versão antiga de um arquivo sem definir uma etiqueta adesiva. Isto pode ser feito com a opção -p no checkout ou update, que manda o conteúdo do arquivo para a saída padrão.  Por exemplo:

     $ cvs update -p -r 1.1 file1 >file1
     ===================================================================
     Checking out file1
     RCS:  /tmp/cvs-sanity/cvsroot/first-dir/Attic/file1,v
     VERS: 1.1
     ***************
     $

Entretanto, esta não é a forma mais fácil, se você está querendo desfazer um envio anterior (neste exemplo, devolver o arquivo file1 ao que ele era na revisão 1.1).  Neste caso é melhor usar a opção -j com o update; Para maiores detalhes, veja em Mesclando duas revisões.

Ramificando e mesclando
***********************

O CVS permite isolar mudanças em uma linha de desenvolvimento separada, chamada de ramo. Quando você muda os arquivos de um ramo, aquelas mudanças não aparecem no tronco principal ou em outros ramos.

Mais tarde você pode mover as mudanças de um ramo para outro (ou para o tronco principal) com uma mesclagem.  Mesclar é primeiro rodar um cvs update -j, para mesclar as mudanças no seu diretório de trabalho.  Depois efetivar (commit) esta revisão, e finalmente fazer a efetiva destas mudanças de um ramo para outro.

Para que ramos são bons
=======================

Suponha que a release 1.0 de tc está pronta.  Você está continua desenvolvendo tc, e planeja lançar a release 1.1 em alguns meses.  Depois de um tempo seus consumidores começam a reclamar de um erro fatal.  Você baixa a release 1.0 (see Etiquetas) e encontra o erro (que tem um conserto fácil).  Entretanto, a revisão atual dos fontes está num estado do fluxo de desenvolvimento que você não espera que estaja estável em pelo menos um mês.  Não tem jeito de lançar uma release baseada nos fontes mais novos.

O que se há para fazer numa situação como esta é criar um ramo na árvore de revisões para todos os arquivos que integram a release 1.0 de tc.  Você pode então fazer modificações no ramo sem perturbar o tronco principal.  Quando as modificações terminarem você pode decidir se incorporam elas ao tronco ou deixa elas no ramo.

Criando um ramo
===============

Você pode criar um ramo com tag -b; por exemplo, supondo que você está numa cópia de trabalho:

     $ cvs tag -b rel-1-0-patches

Isto inicia um ramo baseado nas revisões atuais na cópia de trabalho, dando a este ramo o nome rel-1-0-patches.

É importante entender que ramos são criados no repositório, e não na cópia de tarbalho.  Criar um ramo baseado nas revisões atuais, como no exemplo acima, Não vai mudar automaticamente a cópia de trabalho para o novo ramo.  Para informações sobre como fazer isto, veja em Acessando ramos.

Você também pode criar um ramo sem referência a qualquer cópia de trabalho usando rtag:

     $ cvs rtag -b -r rel-1-0 rel-1-0-patches tc

-r rel-1-0 diz que este ramo deve ser iniciado na revisão que corresponde à etiqueta (tag) rel-1-0.  Não precisa ser a revisão mais recente -- é útil às vezes separar um ramo a partir de uma revisão antiga (por exemplo, quando se está consertando um erro numa release anterior que se pensava estar estável).

Assim como no tag, a opção -b diz ao rtag para criar um ramo (ao invés de simplesmente um nome de revisão simbólico).  Observe que o número de revisão simbólico que casa com rel-1-0 provavelmente ser diferente de arquivo para arquivo.

Então, O efeito total do comando é criar um novo ramo -- chamado rel-1-0-patches -- no módulo tc, partindo da árvore de revisão no ponto etiquetado como rel-1-0.

Acessando ramos
===============

Você pode recuperar um ramo de duas formas: pegando um cópia zerada dele do repositório, ou alternando de uma cópia de trabalho já existente para o ramo.

Para pegar um ramo do repositório, chame o checkout com a opção -r, seguida pelo nome da etiqueta do ramo (see Criando um ramo):

     $ cvs checkout -r rel-1-0-patches tc

Ou, se você já tem uma cópia de trabalho, você pode alternar dela para um dado ramo com update -r:

     $ cvs update -r rel-1-0-patches tc

ou equivalentemente:

     $ cd tc
     $ cvs update -r rel-1-0-patches

Não importa se a cópia de tabalho estava originalmente no tronco principal ou em algum outro ramo -- o comando acima vai alternar ela para o ramo dado.  E similarmente ao comando update normal, update -r mescla quaisquer mudanças que você tenha feito, notificando você sobre conflitos onde eles ocorrerem.

Uma vez que você tenha uma cópia de trabalho referente a um dado, ela continua no ramo até que se diga o contrário.  Isto significa que mudanças inseridas a partir da cópia de trabalho vão adicionar novas revisões naquele ramo, enquanto que não afeta o tronco principal nem os outros ramos.

Para saber em qual ramo uma cópia de trabalho está, você precisa usar o comando status.  Na saída do comando procure pelo campo chamado Sticky tag (etiqueta adesiva) (see Etiquetas adesivas) -- esta é a forma do CVS de dizer a você o ramo, se é que se está num, dos arquivos de trabalho atuais:

     $ cvs status -v driver.c backend.c
     ===================================================================
     File: driver.c          Status: Up-to-date

         Version:            1.7     Sat Dec  5 18:25:54 1992
         RCS Version:        1.7     /u/cvsroot/yoyodyne/tc/driver.c,v
         Sticky Tag:         rel-1-0-patches (branch: 1.7.2)
         Sticky Date:        (none)
         Sticky Options:     (none)

         Existing Tags:
             rel-1-0-patches             (branch: 1.7.2)
             rel-1-0                     (revision: 1.7)

     ===================================================================
     File: backend.c         Status: Up-to-date

         Version:            1.4     Tue Dec  1 14:39:01 1992
         RCS Version:        1.4     /u/cvsroot/yoyodyne/tc/backend.c,v
         Sticky Tag:         rel-1-0-patches (branch: 1.4.2)
         Sticky Date:        (none)
         Sticky Options:     (none)

         Existing Tags:
             rel-1-0-patches             (branch: 1.4.2)
             rel-1-0                     (revision: 1.4)
             rel-0-4                     (revision: 1.4)

Não se confunda pelo fato de que os números de ramo de cada arquivo serem diferentes (1.7.2 e 1.4.2 respectivamente).  A etiqueta do ramo é a mesma, rel-1-0-patches, e os arquivos estão na verdade no mesmo ramo.  Os números simplesmente refletem o ponto em que cada arquivo estava no histórico de revisão quando o ramo foi criado.  No exemplo acima, pode-se deduzir que driver.c tinha tido mais alterações que backend.c antes do ramo ter sido criado.

Veja em Ramos e revisões para detalhes a respeito de como números de ramos são criados.

Ramos e revisões
================

Normalmente, um histórico da revisão do arquivo é uma séria linear de incrementos (see Números de revisão):

            +-----+    +-----+    +-----+    +-----+    +-----+
            ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !
            +-----+    +-----+    +-----+    +-----+    +-----+

Entretanto, o CVS não está limitado a desenvolvimento linear.  A árvore de revisões pode ser separada em ramos, onde cada ramo é uma linha de desenvolvimento que se mantém.  Mudanças feitas em um ramo podem ser facilmente movidas para o tronco principal.

Cada ramo tem um número de ramo, formado por uma quantidade ímpar de números inteiros decimais separados por ponto.  O número do ramo é criado anexando um inteiro ao número de revisão de onde o ramo correpondente saiu.  Com números de ramo é possível se ter mais de uma ramificação partindo de uma certa revisão.

Todas as revisões num ramo têm números de revisão formados pela anexação de um número ordinal ao número do ramo.  A figura seguinte ilustra a ramificação com um exemplo.

                                                           +-------------+
                                Branch 1.2.2.3.2 ->        ! 1.2.2.3.2.1 !
                                                         / +-------------+
                                                        /
                                                       /
                      +---------+    +---------+    +---------+
     Branch 1.2.2 -> _! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 !
                    / +---------+    +---------+    +---------+
                   /
                  /
     +-----+    +-----+    +-----+    +-----+    +-----+
     ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !  <- The main trunk
     +-----+    +-----+    +-----+    +-----+    +-----+
                     !
                     !
                     !   +---------+    +---------+    +---------+
     Branch 1.2.4 -> +---! 1.2.4.1 !----! 1.2.4.2 !----! 1.2.4.3 !
                         +---------+    +---------+    +---------+

Os detalhes exatos de como o número de ramo é construído não são algo com os quais você precisa estar preocupado, mas aqui vai como a coisa funciona: quando o CVS cria um número de ramo ele pega o primeiro número par não usado, a partir de 2.  Logo, quando você quer criar um ramo a partir da revisão 6.4 ele vai ser numerado 6.4.2.  Todos os números de ramos terminados com um zero (tal como 6.4.0) são usados internamente pelo CVS (see Números de ramos mágicos).  O ramo 1.1.1 tem um significado especial. See Acompanhando fontes.

Números de ramos mágicos
========================

Esta seção descreve uma habilidade do CVS chamada ramos mágicos.  Para a maioria dos casos, você não precisa se preocupar com os ramos mágicos; o CVS cuida deles para você.  Entretanto, eles aparecem em algumas situações, sendo importante se ter alguma idéia de como eles funcionam.

Externamente, números de ramos consistem de uma quantidade ímpar de inteiros decimais separados por ponto.  See Números de revisão.  Isto não é toda a verdade, entretanto.  Por questões de eficiência, o CVS insere, em alguns momentos, um 0 extra na segunda posição da direita para a esquerda (1.2.4 se torna 1.2.0.4, 8.9.10.11.12 se torna 8.9.10.11.0.12 e assim por diante).

O CVS faz um bom trabalho escondendo estes tais ramos mágicos, mas em alguns lugares alguma coisa aparece:

  * O número de ramo mágico aparece na saída do cvs log.

  * Você não pode especificar um nome de ramo simbólico para o cvs admin.

Você pode usar o comando admin para reatribuir um nome simbólico para um ramo da forma que o RCS espera que seja.  Se o R4patches está atribuído para o ramo 1.4.2 (número de ramo mágico 1.4.0.2) no arquivo numbers.c você pode fazer isto:

     $ cvs admin -NR4patches:1.4.2 numbers.c

Isto apenas funciona se pelo menos uma revisão já está efetivada no ramo.  Seja bastante cuidadoso para não atribuir a etiqueta ao número errado.  (Não existe jeito de ver como a etiqueta estava atribuída ontem).

Mesclando um ramo inteiro
=========================

Você pode mesclar mudanças feitas num ramo em seu diretório de trabalho passando a opção -j NOME_DO_RAMO para o subcomando update. Com uma opção -j NOME_DO_RAMO ele mescla as mudançãs feitas entre o maior ancestral comum (greatest common ancestor - GCA) do ramo e a revisão de destino (no caso mais simples abaixo, o GCA é o ponto onde o ramo bifurcou) e a nova revisão neste ramo na sua cópia de trabalho.

O -j significa ``join'', ``juntar''.

Considere esta árvore de revisão:

     +-----+    +-----+    +-----+    +-----+
     ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !      <- The main trunk
     +-----+    +-----+    +-----+    +-----+
                     !
                     !
                     !   +---------+    +---------+
     Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !
                         +---------+    +---------+

O ramo 1.2.2 recebeu a etiqueta (nome simbólico) R1fix.  O exemplo seguinte assume que o módulo mod contém apenas um arquivo, m.c.

     $ cvs checkout mod               # Retrieve the latest revision, 1.4

     $ cvs update -j R1fix m.c        # Merge all changes made on the branch,
                                      # i.e. the changes between revision 1.2
                                      # and 1.2.2.2, into your working copy
                                      # of the file.

     $ cvs commit -m "Included R1fix" # Create revision 1.5.

Um conflito pode resultar de uma operação de mesclagem. Se isto acontecer, você deve resolver isto antes de efetivar a nova revisão.  See Exemplo de conflitos.

Se seu código fonte contém palavras-chave (see Substituição de palavra-chave), você deve obter mais conflitos que os ???strictly necessary???. Veja em Mesclagem e palavras-chave, para saber como evitar isto.

O comando checkout também suporta a opção -j BRANCHNAME.  O mesmo efeito que o visto logo acima pode ser obtido com isto:

     $ cvs checkout -j R1fix mod
     $ cvs commit -m "Included R1fix"

Observe que o update -j TAGNAME também vai funcionar mas pode não produzir o efeito desejado. See Mesclando adicionados e removidos, para mais informações.

Mesclando a partir de um ramo várias vezes
==========================================

Continuando nosso exemplo, a árvore de revisão agora vai parecer com isto:

     +-----+    +-----+    +-----+    +-----+    +-----+
     ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !   <- The main trunk
     +-----+    +-----+    +-----+    +-----+    +-----+
                     !                           *
                     !                          *
                     !   +---------+    +---------+
     Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !
                         +---------+    +---------+

Onde a linha de asteriscos representa a mescla entre o ramo R1fix e o tronco principal, como acabamos de ver.

Agora suponha que o desenvolvimento continua no ramo R1fix:

     +-----+    +-----+    +-----+    +-----+    +-----+
     ! 1.1 !----! 1.2 !----! 1.3 !----! 1.4 !----! 1.5 !   <- The main trunk
     +-----+    +-----+    +-----+    +-----+    +-----+
                     !                           *
                     !                          *
                     !   +---------+    +---------+    +---------+
     Branch R1fix -> +---! 1.2.2.1 !----! 1.2.2.2 !----! 1.2.2.3 !
                         +---------+    +---------+    +---------+

e então você quer mesclar as novas mudanças dentro do tronco principal.  Se você usar simplesmente o comando cvs update -j R1fix m.c de novo, o CVS vai tentar mesclar de novo as mudanças que você já mesclou, o que pode gerar efeitos indesejados.

Então, ao invés disto, você precisa especificar que você quer apenas mesclar no tronco as mudanças que ainda não foram mescladas.  Para fazer isto você especifica duas opções -j, e o CVS mescla as mudanças da primeira revisão na segunda revisão.  Por exemplo, neste caso a forma mais simples será

     cvs update -j 1.2.2.2 -j R1fix m.c    # Merge changes from 1.2.2.2 to the
                                           # head of the R1fix branch

O problema com isto é que você precisa especificar a revisão 1.2.2.2 manualmente.  Uma abordagem um pouco melhor seria usar a data em que a última mesclagem foi feita:

     cvs update -j R1fix:yesterday -j R1fix m.c

Ou ainda melhor, etiquete o ramo R1fix depois de cada mesclagem no tronco, e então use a etiqueta para mesclagens subseqüentes:

     cvs update -j merged_from_R1fix_to_trunk -j R1fix m.c

Mesclando diferenças entre duas revisões quaisquer
==================================================

Com duas opções -j REVISÃO, o comando update (e checkout) pode mesclar as diferenças entre quaisquer duas revisões no arquivo do diretório de trabalho.

     $ cvs update -j 1.5 -j 1.3 backend.c

vai desfazer todas as alterações feitas entre as revisões 1.3 e 1.5.  Observe a ordem das revisões!

Se você tentar usar esta opção quando estiver agindo em vários arquivos, lembre-se que as revisões numéricas provavelmente vão ser bastante diferentes nos vários arquivos.  Você vai quase sempre usar etiquetas simbólicas ao invés de números de revisão quando estiver operando em vários arquivos.

Ao especificar duas opções -j você pode também desfazer uma remoção ou adição de arquivo.  Por exemplo, suponhao que você tem um arquivo chamado file1 que existia numa revisão 1.1, e você removeu ele (adicionando então uma revisão morta 1.2). Agora suponha que você quer adicioná-lo novamente, com o mesmo conteúdo que ele tinha anteriormente.  Aqui está como fazer isto:

     $ cvs update -j 1.2 -j 1.1 file1
     U file1
     $ cvs commit -m test
     Checking in file1;
     /tmp/cvs-sanity/cvsroot/first-dir/file1,v  <--  file1
     new revision: 1.3; previous revision: 1.2
     done
     $

Mesclar pode adicionar ou remover arquivos
==========================================

Se as mudanças que você está mesclando envolvem remover ou adicionar alguns arquivos, update -j vai resultar em algumas adições ou remoções.

Por exemplo:

     cvs update -A
     touch a b c
     cvs add a b c ; cvs ci -m "added" a b c
     cvs tag -b branchtag
     cvs update -r branchtag
     touch d ; cvs add d
     rm a ; cvs rm a
     cvs ci -m "added d, removed a"
     cvs update -A
     cvs update -jbranchtag

Depois destes comandos terem sido executados e um cvs commit ser feito, o arquivo a vai ser removido e o arquivo d adicionado no ramo principal.

Observe que ao se usar uma única etiqueta estática (-j TAGNAME) ao invés de uma etiqueta dinâmica (-j BRANCHNAME) para mesclar mudanças a partir de um ramo normalmente não vai remover arquivos que foram removidos do ramo, já que o CVS não adiona etiquetas estáticas a revisões mortas.  A exceção a esta regra ocorre quando uma etiqueta estática foi colocada numa revisão morta manualmente.  Use a etiqueta do ramo para mesclar todas as mudanças a partir do ramo ou use duas etiquetas estáticas como limites da mescla para ter certeza que todas as mudanças pretendidas vão ser propagadas na mesclagem.

Mesclagem e palavras-chave
==========================

Se você mescla arquivos contendo palavras-chave (see Substituição de palavra-chave), você normalmente vai ter muitos conflitos durante a mesclagem, já que as palavras-chave são expandidas de forma diferente nas revisões que você está mesclando.

Portanto, você vai freqüentemente querer especificar a opção -kk (see Modos de substituição) na linha de comando do merge.  Simplesmente substituindo o nome da palavra-chave, e não o valor expandido dela, vai garantir que as revisões que você vai estar mesclando ???will be the same as each other???, e assim evitar conflitos falsos.

Por exemplo, suponha que você tenha um arquivo como este:

            +---------+
           _! 1.1.2.1 !   <-  br1
          / +---------+
         /
        /
     +-----+    +-----+
     ! 1.1 !----! 1.2 !
     +-----+    +-----+

E seu diretório de trabalho está no momento no tronco (revisão 1.2).  Então pode acontecer de você obter os seguintes resultados de uma mescla:

     $ cat file1
     key $Revision: 1.2 $
     . . .
     $ cvs update -j br1
     U file1
     RCS file: /cvsroot/first-dir/file1,v
     retrieving revision 1.1
     retrieving revision 1.1.2.1
     Merging differences between 1.1 and 1.1.2.1 into file1
     rcsmerge: warning: conflicts during merge
     $ cat file1
     <<<<<<< file1
     key $Revision: 1.2 $
     =======
     key $Revision: 1.1.2.1 $
     >>>>>>> 1.1.2.1
     . . .

O que aconteceu é que a mesclagem tentou mesclar as diferenças entre 1.1 e 1.1.2.1 dentro de seu diretório de trabalho.  Então, uma vez que a palavra-chave mudou de Revision: 1.1 para Revision: 1.1.2.1, o CVS tentou mesclar esta mudança no seu diretório de trabalho, o que gerou um conflito com o fato de seu diretório de trabalho continha Revision: 1.2.

Isto é o que aconteceria se você tivesse usado -kk:

     $ cat file1
     key $Revision: 1.2 $
     . . .
     $ cvs update -kk -j br1
     U file1
     RCS file: /cvsroot/first-dir/file1,v
     retrieving revision 1.1
     retrieving revision 1.1.2.1
     Merging differences between 1.1 and 1.1.2.1 into file1
     $ cat file1
     key $Revision$
     . . .

O que está acontecendo aqui é que ambas as revisões 1.1 e 1.1.2.1 expandem em um simples Revision, e consequentemente, não há nenhuma mudança para mesclar entre elas no diretório de trabalho.  Portanto, não há conflito.

WARNING: Em versões do CVS anteriores à 1.12.2, existia um grande problema ao usar -kk em mesclagens.  A saber, -kk sobreescrevia qualquer modo de expansão de palavra-chave padrão ajustado no arquivo do repositório.  Isto podia, infelizmente para alguns usuários, corromper arquivos binários (com um modo de expansão de palavra-chave padrão em -kb).  Portanto, quando um repositório contém arquivos binários, conflitos têm que ser tratados manualmente ao invés de serem tratados com -kk no comando de mescla.

Da versão 1.12.2 para frente do CVS, a expansão por palavra-chave disponível na linha de comando para qualquer comando do CVS não mais sobreescreve o modo de expansão de palavra-chave -kb para arquivos binários, embora ainda sobreescreva os outros modos de expansão de palavra-chave.  Você pode agora mesclar com tranquilidade usando -kk para evitar conflitos falsos em linhas contendo palavras-chave do RCS, mesmo quando seu repositório contém arquivos binários.

Comportamento recursivo
***********************

Quase todos os subcomandos do CVS trabalham de forma recursiva quando você passa um diretório como argumento.  Por exemplo, considere esta estrutura:

           $HOME
             |
             +--tc
             |   |
                 +--CVS
                 |      (internal CVS files)
                 +--Makefile
                 +--backend.c
                 +--driver.c
                 +--frontend.c
                 +--parser.c
                 +--man
                 |    |
                 |    +--CVS
                 |    |  (internal CVS files)
                 |    +--tc.1
                 |
                 +--testing
                      |
                      +--CVS
                      |  (internal CVS files)
                      +--testpgm.t
                      +--test2.t

Se tc é o diretório atual, então é verdade que:

  * cvs update testing é equivalente a

          cvs update testing/testpgm.t testing/test2.t

  * cvs update testing man atualiza todos os arquivos nos subdiretórios

  * cvs update . ou simplesmente cvs update atualiza todos os arquivos no diretório tc

Se nenhum argumento é dado ao update ele atualiza todos os arquivos no diretório atual e nos seus subdiretórios recursivamente.  Em outras palavras, O . é um argumento padrão para o update. O mesmo vale para a maioria dos subcomandos do CVS, e não apenas para o update.

O comportamento recursivo dos subcomandos do CVS pode ser desligado com a opção -l.  De forma oposta, a opção -R pode ser usada para forçar a recursão se o -l estiver especificado no ~/.cvsrc (see ~/.cvsrc).

     $ cvs update -l         # Don't update files in subdirectories

Adicionando, removendo e renomeando arquivos e diretórios
*********************************************************

No decorrer de um projeto, normalmente se adicionam arquivos.  Da mesma forma se remove e se renomeia.  E tudo isto também para diretórios.  O conceito geral que se deve ter em mente em todos estes casos é que ao invés de fazer uma mudança irreversível você vai querer que o CVS registre o fato de que uma mudança ocorreu, da mesma forma que é feito com a modificação de um arquivo existente.  O mecanismo exato para se fazer isto com o CVS varia conforme o caso.

Adicionando arquivos a um diretório
===================================

Para adicionar um novo arquivo a um diretório, siga estes passos.

  * Você deve ter uma cópia de trabalho do diretório. See Obtendo os fontes.

  * Crie o novo arquivo dentro da cópia local do diretório.

  * Use cvs add FILENAME para dizer ao CVS que você quer fazer controle de versões no arquivo.  Se o arquivo contém dados em binário, especifique -kb (see Arquivos binários).

  * Use cvs commit FILENAME para de fato colocar o arquivo no repositório.  Outros desenvolvedores não poderam ver o arquivo até que você tenha feito isto.

Você também pode usar o comando add para adicionar um novo diretório.

Ao contrário da maioria dos outros comandos, o comando add não é recursivo.  Você não pode sequer digitar cvs add foo/bar!  Ao invés disso, você tem que fazer

     $ cd foo
     $ cvs add bar

 -- Comando: cvs add [-k kflag] [-m mensagem] arquivos ...

     Agenda ARQUIVOS para serem adicionados ao repositório. Os arquivos ou diretórios especificados com add já devem existir no diretório atual.  Para adicionar toda uma estrutura de diretórios nova ao repositório de fontes (por exemplo, arquivos recebidos de um fornecedor terceiro), use o comando import ao invés do add.  See import.

     Os arquivos adicionados não são colocados no repositório de fontes até que você use o commit para tornar a mudança permanente.  Aplicar um add num arquivo que foi removido com o comando remove vai desfazer o efeito do remove, a menos que haja um commit entre os dois. See Removendo arquivos, para um exemplo.

     A opção -k especifica a forma padrão como este arquivo vai ser ???checked out???; para mais informações veja Modos de substituição.

     A opção -m especifica uma descrição para o arquivo.  Esta descrição aparece no registro histórico (history log) (se este estiver habilitado, see arquivo history (histórico)). Ela também vai ser guardada no histórico de versões dentro do repositório quando o arquivo é ???committed???.  O comando log mostra esta descrição.  A descrição pode ser alterada usando-se admin -t.  See admin.  Se você omitir a opção -m DESCRIPTION, uma string vazia vai ser usada.  Não vai ser pedido a você uma descrição.

Por exemplo, os seguintes comandos adicionam o arquivo backend.c ao repositório:

     $ cvs add backend.c
     $ cvs commit -m "Early version. Not yet compilable." backend.c

Quando você adiciona um arquivo ele é adicionado apenas no ramo no qual você está trabalhando (see Ramificando e mesclando).  Você pode mais tarde mesclar as adições a outro ramo se você quiser (see Mesclando adicionados e removidos).

Removendo arquivos
==================

Diretórios mudam.  Novos arquivos são adicionados, e arquivos velhos somem.  Ainda assim, você vai querer poder recuperar uma cópia exata de releases antigas.

Aqui está o que você pode fazer para remover um arquivo, mas continuar sendo capaz de recuperar revisões antigas dele:

  * Certifique-se de não ter feito nenhuma alteração que falte fazer ???commit??? nele.  See Vendo as diferenças, para uma forma de fazer isto.  Você também pode usar o comando status ou o update.  Se você remove o arquivo sem fazer ???commit??? nas suas mudanças, obviamente você não vai ser capaz de recuperar o arquivo na forma como ele era imediatamente antes da remoção.

  * Remova o arquivo da cópia local do seu diretório. Você pode usar o rm, por exemplo.

  * Use cvs remove FILENAME para dizer ao CVS que você quer realmente apagar o arquivo.

  * Use cvs commit FILENAME para realizar a remoção de fato do arquivo do repositório.

Quando você faz ???commit??? na remoção do arquivo, o CVS registra o fato de que o arquivo não existe mais.  É possível para um arquivo existir apenas em alguns ramos e não em outros, ou re-adicionar outro arquivo com o mesmo nome depois.  O CVS vai de forma correta criar ou não criar o arquivo, baseado nas opões -r e -D especificadas no checkout ou no update.

 -- Comando: cvs remove [options] files ...

     Prepara arquivo(s) para ser removido do reporitório (arquivos que ainda não foram removidos do diretório de trabalho não são processados).  Na verdade este comando não remove o arquivo do repositório até que você faça ???commit??? no removido.  Para uma lista completa de opções, veja em Chamando o CVS.

Aqui está um exemplo de remoção de vários arquivos:

     $ cd test
     $ rm *.c
     $ cvs remove
     cvs remove: Removing .
     cvs remove: scheduling a.c for removal
     cvs remove: scheduling b.c for removal
     cvs remove: use 'cvs commit' to remove these files permanently
     $ cvs ci -m "Removed unneeded files"
     cvs commit: Examining .
     cvs commit: Committing .

Por conveniência você pode remover o arquivo e fazer cvs remove nele de uma só vez, especificando a opção -f.  Por exemplo, o exemplo acima poderia ser feito assim:

     $ cd test
     $ cvs remove -f *.c
     cvs remove: scheduling a.c for removal
     cvs remove: scheduling b.c for removal
     cvs remove: use 'cvs commit' to remove these files permanently
     $ cvs ci -m "Removed unneeded files"
     cvs commit: Examining .
     cvs commit: Committing .

Se você executa remove para um arquivo, e então muda de idéia antes do ???commit???, você pode desfazer o remove com um add.

     $ ls
     CVS   ja.h  oj.c
     $ rm oj.c
     $ cvs remove oj.c
     cvs remove: scheduling oj.c for removal
     cvs remove: use 'cvs commit' to remove this file permanently
     $ cvs add oj.c
     U oj.c
     cvs add: oj.c, version 1.1.1.1, resurrected

Se você notar  o erro antes de rodar o comando remove você pode usar o update para resuscitar o arquivo:

     $ rm oj.c
     $ cvs update oj.c
     cvs update: warning: oj.c was lost
     U oj.c

Quando você remove um arquivo ele é removido apenas do ramo no qual você está trabalhando (see Ramificando e mesclando).  Você pode depois mesclar as remoções em outro ramo se quiser (see Mesclando adicionados e removidos).

Removendo diretórios
====================

Conceitualmente, remover diretórios é num certo sentido similar a remover arquivos---você quer que o diretório não exista mais  no seu diretório de trabalho atual, mas você também quer ser capaz de recuperar releases antigas nas quais o diretório existe.

A forma de remover um diretório é removendo todos os arquivos nele.  Você não remove o diretório mesmo; não há jeito de fazer isto.  Ao invés disto você especifica a opção -P no cvs update ou no cvs checkout, que vai fazer com que o CVS remova diretórios vazios de seus diretórios de trabalho.  (Observe que o cvs export sempre remove diretórios vazios.) Provavelmente, a melhor maneira de fazer isto é sempre usar o -P; se você quiser manter um diretório vazio, ponha um arquivo sem importância nele (por exemplo .keepme) para evitar que o -P apague o diretório.

Observe que o -P está implícito nas opções -r ou -D do checkout.  Desta forma o CVS vai ser capaz de criar ou não criar corretamente o diretório dependendo de ter ou não algum arquivo na versão que você está fazendo ???check out???.

Movendo e renomeando arquivos
=============================

Mover arquivos para um diretório diferente ou renomeá-los não é difícil, mas algumas das formas de faze-lo podem não ser óbvias.  (Mover ou renomear diretórios é ainda mais difícil.  See Movendo diretórios.).

O exemplos abaixo assumem que o arquivo ANTIGO foi renomeado para NOVO.

A forma normal de renomear
--------------------------

A forma normal de mover um arquivo é copiar ANTIGO para NOVO, e então aplicar os comandos normais do CVS para, no repositório, remover ANTIGO e adicionar NOVO.

     $ mv OLD NEW
     $ cvs remove OLD
     $ cvs add NEW
     $ cvs commit -m "Renamed OLD to NEW" OLD NEW

Esta é a forma mais simples de mover um arquivo, não é anti-falhas, e vai preservar o histórico do que foi feito.  Observe que para acessar o histórico do arquivo você vai precisar especificar o nome antigo ou o novo, dependendo de que porção do histórico você vai estar acessando.  Por exemplo, cvs log ANTIGO vai mostrar o registro (log) até o momento onde o arquivo foi renomeado.

Quando NOVO é ???committed??? seus números de revisão vão recomeçar, normalmente em 1.1.  Portanto, se isto te incomoda, lembre de usar a opção -r rev na hora do ???commit???.  Para mais informações veja em Atribuindo revisões.

Movendo o arquivo com o histórico
---------------------------------

Este método é mais perigoso, já que envolve movimentação de arquivos no repositório.  Leia a seção toda antes de sair tentando!

     $ cd $CVSROOT/DIR
     $ mv OLD,v NEW,v

Vantagens:

  * O registro (log) de alterações permanece intacto.

  * Os números de revisão não são alterados.

Desvantagens:

  * Releases antigas não serão mais facilmente recuperadas a partir do repositório.  (O arquivo vai aparecer como NOVO mesmo em revisões do tempo anterior a ter sido renomeado).

  * Não há informação nos registros de quando o arquivo foi renomeado.

  * Coisas ???Nasty??? podem acontecer se alguém acessar o arquivo de histórico enquanto você estier movendo ele. Certifique-se de que ninguém mais rode qualquer dos comandos do CVS durante a movimentação.

Copiando o arquivo de histórico
-------------------------------

Esta forma também envolve modificações diretas no repositório.  É segura, mas tem seus incovenientes.

     # Copy the RCS file inside the repository
     $ cd $CVSROOT/DIR
     $ cp OLD,v NEW,v
     # Remove the old file
     $ cd ~/DIR
     $ rm OLD
     $ cvs remove OLD
     $ cvs commit OLD
     # Remove all tags from NEW
     $ cvs update NEW
     $ cvs log NEW             # Remember the non-branch tag names
     $ cvs tag -d TAG1 NEW
     $ cvs tag -d TAG2 NEW
     ...

Ao remover as etiquetas você vai ser capaz de ???check out??? revisões antigas.

Vantagens:

  * O ???check out??? de revisões antigas funciona corretamente, ???as long as??? você usa -rTAG e não -DDATE para recuperar as revisões.

  * O registro (log) de mudanças é mantido intacto.

  * Os números de revisão não são afetados.

Desvantagens:

  * Você não pode ver de forma fácil os histórico do arquivo através das ações de renomear.

Movendo e renomeando diretórios
===============================

A forma normal de renomear ou mover um diretório é renomear ou mover cada arquivo dentro dele como descrito em Outside.  Então fazer um ???check out??? com a opção -P, como descrito em Removendo diretórios.

Se você realmente quer ???to hack??? o repositório para renomear ou apagar um diretório no repositório, você pode fazê-lo da seguinte forma:

 1. Avise a todos que fizeram checkout do diretório que o diretório vai ser renomeado.  Eles vão ter que fazer ???commit??? de todas as mudanças, e remover suas cópias de trabalho antes que você faça os passos seguintes.

 2. Renomeie o diretório dentro do repositório.

          $ cd $CVSROOT/PARENT-DIR
          $ mv OLD-DIR NEW-DIR

 3. Conserte os arquivos administrativos do CVS, se necessário (por exemplo, se você está renomeando um módulo inteiro).

 4. Diga a todo mundo que  eles podem fazer check out novamente e continuar o trabalho.

Se alguém manteve uma cópia de trabalho, os comandos do CVS vão parar de funcionar para esta pessoa até que ela remova o diretório que desapareceu do repositório.

Na maioria das vezes é melhor mover os arquivos do diretório ao invés de mover o diretório.  Se você mover o diretório não há garantias de que você seja capaz de recuperar releases antigas corretamente, já que elas dependem provavelmente do nome dos diretórios.

Navegação no Histórico
**********************

Uma vez usando o CVS para guardar um histórico do controle de versões---que arquivos foram mudandos, quando, como e por quem, existe uma variedade de mecanismos para procurar ao longo do histórico.

Mensagens de registro (log)
===========================

Sempre que você ???commit??? um arquivo você especifica uma mensagem de registro (log).

Para ver todas as mensagens de registro que foram especificadas para cada revisão que foi ???committed???, use o comando cvs log (see log).

The history database
====================

Você pode usar o arquivo history (see arquivo history (histórico)) para registrar várias ações do CVS. Para recuperar a informação do arquivo history, use o comando cvs history (see history).

Observação: você pode controlar o que vai ser registrado neste arquivo usando a palavra-chave LogHistory no arquivo CVSROOT/config (see config).

User-defined logging
====================

Você pode personalizar o CVS para registrar vários tipos de ação, da forma que você escolher.  Estes mecanismos operam executando um script várias vezes.  O script deve anexar uma mensagem a um arquivo que lista as informações e o programador que as criou, ou mandar um e-mail para um grupo de desenvolvedores, ou, talvez, mandar uma mensagem para um newsgroup em particular. Para registrar os commits, usar o arquivo loginfo (see loginfo).  Para registrar etiquetamentos, use o comando taginfo (see taginfo). Para registrar ???commits???, ???checkouts???, exportações, e etiquetagens, você pode usar, respectivamente, as opções -i, -o, -e e -t no arquivo modules.  Para uma forma mais flexível de notificar vários usuários, ???which requires less in the way of??? manter scripts centralizados atualizados, use o comando cvs watch add (see Recebendo Notificações); este comando é útil mesmo se você não estiver usando cvs watch on.

O comando annotate
==================

 -- Comando: cvs annotate [-FflR] [-r revisão|-D data] arquivos ...

     Para cada arquivo em ARQUIVOS, imprime a revisão no topo do tronco, junto com informações a respeito da última modificação em cada linha.  Por exemplo:

          $ cvs annotate ssfile
          Annotations for ssfile
          ***************
          1.1          (mary     27-Mar-96): ssfile line 1
          1.2          (joe      28-Mar-96): ssfile line 2

     O arquivo ssfile atualmente contém duas linhas.  A linha 1 de ssfile foi submetida por mary em March 27 (27 de março).  Então, em March 28 (28 de março), joe adicionou a linha 2 de ssfile, sem modificar a linha 1 de ssfile.  Este relatório não te diz nada a respeito de linhas que foram deletadas ou substituídas; Você precisa usar o cvs diff para isto (see diff).

As opções para o cvs annotate são listadas em Chamando o CVS e podem ser usadas para selecionar os arquivos e revisões para o annotate.  As opções são descritas com mais detalhes lá e em Opções comuns.

Manipulando arquivos binários
*****************************

O CVS é usado normalmente para guardar arquivos texto.  Com arquivos texto o CVS pode mesclar revisões, mostrar diferenças entre revisões de uma forma legível para humanos, e outras operações do tipo.  Entretanto, se você está disposto a abrir mão de algumas destas habilidades, o CVS pode guardar arquivos binários.  Por exemplo, pode-se guardar um site no CVS incluindo tanto os arquivos texto quanto as imagens em binário.

The issues with binary files
============================

???While??? a necessidade de armazenar arquivos binários se mostra óbvia se os arquivos com os quais você normalmente trabalha são binários, botá-los dentro do controle de versões requer alguns cuidados adicionais.

Uma habilidade básica de um controle de versões é mostrar as diferenças entre duas revisões.  Por exemplo, se outra pessoa submete (check in) uma nova versão de um arquivo, você pode querer ver o que foi mudado e determinar quais destas mudanças foram boas.  Para arquivos texto, o CVS oferece esta funcionalidade através do comando cvs diff.  Para arquivos binários, existe uma chance de  extrair as duas revisões e então compará-las com uma ferramenta externa ao CVS (por exemplo, alguns processadores de texto têm esta habilidade).  Se não existe tal ferramenta, é possível rastrear mudanças por outros meios, como por exemplo convencendo as pessoas a escreverem boas mensagens de registro (log), e torcendo para que as mudanças que eles realmente fizeram foram as que eles tinham intenção de fazer.

Outra habilidade de um sistema de controle de versões é a capacidade de mesclar duas revisões.  No CVS isto acontece em dois contextos.  O primeiro é quando os usuáriso fazem mudanças em diretórios de trabalho separados (see Múltiplos desenvolvedores).  A segunda é quando alguém mescla explicitamente com o comando update -j (see Ramificando e mesclando).

No caso de arquivos texto, o CVS pode mesclar mudanças feitas independentemente, e avisar sobre um conflito se as mudanças conflitarem.  Com arquivos binários, o melhor que o CVS pode fazer é fornecer as duas cópias diferentes do arquivo, e deixar a cargo do usuário a resolução do conflito.  O usuário pode escolher uma cópia ou a outra, ou pode rodar uma ferramenta externa de mesclagem que entenda aquele formato de arquivo em particular, se é que tal ferramenta exista. Observe que mesclagem feita pelo usuário se baseia no fato de o usuário não omitir acidentalmente algumas mudanças, e portanto é sujeita a erros.

Se você acha que este processo é indesejável, a melhor escolha é evitar mesclagem.  Para evitar mesclagens resultantes de diretórios de trabalho separados, veja a discussão a respeito de ???reserved checkouts??? (travas de arquivo) em Múltiplos desenvolvedores.  Para ecitar mesclagens resultantes de ramificações, restrinja o uso de ramos.

Como guardar arquivos binários
==============================

Existem dois aspectos a considerar quando se usa o CVS para guardar arquivos binários.  O primeiro é que o CVS, por padrão, converte quebras de linhas entre a forma canônica na qual elas são guardadas no repositório (apenas ???linefeed???), e a forma apropriada para o sistema operacional no qual o cliente é usado (por exemplo, carriage return (retorno do carro) seguido por line feed (alimentação de linha) para o Windows NT).

O segundo aspecto é que um arquivo binário pode conter dados que se pareçam com uma palavra-chave (see Substituição de palavra-chave). Logo, a expansão de palavra-chave deve ser desativada.

A opção -kb disponível com alguns comandos do CVS garante que nem conversão de terminação de linha nem expansão de palavra-chave sejam usadas.

Aqui está um exemplo de como você pode criar um novo arquivo usando a opção -kb:

     $ echo '$Id$' > kotest
     $ cvs add -kb -m"A test file" kotest
     $ cvs ci -m"First checkin; contains a keyword" kotest

Se um arquivo for acidentalmente adicionado sem o -kb, é possível usar o comando cvs admin para reverter. Por exemplo:

     $ echo '$Id$' > kotest
     $ cvs add -m"A test file" kotest
     $ cvs ci -m"First checkin; contains a keyword" kotest
     $ cvs admin -kb kotest
     $ cvs update -A kotest
     # For non-unix systems:
     # Copy in a good copy of the file from outside CVS
     $ cvs commit -m "make it binary" kotest

Quando você submete o arquivo kotest o arquivo não é mantido como um arquivo binário, por que você não o submeteu como arquivo binário.  O comando cvs admin -kb ajusta o método de substituição da palavra-chave padrão para este arquivo, mas não altera a cópia de trabalho que você tem.  Se você tem que lidar com terminações de linha (ou seja, você está usando o CVS em um sistema não-unix), então você precisa submeter uma nova cópia do arquivo, como mostrado no comando cvs commit acima. No unix, o comando cvs update -A basta. (Note que você pode usar o cvs log para determinar o métido de substituição de palavra-chave padrão para um arquivo e cvs status para determinar o método de substituição de palavra-chave para uma cópia de trabalho.)

Entretanto, ao usar cvs admin -k para mudar a expansão de palavra-chave, esteja atento para o fato de que o modo de expansão de palavra-chave não tem controle de versão.  Isto significa que, por exemplo, se você tem um arquivo texto em versões antigas, e um arquivo binário com o mesmo nome em novos releases, o CVS não fornece uma forma de obter o arquivo em formato texto, ou binário, dependendo da versão que você estpa pegando.  Não existe uma boa solução alternativa para este problema.

Você também pode ajustar um padrão para quando o cvs add e o cvs import tratarem um arquivo como binário de acordo como o seu nome; por exemplo, você pode dizer que arquivos cujos nomes terminem com .exe são binário.  See Wrappers. Não existe atualmente uma forma de fazer o CVS detectar quando um arquivo é binário baseado em seu conteúdo.  A dificuldade principal em fazer isto é que não é claro como se faz para distinguir entre arquivos binários e não-binários, e as regras para serem aplicadas variam consideravelmente com o sistema operacional.

Múltiplos desenvolvedores
*************************

Quando mais de uma pessoa trabalham em um projeto de software freqüentemente surgem complicações.  Às vezes duas pessoas tentam editar o mesmo arquivo simultaneamente.  Uma solução, conhecida como trava de arquivo ou ???checkout??? reservado, é permitir, para cada arquivo, que apenas uma pessoa por vez edite o arquivo. Esta é a única solução em alguns sistemas de controle de versão, incluindo RCS e SCCS.  Atualmente, a forma normal de se ter ???checkouts??? reservados com o CVS é com o comando cvs admin -l (see admin options).  Isto não é tão integrado com o CVS quanto a habilidade de ???watch???, descrita abaixo, mas vemos que a maioria das pessoas que necessitam de ???checkouts??? reservados acham isto adequado. Também é possível usar a habilidade de trabalhar com descrita a seguir, junto com alguns procedimentos adequados (que o sotware não obriga), para evitar que duas pessoas editem o mesmo arquivo ao mesmo tempo.

O modelo padrão no CVS é conhecido como ???checkouts??? não-reservados.  Neste modelo, os desenvolvedores podem editar sua própria cópia de trabalho de um arquivo simultaneamente.  A primeira pessoa que ???commits??? suas mudanças não tem uma forma automática de saber que outra pessoa começou a editar o mesmo arquivo.  Os outros vão receber uma mensagem de erro quando tentarem ???commit??? o arquivo.  Eles então terão que usar comandos do CVS para tornar sua cópia local atualizada em relação à revisão no repositório.  Este processo é quase automático.

O CVS também dá suporte a mecanismos que facilitam várias formas de comunicação, sem regras realmente obrigatórias como acontece com os ???checkouts??? reservados.

O restante deste capítulo descreve como estes vários modelos funcionam, e alguns dos aspectos envolvidos na hora de escolher entre eles.

Estado de arquivo
=================

Baseado em quais operações você realizou num arquivo ???checked out???, e quais operações outros realizaram neste arquivo no repositório, podemos classificar o arquivo em vários estados.  Os estados, como são mostrados pelo comando status, são:

Up-to-date (Atualizado)
     O arquivo é identico à última revisão no repositório, para o ramo em questão.

Locally Modified (Modificado localmente)
     Você alterou o arquivo, e ainda não ???committed??? suas mudanças.

Locally Added (Adicionado localmente)
     Você adicionou o arquivo com add, e ainda não ???committed??? suas mudanças.

Locally Removed (Removido localmente)
     Você removeu o arquivo com remove, e ainda não ???committed??? suas mudanças.

Needs Checkout (Precisa de ???checkout???)
     Alguém ???committed??? uma revisão nova no repositório. O nome está um pouco confuso; você normalmente vai usar update ao invés de checkout para obter a nova revisão.

Needs Patch (Precisa de ???patch???)
     Igual a 'Needs Checkout', mas o servidor do CVS vai mandar um ???patch??? ao invés de um arquivo inteiro.  Mandar um ???patch??? ou um arquivo inteiro dá no mesmo.

Needs Merge (Precisa mesclar)
     Outra pessoa ???committed??? uma nova revisão no repositório, e você fez modificações no arquivo.

Unresolved Conflict (Conflito não-solucionado)
     Um arquivo com o mesmo nome deste arquivo novo foi adicionado ao repositório a partir de outra área de trabalho.  Este arquivo vai ter que ser movido para que não atrapalhe um update de completar.

File had conflicts on merge (Arquivo teve conflitos na mescla)
     Isto é parecido com 'Locally Modified', com a diferença que o comando update anterior produziu um conflito.  Se você ainda não o fez, precisa resolver o conflito, como é descrito em Exemplo de conflitos.

Unknown (Desconhecido)
     O CVS não sabe nada a respeito deste arquivo.  Por exemplo, você criou um novo arquivo e não rodou um add.

Para facilitar o entendimento do estado do arquivo, o comando status também relata a revisão de trabalho, que é a revisão da qual o arquivo no diretório de trabalho deriva, e a Revisão de repositório que é a mais recente revisão no repositório, para o ramo em uso.

As opções para o comando status são listadas em Chamando o CVS.  Para informações sobre suas saídas Sticky tag (Etiqueta adesiva) e Sticky date (data adesiva) veja em Etiquetas adesivas. Para informações na saída Sticky options (Opções adesivas), veja a opção -k em update options.

Você pode pensar nos comandos status e update como complementares.  Você usa o update para atualizar seus arquivos, e você pode usar o status para ter idéia do que um update deve fazer (obviamente, o estado do repositório pode mudar depois que você rodar o update).  De fato, se você quiser um comando para mostrar o estado de arquivos num formato mais conciso do que o comando status mostra, você pode invocar

     $ cvs -n -q update

A opção -n significa fingir que faz a atualização, mas simplesmente mostrar o estado; a opção -q suprime a exibição do nome de cada diretório.  Para mais informações sobre o comando update, e opções, veja em Chamando o CVS.

Deixando um arquivo atualizado
==============================

Quando você quiser atualizar ou mesclar um arquivo, use o comando update.  Para arquivos que não estão atualizados isto é mais ou menos equivalente ao comando checkout: a revisão mais nova do arquivo é extraída do repositório e posta no diretório de trabalho.

Suas modificações num arquivo nunca são perdidas quando você usa update.  Se não existe uma revisão mais nova, o update não faz nada.  Se você editou o arquivo, e uma nova revisão está disponível, o CVS vai mesclar todas as alterações na sua cópia de trabalho.

Por exemplo, imagine que você ???checked out??? a revisão 1.4 e começou a editá-la.  Enquanto isto, outra pessoa ???committed??? a revisão 1.5, e logo depois a revisão 1.6.  Se você rodar update no arquivo agora, o CVS vai incorporar todas as mudanças entre a revisão 1.4 e 1.6 no seu arquivo.

Se quaisquer das mudanças entre 1.4 e 1.6 ocorreram suficientemente próximas de quaisquer das suas mudanças, uma sobreposição ocorre.  Nestes casos um aviso é mostrado, e o arquivo resultante contém ambas as versões das linhas que se sobrepuseram, delimitadas por marcadores especiais. See update, para uma descrição completa do comando update.

Exemplo de conflitos
====================

Suponha que a revisão 1.4 de driver.c contém isto:

     #include <stdio.h>

     void main()
     {
         parse();
         if (nerr == 0)
             gencode();
         else
             fprintf(stderr, "No code generated.\n");
         exit(nerr == 0 ? 0 : 1);
     }

A revisão 1.6 de driver.c contém isto:

     #include <stdio.h>

     int main(int argc,
              char **argv)
     {
         parse();
         if (argc != 1)
         {
             fprintf(stderr, "tc: No args expected.\n");
             exit(1);
         }
         if (nerr == 0)
             gencode();
         else
             fprintf(stderr, "No code generated.\n");
         exit(!!nerr);
     }

Sua cópia de trabalho de driver.c, baseada na revisão 1.4, contém isto, antes de você rodar um cvs update:

     #include <stdlib.h>
     #include <stdio.h>

     void main()
     {
         init_scanner();
         parse();
         if (nerr == 0)
             gencode();
         else
             fprintf(stderr, "No code generated.\n");
         exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
     }

Então você roda o cvs update:

     $ cvs update driver.c
     RCS file: /usr/local/cvsroot/yoyodyne/tc/driver.c,v
     retrieving revision 1.4
     retrieving revision 1.6
     Merging differences between 1.4 and 1.6 into driver.c
     rcsmerge warning: overlaps during merge
     cvs update: conflicts found in driver.c
     C driver.c

O CVS disse a você que existem conflitos. Seu arquivo de trabalho original é guardado sem modificações em .#driver.c.1.4.  A nova versão de driver.c contém isto:

     #include <stdlib.h>
     #include <stdio.h>

     int main(int argc,
              char **argv)
     {
         init_scanner();
         parse();
         if (argc != 1)
         {
             fprintf(stderr, "tc: No args expected.\n");
             exit(1);
         }
         if (nerr == 0)
             gencode();
         else
             fprintf(stderr, "No code generated.\n");
     <<<<<<< driver.c
         exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
     =======
         exit(!!nerr);
     >>>>>>> 1.6
     }

Observe como todas as modificações sem sobreposição foram incorporadas na sua cópia de trabalho, e que as seções com sobreposição são marcadas de forma clara com <<<<<<<, ======= e >>>>>>>.

Você resolve o conflito editando o arquivo, removendo os marcadores e as linhas erradas.  Suponha que você ficou com este arquivo:

     #include <stdlib.h>
     #include <stdio.h>

     int main(int argc,
              char **argv)
     {
         init_scanner();
         parse();
         if (argc != 1)
         {
             fprintf(stderr, "tc: No args expected.\n");
             exit(1);
         }
         if (nerr == 0)
             gencode();
         else
             fprintf(stderr, "No code generated.\n");
         exit(nerr == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
     }

Você agora pode seguir em frente e ???commit??? ele como a revisão 1.7.

     $ cvs commit -m "Initialize scanner. Use symbolic exit values." driver.c
     Checking in driver.c;
     /usr/local/cvsroot/yoyodyne/tc/driver.c,v  <--  driver.c
     new revision: 1.7; previous revision: 1.6
     done

Para sua segurança, o CVS não vai aceitar o check in de um arquivo se um conflito ocorreu e você não resolveu o conflito.  Atualmente, para resolver um conflito, você deve mudar a data do arquivo.  Em versões anteriores do CVS, você também precisava ter certeza de que o arquivo não continha marcadores de conflito.  Já que seu arquivo pode conter marcadores de conflito ???de forma legítima??? (isto é, a ocorrência de >>>>>>>  no começo de uma linha que não marca um conflito), a versão atual do CVS vai mostrar um aviso e continuar a fazer o ???check in??? do arquivo.

Se você usa a release 1.04 ou posterior do pcl-cvs (uma interface amigável para o  CVS de dentro do GNU Emacs) você pode usar um pacote do Emacs chamado emerge para te ajudar a resolver os conflitos. Veja na documentação do pcl-cvs.

Informando os outros sobre ???commits???
========================================

Às vezes é útil informar os outros quando você ???commit??? uma nova revisão de um arquivo.  A opção -i do arquivo modules, ou do arquivo loginfo, pode ser usada para automatizar este processo.  See modules.  See loginfo.  Você pode usar estas funcionalidades do CVS para, por exemplo, instruir o CVS a enviar uma mensagem a todos os desenvolvedores, ou enviar uma mensagem para um newsgroup local.

Vários desenvolvedores tentando rodar o CVS simultâneamente
===========================================================

Se vários desenvolvedores tentam rodar o CVS no mesmo momento, alguém vai receber esta mensagem:

     [11:43:23] waiting for bach's lock in /usr/local/cvsroot/foo

O CVS vai tentar de novo a cada 30 segundos, e vai ou continuar com a operação ou mostrar a mensagem de novo, se ainda precisar esperar.  Se uma trava (lock) permanece por muito tempo, procure a pessoa que é dona da trava e pergunte que comando do cvs ele está rodando.  Se ele/ela não estiver rodando um comando do cvs, procure no diretório do repositório que está referenciado na mensagem e remova os arquivos cujos nomes começam com #cvs.rfl, #cvs.wfl, or #cvs.lock.

Observe que estas travas são feitas para proteger a estrutura de dados interna do CVS e não tem relação com a palavra lock (trava) no sentido usado pelo RCS---que se refere a ???checkouts??? reservados (see Múltiplos desenvolvedores).

Qualquer quantidade de pessoas pode ler de um repositório num determinado momento; apenas quando alguém está gravando é que as travas evitam que outras pessoas leiam ou gravem.

Espera-se que a seguinte propriedade valha:

     Se alguém ???commits??? algumas mudanças com um comando cvs, então um ???update??? por outra pessoa vai obter ou todas as mudanças, ou nenhuma.

mas o CVS não tem esta propriedade.  Por exemplo, dados os arquivos

     a/one.c
     a/two.c
     b/three.c
     b/four.c

se alguém rodar

     cvs ci a/two.c b/three.c

e outra pessoa rodar cvs update no mesmo momento, a pessoa rodando update pode receber apenas as alterações feitas em b/three.c e não receber as feitas em a/two.c.

Mechanisms to track who is editing files
========================================

Para muitos grupos, o uso do CVS em sua forma padrão é perfeitamente satisfatório.  Os usuários vão algumas vezes ???check in??? uma modificação e descobrir que outras intervenções foram feitas, mas eles tratam isto e seguem em frente com o ???check in???.  Outros grupos preferem ser capazes de saber quem está editando quais arquivos, de forma que se duas pessoas tentam editar o mesmo arquivo elas podem conversar sobre quem vai editar o que ao invés de serem surpreendidos na hora do ???check in???.  As funcionalidades nesta seção permitem tal nível de coordenação, sem abrir mão da possibilidade de que dois desenvolvedores editem o mesmo arquivo ao mesmo tempo.

Para um máximo apreveitamento, os desenvolvedores devem usar cvs edit (e não chmod) para tornar os arquivos com permissão de leitura e escrita para editá-los, e cvs release (não rm) para descartar um diretório de trabalho que não está mais em uso, mas o CVS não é capaz de obrigar tal comportamento.

Dizendo ao CVS para ???watch??? certos arquivos
-----------------------------------------------

Para habilitar a funcionalidade de ???watch???, você deve primeiro especificar que certos arquivos devem ser ???watched???.

 -- Comando: cvs watch on [-lR] [ARQUIVOS]...

     Especifique que os desenvolvedores devem rodar o cvs edit antes de editar arquivos ARQUIVOS.  O CVS vai criar cópias de trabalho dos ARQUIVOS como somente-leitura, para lembrar os desenvolvedores de rodarem o comando cvs edit antes de trabalhar neles.

     Se ARQUIVOS inclui o nome de uma diretório, o CVS faz ???watch??? em todos os arquivos adicionados ao diretório correspondente do repositório, e ajusta um padrão para arquivos adicionados no futuro; isto permite que o usuário ajuste as políticas de notificação baseada em diretórios.  O conteúdo do diretório é processado recursivamente, a menos que a opção -l seja dada. A opção -R pode ser usada para forçar recursão se a opção -l está ativada em ~/.cvsrc (see ~/.cvsrc).

     Se ARQUIVOS é omitido, o padrão é o diretório atual.

 -- Comando: cvs watch off [-lR] [ARQUIVOS]...

     Não cria ARQUIVOS somente-leitura no ???checkout???; portanto, os desenvolvedores não serão lembrados de usar cvs edit e cvs unedit.

     Os ARQUIVOS e opções são processados como no cvs watch on.

Dizendo ao CVS para te notificar
--------------------------------

Você pode dizer ao CVS que você quer receber notificações sobre várias ações tomadas em um arquivo. Você pode fazer isto sem usar o cvs watch on para o arquivo, mas geralmente você vai querer usar cvs watch on, para lembrar os desenvolvedores de usar o comando cvs edit.

 -- Comando: cvs watch add [-lR] [-a AÇÃO]... [ARQUIVOS]...

     Adiciona o usuário atual à lista de pessoas que recebem notificações sobre o trabalho feito em ARQUIVOS.

     A opção -a especifica quais tipos de eventos o CVS deve notificar o usuário.  AÇÃO é uma das seguintes:

     edit
          Outro usuário executou o comando cvs edit (descrito abaixo) para um arquivo ???watched???.

     commit
          Outro usuário fez ???commit??? em mudanças em um dos ARQUIVOS.

     unedit
          Outro usuário abandonou a edição de um arquivo (sem ser por ???committing??? mudanças). Eles podem fazer isto de várias maneiras:

            * rodando o comando cvs unedit (descrito abaixo) no arquivo

            * rodando o comando cvs release (see release) no diretório pai do arquivo (ou num diretório mais acima recursivamente)

            * apagando o arquivo e permitindo que o cvs update o recrie

     all
          Todos acima.

     none
          Nenhum dos acima.  (Isto é útil com o cvs edit, descrito abaixo.)

     A opção -a pode aparecer mais de uma vez, ou nenhuma vez.  Se não aparecer, a ação padrão é all.

     Os ARQUIVOS e opções são processados como no cvs watch on.

 -- Comando: cvs watch remove [-lR] [-a AÇÃO]... [ARQUIVOS]...

     Remove um pedido de notificação posto por um cvs watch add; Os argumentos são os mesmos.  Se a opção -a está presente, apenas os ???watches??? para as ações especificadas são removidos.

Quando as condições existem para a notificação, o CVS chama o arquivo administrativo notify. Edite o notify da mesma forma que se edita os outros arquivos administrativos (see Intro aos arquivos administrativos).  Este arquivo segue as convenções usuais para arquivos administrativos (see syntax), onde cada linha é uma expressão regular seguida de um comando para executar.  O comando pode conter uma única ocorrência de %s que é substituída pelo usuário a ser notificado; o resto da informação a respeito  da notificação vai ser fornecida ao comando na entrada padrão.  O padrão para botar no arquivo notify é esta única linha:

     ALL mail %s -s "CVS notification"

Isto faz com que os usuários sejam avisados por correio eletrônico.

Observe que se você ajusta isto na forma que está, os usuários vão receber as notificações na máquina servidora.  Alguém pode escrever um script notify que direcione notificações para outro lugar, mas para tornar isto fácil, o CVS permite associar um endereço de notificação para cada usuário. Para isto crie um arquivo users em CVSROOT com uma linha para cada usuário no formato USUÁRIO:VALOR.  Então, ao invés de passar o nome do usuário a ser notificado para notify, o CVS vai passar VALOR (normalmente um endereço de email em alguma outra máquina).

O CVS não notifica você de suas próprias mudanças.  Atualmente esta checagem é feita baseada comparando o nome de usuário da pessoa que executou a ação que disparou a notificação com o nome de usuário da pessoa sendo notificada.  De fato, em geral, as funcionalidades de ???watches??? ???only track one edit??? para cada usuário.  Seria provavelmente mais útil se ???watches??? ???tracked??? cada diretório de trabalho separadamente, logo este comportamento ???might be worth changing???.

Como editar um arquivo que está sendo ???watched???
---------------------------------------------------

Já que um arquivo que está sendo ???watched??? é ???checked out??? somente-leitura, você não pode simplesmente editá-lo.  Para torná-lo leitura-escrita, e informaar outros que você está planejando editá-lo, use o comando cvs edit.  Alguns sistemas chamam isto de checkout, mas o CVS usa este termo para obter uma cópia dos fontes (see Obtendo os fontes), uma operação que estes sistemas chamam de get ou fetch.

 -- Comando: cvs edit [-lR] [-a AÇÃO]... [ARQUIVOS]...

     Prepara para serem editados os FILES do diretório de trabalho.  O CVS faz os ARQUIVOS leitura-escrita, e notifica os usuários que pediram notificação de edit para quaisquer dos ARQUIVOS.

     O comando cvs edit acita as mesmas opções que o comando cvs watch add, e estabelece um ???watch??? temporário para o usuário nos ARQUIVOS; CVS vai remover o ???watch??? quando ARQUIVOS forem uneditados ou commitados (argh!!!, ''commitados'' é horrível).  Se o usuário não deseja receber notificações, deve especificar -a none.

     Os ARQUIVOS e as opções são processadas como nos comandos cvs watch.

Normalmente quando você termina com um conjunto de mudanças, você usa o comando cvs commit, que ???checks in??? suas mudanças e retorna os arquivos ???watched??? a seus estados usuais de somente-leitura. Mas se você ao invés disto decide abandonar suas mudanças, ou não fazer nenhuma mudança, você pode usar o comando cvs unedit.

 -- Comando: cvs unedit [-lR] [ARQUIVOS]...

     Abandona o trabalho nos ARQUIVOS no diretório de tabalho, e reverte eles às versões do repositório nas quais eles foram baseados.  O CVS faz estes ARQUIVOS somente-leitura ???for which users have requested notification??? usando cvs watch on. CVS notifica os usuários que pediram notificações do tipo unedit para quaisquer dos ARQUIVOS.

     Os ARQUIVOS e opções são processados como nos comandos cvs watch.

     Se ???watches??? não estão em uso, o comando unedit provavelmente não vai fazer nada, e a forma de reverter à versão do repositório é com o comando cvs update -C arquivo (see update). O significado não é exatamente o mesmo; a última forma pode também trazer algumas mudanças que foram feitas no repositório desde a última vez que você atualizou (fez update).

Quando usando o CVS como cliente/servidor, você pode usar os comandos cvs edit e cvs unedit mesmo se o CVS é incapaz de estabelecer comunicação com o servidor; as notificações vão ser mandadas junto com o próximo comando bem sucedido do CVS.

Informações sobre quem está ???watching??? e editando
-----------------------------------------------------

 -- Comando: cvs watchers [-lR] [ARQUIVOS]...

     Lista os usuários que estão atualmente ???watching??? mudanças em ARQUIVOS.  O relatório inclui os arquivos sendo ???watched???, e o endereço de e-mail de cada ???watcher???.

     Os ARQUIVOS e opções são processados como nos comandos cvs watch.

 -- Command: cvs editors [-lR] [FILES]...

     Lista os usuários atualmente trabalhando em ARQUIVOS.  O relatório inclui o endereço de e-mail de cada usuário, o momento no qual o usuário começou a trabalhar com o arquivo, e a máquina e caminho do diretório de trabalho contendo o arquivo.

     Os ARQUIVOS e opções são processados como nos comandos cvs watch.

Using watches with old versions of CVS
--------------------------------------

If you use the watch features on a repository, it creates CVS directories in the repository and stores the information about watches in that directory. If you attempt to use CVS 1.6 or earlier with the repository, you get an error message such as the following (all on one line):

     cvs update: cannot open CVS/Entries for reading:
     No such file or directory

and your operation will likely be aborted.  To use the watch features, you must upgrade all copies of CVS which use that repository in local or server mode.  If you cannot upgrade, use the watch off and watch remove commands to remove all watches, and that will restore the repository to a state which CVS 1.6 can cope with.

Escolhendo entre ???checkouts??? reservados ou não-reservados
=============================================================

???Checkouts??? reservados e não-reservados têem cada um prós e contras.  Digamos que muito disto é uma questão de opinião ou que funciona dependendo dos diferentes estilos de trabalho em grupo, mas aqui está uma breve descrição de alguns dos aspectos.  Existem muitas formas de organizar um time de desenvolvedores. O CVS não tenta induzir uma determinada forma de se organizar.  Ele é uma ferramenta que pode ser usada de várias maneiras.

Checkout reservado pode ser bastante improdutivo.  Se duas pessoas quiserem editar diferentes partes de um mesmo arquivo, não há motivos para proibir nenhuma delas.  Além disto, é normal alguém travar um arquivo por que planeja editá-lo, mas então esquecer de destravar.

As pessoas, especialmente aquelas acostumadas com ???checkouts??? reservados, freqüentemente pensam sobre a freqüencia com que conlitos acontecem quando ???checkouts??? não-reservados estão em uso, e o quão difíceis eles são de resolver.  A experiência de muitos grupos é que os conflitos ocorrem raramente e em geral são relativamente fáceis de resolver.

A dificuldade para encontrar conflitos sérios pode ser surpreendente, até se perceber que eles ocorrem apenas quando dois desenvolvedores discordam mesmo é no projeto de uma dada seção do código; tal desacordo indica a princípio que a equipe não está se comunicando direito.  Para colaborar em qualquer regime de gerenciamento de código, os desenvolvedores devem concordar com o projeto geral do sistema; com este acordo, mudanças sobrepostas são em geral simples de mesclar.

Em alguns casos, ???checkouts??? não-reservados são claramente inapropriados.  Se não existe uma ferramenta de mescla para o tipo de arquivo que você está lidando (por exemplo, arquivos de processadores de texto ou arquivos editados por programas de ???Computer Aided Design???), e não é desejável mudar para um programa que usa um formato de dados que se possa mesclar, então resolver conflitos se torna tão desagradável que você vai estar melhor simplesmente evitando-os, com o uso de ???checkouts??? não-reservados.

As funcionalidade de ???watches??? descritas acima em ???Watches??? podem ser consideradas um modelo intermediário entre ???checkouts??? reservados e ???checkouts??? não-reservados.  Quando você vai editar um arquivo, é possível descobrir quem o está editando. E ao invés de simplesmente o sistema proibir os dois de trabalhar, ele pode dizer como está a situação e deixar você decidir se isto é ou não é um problema neste caso específico. Portanto, para alguns grupos esta é o melhor dos dois mundos de ???checkouts??? reservados e ???checkouts??? não-reservados.

Gerenciamento de revisões
*************************

Se você leu até este ponto, você provavelmente tem uma boa noção do que o CVS pode fazer por você.  Este capítulo fala um pouco sobre coisas que ainda cabe a você decidir.

Se você está desenvolvendo sozinho com o CVS, você provavelmente pode pular este capítulo.  As questões que este capítulo levanta são mais importante quando mais de uma pessoa está trabalhando num mesmo repositório.

Quando ???commit??? ?
=====================

Seu grupo deve decidir qual vai ser a política a respeito de ???commits???.  Várias políticas são possíveis, e à medida que sua experiência com o CVS crescer, você provavelmente vai encontrar a que funciona com você.

Se você ???commit??? arquivos muito rapidamente provavelmente você vai ???commit??? arquivos que nem mesmo compilam.  Se seu parceiro atualiza as cópias de trabalho dele e inclui seu arquivo bichado, ele não vai conseguir compilar o código.  Por outro lado, as outras pessoas não vão poder se beneficiar das melhorias que você fizer no código se você ???commit??? muito raramente, e os conflitos provavelmente vão aumentar.

É comum apenas ???commit??? arquivos depois de se certificar que eles podem ser compilados.  Alguns lugares exigem que os arquivos passem num conjunto de testes.  Políticas deste tipo podem ser impostas usando o arquivo commitinfo (see commitinfo), mas você deve pensar duas vezes antes de impor tal convenção. Tornando o ambiente de desenvolvimento muito controlado ele se torna muito rígido e contraprodutivo para o objetivo real, que é ter o software escrito.

Substituição de palavra-chave
*****************************

À medida em que você edita arquivos fonte dentro de um diretório de trabalho você pode sempre obter o estado de seus arquivos via cvs status e cvs log.  Mas assim que você exporta os arquivos de seu ambiente de desenvolvimento se torna mais difícil dizer de quais revisões eles são.

O CVS pode usar um mecanismo chamado de substituição de palavra-chave (ou expansão de palavra-chave) para ajudar na identificação de arquivos.  Strings embutidas na forma $KEYWORD$ e $KEYWORD:...$ em um arquivo são substituídas por strings da forma $KEYWORD:VALUE$ sempre que você obtém uma nova revisão do arquivo.

Lista de Palavras-chave
=======================

Esta é uma lista de palavras-chave:

$Author$
     O login do usuário que ???checked in??? a revisão.

$CVSHeader
     Um cabeçalho padrão (similar ao $Header$, mas com a raíz do CVS retirada). Ele contém o caminho do arquivo RCS relativo à raíz do CVS, o número da revisão, a data (UTC), o autor, o estado, e o ???locker??? (se estiver travado). Arquivos normalmente nunca são travados quando você usa CVS.

     Observe que esta palavra-chave foi adicionada apenas recentemente no CVS e pode causar problemas com instalações existentes se $CVSHeader$ já está nos arquivos por um motivo diferente. Esta palavra-chave deve ser excluída usando o KeywordExpansion=eCVSHeader no arquivo CVSROOT/config. Veja em Configurando a expansão do teclado para maiores detalhes.

$Date$
     A data e hora (UTC) na qual a revisão foi ???checked in???.

$Header$
     Um cabeçalho padrão contendo o caminho completo do arquivo RCS, o número da revisão, a data (UTC), o autor, o estado, e o ???locker??? (se estiver travado). Arquivos normalmente nunca são travados quando você usa CVS.

$Id$
     Similar ao $Header$, exceto que o nome do arquivo RCS não tem o caminho.

$Name$
     Nome da etiqueta (tag) usada para ???check out??? este arquivo.  A palavra-chave é expandida apenas se foi ???check out??? com um nome de etiqueta explícito.  Por exemplo, quando rodou o comando cvs co -r inicio, a palavra-chave expande para Name: inicio.

$Locker$
     O login do usuário que travou a revisão (vazio se não estiver travado, que é o normal a menos que cvs admin -l esteja em uso).

$Log$
     A mensagem de log (registro) fornecida durante o ???commit???, precedida por um cabeçalho contendo o nome do arquivo RCS, o número de revisão, o autor, e a data (UTC).  Mensagens de log (registro) não são substituídas.  Ao invés disto, A nova mensagem de log (registro) é inserida depois do $Log:...$. Cada nova linha é prefixada com a mesma string que precede a palavra-chave $Log.  Por exemplo, se o arquivo contém:

            /* Here is what people have been up to:
             *
             * $Log: frob.c,v $
             * Revision 1.1  1997/01/03 14:23:51  joe
             * Add the superfrobnicate option
             *
             */

     Então, linhas adicionais que são adicionadas quando a palavra-chave $Log é expandida vão ser precedidas por    * . Ao contrário de versões prévias do CVS e do RCS, o comment leader do arquivo RCS não é usado. A palavra-chave $Log é útil para acumular um ???change log??? completo num fonte, mas pode ser problemática por várias razões. Veja em Log keyword.

$RCSfile$
     O nome do arquivo RCS sem o caminho.

$Revision$
     O número de revisão atribuído à revisão.

$Source$
     O caminho completo do arquivo RCS.

$State$
     O estado atribuído à revisão.  Estados podem ser atribuídos com cvs admin -s---veja em admin options.

Palavra-chave Local
     A opção LocalKeyword no arquivo CVSROOT/config pode ser usada para especificar uma palavra-chave que não é usada como um alias para uma das seguintes palavras-chave: $Id$, $Header$, ou $CVSHeader$. Por exemplo, se o arquivo CVSROOT/config contém uma linha com LocalKeyword=MYBSD=CVSHeader, então um arquivo com a palavra-chave local $MYBSD$ vai ser expandido como se ele fosse uma palavra-chave $CVSHeader$. Se o arquivo src/frob.c contiver esta palavra-chave, ele pode parecer com algo assim:

            /*
             * $MYBSD: src/frob.c,v 1.1 2003/05/04 09:27:45 john Exp $
             */

     Muitos repositórios fazem uso de tal ``palavra-chave local''. Uma ???patch??? antiga ao CVS fornecia a funcionalidade LocalKeyword usando uma opção tag= e chamava esta funcionalidade de ``custom tag'' ou ``local tag''. ela foi usada em conjunto com o que chamavam de opção tagexpand=. No CVS esta outra opção é conhecida como a opção KeywordExpand. Veja em Configurando a expansão do teclado para maiores detalhes.

     Exemplos de projetos populares incluem: $FreeBSD$, $NetBSD$, $OpenBSD$, $XFree86$, $Xorg$.

     A vantagem disto é que você pode incluir sua informação de versão local num arquivo usando esta palavra-chave local sem romper com a informação da versão principal (que pode ser uma palavra-chave local diferente ou uma palavra-chave padrão). Permitir relatório de bug (bug report) e coisas do gênero para identificar mais adequadamente a origem do bug original para o terceiro e reduzir o número de conflitos que surgem durante uma importação de uma nova versão.

     Toda expansão de palavra-chave com exceção da palavra-chave local deve ser disabilitada usando a opção KeywordExpand no arquivo CVSROOT/config---veja em Configurando a expansão do teclado para mais detalhes.

Usando palavras-chave
=====================

Para incluir uma string de palavra-chave você deve simplesmente incluir o a string de texto relevante, como $Id$, dentro do arquivo, e ???commit??? o arquivo.  O CVS vai automaticamente (Ou, mais precisamente, como parte da execução do ???update??? que acontece automaticamente depois do ???commit???.) expandir a string como parte da operação de commit.

É normal imergir a string $Id$ nos arquivos fonte de forma que ela seja ignorada nos arquivos gerados.  Por exemplo, se você está gerenciando código fonte de programas de computador, você deve incluir uma variável que é inicializada para conter aquela string. Ou alguns compiladores C podem fornecer uma diretiva #pragma ident.  Ou um sistema de gerência de documentos pode fornecer um jeito de entregar a string diretamente ao arquivos gerados.

O comando ident (que é parte do pacote RCS) pode ser usado para extrair palavras-chave e seus valores de um arquivo.  Isto pode ser útil para arquivos texto, mas é mais útil para extração de palavras-chave de arquivos binários.

     $ ident samp.c
     samp.c:
          $Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $
     $ gcc samp.c
     $ ident a.out
     a.out:
          $Id: samp.c,v 1.5 1993/10/19 14:57:32 ceder Exp $

SCCS é outro sistema de controle de revisões popular. Ele tem um comando, what (o que, em português), que é bastante similar ao ident e usado para o mesmo propósito.  Muitos ???sites??? sem RCS tem SCCS.  Uma vez que o what procura pela seqüência de caracteres @(#) é fácil incluir palavras-chave que são detectadas por qualquer comando.  Simplesmente bote um prefixo na palavra-chave com a frase mágica SCCS, como esta:

     static char *id="@(#) $Id: ab.c,v 1.5 1993/10/19 14:57:32 ceder Exp $";

Evitando substituições
======================

Substituição de palavra-chave tem suas desvantagens. Algumas vezes você pode querer que a string de texto literal $Author$ apareça dentro de um arquivo sem que o CVS a interprete como uma palavra-chave e a expanda em algo como $Author: ceder $.

Infelizmente não há como desligar a substituição de palavra-chave de forma seletiva.  Você pode usar -ko (see Modos de substituição) para desligar a substituição de palavra-chave completamente.

Em muitos casos você pode evitar o uso de palavra-chave nos fontes, mesmo que elas apareçam no produto final. Por exemplo, o código-fonte deste manual contém $@asis{}Author$ sempre que o texto $Author$ deva aparecer.  Em nroff e troff você pode imergir o caractere nulo \& dentro de uma palavra-chave para obter um efeito similar.

Também é possível especificar explicitamente uma lista de palavras-chave para incluir ou excluir usando a opção KeywordExpand no arquivo CVSROOT/config--veja em Configurando a expansão do teclado para maiores detalhes. Esta funcionalidade foi pensada para ser usada a princípio com a opção LocalKeyword--veja Lista de palavras-chave.

Modos de substituição
=====================

Cada arquivo tem um modo de substituição padrão armazenado, e cada cópia de um arquivo num diretório de trabalho também tem um modo de substituição.  O primeiro é ajustado pela opção -k no cvs add e no cvs admin; o último é ajustado pelas opções -k ou -A do cvs checkout ou do cvs update.  O cvs diff também tem uma opção -k.  Para alguns exemplos, veja em Arquivos binários, e Mesclagem e palavras-chave.

Os modos disponíveis são:

-kkv
     Gera strings de palavras-chave usando a forma padrão, e.g. $Revision: 5.7 $ para a palavra-chave Revision.

-kkvl
     Parecido com o -kkv, exceto que um nome de ???locker??? é sempre inserido se a revisão dada estiver atualmente ???locked???. O nome do ???locker??? é relevante apenas se cvs admin -l estiver em uso.

-kk
     Gera nomes de palavras-chave apenas nas strings da palavras-chave; omite seus valores.  Por exemplo, para a palavra-chave Revision , gera a string $Revision$ ao invés de $Revision: 5.7 $. Esta opção é útil para ignorar diferenças devido a substituição de palavras-chave quando comparando revisões diferentes de um mesmo arquivo (see Mesclagem e palavras-chave).

-ko
     Gera a antiga string da palavra-chave, presente no arquivo de trabalho antes dele ter sido ???checked in???.  Por exemplo, para a palavra-chave Revision, gera a string $Revision: 1.1 $ ao invés de $Revision: 5.7 $ se era assim que a string aparecia quando o arquivo foi ???checked in???.

-kb
     Como o -ko, mas também inibindo conversão de fim-de-linhas entre a forma canônica nas qual os arquivo são arquivados no repositório (apenas linefeed), e a forma apropriada para o sistema operacional em uso no cliente.  Para sistemas, como o unix, que usam apenas o linefeed para terminar linhas, isto é bastante similar ao -ko.  Para mais informações sobre arquivos binários, veja em Arquivos binários.  No CVS versão 1.12.2 ou mais novas -kb, ajustado por cvs add, cvs admin, ou cvs import não vai ser sobreescrito pela opção -k especificada na linha de comando.

-kv
     Gera apenas os valores das palavras-chaves para strings de palavras-chave.  Por exemplo, para a palavra-chave Revision, gera a string 5.7 ao invés de $Revision: 5.7 $. Isto pode ajudar a gerar arquivos em linguagens de programação onde é difícil ???strip??? delimitadores de palavras-chave, como o $Revision: $ para uma string. Entretanto, outras substituições de palavras-chave não poderam ser feitas, uma vez que os nomes de palavras-chave foram removidos. Logo, esta opção deve ser usada com cuidado.

     É comum querer usar o -kv com cvs export---see export.  Mas lembre-se que isto não trata um export contendo binários direito.

Configurando a Expansão do Teclado
==================================

Num repositório que inclua software de terceiros em ramos de fornecedor, às vezes é útil configurar o CVS para usar uma palavra-chave local ao invés das palavras-chave padrão $Id$ ou $Header$. Exemplos de projetos reais incluem, $Xorg$, $XFree86$, $FreeBSD$, $NetBSD$, $OpenBSD$, e ainda $dotat$. A vantagem disto é que você pode incluir sua ???local version information??? num arquivo usando esta palavra-chave local (algumas vezes chamada de ``custom tag'' ou ``local tag'') sem romper com a ???upstream version information??? (que pode ser uma palavra-chave local diferente ou uma palavra-chave padrão). Nestes casos, é normalmente desejável desabilitar a expansão de todas as palavras-chave exceto a palavra-chave local configurada.

The KeywordExpansion option in the CVSROOT/config file is intended to allow for the either the explicit exclusion of a keyword or list of keywords, or for the explicit inclusion of a keyword or a list of keywords. This list may include the LocalKeyword that has been configured.

The KeywordExpansion option is followed by = and the next character may either be i to start an inclusion list or e to start an exclusion list. If the following lines were added to the CVSROOT/config file:

             # Add a "MyBSD" keyword and restrict keyword
             # expansion
             LocalKeyword=MyBSD=CVSHeader
             KeywordExpand=iMyBSD

then only the $MyBSD$ keyword would be expanded. A list may be used. The this example:

             # Add a "MyBSD" keyword and restrict keyword
             # expansion to the MyBSD, Name and Date keywords.
             LocalKeyword=MyBSD=CVSHeader
             KeywordExpand=iMyBSD,Name,Date

would allow $MyBSD$, $Name$, and $Date$ to be expanded. would allow $MyBSD$, $Name$, and $Date$ to be expanded.

It is also possible to configure an exclusion list using the following: It is also possible to configure an exclusion list using the following:

             # Do not expand the non-RCS keyword CVSHeader
             KeywordExpand=eCVSHeader

This allows CVS to ignore the recently introduced $CVSHeader$ keyword and retain all of the others. The exclusion entry could also contain the standard RCS keyword list, but this could be confusing to users that expect RCS keywords to be expanded, so ycare should be taken to properly set user expectations for a repository that is configured in that manner.

If there is a desire to not have any RCS keywords expanded and not use the -ko flags everywhere, an administrator may disable all keyword expansion using the CVSROOT/config line:

     	# Do not expand any RCS keywords
     	KeywordExpand=i

this could be confusing to users that expect RCS keywords like $Id$ to be expanded properly, so care should be taken to properly set user expectations for a repository so configured.

It should be noted that a patch to provide both the KeywordExpand and LocalKeyword features has been around a long time. However, that patch implemented these features using tag= and tagexpand= keywords and those keywords are NOT recognized.

Problems with the $Log$ keyword.
================================

The $Log$ keyword is somewhat controversial.  As long as you are working on your development system the information is easily accessible even if you do not use the $Log$ keyword---just do a cvs log.  Once you export the file the history information might be useless anyhow.

A more serious concern is that CVS is not good at handling $Log$ entries when a branch is merged onto the main trunk.  Conflicts often result from the merging operation.

People also tend to "fix" the log entries in the file (correcting spelling mistakes and maybe even factual errors).  If that is done the information from cvs log will not be consistent with the information inside the file.  This may or may not be a problem in real life.

It has been suggested that the $Log$ keyword should be inserted last in the file, and not in the files header, if it is to be used at all. That way the long list of change messages will not interfere with everyday source file browsing.

Tracking third-party sources
****************************

Se você modificar um programa para se adequar melhor ao seu ambiente, você provavelmente vai querer incluir suas modificações quando a nova release do do programa chegar.  O CVS pode te ajudar nesta tarefa.

Na terminologia usada no CVS, quem fornece um programa é chamado de vendor (fornecedor, em português).  A distribuição não modificada do fornecedor é ???checked in??? no seu próprio ramo, o vendor branch (ramo do fornecedor).  O CVS reserva o ramo 1.1.1 para isto.

Quando você modifica a fonte e a ???commit???, sua revisão vai terminar na ???main trunk???.  Quando uma nova release é feita pelo fornecedor, você ???commit??? ela no ramo do fornecedor e copia as modificações no ???main trunk???.

Use o comando import para criar e atualizar o ramo do fornecedor.  Quando você importa um novo arquivo, o ramo do fornecedor se torna a revisão `head', logo qualquer um que ???checks out??? uma cópia do arquivo pega esta revisão.  Quando uma modificação local é ???committed???, ela é posta no ???main trunk???, e se torna a revisão `head'.

Importing for the first time
============================

Use the import command to check in the sources for the first time.  When you use the import command to track third-party sources, the vendor tag and release tags are useful.  The vendor tag is a symbolic name for the branch (which is always 1.1.1, unless you use the -b BRANCH flag---see Ramos de fornecedor múltiplos.).  The release tags are symbolic names for a particular release, such as FSF_0_04.

Note that import does not change the directory in which you invoke it.  In particular, it does not set up that directory as a CVS working directory; if you want to work with the sources import them first and then check them out into a different directory (see Obtendo os fontes).

Suppose you have the sources to a program called wdiff in a directory wdiff-0.04, and are going to make private modifications that you want to be able to use even when new releases are made in the future.  You start by importing the source to your repository:

     $ cd wdiff-0.04
     $ cvs import -m "Import of FSF v. 0.04" fsf/wdiff FSF_DIST WDIFF_0_04

The vendor tag is named FSF_DIST in the above example, and the only release tag assigned is WDIFF_0_04.

Updating with the import command
================================

When a new release of the source arrives, you import it into the repository with the same import command that you used to set up the repository in the first place.  The only difference is that you specify a different release tag this time:

     $ tar xfz wdiff-0.05.tar.gz
     $ cd wdiff-0.05
     $ cvs import -m "Import of FSF v. 0.05" fsf/wdiff FSF_DIST WDIFF_0_05

For files that have not been modified locally, the newly created revision becomes the head revision.  If you have made local changes, import will warn you that you must merge the changes into the main trunk, and tell you to use checkout -j to do so:

     $ cvs checkout -jFSF_DIST:yesterday -jFSF_DIST wdiff

The above command will check out the latest revision of wdiff, merging the changes made on the vendor branch FSF_DIST since yesterday into the working copy.  If any conflicts arise during the merge they should be resolved in the normal way (see Exemplo de conflitos).  Then, the modified files may be committed.

However, it is much better to use the two release tags rather than using a date on the branch as suggested above:

     $ cvs checkout -jWDIFF_0_04 -jWDIFF_0_05 wdiff

The reason this is better is that using a date, as suggested above, assumes that you do not import more than one release of a product per day. More importantly, using the release tags allows CVS to detect files that were removed between the two vendor releases and mark them for removal.  Since import has no way to detect removed files, you should do a merge like this even if import doesn't tell you to.

Reverting to the latest vendor release
======================================

You can also revert local changes completely and return to the latest vendor release by changing the `head' revision back to the vendor branch on all files.  For example, if you have a checked-out copy of the sources in ~/work.d/wdiff, and you want to revert to the vendor's version for all the files in that directory, you would type:

     $ cd ~/work.d/wdiff
     $ cvs admin -bFSF_DIST .

You must specify the -bFSF_DIST without any space after the -b.  See admin options.

How to handle binary files with cvs import
==========================================

Use the -k wrapper option to tell import which files are binary.  See Wrappers.

Como lidar com substituição de palavras-chave com o cvs import
==============================================================

The sources which you are importing may contain keywords (see Substituição de palavra-chave).  For example, the vendor may use CVS or some other system which uses similar keyword expansion syntax.  If you just import the files in the default fashion, then the keyword expansions supplied by the vendor will be replaced by keyword expansions supplied by your own copy of CVS.  It may be more convenient to maintain the expansions supplied by the vendor, so that this information can supply information about the sources that you imported from the vendor.

To maintain the keyword expansions supplied by the vendor, supply the -ko option to cvs import the first time you import the file. This will turn off keyword expansion for that file entirely, so if you want to be more selective you'll have to think about what you want and use the -k option to cvs update or cvs admin as appropriate.

Ramos de fornecedor múltiplos
=============================

All the examples so far assume that there is only one vendor from which you are getting sources.  In some situations you might get sources from a variety of places.  For example, suppose that you are dealing with a project where many different people and teams are modifying the software.  There are a variety of ways to handle this, but in some cases you have a bunch of source trees lying around and what you want to do more than anything else is just to all put them in CVS so that you at least have them in one place.

For handling situations in which there may be more than one vendor, you may specify the -b option to cvs import.  It takes as an argument the vendor branch to import to.  The default is -b 1.1.1.

For example, suppose that there are two teams, the red team and the blue team, that are sending you sources. You want to import the red team's efforts to branch 1.1.1 and use the vendor tag RED.  You want to import the blue team's efforts to branch 1.1.3 and use the vendor tag BLUE.  So the commands you might use are:

     $ cvs import dir RED RED_1-0
     $ cvs import -b 1.1.3 dir BLUE BLUE_1-5

Note that if your vendor tag does not match your -b option, CVS will not detect this case!  For example,

     $ cvs import -b 1.1.3 dir RED RED_1-0

Be careful; this kind of mismatch is sure to sow confusion or worse.  I can't think of a useful purpose for the ability to specify a mismatch here, but if you discover such a use, don't.  CVS is likely to make this an error in some future release.

How your build system interacts with CVS
****************************************

As mentioned in the introduction, CVS does not contain software for building your software from source code.  This section describes how various aspects of your build system might interact with CVS.

One common question, especially from people who are accustomed to RCS, is how to make their build get an up to date copy of the sources.  The answer to this with CVS is two-fold.  First of all, since CVS itself can recurse through directories, there is no need to modify your Makefile (or whatever configuration file your build tool uses) to make sure each file is up to date.  Instead, just use two commands, first cvs -q update and then make or whatever the command is to invoke your build tool.  Secondly, you do not necessarily want to get a copy of a change someone else made until you have finished your own work.  One suggested approach is to first update your sources, then implement, build and test the change you were thinking of, and then commit your sources (updating first if necessary).  By periodically (in between changes, using the approach just described) updating your entire tree, you ensure that your sources are sufficiently up to date.

One common need is to record which versions of which source files went into a particular build.  This kind of functionality is sometimes called bill of materials or something similar.  The best way to do this with CVS is to use the tag command to record which versions went into a given build (see Etiquetas).

Using CVS in the most straightforward manner possible, each developer will have a copy of the entire source tree which is used in a particular build.  If the source tree is small, or if developers are geographically dispersed, this is the preferred solution.  In fact one approach for larger projects is to break a project down into smaller separately-compiled subsystems, and arrange a way of releasing them internally so that each developer need check out only those subsystems which they are actively working on.

Another approach is to set up a structure which allows developers to have their own copies of some files, and for other files to access source files from a central location.  Many people have come up with some such a system using features such as the symbolic link feature found in many operating systems, or the VPATH feature found in many versions of make.  One build tool which is designed to help with this kind of thing is Odin (see ftp://ftp.cs.colorado.edu/pub/distribs/odin).

Arquivos especiais
******************

In normal circumstances, CVS works only with regular files.  Every file in a project is assumed to be persistent; it must be possible to open, read and close them; and so on.  CVS also ignores file permissions and ownerships, leaving such issues to be resolved by the developer at installation time.  In other words, it is not possible to "check in" a device into a repository; if the device file cannot be opened, CVS will refuse to handle it.  Files also lose their ownerships and permissions during repository transactions.

Guia dos comandos do CVS
************************

Este apêndice descreve a estrutura geral dos comandos do CVS, e descreve alguns comandos em detalhe (outros são descritos em outra parte; para uma referência rápida dos comandos do CVS, see Chamando o CVS).

Estrutura geral dos comandos do CVS
===================================

O formato geral de todos os comandos do CVS é:

     cvs [ cvs_options ] cvs_command [ command_options ] [ command_args ]

cvs
     O nome do programa CVS.

cvs_options
     Algumas opções que afetam todos os sub-comandos do CVS.  Estes estão descritos abaixo.

cvs_command
     Um dos vários sub-comandos.  Alguns dos comandos têm ???aliases??? substituí-los; estes ???aliases??? são listados no manual de referência do comando.  Existem apenas duas situações onde você pode omitir o cvs_command: cvs -H retorna uma lista de comandos disponíveis, e cvs -v mostra informações sobre a versão do próprio CVS.

command_options
     Opções que são específicas para o comando.

command_args
     Argumentos para os comandos.

Infelizmente, existe alguma confusão entre cvs_options e command_options. -l, quando passado como cvs_option, afeta apenas alguns dos comandos.  Quando é passado como um command_option tem um significado diferente, e é aceito por mais comandos.  Em outras palavras, não leve a categorização acima tão a sério.  Olhe a documentação, ao invés disto.

estado de saída do CVS
======================

O CVS pode indicar para o ambiente que o chamou se ele foi bem-sucedido ou falhou ao ajustar seu estado de saída.  A forma exata de testar o estado de saída varia de um sistema operacional para outro.  Por exemplo, num shell script do unix a variável $? será 0 se o último comando retornar um estado de saída bem-sucedido, ou maior que 0 se o estado de saída indicar uma falha.

Se o CVS é bem-sucedido, retorna um estado de sucesso; se existe um erro, mostra uma mensagem de erro e retorna um estado de falha.  A única exceção para isto é o comando cvs diff.  Ele retornará um estado de sucesso se não encontrar diferenças, ou um estado de sucesso se existirem diferenças ou acontecer um erro. Já que este comportamento não fornece uma boa maneira de detectar erros, é possível que no futuro o cvs diff seja mudado para se comportar como os outros comandos do CVS.

Opções padrão e o arquivo ~/.cvsrc
==================================

Existem algumas opções_de_comando que são tão usadas que você vai querer  preparar um atalho ou alguma outra forma de ter certeza que tais opções sempre vão ser especificadas.  Um exemplo (o que motivou a implementação do suporte ao arquivo .cvsrc, na verdade) é que muitas pessoas acham a saída do comando diff muito difícil de ler, e que tanto diffs de contexto quanto unidiffs são muito mais fáceis de entender.

O arquivo ~/.cvsrc é uma forma de você adicionar opções padrão aos comandos_cvs dentro do cvs, ao invés de usar alias (apelidos) ou outros scripts de shell.

O formato do arquivo ~/.cvsrc é simples.  O arquivo é varrido por uma linha que comece com o mesmo nome do comando_cvs sendo executado.  Se encontra, então o restante da linha é dividido (pelos espaços) em opções distintas e adicionadas aos argumentos do comando antes de quaisquer opções da linha de comando.

Se um comando tem dois nomes (e.g., checkout e co), o nome oficial, que não é necessariamente o usado na linha de comando,  vai ser usado para fazer a busca no arquivo.  Logo, se este é o conteúdo do arquivo ~/.cvsrc do usuário:

     log -N
     diff -uN
     rdiff -u
     update -Pd
     checkout -P
     release -d

o comando cvs checkout foo vai ter a opção -P adicionada a seus argumentos, assim como cvs co foo.

Com o arquivo de exemplo acima, a saída de cvs diff foobar vai ser no formato unidiff.  cvs diff -c foobar vai dar diffs de contexto, que é o normal. Obter o diff no formato "velho" vai ser um pouco mais complicado, já que o diff não tem uma opção para especificar o uso do formato "velho", logo você vai ter que usar cvs -f diff foobar.

Ao invés de no nome do comando você pode usar o cvs especificando opções globais (see Opções globais).  Por exemplo a seguinte linha em .cvsrc

     cvs -z6

faz com que o CVS use compressão de nível 6.

Opções globais
==============

The available cvs_options (that are given to the left of cvs_command) are:

--allow-root=ROOTDIR
     Specify legal CVSROOT directory.  See Servidor de autenticação por senha.

-a
     Authenticate all communication between the client and the server.  Only has an effect on the CVS client. As of this writing, this is only implemented when using a GSSAPI connection (see Autenticação GSSAPI). Authentication prevents certain sorts of attacks involving hijacking the active TCP connection. Enabling authentication does not enable encryption.

-b BINDIR
     In CVS 1.9.18 and older, this specified that RCS programs are in the BINDIR directory. Current versions of CVS do not run RCS programs; for compatibility this option is accepted, but it does nothing.

-T TEMPDIR
     Use TEMPDIR as the directory where temporary files are located.  Overrides the setting of the $TMPDIR environment variable and any precompiled directory.  This parameter should be specified as an absolute pathname. (When running client/server, -T affects only the local process; specifying -T for the client has no effect on the server and vice versa.)

-d CVS_ROOT_DIRECTORY
     Use CVS_ROOT_DIRECTORY as the root directory pathname of the repository.  Overrides the setting of the $CVSROOT environment variable.  See Repositório.

-e EDITOR
     Use EDITOR to enter revision log information.  Overrides the setting of the $CVSEDITOR and $EDITOR environment variables.  For more information, see Efetivando suas alterações.

-f
     Do not read the ~/.cvsrc file.  This option is most often used because of the non-orthogonality of the CVS option set.  For example, the cvs log option -N (turn off display of tag names) does not have a corresponding option to turn the display on.  So if you have -N in the ~/.cvsrc entry for log, you may need to use -f to show the tag names.

-H
--help
     Display usage information about the specified cvs_command (but do not actually execute the command).  If you don't specify a command name, cvs -H displays overall help for CVS, including a list of other help options.

-l
     Do not log the cvs_command in the command history (but execute it anyway).  See history, for information on command history.

-R
     Turns on read-only repository mode.  This allows one to check out from a read-only repository, such as within an anoncvs server, or from a CDROM repository.

     Same effect as if the CVSREADONLYFS environment variable is set. Using -R can also considerably speed up checkout's over NFS.

-n
     Do not change any files.  Attempt to execute the cvs_command, but only to issue reports; do not remove, update, or merge any existing files, or create any new files.

     Note that CVS will not necessarily produce exactly the same output as without -n.  In some cases the output will be the same, but in other cases CVS will skip some of the processing that would have been required to produce the exact same output.

-Q
     Cause the command to be really quiet; the command will only generate output for serious problems.

-q
     Cause the command to be somewhat quiet; informational messages, such as reports of recursion through subdirectories, are suppressed.

-r
     Make new working files read-only.  Same effect as if the $CVSREAD environment variable is set (see Variáveis de ambiente).  The default is to make working files writable, unless watches are on (see ???Watches???).

-s VARIABLE=VALUE
     Set a user variable (see Variables).

-t
     Trace program execution; display messages showing the steps of CVS activity.  Particularly useful with -n to explore the potential impact of an unfamiliar command.

-v

--version
     Display version and copyright information for CVS.

-w
     Make new working files read-write.  Overrides the setting of the $CVSREAD environment variable. Files are created read-write by default, unless $CVSREAD is set or -r is given.

-x
     Encrypt all communication between the client and the server.  Only has an effect on the CVS client.  As of this writing, this is only implemented when using a GSSAPI connection (see Autenticação GSSAPI) or a Kerberos connection (see Autenticação kerberos). Enabling encryption implies that message traffic is also authenticated.  Encryption support is not available by default; it must be enabled using a special configure option, --enable-encryption, when you build CVS.

-z GZIP-LEVEL
     Set the compression level. Valid levels are 1 (high speed, low compression) to 9 (low speed, high compression), or 0 to disable compression (the default). Only has an effect on the CVS client.

Common command options
======================

This section describes the command_options that are available across several CVS commands.  These options are always given to the right of cvs_command. Not all commands support all of these options; each option is only supported for commands where it makes sense. However, when a command has one of these options you can almost always count on the same behavior of the option as in other commands.  (Other command options, which are listed with the individual commands, may have different behavior from one CVS command to the other).

Note: the history command is an exception; it supports many options that conflict even with these standard options.

-D DATE_SPEC
     Use the most recent revision no later than DATE_SPEC. DATE_SPEC is a single argument, a date description specifying a date in the past.

     The specification is sticky when you use it to make a private copy of a source file; that is, when you get a working file using -D, CVS records the date you specified, so that further updates in the same directory will use the same date (for more information on sticky tags/dates, see Etiquetas adesivas).

     -D is available with the annotate, checkout, diff, export, history, rdiff, rtag, tag, and update commands. (The history command uses this option in a slightly different way; see history options).

     A wide variety of date formats are supported by CVS.  The most standard ones are ISO8601 (from the International Standards Organization) and the Internet e-mail standard (specified in RFC822 as amended by RFC1123).

     ISO8601 dates have many variants but a few examples are:

          1972-09-24
          1972-09-24 20:05

     There are a lot more ISO8601 date formats, and CVS accepts many of them, but you probably don't want to hear the whole long story :-).

     In addition to the dates allowed in Internet e-mail itself, CVS also allows some of the fields to be omitted.  For example:

          24 Sep 1972 20:05
          24 Sep

     The date is interpreted as being in the local timezone, unless a specific timezone is specified.

     These two date formats are preferred.  However, CVS currently accepts a wide variety of other date formats.  They are intentionally not documented here in any detail, and future versions of CVS might not accept all of them.

     One such format is MONTH/DAY/YEAR.  This may confuse people who are accustomed to having the month and day in the other order; 1/4/96 is January 4, not April 1.

     Remember to quote the argument to the -D flag so that your shell doesn't interpret spaces as argument separators.  A command using the -D flag can look like this:

          $ cvs diff -D "1 hour ago" cvs.texinfo

-f
     When you specify a particular date or tag to CVS commands, they normally ignore files that do not contain the tag (or did not exist prior to the date) that you specified.  Use the -f option if you want files retrieved even when there is no match for the tag or date.  (The most recent revision of the file will be used).

     Note that even with -f, a tag that you specify must exist (that is, in some file, not necessary in every file).  This is so that CVS will continue to give an error if you mistype a tag name.

     -f is available with these commands: annotate, checkout, export, rdiff, rtag, and update.

     WARNING:  The commit and remove commands also have a -f option, but it has a different behavior for those commands.  See commit options, and Removendo arquivos.

-k KFLAG
     Override the default processing of RCS keywords other than -kb.  See Substituição de palavra-chave, for the meaning of KFLAG.  Used with the checkout and update commands, your KFLAG specification is sticky; that is, when you use this option with a checkout or update command, CVS associates your selected KFLAG with any files it operates on, and continues to use that KFLAG with future commands on the same files until you specify otherwise.

     The -k option is available with the add, checkout, diff, export, import and update commands.

     WARNING: Prior to CVS version 1.12.2, the -k flag overrode the -kb indication for a binary file.  This could sometimes corrupt binary files.  See Mesclagem e palavras-chave, for more.

-l
     Local; run only in current working directory, rather than recursing through subdirectories.

     Available with the following commands: annotate, checkout, commit, diff, edit, editors, export, log, rdiff, remove, rtag, status, tag, unedit, update, watch, and watchers.

-m MESSAGE
     Use MESSAGE as log information, instead of invoking an editor.

     Available with the following commands: add, commit and import.

-n
     Do not run any tag program.  (A program can be specified to run in the modules database (see modules); this option bypasses it).

     Note: this is not the same as the cvs -n program option, which you can specify to the left of a cvs command!

     Available with the checkout, commit, export, and rtag commands.

-P
     Prune empty directories.  See Removendo diretórios.

-p
     Pipe the files retrieved from the repository to standard output, rather than writing them in the current directory.  Available with the checkout and update commands.

-R
     Process directories recursively.  This is on by default.

     Available with the following commands: annotate, checkout, commit, diff, edit, editors, export, rdiff, remove, rtag, status, tag, unedit, update, watch, and watchers.

-r TAG
     Use the revision specified by the TAG argument instead of the default head revision.  As well as arbitrary tags defined with the tag or rtag command, two special tags are always available: HEAD refers to the most recent version available in the repository, and BASE refers to the revision you last checked out into the current working directory.

     The tag specification is sticky when you use this with checkout or update to make your own copy of a file: CVS remembers the tag and continues to use it on future update commands, until you specify otherwise (for more information on sticky tags/dates, see Etiquetas adesivas).

     The tag can be either a symbolic or numeric tag, as described in Etiquetas, or the name of a branch, as described in Ramificando e mesclando.

     Specifying the -q global option along with the -r command option is often useful, to suppress the warning messages when the RCS file does not contain the specified tag.

     Note: this is not the same as the overall cvs -r option, which you can specify to the left of a CVS command!

     -r is available with the annotate, checkout, commit, diff, history, export, rdiff, rtag, and update commands.

-W
     Specify file names that should be filtered.  You can use this option repeatedly.  The spec can be a file name pattern of the same type that you can specify in the .cvswrappers file. Available with the following commands: import, and update.

admin---Administration
======================

  * Requires: repository, working directory.

  * Changes: repository.

  * Synonym: rcs

This is the CVS interface to assorted administrative facilities.  Some of them have questionable usefulness for CVS but exist for historical purposes.  Some of the questionable options are likely to disappear in the future.  This command does work recursively, so extreme care should be used.

On unix, if there is a group named cvsadmin, only members of that group can run cvs admin commands, except for those specified using the UserAdminOptions configuration option in the CVSROOT/config file.  Options specified using UserAdminOptions can be run by any user.  See config for more on UserAdminOptions.

The cvsadmin group should exist on the server, or any system running the non-client/server CVS. To disallow cvs admin for all users, create a group with no users in it.  On NT, the cvsadmin feature does not exist and all users can run cvs admin.

admin options
-------------

Some of these options have questionable usefulness for CVS but exist for historical purposes.  Some even make it impossible to use CVS until you undo the effect!

-AOLDFILE
     Might not work together with CVS.  Append the access list of OLDFILE to the access list of the RCS file.

-aLOGINS
     Might not work together with CVS.  Append the login names appearing in the comma-separated list LOGINS to the access list of the RCS file.

-b[REV]
     Set the default branch to REV.  In CVS, you normally do not manipulate default branches; sticky tags (see Etiquetas adesivas) are a better way to decide which branch you want to work on.  There is one reason to run cvs admin -b: to revert to the vendor's version when using vendor branches (see Reverting local changes). There can be no space between -b and its argument.

-cSTRING
     Sets the comment leader to STRING.  The comment leader is not used by current versions of CVS or RCS 5.7.  Therefore, you can almost surely not worry about it.  See Substituição de palavra-chave.

-e[LOGINS]
     Might not work together with CVS.  Erase the login names appearing in the comma-separated list LOGINS from the access list of the RCS file.  If LOGINS is omitted, erase the entire access list. There can be no space between -e and its argument.

-I
     Run interactively, even if the standard input is not a terminal.  This option does not work with the client/server CVS and is likely to disappear in a future release of CVS.

-i
     Useless with CVS.  This creates and initializes a new RCS file, without depositing a revision.  With CVS, add files with the cvs add command (see Adicionando arquivos).

-kSUBST
     Set the default keyword substitution to SUBST. See Substituição de palavra-chave.  Giving an explicit -k option to cvs update, cvs export, or cvs checkout overrides this default.

-l[REV]
     Lock the revision with number REV.  If a branch is given, lock the latest revision on that branch.  If REV is omitted, lock the latest revision on the default branch.  There can be no space between -l and its argument.

     This can be used in conjunction with the rcslock.pl script in the contrib directory of the CVS source distribution to provide reserved checkouts (where only one user can be editing a given file at a time).  See the comments in that file for details (and see the README file in that directory for disclaimers about the unsupported nature of contrib).  According to comments in that file, locking must set to strict (which is the default).

-L
     Set locking to strict.  Strict locking means that the owner of an RCS file is not exempt from locking for checkin.  For use with CVS, strict locking must be set; see the discussion under the -l option above.

-mREV:MSG
     Replace the log message of revision REV with MSG.

-NNAME[:[REV]]
     Act like -n, except override any previous assignment of NAME.  For use with magic branches, see Números de ramos mágicos.

-nNAME[:[REV]]
     Associate the symbolic name NAME with the branch or revision REV.  It is normally better to use cvs tag or cvs rtag instead.  Delete the symbolic name if both : and REV are omitted; otherwise, print an error message if NAME is already associated with another number. If REV is symbolic, it is expanded before association.  A REV consisting of a branch number followed by a . stands for the current latest revision in the branch.  A : with an empty REV stands for the current latest revision on the default branch, normally the trunk.  For example, cvs admin -nNAME: associates NAME with the current latest revision of all the RCS files; this contrasts with cvs admin -nNAME:$ which associates NAME with the revision numbers extracted from keyword strings in the corresponding working files.

-oRANGE
     Deletes (outdates) the revisions given by RANGE.

     Note that this command can be quite dangerous unless you know exactly what you are doing (for example see the warnings below about how the REV1:REV2 syntax is confusing).

     If you are short on disc this option might help you. But think twice before using it---there is no way short of restoring the latest backup to undo this command! If you delete different revisions than you planned, either due to carelessness or (heaven forbid) a CVS bug, there is no opportunity to correct the error before the revisions are deleted.  It probably would be a good idea to experiment on a copy of the repository first.

     Specify RANGE in one of the following ways:

     REV1::REV2
          Collapse all revisions between rev1 and rev2, so that CVS only stores the differences associated with going from rev1 to rev2, not intermediate steps.  For example, after -o 1.3::1.5 one can retrieve revision 1.3, revision 1.5, or the differences to get from 1.3 to 1.5, but not the revision 1.4, or the differences between 1.3 and 1.4.  Other examples: -o 1.3::1.4 and -o 1.3::1.3 have no effect, because there are no intermediate revisions to remove.

     ::REV
          Collapse revisions between the beginning of the branch containing REV and REV itself.  The branchpoint and REV are left intact.  For example, -o ::1.3.2.6 deletes revision 1.3.2.1, revision 1.3.2.5, and everything in between, but leaves 1.3 and 1.3.2.6 intact.

     REV::
          Collapse revisions between REV and the end of the branch containing REV.  Revision REV is left intact but the head revision is deleted.

     REV
          Delete the revision REV.  For example, -o 1.3 is equivalent to -o 1.2::1.4.

     REV1:REV2
          Delete the revisions from REV1 to REV2, inclusive, on the same branch.  One will not be able to retrieve REV1 or REV2 or any of the revisions in between.  For example, the command cvs admin -oR_1_01:R_1_02 . is rarely useful. It means to delete revisions up to, and including, the tag R_1_02.  But beware!  If there are files that have not changed between R_1_02 and R_1_03 the file will have the same numerical revision number assigned to the tags R_1_02 and R_1_03.  So not only will it be impossible to retrieve R_1_02; R_1_03 will also have to be restored from the tapes!  In most cases you want to specify REV1::REV2 instead.

     :REV
          Delete revisions from the beginning of the branch containing REV up to and including REV.

     REV:
          Delete revisions from revision REV, including REV itself, to the end of the branch containing REV.

     None of the revisions to be deleted may have branches or locks.

     If any of the revisions to be deleted have symbolic names, and one specifies one of the :: syntaxes, then CVS will give an error and not delete any revisions.  If you really want to delete both the symbolic names and the revisions, first delete the symbolic names with cvs tag -d, then run cvs admin -o.  If one specifies the non-:: syntaxes, then CVS will delete the revisions but leave the symbolic names pointing to nonexistent revisions.  This behavior is preserved for compatibility with previous versions of CVS, but because it isn't very useful, in the future it may change to be like the :: case.

     Due to the way CVS handles branches REV cannot be specified symbolically if it is a branch. See Números de ramos mágicos, for an explanation.

     Make sure that no-one has checked out a copy of the revision you outdate.  Strange things will happen if he starts to edit it and tries to check it back in.  For this reason, this option is not a good way to take back a bogus commit; commit a new revision undoing the bogus change instead (see Mesclando duas revisões).

-q
     Run quietly; do not print diagnostics.

-sSTATE[:REV]
     Useful with CVS.  Set the state attribute of the revision REV to STATE.  If REV is a branch number, assume the latest revision on that branch.  If REV is omitted, assume the latest revision on the default branch.  Any identifier is acceptable for STATE.  A useful set of states is Exp (for experimental), Stab (for stable), and Rel (for released).  By default, the state of a new revision is set to Exp when it is created.  The state is visible in the output from CVS LOG (see log), and in the $Log$ and $State$ keywords (see Substituição de palavra-chave).  Note that CVS uses the dead state for its own purposes; to take a file to or from the dead state use commands like cvs remove and cvs add, not cvs admin -s.

-t[FILE]
     Useful with CVS.  Write descriptive text from the contents of the named FILE into the RCS file, deleting the existing text.  The FILE pathname may not begin with -.  The descriptive text can be seen in the output from cvs log (see log). There can be no space between -t and its argument.

     If FILE is omitted, obtain the text from standard input, terminated by end-of-file or by a line containing . by itself. Prompt for the text if interaction is possible; see -I.

-t-STRING
     Similar to -tFILE. Write descriptive text from the STRING into the RCS file, deleting the existing text. There can be no space between -t and its argument.

-U
     Set locking to non-strict.  Non-strict locking means that the owner of a file need not lock a revision for checkin.  For use with CVS, strict locking must be set; see the discussion under the -l option above.

-u[REV]
     See the option -l above, for a discussion of using this option with CVS.  Unlock the revision with number REV.  If a branch is given, unlock the latest revision on that branch.  If REV is omitted, remove the latest lock held by the caller. Normally, only the locker of a revision may unlock it; somebody else unlocking a revision breaks the lock. This causes the original locker to be sent a commit notification (see Recebendo Notificações). There can be no space between -u and its argument.

-VN
     In previous versions of CVS, this option meant to write an RCS file which would be acceptable to RCS version N, but it is now obsolete and specifying it will produce an error.

-xSUFFIXES
     In previous versions of CVS, this was documented as a way of specifying the names of the RCS files.  However, CVS has always required that the RCS files used by CVS end in ,v, so this option has never done anything useful.

checkout---Check out sources for editing
========================================

  * Synopsis: checkout [options] modules...

  * Requires: repository.

  * Changes: working directory.

  * Synonyms: co, get

Create or update a working directory containing copies of the source files specified by MODULES.  You must execute checkout before using most of the other CVS commands, since most of them operate on your working directory.

The MODULES are either symbolic names for some collection of source directories and files, or paths to directories or files in the repository.  The symbolic names are defined in the modules file. See modules.

Depending on the modules you specify, checkout may recursively create directories and populate them with the appropriate source files.  You can then edit these source files at any time (regardless of whether other software developers are editing their own copies of the sources); update them to include new changes applied by others to the source repository; or commit your work as a permanent change to the source repository.

Note that checkout is used to create directories.  The top-level directory created is always added to the directory where checkout is invoked, and usually has the same name as the specified module.  In the case of a module alias, the created sub-directory may have a different name, but you can be sure that it will be a sub-directory, and that checkout will show the relative path leading to each file as it is extracted into your private work area (unless you specify the -Q global option).

The files created by checkout are created read-write, unless the -r option to CVS (see Opções globais) is specified, the CVSREAD environment variable is specified (see Variáveis de ambiente), or a watch is in effect for that file (see ???Watches???).

Note that running checkout on a directory that was already built by a prior checkout is also permitted. This is similar to specifying the -d option to the update command in the sense that new directories that have been created in the repository will appear in your work area. However, checkout takes a module name whereas update takes a directory name.  Also to use checkout this way it must be run from the top level directory (where you originally ran checkout from), so before you run checkout to update an existing directory, don't forget to change your directory to the top level directory.

For the output produced by the checkout command see update output.

checkout options
----------------

These standard options are supported by checkout (see Opções comuns, for a complete description of them):

-D DATE
     Use the most recent revision no later than DATE. This option is sticky, and implies -P.  See Etiquetas adesivas, for more information on sticky tags/dates. Use the most recent revision no later than DATE. This option is sticky, and implies -P.  See Etiquetas adesivas, for more information on sticky tags/dates.

-f
     Only useful with the -D DATE or -r TAG flags.  If no matching revision is found, retrieve the most recent revision (instead of ignoring the file).

-k KFLAG
     Process keywords according to KFLAG.  See Substituição de palavra-chave. This option is sticky; future updates of this file in this working directory will use the same KFLAG.  The status command can be viewed to see the sticky options.  See Chamando o CVS, for more information on the status command.

-l
     Local; run only in current working directory.

-n
     Do not run any checkout program (as specified with the -o option in the modules file; see modules).

-P
     Prune empty directories.  See Movendo diretórios.

-p
     Pipe files to the standard output.

-R
     Checkout directories recursively.  This option is on by default.

-r TAG
     Use revision TAG.  This option is sticky, and implies -P. See Etiquetas adesivas, for more information on sticky tags/dates.

In addition to those, you can use these special command options with checkout:

-A
     Reset any sticky tags, dates, or -k options. See Etiquetas adesivas, for more information on sticky tags/dates.

-c
     Copy the module file, sorted, to the standard output, instead of creating or modifying any files or directories in your working directory.

-d DIR
     Create a directory called DIR for the working files, instead of using the module name.  In general, using this flag is equivalent to using mkdir DIR; cd DIR followed by the checkout command without the -d flag.

     There is an important exception, however.  It is very convenient when checking out a single item to have the output appear in a directory that doesn't contain empty intermediate directories.  In this case only, CVS tries to ``shorten'' pathnames to avoid those empty directories.

     For example, given a module foo that contains the file bar.c, the command cvs co -d dir foo will create directory dir and place bar.c inside.  Similarly, given a module bar which has subdirectory baz wherein there is a file quux.c, the command cvs co -d dir bar/baz will create directory dir and place quux.c inside.

     Using the -N flag will defeat this behavior. Given the same module definitions above, cvs co -N -d dir foo will create directories dir/foo and place bar.c inside, while cvs co -N -d dir bar/baz will create directories dir/bar/baz and place quux.c inside.

-j TAG
     With two -j options, merge changes from the revision specified with the first -j option to the revision specified with the second j option, into the working directory.

     With one -j option, merge changes from the ancestor revision to the revision specified with the -j option, into the working directory.  The ancestor revision is the common ancestor of the revision which the working directory is based on, and the revision specified in the -j option.

     In addition, each -j option can contain an optional date specification which, when used with branches, can limit the chosen revision to one within a specific date.  An optional date is specified by adding a colon (:) to the tag: -jSYMBOLIC_TAG:DATE_SPECIFIER.

     See Ramificando e mesclando.

-N
     Only useful together with -d DIR.  With this option, CVS will not ``shorten'' module paths in your working directory when you check out a single module.  See the -d flag for examples and a discussion.

-s
     Like -c, but include the status of all modules, and sort it by the status string.  See modules, for info about the -s option that is used inside the modules file to set the module status.

checkout examples
-----------------

Get a copy of the module tc:

     $ cvs checkout tc

Get a copy of the module tc as it looked one day ago:

     $ cvs checkout -D yesterday tc

commit---Check files into the repository
========================================

  * Synopsis: commit [-lnRf] [-m 'log_message' | -F file] [-r revision] [files...]

  * Requires: working directory, repository.

  * Changes: repository.

  * Synonym: ci

Use commit when you want to incorporate changes from your working source files into the source repository.

If you don't specify particular files to commit, all of the files in your working current directory are examined.  commit is careful to change in the repository only those files that you have really changed.  By default (or if you explicitly specify the -R option), files in subdirectories are also examined and committed if they have changed; you can use the -l option to limit commit to the current directory only.

commit verifies that the selected files are up to date with the current revisions in the source repository; it will notify you, and exit without committing, if any of the specified files must be made current first with update (see update). commit does not call the update command for you, but rather leaves that for you to do when the time is right.

When all is well, an editor is invoked to allow you to enter a log message that will be written to one or more logging programs (see modules, and see loginfo) and placed in the RCS file inside the repository.  This log message can be retrieved with the log command; see log.  You can specify the log message on the command line with the -m MESSAGE option, and thus avoid the editor invocation, or use the -F FILE option to specify that the argument file contains the log message.

commit options
--------------

These standard options are supported by commit (see Opções comuns, for a complete description of them):

-l
     Local; run only in current working directory.

-R
     Commit directories recursively.  This is on by default.

-r REVISION
     Commit to REVISION.  REVISION must be either a branch, or a revision on the main trunk that is higher than any existing revision number (see Atribuindo revisões).  You cannot commit to a specific revision on a branch.

commit also supports these options:

-F FILE
     Read the log message from FILE, instead of invoking an editor.

-f
     Note that this is not the standard behavior of the -f option as defined in Opções comuns.

     Force CVS to commit a new revision even if you haven't made any changes to the file.  If the current revision of FILE is 1.7, then the following two commands are equivalent:

          $ cvs commit -f FILE
          $ cvs commit -r 1.8 FILE

     The -f option disables recursion (i.e., it implies -l).  To force CVS to commit a new revision for all files in all subdirectories, you must use -f -R.

-m MESSAGE
     Use MESSAGE as the log message, instead of invoking an editor.

commit examples
---------------

Committing to a branch
......................

You can commit to a branch revision (one that has an even number of dots) with the -r option.  To create a branch revision, use the -b option of the rtag or tag commands (see Ramificando e mesclando).  Then, either checkout or update can be used to base your sources on the newly created branch.  From that point on, all commit changes made within these working sources will be automatically added to a branch revision, thereby not disturbing main-line development in any way.  For example, if you had to create a patch to the 1.2 version of the product, even though the 2.0 version is already under development, you might do:

     $ cvs rtag -b -r FCS1_2 FCS1_2_Patch product_module
     $ cvs checkout -r FCS1_2_Patch product_module
     $ cd product_module
     [[ hack away ]]
     $ cvs commit

This works automatically since the -r option is sticky.

Creating the branch after editing
.................................

Say you have been working on some extremely experimental software, based on whatever revision you happened to checkout last week.  If others in your group would like to work on this software with you, but without disturbing main-line development, you could commit your change to a new branch.  Others can then checkout your experimental stuff and utilize the full benefit of CVS conflict resolution.  The scenario might look like:

     [[ hacked sources are present ]]
     $ cvs tag -b EXPR1
     $ cvs update -r EXPR1
     $ cvs commit

The update command will make the -r EXPR1 option sticky on all files.  Note that your changes to the files will never be removed by the update command.  The commit will automatically commit to the correct branch, because the -r is sticky.  You could also do like this:

     [[ hacked sources are present ]]
     $ cvs tag -b EXPR1
     $ cvs commit -r EXPR1

but then, only those files that were changed by you will have the -r EXPR1 sticky flag.  If you hack away, and commit without specifying the -r EXPR1 flag, some files may accidentally end up on the main trunk.

To work with you on the experimental change, others would simply do

     $ cvs checkout -r EXPR1 whatever_module

diff---Show differences between revisions
=========================================

  * Synopsis: diff [-lR] [-k kflag] [format_options] [[-r rev1 | -D date1] [-r rev2 |  -D date2]] [files...]

  * Requires: working directory, repository.

  * Changes: nothing.

The diff command is used to compare different revisions of files.  The default action is to compare your working files with the revisions they were based on, and report any differences that are found.

If any file names are given, only those files are compared.  If any directories are given, all files under them will be compared.

The exit status for diff is different than for other CVS commands; for details Estados de saída.

diff options
------------

These standard options are supported by diff (see Opções comuns, for a complete description of them):

-D DATE
     Use the most recent revision no later than DATE. See -r for how this affects the comparison.

-k KFLAG
     Process keywords according to KFLAG.  See Substituição de palavra-chave.

-l
     Local; run only in current working directory.

-R
     Examine directories recursively.  This option is on by default.

-r TAG
     Compare with revision TAG.  Zero, one or two -r options can be present.  With no -r option, the working file will be compared with the revision it was based on.  With one -r, that revision will be compared to your current working file. With two -r options those two revisions will be compared (and your working file will not affect the outcome in any way).

     One or both -r options can be replaced by a -D DATE option, described above.

The following options specify the format of the output.  They have the same meaning as in GNU diff. Most options have two equivalent names, one of which is a single letter preceded by -, and the other of which is a long name preceded by --.

-LINES
     Show LINES (an integer) lines of context.  This option does not specify an output format by itself; it has no effect unless it is combined with -c or -u.  This option is obsolete.  For proper operation, patch typically needs at least two lines of context.

-a
     Treat all files as text and compare them line-by-line, even if they do not seem to be text.

-b
     Ignore trailing white space and consider all other sequences of one or more white space characters to be equivalent.

-B
     Ignore changes that just insert or delete blank lines.

--binary
     Read and write data in binary mode.

--brief
     Report only whether the files differ, not the details of the differences.

-c
     Use the context output format.

-C LINES
--context[=LINES]
     Use the context output format, showing LINES (an integer) lines of context, or three if LINES is not given. For proper operation, patch typically needs at least two lines of context.

--changed-group-format=FORMAT
     Use FORMAT to output a line group containing differing lines from both files in if-then-else format.  See Line group formats.

-d
     Change the algorithm to perhaps find a smaller set of changes.  This makes diff slower (sometimes much slower).

-e
--ed
     Make output that is a valid ed script.

--expand-tabs
     Expand tabs to spaces in the output, to preserve the alignment of tabs in the input files.

-f
     Make output that looks vaguely like an ed script but has changes in the order they appear in the file.

-F REGEXP
     In context and unified format, for each hunk of differences, show some of the last preceding line that matches REGEXP.

--forward-ed
     Make output that looks vaguely like an ed script but has changes in the order they appear in the file.

-H
     Use heuristics to speed handling of large files that have numerous scattered small changes.

--horizon-lines=LINES
     Do not discard the last LINES lines of the common prefix and the first LINES lines of the common suffix.

-i
     Ignore changes in case; consider upper- and lower-case letters equivalent.

-I REGEXP
     Ignore changes that just insert or delete lines that match REGEXP.

--ifdef=NAME
     Make merged if-then-else output using NAME.

--ignore-all-space
     Ignore white space when comparing lines.

--ignore-blank-lines
     Ignore changes that just insert or delete blank lines.

--ignore-case
     Ignore changes in case; consider upper- and lower-case to be the same.

--ignore-matching-lines=REGEXP
     Ignore changes that just insert or delete lines that match REGEXP.

--ignore-space-change
     Ignore trailing white space and consider all other sequences of one or more white space characters to be equivalent.

--initial-tab
     Output a tab rather than a space before the text of a line in normal or context format.  This causes the alignment of tabs in the line to look normal.

-L LABEL
     Use LABEL instead of the file name in the context format and unified format headers.

--label=LABEL
     Use LABEL instead of the file name in the context format and unified format headers.

--left-column
     Print only the left column of two common lines in side by side format.

--line-format=FORMAT
     Use FORMAT to output all input lines in if-then-else format. See Line formats.

--minimal
     Change the algorithm to perhaps find a smaller set of changes.  This makes diff slower (sometimes much slower).

-n
     Output RCS-format diffs; like -f except that each command specifies the number of lines affected.

-N
--new-file
     In directory comparison, if a file is found in only one directory, treat it as present but empty in the other directory.

--new-group-format=FORMAT
     Use FORMAT to output a group of lines taken from just the second file in if-then-else format.  See Line group formats.

--new-line-format=FORMAT
     Use FORMAT to output a line taken from just the second file in if-then-else format.  See Line formats.

--old-group-format=FORMAT
     Use FORMAT to output a group of lines taken from just the first file in if-then-else format.  See Line group formats.

--old-line-format=FORMAT
     Use FORMAT to output a line taken from just the first file in if-then-else format.  See Line formats.

-p
     Show which C function each change is in.

--rcs
     Output RCS-format diffs; like -f except that each command specifies the number of lines affected.

--report-identical-files
-s
     Report when two files are the same.

--show-c-function
     Show which C function each change is in.

--show-function-line=REGEXP
     In context and unified format, for each hunk of differences, show some of the last preceding line that matches REGEXP.

--side-by-side
     Use the side by side output format.

--speed-large-files
     Use heuristics to speed handling of large files that have numerous scattered small changes.

--suppress-common-lines
     Do not print common lines in side by side format.

-t
     Expand tabs to spaces in the output, to preserve the alignment of tabs in the input files.

-T
     Output a tab rather than a space before the text of a line in normal or context format.  This causes the alignment of tabs in the line to look normal.

--text
     Treat all files as text and compare them line-by-line, even if they do not appear to be text.

-u
     Use the unified output format.

--unchanged-group-format=FORMAT
     Use FORMAT to output a group of common lines taken from both files in if-then-else format.  See Line group formats.

--unchanged-line-format=FORMAT
     Use FORMAT to output a line common to both files in if-then-else format.  See Line formats.

-U LINES
--unified[=LINES]
     Use the unified output format, showing LINES (an integer) lines of context, or three if LINES is not given. For proper operation, patch typically needs at least two lines of context.

-w
     Ignore white space when comparing lines.

-W COLUMNS
--width=COLUMNS
     Use an output width of COLUMNS in side by side format.

-y
     Use the side by side output format.

Line group formats
..................

Line group formats let you specify formats suitable for many applications that allow if-then-else input, including programming languages and text formatting languages.  A line group format specifies the output format for a contiguous group of similar lines.

For example, the following command compares the TeX file myfile with the original version from the repository, and outputs a merged file in which old regions are surrounded by \begin{em}-\end{em} lines, and new regions are surrounded by \begin{bf}-\end{bf} lines.

     cvs diff \
        --old-group-format='\begin{em}
     %<\end{em}
     ' \
        --new-group-format='\begin{bf}
     %>\end{bf}
     ' \
        myfile

The following command is equivalent to the above example, but it is a little more verbose, because it spells out the default line group formats.

     cvs diff \
        --old-group-format='\begin{em}
     %<\end{em}
     ' \
        --new-group-format='\begin{bf}
     %>\end{bf}
     ' \
        --unchanged-group-format='%=' \
        --changed-group-format='\begin{em}
     %<\end{em}
     \begin{bf}
     %>\end{bf}
     ' \
        myfile

Here is a more advanced example, which outputs a diff listing with headers containing line numbers in a ``plain English'' style.

     cvs diff \
        --unchanged-group-format='' \
        --old-group-format='-------- %dn line%(n=1?:s) deleted at %df:
     %<' \
        --new-group-format='-------- %dN line%(N=1?:s) added after %de:
     %>' \
        --changed-group-format='-------- %dn line%(n=1?:s) changed at %df:
     %<-------- to:
     %>' \
        myfile

To specify a line group format, use one of the options listed below.  You can specify up to four line group formats, one for each kind of line group.  You should quote FORMAT, because it typically contains shell metacharacters.

--old-group-format=FORMAT
     These line groups are hunks containing only lines from the first file. The default old group format is the same as the changed group format if it is specified; otherwise it is a format that outputs the line group as-is.

--new-group-format=FORMAT
     These line groups are hunks containing only lines from the second file.  The default new group format is same as the changed group format if it is specified; otherwise it is a format that outputs the line group as-is.

--changed-group-format=FORMAT
     These line groups are hunks containing lines from both files.  The default changed group format is the concatenation of the old and new group formats.

--unchanged-group-format=FORMAT
     These line groups contain lines common to both files.  The default unchanged group format is a format that outputs the line group as-is.

In a line group format, ordinary characters represent themselves; conversion specifications start with % and have one of the following forms.

%<
     stands for the lines from the first file, including the trailing newline. Each line is formatted according to the old line format (see Line formats).

%>
     stands for the lines from the second file, including the trailing newline. Each line is formatted according to the new line format.

%=
     stands for the lines common to both files, including the trailing newline. Each line is formatted according to the unchanged line format.

%%
     stands for %.

%c'C'
     where C is a single character, stands for C. C may not be a backslash or an apostrophe. For example, %c':' stands for a colon, even inside the then-part of an if-then-else format, which a colon would normally terminate.

%c'\O'
     where O is a string of 1, 2, or 3 octal digits, stands for the character with octal code O. For example, %c'\0' stands for a null character.

FN
     where F is a printf conversion specification and N is one of the following letters, stands for N's value formatted with F.

     e
          The line number of the line just before the group in the old file.

     f
          The line number of the first line in the group in the old file; equals E + 1.

     l
          The line number of the last line in the group in the old file.

     m
          The line number of the line just after the group in the old file; equals L + 1.

     n
          The number of lines in the group in the old file; equals L - F + 1.

     E, F, L, M, N
          Likewise, for lines in the new file.

     The printf conversion specification can be %d, %o, %x, or %X, specifying decimal, octal, lower case hexadecimal, or upper case hexadecimal output respectively.  After the % the following options can appear in sequence: a - specifying left-justification; an integer specifying the minimum field width; and a period followed by an optional integer specifying the minimum number of digits. For example, %5dN prints the number of new lines in the group in a field of width 5 characters, using the printf format "%5d".

(A=B?T:E)
     If A equals B then T else E. A and B are each either a decimal constant or a single letter interpreted as above. This format spec is equivalent to T if A's value equals B's; otherwise it is equivalent to E.

     For example, %(N=0?no:%dN) line%(N=1?:s) is equivalent to no lines if N (the number of lines in the group in the new file) is 0, to 1 line if N is 1, and to %dN lines otherwise.

Line formats
............

Line formats control how each line taken from an input file is output as part of a line group in if-then-else format.

For example, the following command outputs text with a one-column change indicator to the left of the text.  The first column of output is - for deleted lines, | for added lines, and a space for unchanged lines.  The formats contain newline characters where newlines are desired on output.

     cvs diff \
        --old-line-format='-%l
     ' \
        --new-line-format='|%l
     ' \
        --unchanged-line-format=' %l
     ' \
        myfile

To specify a line format, use one of the following options.  You should quote FORMAT, since it often contains shell metacharacters.

--old-line-format=FORMAT
     formats lines just from the first file.

--new-line-format=FORMAT
     formats lines just from the second file.

--unchanged-line-format=FORMAT
     formats lines common to both files.

--line-format=FORMAT
     formats all lines; in effect, it sets all three above options simultaneously.

In a line format, ordinary characters represent themselves; conversion specifications start with % and have one of the following forms.

%l
     stands for the contents of the line, not counting its trailing newline (if any).  This format ignores whether the line is incomplete.

%L
     stands for the contents of the line, including its trailing newline (if any).  If a line is incomplete, this format preserves its incompleteness.

%%
     stands for %.

%c'C'
     where C is a single character, stands for C. C may not be a backslash or an apostrophe. For example, %c':' stands for a colon.

%c'\O'
     where O is a string of 1, 2, or 3 octal digits, stands for the character with octal code O. For example, %c'\0' stands for a null character.

Fn
     where F is a printf conversion specification, stands for the line number formatted with F. For example, %.5dn prints the line number using the printf format "%.5d".  See Line group formats, for more about printf conversion specifications.

The default line format is %l followed by a newline character.

If the input contains tab characters and it is important that they line up on output, you should ensure that %l or %L in a line format is just after a tab stop (e.g. by preceding %l or %L with a tab character), or you should use the -t or --expand-tabs option.

Taken together, the line and line group formats let you specify many different formats.  For example, the following command uses a format similar to diff's normal format.  You can tailor this command to get fine control over diff's output.

     cvs diff \
        --old-line-format='< %l
     ' \
        --new-line-format='> %l
     ' \
        --old-group-format='%df%(f=l?:,%dl)d%dE
     %<' \
        --new-group-format='%dea%dF%(F=L?:,%dL)
     %>' \
        --changed-group-format='%df%(f=l?:,%dl)c%dF%(F=L?:,%dL)
     %<---
     %>' \
        --unchanged-group-format='' \
        myfile

diff examples
-------------

The following line produces a Unidiff (-u flag) between revision 1.14 and 1.19 of backend.c.  Due to the -kk flag no keywords are substituted, so differences that only depend on keyword substitution are ignored.

     $ cvs diff -kk -u -r 1.14 -r 1.19 backend.c

Suppose the experimental branch EXPR1 was based on a set of files tagged RELEASE_1_0.  To see what has happened on that branch, the following can be used:

     $ cvs diff -r RELEASE_1_0 -r EXPR1

A command like this can be used to produce a context diff between two releases:

     $ cvs diff -c -r RELEASE_1_0 -r RELEASE_1_1 > diffs

If you are maintaining ChangeLogs, a command like the following just before you commit your changes may help you write the ChangeLog entry.  All local modifications that have not yet been committed will be printed.

     $ cvs diff -u | less

export---Export sources from CVS, similar to checkout
=====================================================

  * Synopsis: export [-flNnR] [-r rev|-D date] [-k subst] [-d dir] module...

  * Requires: repository.

  * Changes: current directory.

This command is a variant of checkout; use it when you want a copy of the source for module without the CVS administrative directories.  For example, you might use export to prepare source for shipment off-site.  This command requires that you specify a date or tag (with -D or -r), so that you can count on reproducing the source you ship to others (and thus it always prunes empty directories).

One often would like to use -kv with cvs export.  This causes any keywords to be expanded such that an import done at some other site will not lose the keyword revision information.  But be aware that doesn't handle an export containing binary files correctly.  Also be aware that after having used -kv, one can no longer use the ident command (which is part of the RCS suite---see ident(1)) which looks for keyword strings.  If you want to be able to use ident you must not use -kv.

export options
--------------

These standard options are supported by export (see Opções comuns, for a complete description of them):

-D DATE
     Use the most recent revision no later than DATE.

-f
     If no matching revision is found, retrieve the most recent revision (instead of ignoring the file).

-l
     Local; run only in current working directory.

-n
     Do not run any checkout program.

-R
     Export directories recursively.  This is on by default.

-r TAG
     Use revision TAG.

In addition, these options (that are common to checkout and export) are also supported:

-d DIR
     Create a directory called DIR for the working files, instead of using the module name. See checkout options, for complete details on how CVS handles this flag.

-k SUBST
     Set keyword expansion mode (see Modos de substituição).

-N
     Only useful together with -d DIR. See checkout options, for complete details on how CVS handles this flag.

history---Show status of files and users
========================================

  * Synopsis:     history [-report] [-flags] [-options args] [files...]

  * Requires: the file $CVSROOT/CVSROOT/history

  * Changes: nothing.

CVS can keep a history file that tracks each use of the checkout, commit, rtag, update, and release commands.  You can use history to display this information in various formats.

Logging must be enabled by creating the file $CVSROOT/CVSROOT/history.

Note: history uses -f, -l, -n, and -p in ways that conflict with the normal use inside CVS (see Opções comuns).

history options
---------------

Several options (shown above as -report)  control  what kind of report is generated:

-c
     Report on each time commit was used (i.e., each time the repository was modified).

-e
     Everything (all record types).  Equivalent to specifying -x with all record types.  Of course, -e will also include record types which are added in a future version of CVS; if you are writing a script which can only handle certain record types, you'll want to specify -x.

-m MODULE
     Report on a particular module.  (You can meaningfully use -m more than once on the command line.)

-o
     Report on checked-out modules.  This is the default report type.

-T
     Report on all tags.

-x TYPE
     Extract a particular set of record types TYPE from the CVS history.  The types are indicated by single letters, which you may specify in combination.

     Certain commands have a single record type:

     F
          release

     O
          checkout

     E
          export

     T
          rtag

     One of five record types may result from an update:

     C
          A merge was necessary but collisions were detected (requiring manual merging).

     G
          A merge was necessary and it succeeded.

     U
          A working file was copied from the repository.

     P
          A working file was patched to match the repository.

     W
          The working copy of a file was deleted during update (because it was gone from the repository).

     One of three record types results from commit:

     A
          A file was added for the first time.

     M
          A file was modified.

     R
          A file was removed.

The options shown as -flags constrain or expand the report without requiring option arguments:

-a
     Show data for all users (the default is to show data only for the user executing history).

-l
     Show last modification only.

-w
     Show only the records for modifications done from the same working directory where history is executing.

The options shown as -options ARGS constrain the report based on an argument:

-b STR
     Show data back to a record containing  the  string STR  in  either the module name, the file name, or the repository path.

-D DATE
     Show data since DATE.  This is slightly different from the normal use of -D DATE, which selects the newest revision older than DATE.

-f FILE
     Show data for a particular file (you can specify several -f options on the same command line). This is equivalent to specifying the file on the command line.

-n MODULE
     Show data for a particular module (you can specify several -n options on the same command line).

-p REPOSITORY
     Show data for a particular source repository  (you can specify several -p options on the same command line).

-r REV
     Show records referring to revisions since the revision or tag named REV appears in individual RCS files.  Each RCS file is searched for the revision or tag.

-t TAG
     Show records since tag TAG was last added to the history file.  This differs from the -r flag above in that it reads only the history file, not the RCS files, and is much faster.

-u NAME
     Show records for user NAME.

-z TIMEZONE
     Show times in the selected records using the specified time zone instead of UTC.

import---Import sources into CVS, using vendor branches
=======================================================

  * Synopsis: import [-options] repository vendortag releasetag...

  * Requires: Repository, source distribution directory.

  * Changes: repository.

Use import to incorporate an entire source distribution from an outside source (e.g., a source vendor) into your source repository directory.  You can use this command both for initial creation of a repository, and for wholesale updates to the module from the outside source.  See Acompanhando fontes, for a discussion on this subject.

The REPOSITORY argument gives a directory name (or a path to a directory) under the CVS root directory for repositories; if the directory did not exist, import creates it.

When you use import for updates to source that has been modified in your source repository (since a prior import), it will notify you of any files that conflict in the two branches of development; use checkout -j to reconcile the differences, as import instructs you to do.

If CVS decides a file should be ignored (see cvsignore), it does not import it and prints I  followed by the filename (see import output, for a complete description of the output).

If the file $CVSROOT/CVSROOT/cvswrappers exists, any file whose names match the specifications in that file will be treated as packages and the appropriate filtering will be performed on the file/directory before being imported.  See Wrappers.

The outside source is saved in a first-level branch, by default 1.1.1.  Updates are leaves of this branch; for example, files from the first imported collection of source will be revision 1.1.1.1, then files from the first imported update will be revision 1.1.1.2, and so on.

At least three arguments are required. REPOSITORY is needed to identify the collection of source.  VENDORTAG is a tag for the entire branch (e.g., for 1.1.1).  You must also specify at least one RELEASETAG to identify the files at the leaves created each time you execute import.

Note that import does not change the directory in which you invoke it.  In particular, it does not set up that directory as a CVS working directory; if you want to work with the sources import them first and then check them out into a different directory (see Obtendo os fontes).

import options
--------------

This standard option is supported by import (see Opções comuns, for a complete description):

-m MESSAGE
     Use MESSAGE as log information, instead of invoking an editor.

There are the following additional special options.

-b BRANCH
     See Ramos de fornecedor múltiplos.

-k SUBST
     Indicate the keyword expansion mode desired.  This setting will apply to all files created during the import, but not to any files that previously existed in the repository.  See Modos de substituição, for a list of valid -k settings.

-I NAME
     Specify file names that should be ignored during import.  You can use this option repeatedly.  To avoid ignoring any files at all (even those ignored by default), specify `-I !'.

     NAME can be a file name pattern of the same type that you can specify in the .cvsignore file. See cvsignore.

-W SPEC
     Specify file names that should be filtered during import.  You can use this option repeatedly.

     SPEC can be a file name pattern of the same type that you can specify in the .cvswrappers file. See Wrappers.

import output
-------------

O import mantém você informado de seu progresso escrevendo uma linha para cada arquivo, iniciando com um caractere que indica o status do arquivo:

U ARQUIVO
     O arquivo já existe no repositório não foi modificado localmente; uma nova revisão foi criada (se necessário).

N ARQUIVO
     O arquivo é um arquivo novo que foi adicionado ao repositório.

C ARQUIVO
     O arquivo já existe no repositório mas foi modificado localmente; Você vai ter que mesclar as mudanças.

I ARQUIVO
     O arquivo foi ignorado (see cvsignore).

L ARQUIVO
     O arquivo é uma ligação simbólica; O cvs import ignora ligações simbólicas.  De vez em quando alguem sugere que este comportamento seja mudado, mas se há um consenso quanto a que mudança fazer, não é claro.  (Várias opções no arquivo modules podem ser usadas para recriar ligações simbólicas no checkout, update, etc.; see modules.)

import examples
---------------

See Acompanhando fontes, and De arquivos.

log---Print out log information for files
=========================================

  * Synopsis: log [options] [files...]

  * Requires: repository, working directory.

  * Changes: nothing.

Display log information for files.  log used to call the RCS utility rlog.  Although this is no longer true in the current sources, this history determines the format of the output and the options, which are not quite in the style of the other CVS commands.

The output includes the location of the RCS file, the head revision (the latest revision on the trunk), all symbolic names (tags) and some other things.  For each revision, the revision number, the author, the number of lines added/deleted and the log message are printed.  All times are displayed in Coordinated Universal Time (UTC).  (Other parts of CVS print times in the local timezone).

Note: log uses -R in a way that conflicts with the normal use inside CVS (see Opções comuns).

log options
-----------

By default, log prints all information that is available.  All other options restrict the output.

-b
     Print information about the revisions on the default branch, normally the highest branch on the trunk.

-d DATES
     Print information about revisions with a checkin date/time in the range given by the semicolon-separated list of dates.  The date formats accepted are those accepted by the -D option to many other CVS commands (see Opções comuns). Dates can be combined into ranges as follows:

     D1<D2
     D2>D1
          Select the revisions that were deposited between D1 and D2.

     <D
     D>
          Select all revisions dated D or earlier.

     D<
     >D
          Select all revisions dated D or later.

     D
          Select the single, latest revision dated D or earlier.

     The > or < characters may be followed by = to indicate an inclusive range rather than an exclusive one.

     Note that the separator is a semicolon (;).

-h
     Print only the name of the RCS file, name of the file in the working directory, head, default branch, access list, locks, symbolic names, and suffix.

-l
     Local; run only in current working directory.  (Default is to run recursively).

-N
     Do not print the list of tags for this file.  This option can be very useful when your site uses a lot of tags, so rather than "more"'ing over 3 pages of tag information, the log information is presented without tags at all.

-R
     Print only the name of the RCS file.

-rREVISIONS
     Print information about revisions given in the comma-separated list REVISIONS of revisions and ranges.  The following table explains the available range formats:

     REV1:REV2
          Revisions REV1 to REV2 (which must be on the same branch).

     REV1::REV2
          The same, but excluding REV1.

     :REV
     ::REV
          Revisions from the beginning of the branch up to and including REV.

     REV:
          Revisions starting with REV to the end of the branch containing REV.

     REV::
          Revisions starting just after REV to the end of the branch containing REV.

     BRANCH
          An argument that is a branch means all revisions on that branch.

     BRANCH1:BRANCH2
     BRANCH1::BRANCH2
          A range of branches means all revisions on the branches in that range.

     BRANCH.
          The latest revision in BRANCH.

     A bare -r with no revisions means the latest revision on the default branch, normally the trunk. There can be no space between the -r option and its argument.

-S
     Suppress the header if no revisions are selected.

-s STATES
     Print information about revisions whose state attributes match one of the states given in the comma-separated list STATES.

-t
     Print the same as -h, plus the descriptive text.

-wLOGINS
     Print information about revisions checked in by users with login names appearing in the comma-separated list LOGINS.  If LOGINS is omitted, the user's login is assumed.  There can be no space between the -w option and its argument.

log prints the intersection of the revisions selected with the options -d, -s, and -w, intersected with the union of the revisions selected by -b and -r.

log examples
------------

Contributed examples are gratefully accepted.

rdiff---'patch' format diffs between releases
=============================================

  * rdiff [-flags] [-V vn] [-r t|-D d [-r t2|-D d2]] modules...

  * Requires: repository.

  * Changes: nothing.

  * Synonym: patch

Builds a Larry Wall format patch(1) file between two releases, that can be fed directly into the patch program to bring an old release up-to-date with the new release.  (This is one of the few CVS commands that operates directly from the repository, and doesn't require a prior checkout.) The diff output is sent to the standard output device.

You can specify (using the standard -r and -D options) any combination of one or two revisions or dates.  If only one revision or date is specified, the patch file reflects differences between that revision or date and the current head revisions in the RCS file.

Note that if the software release affected is contained in more than one directory, then it may be necessary to specify the -p option to the patch command when patching the old sources, so that patch is able to find the files that are located in other directories.

rdiff options
-------------

These standard options are supported by rdiff (see Opções comuns, for a complete description of them):

-D DATE
     Use the most recent revision no later than DATE.

-f
     If no matching revision is found, retrieve the most recent revision (instead of ignoring the file).

-l
     Local; don't descend subdirectories.

-R
     Examine directories recursively.  This option is on by default.

-r TAG
     Use revision TAG.

In addition to the above, these options are available:

-c
     Use the context diff format.  This is the default format.

-s
     Create a summary change report instead of a patch.  The summary includes information about files that were changed or added between the releases.  It is sent to the standard output device.  This is useful for finding out, for example, which files have changed between two dates or revisions.

-t
     A diff of the top two revisions is sent to the standard output device.  This is most useful for seeing what the last change to a file was.

-u
     Use the unidiff format for the context diffs. Remember that old versions of the patch program can't handle the unidiff format, so if you plan to post this patch to the net you should probably not use -u.

-V VN
     Expand keywords according to the rules current in RCS version VN (the expansion format changed with RCS version 5).  Note that this option is no longer accepted.  CVS will always expand keywords the way that RCS version 5 does.

rdiff examples
--------------

Suppose you receive mail from foo@example.net asking for an update from release 1.2 to 1.4 of the tc compiler.  You have no such patches on hand, but with CVS that can easily be fixed with a command such as this:

     $ cvs rdiff -c -r FOO1_2 -r FOO1_4 tc | \
     $$ Mail -s 'The patches you asked for' foo@example.net

Suppose you have made release 1.3, and forked a branch called R_1_3fix for bugfixes.  R_1_3_1 corresponds to release 1.3.1, which was made some time ago.  Now, you want to see how much development has been done on the branch.  This command can be used:

     $ cvs patch -s -r R_1_3_1 -r R_1_3fix module-name
     cvs rdiff: Diffing module-name
     File ChangeLog,v changed from revision 1.52.2.5 to 1.52.2.6
     File foo.c,v changed from revision 1.52.2.3 to 1.52.2.4
     File bar.h,v changed from revision 1.29.2.1 to 1.2

release---Indicate that a Module is no longer in use
====================================================

  * release [-d] directories...

  * Requires: Working directory.

  * Changes: Working directory, history log.

This command is meant to safely cancel the effect of cvs checkout.  Since CVS doesn't lock files, it isn't strictly necessary to use this command.  You can always simply delete your working directory, if you like; but you risk losing changes you may have forgotten, and you leave no trace in the CVS history file (see arquivo history (histórico)) that you've abandoned your checkout.

Use cvs release to avoid these problems.  This command checks that no uncommitted changes are present; that you are executing it from immediately above a CVS working directory; and that the repository recorded for your files is the same as the repository defined in the module database.

If all these conditions are true, cvs release leaves a record of its execution (attesting to your intentionally abandoning your checkout) in the CVS history log.

release options
---------------

The release command supports one command option:

-d
     Delete your working copy of the file if the release succeeds.  If this flag is not given your files will remain in your working directory.

     WARNING:  The release command deletes all directories and files recursively.  This has the very serious side-effect that any directory that you have created inside your checked-out sources, and not added to the repository (using the add command; see Adicionando arquivos) will be silently deleted---even if it is non-empty!

release output
--------------

Before release releases your sources it will print a one-line message for any file that is not up-to-date.

U FILE
P FILE
     There exists a newer revision of this file in the repository, and you have not modified your local copy of the file (U and P mean the same thing).

A FILE
     The file has been added to your private copy of the sources, but has not yet been committed to the repository.  If you delete your copy of the sources this file will be lost.

R FILE
     The file has been removed from your private copy of the sources, but has not yet been removed from the repository, since you have not yet committed the removal.  See commit.

M FILE
     The file is modified in your working directory.  There might also be a newer revision inside the repository.

? FILE
     FILE is in your working directory, but does not correspond to anything in the source repository, and is not in the list of files for CVS to ignore (see the description of the -I option, and see cvsignore).  If you remove your working sources, this file will be lost.

release examples
----------------

Release the tc directory, and delete your local working copy of the files.

     $ cd ..         # You must stand immediately above the
                     # sources when you issue cvs release.
     $ cvs release -d tc
     You have [0] altered files in this repository.
     Are you sure you want to release (and delete) directory `tc': y
     $

update---Bring work tree in sync with repository
================================================

  * update [-ACdflPpR] [-I name] [-j rev [-j rev]] [-k kflag] [-r tag|-D date] [-W spec] files...

  * Requires: repository, working directory.

  * Changes: working directory.

After you've run checkout to create your private copy of source from the common repository, other developers will continue changing the central source.  From time to time, when it is convenient in your development process, you can use the update command from within your working directory to reconcile your work with any revisions applied to the source repository since your last checkout or update.  Without the -C option, update will also merge any differences between the local copy of files and their base revisions into any destination revisions specified with -r, -D, or -A.

update options
--------------

These standard options are available with update (see Opções comuns, for a complete description of them):

-D date
     Use the most recent revision no later than DATE. This option is sticky, and implies -P. See Etiquetas adesivas, for more information on sticky tags/dates.

-f
     Only useful with the -D DATE or -r TAG flags.  If no matching revision is found, retrieve the most recent revision (instead of ignoring the file).

-k KFLAG
     Process keywords according to KFLAG.  See Substituição de palavra-chave. This option is sticky; future updates of this file in this working directory will use the same KFLAG.  The status command can be viewed to see the sticky options.  See Chamando o CVS, for more information on the status command.

-l
     Local; run only in current working directory.  See Comportamento recursivo.

-P
     Prune empty directories.  See Movendo diretórios.

-p
     Pipe files to the standard output.

-R
     Update directories recursively (default). See Comportamento recursivo.

-r rev
     Retrieve revision/tag REV.  This option is sticky, and implies -P. See Etiquetas adesivas, for more information on sticky tags/dates.

These special options are also available with update.

-A
     Reset any sticky tags, dates, or -k options. See Etiquetas adesivas, for more information on sticky tags/dates.

-C
     Overwrite locally modified files with clean copies from the repository (the modified file is saved in .#FILE.REVISION, however).

-d
     Create any directories that exist in the repository if they're missing from the working directory.  Normally, update acts only on directories and files that were already enrolled in your working directory.

     This is useful for updating directories that were created in the repository since the initial checkout; but it has an unfortunate side effect.  If you deliberately avoided certain directories in the repository when you created your working directory (either through use of a module name or by listing explicitly the files and directories you wanted on the command line), then updating with -d will create those directories, which may not be what you want.

-I NAME
     Ignore files whose names match NAME (in your working directory) during the update.  You can specify -I more than once on the command line to specify several files to ignore.  Use -I ! to avoid ignoring any files at all.  See cvsignore, for other ways to make CVS ignore some files.

-WSPEC
     Specify file names that should be filtered during update.  You can use this option repeatedly.

     SPEC can be a file name pattern of the same type that you can specify in the .cvswrappers file. See Wrappers.

-jREVISION
     With two -j options, merge changes from the revision specified with the first -j option to the revision specified with the second j option, into the working directory.

     With one -j option, merge changes from the ancestor revision to the revision specified with the -j option, into the working directory.  The ancestor revision is the common ancestor of the revision which the working directory is based on, and the revision specified in the -j option.

     Note that using a single -j TAGNAME option rather than -j BRANCHNAME to merge changes from a branch will often not remove files which were removed on the branch. See Mesclando adicionados e removidos, for more.

     In addition, each -j option can contain an optional date specification which, when used with branches, can limit the chosen revision to one within a specific date.  An optional date is specified by adding a colon (:) to the tag: -jSYMBOLIC_TAG:DATE_SPECIFIER.

     See Ramificando e mesclando.

update output
-------------

O update e o checkout mantém você informado de seu progresso escrevendo uma linha para cada arquivo, iniciando com um caractere que indica o status do arquivo:

U ARQUIVO
     O arquivo foi atualizado com base no repositório.  Isto é feito para qualquer arquivo que exista no repositório mas não esteja nos seus fontes (no seu diretório da trabalho) e para arquivos que você não mudou mas não estão na versão mais recente que está disponível no repositório.

P ARQUIVO

     Como o U, mas o servidor CVS manda um patch (remendo) ao invés de mandar um arquivo inteiro.  Tem o mesmo resultado que U usando menos largura de banda.

A ARQUIVO
     O arquivo foi adicionado a sua cópia local dos fontes, e vai ser adicionado ao repositório quando você rodar o commit no arquivo.  Funciona como um lembrete de que o arquivo precisa ser ???commitado???.

R ARQUIVO
     O arquivo foi removido de sua cópia local dos fontes, e será removido do repositório quando você executar um commit no arquivo.  Funciona como um lembrete de que o arquivo precisa ser ???commitado???.

M ARQUIVO
     O arquivo está modificado no seu diretório de trabalho.

     O M pode indicar um dos dois estados para um arquivo no qual você esteja trabalhando: ou não existem modificações do arquivo equivalente no repositório, de forma que seu arquivo continua da forma como você o deixou; ou existem modificações no repositório assim como na sua cópia, mas elas foram mescladas com sucesso, sem conflito, no seu diretório de trabalho.

     O CVS vai escrever algumas mensagens se ele mesclar seu trabalho, e colocará uma cópia de segurança no seu diretório de trabalho (na forma que estava antes de executar o update).  O nome exato do arquivo será escrito quando o update rodar.

C ARQUIVO
     Um conflito foi detectado quando se tentava mesclar suas mudanças no ARQUIVO com as mudanças no repositório.  O ARQUIVO (a cópia no seu diretório de trabalho) é agora o resultado da tentativa de mesclar as duas revisões; uma cópia inalterada do arquivo também está no diretório de trabalho, com o nome de .#ARQUIVO.REVISÃO onde REVISÃO é a revisão de onde o seu arquivo modificado saiu.  Resolva o conflito como é mostrado em Exemplo de conflitos. (Note que alguns sistemas eliminam automaticamente arquivos que começam com .# se eles não são acessados por alguns dias.  Se você pretende manter uma cópia do arquivo original, é um ótima idéia renomeá-lo.)  No VMS, o nome do arquivo começa com __ ao invés de .#.

? ARQUIVO
     O ARQUIVO is in your working directory, but does not correspond to anything in the source repository, and is not in the list of files for CVS to ignore (see the description of the -I option, and see cvsignore).

Quick reference to CVS commands
*******************************

This appendix describes how to invoke CVS, with references to where each command or feature is described in detail.  For other references run the cvs --help command, or see Indice.

A CVS command looks like:

     cvs [ GLOBAL_OPTIONS ] COMMAND [ COMMAND_OPTIONS ] [ COMMAND_ARGS ]

Global options:

--allow-root=ROOTDIR
     Specify legal CVSROOT directory (server only) (not in CVS 1.9 and older).  See Servidor de autenticação por senha.

-a
     Authenticate all communication (client only) (not in CVS 1.9 and older).  See Opções globais.

-b
     Specify RCS location (CVS 1.9 and older).  See Opções globais.

-d ROOT
     Specify the CVSROOT.  See Repositório.

-e EDITOR
     Edit messages with EDITOR.  See Efetivando suas alterações.

-f
     Do not read the ~/.cvsrc file.  See Opções globais.

-H
--help
     Print a help message.  See Opções globais.

-l
     Do not log in $CVSROOT/CVSROOT/history file.  See Opções globais.

-n
     Do not change any files.  See Opções globais.

-Q
     Be really quiet.  See Opções globais.

-q
     Be somewhat quiet.  See Opções globais.

-r
     Make new working files read-only.  See Opções globais.

-s VARIABLE=VALUE
     Set a user variable.  See Variables.

-T TEMPDIR
     Put temporary files in TEMPDIR.  See Opções globais.

-t
     Trace CVS execution.  See Opções globais.

-v

--version
     Display version and copyright information for CVS.

-w
     Make new working files read-write.  See Opções globais.

-x
     Encrypt all communication (client only). See Opções globais.

-z GZIP-LEVEL
     Set the compression level (client only). See Opções globais.

Keyword expansion modes (see Modos de substituição):

     -kkv  $Id: file1,v 1.1 1993/12/09 03:21:13 joe Exp $
     -kkvl $Id: file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $
     -kk   $Id$
     -kv   file1,v 1.1 1993/12/09 03:21:13 joe Exp
     -ko   no expansion
     -kb   no expansion, file is binary

Keywords (see Lista de palavras-chave):

     $Author: joe $
     $Date: 1993/12/09 03:21:13 $
     $CVSHeader: files/file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $
     $Header: /home/files/file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $
     $Id: file1,v 1.1 1993/12/09 03:21:13 joe Exp harry $
     $Locker: harry $
     $Name: snapshot_1_14 $
     $RCSfile: file1,v $
     $Revision: 1.1 $
     $Source: /home/files/file1,v $
     $State: Exp $
     $Log: file1,v $
     Revision 1.1  1993/12/09 03:30:17  joe
     Initial revision

Commands, command options, and command arguments:

add [OPTIONS] [FILES...]
     Add a new file/directory.  See Adicionando arquivos.

     -k KFLAG
          Set keyword expansion.

     -m MSG
          Set file description.

admin [OPTIONS] [FILES...]
     Administration of history files in the repository.  See admin.

     -b[REV]
          Set default branch.  See Reverting local changes.

     -cSTRING
          Set comment leader.

     -kSUBST
          Set keyword substitution.  See Substituição de palavra-chave.

     -l[REV]
          Lock revision REV, or latest revision.

     -mREV:MSG
          Replace the log message of revision REV with MSG.

     -oRANGE
          Delete revisions from the repository.  See admin options.

     -q
          Run quietly; do not print diagnostics.

     -sSTATE[:REV]
          Set the state.

     -t
          Set file description from standard input.

     -tFILE
          Set file description from FILE.

     -t-STRING
          Set file description to STRING.

     -u[REV]
          Unlock revision REV, or latest revision.

annotate [OPTIONS] [FILES...]
     Show last revision where each line was modified.  See annotate.

     -D DATE
          Annotate the most recent revision no later than DATE.  See Opções comuns.

     -F
          Force annotation of binary files.  (Without this option, binary files are skipped with a message.)

     -f
          Use head revision if tag/date not found.  See Opções comuns.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -R
          Operate recursively (default). See Comportamento recursivo.

     -r TAG
          Annotate revision TAG.  See Opções comuns.

checkout [OPTIONS] MODULES...
     Get a copy of the sources.  See checkout.

     -A
          Reset any sticky tags/date/options.  See Etiquetas adesivas and Substituição de palavra-chave.

     -c
          Output the module database.  See checkout options.

     -D DATE
          Check out revisions as of DATE (is sticky).  See Opções comuns.

     -d DIR
          Check out into DIR.  See checkout options.

     -f
          Use head revision if tag/date not found.  See Opções comuns.

     -j REV
          Merge in changes.  See checkout options.

     -k KFLAG
          Use KFLAG keyword expansion.  See Modos de substituição.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -N
          Don't ``shorten'' module paths if -d specified.  See checkout options.

     -n
          Do not run module program (if any).  See checkout options.

     -P
          Prune empty directories.  See Movendo diretórios.

     -p
          Check out files to standard output (avoids stickiness).  See checkout options.

     -R
          Operate recursively (default).  See Comportamento recursivo.

     -r TAG
          Checkout revision TAG (is sticky).  See Opções comuns.

     -s
          Like -c, but include module status.  See checkout options.

commit [OPTIONS] [FILES...]
     Check changes into the repository.  See commit.

     -F FILE
          Read log message from FILE.  See commit options.

     -f
          Force the file to be committed; disables recursion. See commit options.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -m MSG
          Use MSG as log message.  See commit options.

     -n
          Do not run module program (if any).  See commit options.

     -R
          Operate recursively (default).  See Comportamento recursivo.

     -r REV
          Commit to REV.  See commit options.

diff [OPTIONS] [FILES...]
     Show differences between revisions.  See diff. In addition to the options shown below, accepts a wide variety of options to control output style, for example -c for context diffs.

     -D DATE1
          Diff revision for date against working file.  See diff options.

     -D DATE2
          Diff REV1/DATE1 against DATE2.  See diff options.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -N
          Include diffs for added and removed files.  See diff options.

     -R
          Operate recursively (default).  See Comportamento recursivo.

     -r REV1
          Diff revision for REV1 against working file.  See diff options.

     -r REV2
          Diff REV1/DATE1 against REV2.  See diff options.

edit [OPTIONS] [FILES...]
     Get ready to edit a watched file.  See Editando arquivos.

     -a ACTIONS
          Specify actions for temporary watch, where ACTIONS is edit, unedit, commit, all, or none.  See Editando arquivos.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -R
          Operate recursively (default).  See Comportamento recursivo.

editors [OPTIONS] [FILES...]
     See who is editing a watched file.  See Informações de ???Watch???.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -R
          Operate recursively (default).  See Comportamento recursivo.

export [OPTIONS] MODULES...
     Export files from CVS.  See export.

     -D DATE
          Check out revisions as of DATE.  See Opções comuns.

     -d DIR
          Check out into DIR.  See export options.

     -f
          Use head revision if tag/date not found.  See Opções comuns.

     -k KFLAG
          Use KFLAG keyword expansion.  See Modos de substituição.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -N
          Don't ``shorten'' module paths if -d specified.  See export options.

     -n
          Do not run module program (if any).  See export options.

     -R
          Operate recursively (default).  See Comportamento recursivo.

     -r TAG
          Checkout revision TAG.  See Opções comuns.

history [OPTIONS] [FILES...]
     Show repository access history.  See history.

     -a
          All users (default is self).  See history options.

     -b STR
          Back to record with STR in module/file/repos field.  See history options.

     -c
          Report on committed (modified) files.  See history options.

     -D DATE
          Since DATE.  See history options.

     -e
          Report on all record types.  See history options.

     -l
          Last modified (committed or modified report).  See history options.

     -m MODULE
          Report on MODULE (repeatable).  See history options.

     -n MODULE
          In MODULE.  See history options.

     -o
          Report on checked out modules.  See history options.

     -p REPOSITORY
          In REPOSITORY.  See history options.

     -r REV
          Since revision REV.  See history options.

     -T
          Produce report on all TAGs.  See history options.

     -t TAG
          Since tag record placed in history file (by anyone). See history options.

     -u USER
          For user USER (repeatable).  See history options.

     -w
          Working directory must match.  See history options.

     -x TYPES
          Report on TYPES, one or more of TOEFWUPCGMAR.  See history options.

     -z ZONE
          Output for time zone ZONE.  See history options.

import [OPTIONS] REPOSITORY VENDOR-TAG RELEASE-TAGS...
     Import files into CVS, using vendor branches.  See import.

     -b BRA
          Import to vendor branch BRA.  See Ramos de fornecedor múltiplos.

     -d
          Use the file's modification time as the time of import.  See import options.

     -k KFLAG
          Set default keyword substitution mode.  See import options.

     -m MSG
          Use MSG for log message.  See import options.

     -I IGN
          More files to ignore (! to reset).  See import options.

     -W SPEC
          More wrappers.  See import options.

init
     Create a CVS repository if it doesn't exist.  See Criando um repositório.

kserver
     Kerberos authenticated server. See Autenticação kerberos.

log [OPTIONS] [FILES...]
     Print out history information for files.  See log.

     -b
          Only list revisions on the default branch.  See log options.

     -d DATES
          Specify dates (D1<D2 for range, D for latest before).  See log options.

     -h
          Only print header.  See log options.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -N
          Do not list tags.  See log options.

     -R
          Only print name of RCS file.  See log options.

     -rREVS
          Only list revisions REVS.  See log options.

     -s STATES
          Only list revisions with specified states.  See log options.

     -t
          Only print header and descriptive text.  See log options.

     -wLOGINS
          Only list revisions checked in by specified logins.  See log options.

login
     Pede por uma senha para o servidor de autenticação.  Veja em Cliente de autenticação por senha.

logout
     Remove senhas armazenadas para a autenticação no servidor.  Veja em Cliente de autenticação por senha.

pserver
     Password authenticated server. See Servidor de autenticação por senha.

rannotate [OPTIONS] [MODULES...]
     Show last revision where each line was modified.  See annotate.

     -D DATE
          Annotate the most recent revision no later than DATE.  See Opções comuns.

     -F
          Force annotation of binary files.  (Without this option, binary files are skipped with a message.)

     -f
          Use head revision if tag/date not found.  See Opções comuns.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -R
          Operate recursively (default).  See Comportamento recursivo.

     -r TAG
          Annotate revision TAG.  See Opções comuns.

rdiff [OPTIONS] MODULES...
     Show differences between releases.  See rdiff.

     -c
          Context diff output format (default).  See rdiff options.

     -D DATE
          Select revisions based on DATE.  See Opções comuns.

     -f
          Use head revision if tag/date not found.  See Opções comuns.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -R
          Operate recursively (default).  See Comportamento recursivo.

     -r REV
          Select revisions based on REV.  See Opções comuns.

     -s
          Short patch - one liner per file.  See rdiff options.

     -t
          Top two diffs - last change made to the file.  See diff options.

     -u
          Unidiff output format.  See rdiff options.

     -V VERS
          Use RCS Version VERS for keyword expansion (obsolete).  See rdiff options.

release [OPTIONS] DIRECTORY
     Indicate that a directory is no longer in use.  See release.

     -d
          Delete the given directory.  See release options.

remove [OPTIONS] [FILES...]
     Remove an entry from the repository.  See Removendo arquivos.

     -f
          Delete the file before removing it.  See Removendo arquivos.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -R
          Operate recursively (default).  See Comportamento recursivo.

rlog [OPTIONS] [FILES...]
     Print out history information for modules.  See log.

     -b
          Only list revisions on the default branch.  See log options.

     -d DATES
          Specify dates (D1<D2 for range, D for latest before).  See log options.

     -h
          Only print header.  See log options.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -N
          Do not list tags.  See log options.

     -R
          Only print name of RCS file.  See log options.

     -rREVS
          Only list revisions REVS.  See log options.

     -s STATES
          Only list revisions with specified states.  See log options.

     -t
          Only print header and descriptive text.  See log options.

     -wLOGINS
          Only list revisions checked in by specified logins.  See log options.

rtag [OPTIONS] TAG MODULES...
     Add a symbolic tag to a module. See Revisões and Ramificando e mesclando.

     -a
          Clear tag from removed files that would not otherwise be tagged.  See Etiquetando adicionados/removidos.

     -b
          Create a branch named TAG.  See Ramificando e mesclando.

     -B
          Used in conjunction with -F or -d, enables movement and deletion of branch tags.  Use with extreme caution.

     -D DATE
          Tag revisions as of DATE.  See Etiquetando por data/etiqueta.

     -d
          Delete TAG.  See Modificando etiquetas.

     -F
          Move TAG if it already exists.  See Modificando etiquetas.

     -f
          Force a head revision match if tag/date not found. See Etiquetando por data/etiqueta.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -n
          No execution of tag program.  See Opções comuns.

     -R
          Operate recursively (default).  See Comportamento recursivo.

     -r REV
          Tag existing tag REV.  See Etiquetando por data/etiqueta.

server
     Rsh server.  See Se conectando via rsh.

status [OPTIONS] FILES...
     Display status information in a working directory.  See Estado de arquivo.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -R
          Operate recursively (default).  See Comportamento recursivo.

     -v
          Include tag information for file.  See Etiquetas.

tag [OPTIONS] TAG [FILES...]
     Add a symbolic tag to checked out version of files. See Revisões and Ramificando e mesclando.

     -b
          Create a branch named TAG.  See Ramificando e mesclando.

     -c
          Check that working files are unmodified.  See Etiquetando o diretório de trabalho.

     -D DATE
          Tag revisions as of DATE.  See Etiquetando por data/etiqueta.

     -d
          Delete TAG.  See Modificando etiquetas.

     -F
          Move TAG if it already exists.  See Modificando etiquetas.

     -f
          Force a head revision match if tag/date not found. See Etiquetando por data/etiqueta.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -R
          Operate recursively (default).  See Comportamento recursivo.

     -r REV
          Tag existing tag REV.  See Etiquetando por data/etiqueta.

unedit [OPTIONS] [FILES...]
     Undo an edit command.  See Editando arquivos.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -R
          Operate recursively (default).  See Comportamento recursivo.

update [OPTIONS] [FILES...]
     Bring work tree in sync with repository.  See update.

     -A
          Reset any sticky tags/date/options.  See Etiquetas adesivas and Substituição de palavra-chave.

     -C
          Overwrite locally modified files with clean copies from the repository (the modified file is saved in .#FILE.REVISION, however).

     -D DATE
          Check out revisions as of DATE (is sticky).  See Opções comuns.

     -d
          Create directories.  See update options.

     -f
          Use head revision if tag/date not found.  See Opções comuns.

     -I IGN
          More files to ignore (! to reset).  See import options.

     -j REV
          Merge in changes.  See update options.

     -k KFLAG
          Use KFLAG keyword expansion.  See Modos de substituição.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -P
          Prune empty directories.  See Movendo diretórios.

     -p
          Check out files to standard output (avoids stickiness).  See update options.

     -R
          Operate recursively (default).  See Comportamento recursivo.

     -r TAG
          Checkout revision TAG (is sticky).  See Opções comuns.

     -W SPEC
          More wrappers.  See import options.

version

     Display the version of CVS being used.  If the repository is remote, display both the client and server versions.

watch [on|off|add|remove] [OPTIONS] [FILES...]

     on/off: turn on/off read-only checkouts of files.  See Ajustando um ???watch???.

     add/remove: add or remove notification on actions.  See Recebendo Notificações.

     -a ACTIONS
          Specify actions for temporary watch, where ACTIONS is edit, unedit, commit, all, or none.  See Editando arquivos.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -R
          Operate recursively (default).  See Comportamento recursivo.

watchers [OPTIONS] [FILES...]
     See who is watching a file.  See Informações de ???Watch???.

     -l
          Local; run only in current working directory.  See Comportamento recursivo.

     -R
          Operate recursively (default).  See Comportamento recursivo.

Manual de referência para Arquivos administrativos
**************************************************

Dentro do repositório, no diretório $CVSROOT/CVSROOT, existem vários arquivos de suporte para o CVS.  Você pode usar o CVS de uma forma limitada sem se aproveitar deles, mas se eles estiverem ajustados corretamente eles podem facilitar muito seu trabalho.  Para uma discussão sobre como editá-los, veja em Intro aos arquivos administrativos.

O mais importante destes arquivos é o arquivo modules, que define os módulos dentro do repositório.

O arquivo modules
=================

O arquivo modules registra suas definições de nomes para coleções de código fonte.  CVS vai usar estas definições se você usar o CVS para atualizar o arquivo modules (use comandos normais, como add, commit, etc).

The modules file may contain blank lines and comments (lines beginning with #) as well as module definitions.  Long lines can be continued on the next line by specifying a backslash (\) as the last character on the line.

There are three basic types of modules: alias modules, regular modules, and ampersand modules.  The difference between them is the way that they map files in the repository to files in the working directory.  In all of the following examples, the top-level repository contains a directory called first-dir, which contains two files, file1 and file2, and a directory sdir.  first-dir/sdir contains a file sfile.

Alias modules
-------------

Alias modules are the simplest kind of module:

MNAME -a ALIASES...
     This represents the simplest way of defining a module MNAME.  The -a flags the definition as a simple alias: CVS will treat any use of MNAME (as a command argument) as if the list of names ALIASES had been specified instead. ALIASES may contain either other module names or paths.  When you use paths in aliases, checkout creates all intermediate directories in the working directory, just as if the path had been specified explicitly in the CVS arguments.

For example, if the modules file contains:

     amodule -a first-dir

then the following two commands are equivalent:

     $ cvs co amodule
     $ cvs co first-dir

and they each would provide output such as:

     cvs checkout: Updating first-dir
     U first-dir/file1
     U first-dir/file2
     cvs checkout: Updating first-dir/sdir
     U first-dir/sdir/sfile

Regular modules
---------------

MNAME [ options ] DIR [ FILES... ]
     In the simplest case, this form of module definition reduces to MNAME DIR.  This defines all the files in directory DIR as module mname. DIR is a relative path (from $CVSROOT) to a directory of source in the source repository.  In this case, on checkout, a single directory called MNAME is created as a working directory; no intermediate directory levels are used by default, even if DIR was a path involving several directory levels.

For example, if a module is defined by:

     regmodule first-dir

then regmodule will contain the files from first-dir:

     $ cvs co regmodule
     cvs checkout: Updating regmodule
     U regmodule/file1
     U regmodule/file2
     cvs checkout: Updating regmodule/sdir
     U regmodule/sdir/sfile
     $

By explicitly specifying files in the module definition after DIR, you can select particular files from directory DIR.  Here is an example:

     regfiles first-dir/sdir sfile

With this definition, getting the regfiles module will create a single working directory regfiles containing the file listed, which comes from a directory deeper in the CVS source repository:

     $ cvs co regfiles
     U regfiles/sfile
     $

Ampersand modules
-----------------

A module definition can refer to other modules by including &MODULE in its definition.

     MNAME [ options ] &MODULE...

Then getting the module creates a subdirectory for each such module, in the directory containing the module.  For example, if modules contains

     ampermod &first-dir

then a checkout will create an ampermod directory which contains a directory called first-dir, which in turns contains all the directories and files which live there.  For example, the command

     $ cvs co ampermod

will create the following files:

     ampermod/first-dir/file1
     ampermod/first-dir/file2
     ampermod/first-dir/sdir/sfile

There is one quirk/bug: the messages that CVS prints omit the ampermod, and thus do not correctly display the location to which it is checking out the files:

     $ cvs co ampermod
     cvs checkout: Updating first-dir
     U first-dir/file1
     U first-dir/file2
     cvs checkout: Updating first-dir/sdir
     U first-dir/sdir/sfile
     $

Do not rely on this buggy behavior; it may get fixed in a future release of CVS.

Excluding directories
---------------------

An alias module may exclude particular directories from other modules by using an exclamation mark (!) before the name of each directory to be excluded.

For example, if the modules file contains:

     exmodule -a !first-dir/sdir first-dir

then checking out the module exmodule will check out everything in first-dir except any files in the subdirectory first-dir/sdir.

Module options
--------------

Either regular modules or ampersand modules can contain options, which supply additional information concerning the module.

-d NAME
     Name the working directory something other than the module name.

-e PROG
     Specify a program PROG to run whenever files in a module are exported.  PROG runs with a single argument, the module name.

-o PROG
     Specify a program PROG to run whenever files in a module are checked out.  PROG runs with a single argument, the module name.  See Module program options for information on how PROG is called.

-s STATUS
     Assign a status to the module.  When the module file is printed with cvs checkout -s the modules are sorted according to primarily module status, and secondarily according to the module name.  This option has no other meaning.  You can use this option for several things besides status: for instance, list the person that is responsible for this module.

-t PROG
     Specify a program PROG to run whenever files in a module are tagged with rtag.  PROG runs with two arguments: the module name and the symbolic tag specified to rtag.  It is not run when tag is executed.  Generally you will find that the taginfo file is a better solution(see taginfo).

You should also see Module program options about how the ``program options'' programs are run.

How the modules file ``program options'' programs are run
---------------------------------------------------------

For checkout, rtag, and export, the program is server-based, and as such the following applies:-

If using remote access methods (pserver, ext, etc.), CVS will execute this program on the server from a temporary directory. The path is searched for this program.

If using ``local access'' (on a local or remote NFS file system, i.e. repository set just to a path), the program will be executed from the newly checked-out tree, if found there, or alternatively searched for in the path if not.

The programs are all run after the operation has effectively completed.

The cvswrappers file
====================

Wrappers refers to a CVS feature which lets you control certain settings based on the name of the file which is being operated on.  The settings are -k for binary files, and -m for nonmergeable text files.

The -m option specifies the merge methodology that should be used when a non-binary file is updated.  MERGE means the usual CVS behavior: try to merge the files.  COPY means that cvs update will refuse to merge files, as it also does for files specified as binary with -kb (but if the file is specified as binary, there is no need to specify -m 'COPY'). CVS will provide the user with the two versions of the files, and require the user using mechanisms outside CVS, to insert any necessary changes.

WARNING: do not use COPY with CVS 1.9 or earlier - such versions of CVS will copy one version of your file over the other, wiping out the previous contents. The -m wrapper option only affects behavior when merging is done on update; it does not affect how files are stored.  See Arquivos binários, for more on binary files.

The basic format of the file cvswrappers is:

     wildcard     [option value][option value]...

     where option is one of
     -m           update methodology      value: MERGE or COPY
     -k           keyword expansion       value: expansion mode

     and value is a single-quote delimited value.

For example, the following command imports a directory, treating files whose name ends in .exe as binary:

     cvs import -I ! -W "*.exe -k 'b'" first-dir vendortag reltag

The commit support files
========================

The -i flag in the modules file can be used to run a certain program whenever files are committed (see modules).  The files described in this section provide other, more flexible, ways to run programs whenever something is committed.

There are three kind of programs that can be run on commit.  They are specified in files in the repository, as described below.  The following table summarizes the file names and the purpose of the corresponding programs.

commitinfo
     The program is responsible for checking that the commit is allowed.  If it exits with a non-zero exit status the commit will be aborted.

verifymsg
     The specified program is used to evaluate the log message, and possibly verify that it contains all required fields.  This is most useful in combination with the rcsinfo file, which can hold a log message template (see rcsinfo).

loginfo
     The specified program is called when the commit is complete.  It receives the log message and some additional information and can store the log message in a file, or mail it to appropriate persons, or maybe post it to a local newsgroup, or...  Your imagination is the limit!

The common syntax
-----------------

The administrative files such as commitinfo, loginfo, rcsinfo, verifymsg, etc., all have a common format.  The purpose of the files are described later on.  The common syntax is described here.

Each line contains the following:

  * A regular expression.  This is a basic regular expression in the syntax used by GNU emacs.

  * A whitespace separator---one or more spaces and/or tabs.

  * A file name or command-line template.

Blank lines are ignored.  Lines that start with the character # are treated as comments.  Long lines unfortunately can not be broken in two parts in any way.

The first regular expression that matches the current directory name in the repository is used.  The rest of the line is used as a file name or command-line as appropriate.

Commitinfo
----------

The commitinfo file defines programs to execute whenever cvs commit is about to execute.  These programs are used for pre-commit checking to verify that the modified, added and removed files are really ready to be committed.  This could be used, for instance, to verify that the changed files conform to to your site's standards for coding practice.

As mentioned earlier, each line in the commitinfo file consists of a regular expression and a command-line template.  The template can include a program name and any number of arguments you wish to supply to it.  The full path to the current source repository is appended to the template, followed by the file names of any files involved in the commit (added, removed, and modified files).

The first line with a regular expression matching the directory within the repository will be used.  If the command returns a non-zero exit status the commit will be aborted.

If the repository name does not match any of the regular expressions in this file, the DEFAULT line is used, if it is specified.

All occurrences of the name ALL appearing as a regular expression are used in addition to the first matching regular expression or the name DEFAULT.

The command will be run in the root of the workspace containing the new versions of any files the user would like to modify (commit), or in a copy of the workspace on the server (see Repositórios remotos).  If a file is being removed, there will be no copy of the file under the current directory.  If a file is being added, there will be no corresponding archive file in the repository unless the file is being resurrected.

Note that both the repository directory and the corresponding Attic (see Attic) directory may need to be checked to locate the archive file corresponding to any given file being committed.  Much of the information about the specific commit request being made, including the destination branch, commit message, and command line options specified, is not available to the command.

Verifying log messages
----------------------

Once you have entered a log message, you can evaluate that message to check for specific content, such as a bug ID.  Use the verifymsg file to specify a program that is used to verify the log message. This program could be a simple script that checks that the entered message contains the required fields.

The verifymsg file is often most useful together with the rcsinfo file, which can be used to specify a log message template.

Each line in the verifymsg file consists of a regular expression and a command-line template.  The template must include a program name, and can include any number of arguments.  The full path to the current log message template file is appended to the template.

One thing that should be noted is that the ALL keyword is not supported.  If more than one matching line is found, the first one is used.  This can be useful for specifying a default verification script in a directory, and then overriding it in a subdirectory.

If the repository name does not match any of the regular expressions in this file, the DEFAULT line is used, if it is specified.

If the verification script exits with a non-zero exit status, the commit is aborted.

In the default configuration, CVS allows the verification script to change the log message. This is controlled via the RereadLogAfterVerify CVSROOT/config option.

When RereadLogAfterVerify=always or RereadLogAfterVerify=stat, the log message will either always be reread after the verification script is run or reread only if the log message file status has changed.

See config, for more on CVSROOT/config options.

It is NOT a good idea for a verifymsg script to interact directly with the user in the various client/server methods. For the pserver method, there is no protocol support for communicating between verifymsg and the client on the remote end. For the ext and server methods, it is possible for CVS to become confused by the characters going along the same channel as the CVS protocol messages. See Repositórios remotos, for more information on client/server setups.  In addition, at the time the verifymsg script runs, the CVS server has locks in place in the repository.  If control is returned to the user here then other users may be stuck waiting for access to the repository.

This option can be useful if you find yourself using an rcstemplate that needs to be modified to remove empty elements or to fill in default values.  It can also be useful if the rcstemplate has changed in the repository and the CVS/Template was not updated, but is able to be adapted to the new format by the verification script that is run by verifymsg.

An example of an update might be to change all occurrences of 'BugId:' to be 'DefectId:' (which can be useful if the rcstemplate has recently been changed and there are still checked-out user trees with cached copies in the CVS/Template file of the older version).

Another example of an update might be to delete a line that contains 'BugID: none' from the log message after validation of that value as being allowed is made.

The following is a little silly example of a verifymsg file, together with the corresponding rcsinfo file, the log message template and an verification  script.  We begin with the log message template. We want to always record a bug-id number on the first line of the log message.  The rest of log message is free text.  The following template is found in the file /usr/cvssupport/tc.template.

     BugId:

The script /usr/cvssupport/bugid.verify is used to evaluate the log message.

     #!/bin/sh
     #
     #       bugid.verify filename
     #
     #  Verify that the log message contains a valid bugid
     #  on the first line.
     #
     if sed 1q < $1 | grep '^BugId:[ ]*[0-9][0-9]*$' > /dev/null; then
         exit 0
     elif sed 1q < $1 | grep '^BugId:[ ]*none$' > /dev/null; then
         # It is okay to allow commits with 'BugId: none',
         # but do not put that text into the real log message.
         grep -v '^BugId:[ ]*none$' > $1.rewrite
         mv $1.rewrite $1
         exit 0
     else
         echo "No BugId found."
         exit 1
     fi

The verifymsg file contains this line:

     ^tc     /usr/cvssupport/bugid.verify

The rcsinfo file contains this line:

     ^tc     /usr/cvssupport/tc.template

The config file contains this line:

     RereadLogAfterVerify=always

Loginfo
-------

The loginfo file is used to control where cvs commit log information is sent.  The first entry on a line is a regular expression which is tested against the directory that the change is being made to, relative to the $CVSROOT.  If a match is found, then the remainder of the line is a filter program that should expect log information on its standard input.

If the repository name does not match any of the regular expressions in this file, the DEFAULT line is used, if it is specified.

All occurrences of the name ALL appearing as a regular expression are used in addition to the first matching regular expression or DEFAULT.

The first matching regular expression is used.

See Arquivos de ???commit???, for a description of the syntax of the loginfo file.

The user may specify a format string as part of the filter.  The string is composed of a % followed by a space, or followed by a single format character, or followed by a set of format characters surrounded by { and } as separators.  The format characters are:

s
     file name

V
     old version number (pre-checkin)

v
     new version number (post-checkin)

All other characters that appear in a format string expand to an empty field (commas separating fields are still provided).

For example, some valid format strings are %, %s, %{s}, and %{sVv}.

The output will be a space separated string of tokens enclosed in quotation marks ("). Any embedded dollar signs ($), backticks (`), backslashes (\), or quotation marks will be preceded by a backslash (this allows the shell to correctly parse it as a single string, regardless of the characters it contains). For backwards compatibility, the first token will be the repository subdirectory.  The rest of the tokens will be comma-delimited lists of the information requested in the format string.  For example, if /u/src/master/yoyodyne/tc is the repository, %{sVv} is the format string, and three files (ChangeLog, Makefile, foo.c) were modified, the output might be:

     "yoyodyne/tc ChangeLog,1.1,1.2 Makefile,1.3,1.4 foo.c,1.12,1.13"

As another example, %{} means that only the name of the repository will be generated.

Note: when CVS is accessing a remote repository, loginfo will be run on the remote (i.e., server) side, not the client side (see Repositórios remotos).

Loginfo example
...............

The following loginfo file, together with the tiny shell-script below, appends all log messages to the file $CVSROOT/CVSROOT/commitlog, and any commits to the administrative files (inside the CVSROOT directory) are also logged in /usr/adm/cvsroot-log. Commits to the prog1 directory are mailed to ceder.

     ALL             /usr/local/bin/cvs-log $CVSROOT/CVSROOT/commitlog $USER
     ^CVSROOT        /usr/local/bin/cvs-log /usr/adm/cvsroot-log
     ^prog1          Mail -s %s ceder

The shell-script /usr/local/bin/cvs-log looks like this:

     #!/bin/sh
     (echo "------------------------------------------------------";
      echo -n $2"  ";
      date;
      echo;
      cat) >> $1

Keeping a checked out copy
..........................

It is often useful to maintain a directory tree which contains files which correspond to the latest version in the repository.  For example, other developers might want to refer to the latest sources without having to check them out, or you might be maintaining a web site with CVS and want every checkin to cause the files used by the web server to be updated.

The way to do this is by having loginfo invoke cvs update.  Doing so in the naive way will cause a problem with locks, so the cvs update must be run in the background. Here is an example for unix (this should all be on one line):

     ^cyclic-pages		(date; cat; (sleep 2; cd /u/www/local-docs;
      cvs -q update -d) &) >> $CVSROOT/CVSROOT/updatelog 2>&1

This will cause checkins to repository directories starting with cyclic-pages to update the checked out tree in /u/www/local-docs.

Rcsinfo
=======

The rcsinfo file can be used to specify a form to edit when filling out the commit log.  The rcsinfo file has a syntax similar to the verifymsg, commitinfo and loginfo files.  See syntax.  Unlike the other files the second part is not a command-line template.  Instead, the part after the regular expression should be a full pathname to a file containing the log message template.

If the repository name does not match any of the regular expressions in this file, the DEFAULT line is used, if it is specified.

All occurrences of the name ALL appearing as a regular expression are used in addition to the first matching regular expression or DEFAULT.

The log message template will be used as a default log message.  If you specify a log message with cvs commit -m MESSAGE or cvs commit -f FILE that log message will override the template.

See verifymsg, for an example rcsinfo file.

When CVS is accessing a remote repository, the contents of rcsinfo at the time a directory is first checked out will specify a template. This template will be updated on all cvs update commands. It will also be added to new directories added with a cvs add new-directry command. In versions of CVS prior to version 1.12, the CVS/Template file was not updated. If the CVS server is at version 1.12 or higher an older client may be used and the CVS/Template will be updated from the server.

Taginfo
=======

The taginfo file defines programs to execute when someone executes a tag or rtag command.  The taginfo file has the standard form for administrative files (see syntax), where each line is a regular expression followed by a command to execute.  The arguments passed to the command are, in order, the TAGNAME, OPERATION (add for tag, mov for tag -F, and del for tag -d), REPOSITORY, and any remaining are pairs of FILENAME REVISION.  A non-zero exit of the filter program will cause the tag to be aborted.

Here is an example of using the taginfo file to log tag and rtag commands.  In the taginfo file put:

     ALL /usr/local/cvsroot/CVSROOT/loggit

Where /usr/local/cvsroot/CVSROOT/loggit contains the following script:

     #!/bin/sh
     echo "$@" >>/home/kingdon/cvsroot/CVSROOT/taglog

Ignoring files via cvsignore
============================

There are certain file names that frequently occur inside your working copy, but that you don't want to put under CVS control.  Examples are all the object files that you get while you compile your sources. Normally, when you run cvs update, it prints a line for each file it encounters that it doesn't know about (see update output).

CVS has a list of files (or sh(1) file name patterns) that it should ignore while running update, import and release. This list is constructed in the following way.

  * The list is initialized to include certain file name patterns: names associated with CVS administration, or with other common source control systems; common names for patch files, object files, archive files, and editor backup files; and other names that are usually artifacts of assorted utilities. Currently, the default list of ignored file name patterns is:

              RCS     SCCS    CVS     CVS.adm
              RCSLOG  cvslog.*
              tags    TAGS
              .make.state     .nse_depinfo
              *~      #*      .#*     ,*      _$*     *$
              *.old   *.bak   *.BAK   *.orig  *.rej   .del-*
              *.a     *.olb   *.o     *.obj   *.so    *.exe
              *.Z     *.elc   *.ln
              core

  * The per-repository list in $CVSROOT/CVSROOT/cvsignore is appended to the list, if that file exists.

  * The per-user list in .cvsignore in your home directory is appended to the list, if it exists.

  * Any entries in the environment variable $CVSIGNORE is appended to the list.

  * Any -I options given to CVS is appended.

  * As CVS traverses through your directories, the contents of any .cvsignore will be appended to the list. The patterns found in .cvsignore are only valid for the directory that contains them, not for any sub-directories.

In any of the 5 places listed above, a single exclamation mark (!) clears the ignore list. This can be used if you want to store any file which normally is ignored by CVS.

Specifying -I ! to cvs import will import everything, which is generally what you want to do if you are importing files from a pristine distribution or any other source which is known to not contain any extraneous files.  However, looking at the rules above you will see there is a fly in the ointment; if the distribution contains any .cvsignore files, then the patterns from those files will be processed even if -I ! is specified.  The only workaround is to remove the .cvsignore files in order to do the import.  Because this is awkward, in the future -I ! might be modified to override .cvsignore files in each directory.

Note that the syntax of the ignore files consists of a series of lines, each of which contains a space separated list of filenames.  This offers no clean way to specify filenames which contain spaces, but you can use a workaround like foo?bar to match a file named foo bar (it also matches fooxbar and the like).  Also note that there is currently no way to specify comments.

The checkoutlist file
=====================

It may be helpful to use CVS to maintain your own files in the CVSROOT directory.  For example, suppose that you have a script logcommit.pl which you run by including the following line in the commitinfo administrative file:

     ALL   $CVSROOT/CVSROOT/logcommit.pl

To maintain logcommit.pl with CVS you would add the following line to the checkoutlist administrative file:

     logcommit.pl

The format of checkoutlist is one line for each file that you want to maintain using CVS, giving the name of the file, followed optionally by more whitespace and any error message that should print if the file cannot be checked out into CVSROOT after a commit:

     logcommit.pl	Could not update CVSROOT/logcommit.pl.

After setting up checkoutlist in this fashion, the files listed there will function just like CVS's built-in administrative files.  For example, when checking in one of the files you should get a message such as:

     cvs commit: Rebuilding administrative file database

and the checked out copy in the CVSROOT directory should be updated.

Note that listing passwd (see Servidor de autenticação por senha) in checkoutlist is not recommended for security reasons.

For information about keeping a checkout out copy in a more general context than the one provided by checkoutlist, see Keeping a checked out copy.

O arquivo history (histórico)
=============================

The file $CVSROOT/CVSROOT/history is used to log information for the history command (see history).  This file must be created to turn on logging.  This is done automatically if the cvs init command is used to set up the repository (see Criando um repositório).

The file format of the history file is documented only in comments in the CVS source code, but generally programs should use the cvs history command to access it anyway, in case the format changes with future releases of CVS.

Expansions in administrative files
==================================

Sometimes in writing an administrative file, you might want the file to be able to know various things based on environment CVS is running in.  There are several mechanisms to do that.

To find the home directory of the user running CVS (from the HOME environment variable), use ~ followed by / or the end of the line. Likewise for the home directory of USER, use ~USER.  These variables are expanded on the server machine, and don't get any reasonable expansion if pserver (see Autenticação por senha) is in use; therefore user variables (see below) may be a better choice to customize behavior based on the user running CVS.

One may want to know about various pieces of information internal to CVS.  A CVS internal variable has the syntax ${VARIABLE}, where VARIABLE starts with a letter and consists of alphanumeric characters and _.  If the character following VARIABLE is a non-alphanumeric character other than _, the { and } can be omitted.  The CVS internal variables are:

CVSROOT
     This is the absolute path to the current CVS root directory. See Repositório, for a description of the various ways to specify this, but note that the internal variable contains just the directory and not any of the access method information.

RCSBIN
     In CVS 1.9.18 and older, this specified the directory where CVS was looking for RCS programs.  Because CVS no longer runs RCS programs, specifying this internal variable is now an error.

CVSEDITOR
EDITOR
VISUAL
     These all expand to the same value, which is the editor that CVS is using.  See Opções globais, for how to specify this.

USER
     Username of the user running CVS (on the CVS server machine). When using pserver, this is the user specified in the repository specification which need not be the same as the username the server is running as (see Servidor de autenticação por senha). Do not confuse this with the environment variable of the same name.

If you want to pass a value to the administrative files which the user who is running CVS can specify, use a user variable. To expand a user variable, the administrative file contains ${=VARIABLE}.  To set a user variable, specify the global option -s to CVS, with argument VARIABLE=VALUE.  It may be particularly useful to specify this option via .cvsrc (see ~/.cvsrc).

For example, if you want the administrative file to refer to a test directory you might create a user variable TESTDIR.  Then if CVS is invoked as

     cvs -s TESTDIR=/work/local/tests

and the administrative file contains sh ${=TESTDIR}/runtests, then that string is expanded to sh /work/local/tests/runtests.

All other strings containing $ are reserved; there is no way to quote a $ character so that $ represents itself.

Environment variables passed to administrative files are:

CVS_USER
     The CVS-specific username provided by the user, if it can be provided (currently just for the pserver access method), and to the empty string otherwise.  (CVS_USER and USER may differ when $CVSROOT/CVSROOT/passwd is used to map CVS usernames to system usernames.)

LOGNAME
     The username of the system user.

USER
     Same as LOGNAME. Do not confuse this with the internal variable of the same name.

The CVSROOT/config configuration file
=====================================

The administrative file config contains various miscellaneous settings which affect the behavior of CVS.  The syntax is slightly different from the other administrative files.  Variables are not expanded.  Lines which start with # are considered comments. Other lines consist of a keyword, =, and a value.  Note that this syntax is very strict. Extraneous spaces or tabs are not permitted.

Currently defined keywords are:

RCSBIN=BINDIR
     For CVS 1.9.12 through 1.9.18, this setting told CVS to look for RCS programs in the BINDIR directory.  Current versions of CVS do not run RCS programs; for compatibility this setting is accepted, but it does nothing.

SystemAuth=VALUE
     If VALUE is yes, then pserver should check for users in the system's user database if not found in CVSROOT/passwd.  If it is no, then all pserver users must exist in CVSROOT/passwd. The default is yes.  For more on pserver, see Autenticação por senha.

TopLevelAdmin=VALUE
     Modify the checkout command to create a CVS directory at the top level of the new working directory, in addition to CVS directories created within checked-out directories. The default value is no.

     This option is useful if you find yourself performing many commands at the top level of your working directory, rather than in one of the checked out subdirectories.  The CVS directory created there will mean you don't have to specify CVSROOT for each command.  It also provides a place for the CVS/Template file (see Armazenamento do Diretório de trabalho).

LockDir=DIRECTORY
     Put CVS lock files in DIRECTORY rather than directly in the repository.  This is useful if you want to let users read from the repository while giving them write access only to DIRECTORY, not to the repository. It can also be used to put the locks on a very fast in-memory file system to speed up locking and unlocking the repository. You need to create DIRECTORY, but CVS will create subdirectories of DIRECTORY as it needs them.  For information on CVS locks, see Concorrência.

     Before enabling the LockDir option, make sure that you have tracked down and removed any copies of CVS 1.9 or older.  Such versions neither support LockDir, nor will give an error indicating that they don't support it. The result, if this is allowed to happen, is that some CVS users will put the locks one place, and others will put them another place, and therefore the repository could become corrupted.  CVS 1.10 does not support LockDir but it will print a warning if run on a repository with LockDir enabled.

LogHistory=VALUE
     Control what is logged to the CVSROOT/history file (see history). Default of TOEFWUPCGMAR (or simply all) will log all transactions.  Any subset of the default is legal.  (For example, to only log transactions that modify the *,v files, use LogHistory=TMAR.)

RereadLogAfterVerify=VALUE
     Modify the commit command such that CVS will reread the log message after running the program specified by verifymsg. VALUE may be one of yes or always, indicating that the log message should always be reread; no or never, indicating that it should never be reread; or VALUE may be stat, indicating that the file should be checked with the filesystem stat() function to see if it has changed (see warning below) before rereading.  The default value is always.

     Note: the `stat' mode can cause CVS to pause for up to one extra second per directory committed.  This can be less IO and CPU intensive but is not recommended for use with large repositories

     See verifymsg, for more information on how verifymsg may be used.

UserAdminOptions=VALUE
     Control what options will be allowed with the cvs admin command (see admin) for users not in the cvsadmin group. The VALUE string is a list of single character options which should be allowed.  If a user who is not a member of the cvsadmin group tries to execute any cvs admin option which is not listed they will will receive an error message reporting that the option is restricted.

     If no cvsadmin group exists on the server, CVS will ignore the UserAdminOptions keyword (see admin).

     When not specified, UserAdminOptions defaults to k.  In other words, it defaults to allowing users outside of the cvsadmin group to use the cvs admin command only to change the default keyword expansion mode for files.

     As an example, to restrict users not in the cvsadmin group to using cvs admin to change the default keyword substitution mode, lock revisions, unlock revisions, and replace the log message, use UserAdminOptions=klum.

Todas as variáveis de ambiente que afetam o CVS
***********************************************

This is a complete list of all environment variables that affect CVS.

$CVSIGNORE
     A whitespace-separated list of file name patterns that CVS should ignore. See cvsignore.

$CVSWRAPPERS
     A whitespace-separated list of file name patterns that CVS should treat as wrappers. See Wrappers.

$CVSREAD
     If this is set, checkout and update will try hard to make the files in your working directory read-only.  When this is not set, the default behavior is to permit modification of your working files.

$CVSREADONLYFS
     Turns on read-only repository mode. This allows one to check out from a read-only repository, such as within an anoncvs server, or from a CDROM repository.

     It has the same effect as if the -R command-line option is used. This can also allow the use of read-only NFS repositories.

$CVSUMASK
     Controls permissions of files in the repository.  See Permissões de arquivos.

$CVSROOT
     Should contain the full pathname to the root of the CVS source repository (where the RCS files are kept).  This information must be available to CVS for most commands to execute; if $CVSROOT is not set, or if you wish to override it for one invocation, you can supply it on the command line: cvs -d cvsroot cvs_command... Once you have checked out a working directory, CVS stores the appropriate root (in the file CVS/Root), so normally you only need to worry about this when initially checking out a working directory.

$CVSEDITOR
$EDITOR
$VISUAL
     Specifies the program to use for recording log messages during commit.  $CVSEDITOR overrides $EDITOR, which overrides $VISUAL. See Efetivando suas alterações for more or Opções globais for alternative ways of specifying a log editor.

$PATH
     If $RCSBIN is not set, and no path is compiled into CVS, it will use $PATH to try to find all programs it uses.

$HOME

$HOMEPATH

$HOMEDRIVE
     Used to locate the directory where the .cvsrc file, and other such files, are searched.  On Unix, CVS just checks for HOME.  On Windows NT, the system will set HOMEDRIVE, for example to d: and HOMEPATH, for example to \joe.  On Windows 95, you'll probably need to set HOMEDRIVE and HOMEPATH yourself.

$CVS_RSH
     Specifies the external program which CVS connects with, when :ext: access method is specified. see Se conectando via rsh.

$CVS_SERVER
     Used in client-server mode when accessing a remote repository using RSH.  It specifies the name of the program to start on the server side (and any necessary arguments) when accessing a remote repository using the :ext:, :fork:, or :server: access methods. The default value for :ext: and :server: is cvs; the default value for :fork: is the name used to run the client. see Se conectando via rsh

$CVS_PASSFILE
     Used in client-server mode when accessing the cvs login server.  Default value is $HOME/.cvspass. see Cliente de autenticação por senha

$CVS_CLIENT_PORT
     Used in client-server mode to set the port to use when accessing the server via Kerberos, GSSAPI, or CVS's password authentication protocol if the port is not specified in the CVSROOT. see Repositórios remotos

$CVS_RCMD_PORT
     Used in client-server mode.  If set, specifies the port number to be used when accessing the RCMD demon on the server side. (Currently not used for Unix clients).

$CVS_CLIENT_LOG
     Used for debugging only in client-server mode.  If set, everything sent to the server is logged into $CVS_CLIENT_LOG.in and everything sent from the server is logged into $CVS_CLIENT_LOG.out.

$CVS_SERVER_SLEEP
     Used only for debugging the server side in client-server mode.  If set, delays the start of the server child process the specified amount of seconds so that you can attach to it with a debugger.

$CVS_IGNORE_REMOTE_ROOT
     For CVS 1.10 and older, setting this variable prevents CVS from overwriting the CVS/Root file when the -d global option is specified. Later versions of CVS do not rewrite CVS/Root, so CVS_IGNORE_REMOTE_ROOT has no effect.

$CVS_LOCAL_BRANCH_NUM
     Setting this variable allows some control over the branch number that is assigned. This is specifically to support the local commit feature of CVSup. If one sets CVS_LOCAL_BRANCH_NUM to (say) 1000 then branches the local repository, the revision numbers will look like 1.66.1000.xx. There is almost a dead-set certainty that there will be no conflicts with version numbers.

$COMSPEC
     Used under OS/2 only.  It specifies the name of the command interpreter and defaults to CMD.EXE.

$TMPDIR
$TMP
$TEMP
     Directory in which temporary files are located. The CVS server uses TMPDIR.  See Opções globais, for a description of how to specify this. Some parts of CVS will always use /tmp (via the tmpnam function provided by the system).

     On Windows NT, TMP is used (via the _tempnam function provided by the system).

     The patch program which is used by the CVS client uses TMPDIR, and if it is not set, uses /tmp (at least with GNU patch 2.1).  Note that if your server and client are both running CVS 1.9.10 or later, CVS will not invoke an external patch program.

$CVS_PID
     This is the process identification (aka pid) number of the CVS process. It is often useful in the programs and/or scripts specified by the commitinfo, verifymsg, loginfo files.

Compatibility between CVS Versions
**********************************

The repository format is compatible going back to CVS 1.3.  But see Compatibilidade de ???Watches???, if you have copies of CVS 1.6 or older and you want to use the optional developer communication features.

The working directory format is compatible going back to CVS 1.5.  It did change between CVS 1.3 and CVS 1.5.  If you run CVS 1.5 or newer on a working directory checked out with CVS 1.3, CVS will convert it, but to go back to CVS 1.3 you need to check out a new working directory with CVS 1.3.

The remote protocol is interoperable going back to CVS 1.5, but no further (1.5 was the first official release with the remote protocol, but some older versions might still be floating around).  In many cases you need to upgrade both the client and the server to take advantage of new features and bugfixes, however.

Resolução de problemas
**********************

If you are having trouble with CVS, this appendix may help.  If there is a particular error message which you are seeing, then you can look up the message alphabetically.  If not, you can look through the section on other problems to see if your problem is mentioned there.

Partial list of error messages
==============================

Here is a partial list of error messages that you may see from CVS.  It is not a complete list---CVS is capable of printing many, many error messages, often with parts of them supplied by the operating system, but the intention is to list the common and/or potentially confusing error messages.

The messages are alphabetical, but introductory text such as cvs update:  is not considered in ordering them.

In some cases the list includes messages printed by old versions of CVS (partly because users may not be sure which version of CVS they are using at any particular moment).

FILE:LINE: Assertion 'TEXT' failed
     The exact format of this message may vary depending on your system.  It indicates a bug in CVS, which can be handled as described in Paus.

cvs COMMAND: authorization failed: server HOST rejected access
     This is a generic response when trying to connect to a pserver server which chooses not to provide a specific reason for denying authorization.  Check that the username and password specified are correct and that the CVSROOT specified is allowed by --allow-root in inetd.conf.  See Autenticação por senha.

cvs COMMAND: conflict: removed FILE was modified by second party
     This message indicates that you removed a file, and someone else modified it.  To resolve the conflict, first run cvs add FILE.  If desired, look at the other party's modification to decide whether you still want to remove it.  If you don't want to remove it, stop here.  If you do want to remove it, proceed with cvs remove FILE and commit your removal.

cannot change permissions on temporary directory

          Operation not permitted

     This message has been happening in a non-reproducible, occasional way when we run the client/server testsuite, both on Red Hat Linux 3.0.3 and 4.1.  We haven't been able to figure out what causes it, nor is it known whether it is specific to linux (or even to this particular machine!).  If the problem does occur on other unices, Operation not permitted would be likely to read Not owner or whatever the system in question uses for the unix EPERM error.  If you have any information to add, please let us know as described in Paus.  If you experience this error while using CVS, retrying the operation which produced it should work fine.

cvs [server aborted]: Cannot check out files into the repository itself
     The obvious cause for this message (especially for non-client/server CVS) is that the CVS root is, for example, /usr/local/cvsroot and you try to check out files when you are in a subdirectory, such as /usr/local/cvsroot/test.  However, there is a more subtle cause, which is that the temporary directory on the server is set to a subdirectory of the root (which is also not allowed).  If this is the problem, set the temporary directory to somewhere else, for example /var/tmp; see TMPDIR in Variáveis de ambiente, for how to set the temporary directory.

cannot commit files as 'root'
     See 'root' is not allowed to commit files.

cannot open CVS/Entries for reading: No such file or directory
     This generally indicates a CVS internal error, and can be handled as with other CVS bugs (see Paus).  Usually there is a workaround---the exact nature of which would depend on the situation but which hopefully could be figured out.

cvs [init aborted]: cannot open CVS/Root: No such file or directory
     This message is harmless.  Provided it is not accompanied by other errors, the operation has completed successfully.  This message should not occur with current versions of CVS, but it is documented here for the benefit of CVS 1.9 and older.

cvs server: cannot open /root/.cvsignore: Permission denied
cvs [server aborted]: can't chdir(/root): Permission denied
     See Conexão.

cvs [checkout aborted]: cannot rename file FILE to CVS/,,FILE: Invalid argument
     This message has been reported as intermittently happening with CVS 1.9 on Solaris 2.5.  The cause is unknown; if you know more about what causes it, let us know as described in Paus.

cvs [COMMAND aborted]: cannot start server via rcmd
     This, unfortunately, is a rather nonspecific error message which CVS 1.9 will print if you are running the CVS client and it is having trouble connecting to the server.  Current versions of CVS should print a much more specific error message.  If you get this message when you didn't mean to run the client at all, you probably forgot to specify :local:, as described in Repositório.

ci: FILE,v: bad diff output line: Binary files - and /tmp/T2a22651 differ
     CVS 1.9 and older will print this message when trying to check in a binary file if RCS is not correctly installed.  Re-read the instructions that came with your RCS distribution and the INSTALL file in the CVS distribution.  Alternately, upgrade to a current version of CVS, which checks in files itself rather than via RCS.

cvs checkout: could not check out FILE
     With CVS 1.9, this can mean that the co program (part of RCS) returned a failure.  It should be preceded by another error message, however it has been observed without another error message and the cause is not well-understood.  With the current version of CVS, which does not run co, if this message occurs without another error message, it is definitely a CVS bug (see Paus).

cvs [login aborted]: could not find out home directory
     This means that you need to set the environment variables that CVS uses to locate your home directory. See the discussion of HOME, HOMEDRIVE, and HOMEPATH in Variáveis de ambiente.

cvs update: could not merge revision REV of FILE: No such file or directory
     CVS 1.9 and older will print this message if there was a problem finding the rcsmerge program.  Make sure that it is in your PATH, or upgrade to a current version of CVS, which does not require an external rcsmerge program.

cvs [update aborted]: could not patch FILE: No such file or directory
     This means that there was a problem finding the patch program.  Make sure that it is in your PATH.  Note that despite appearances the message is not referring to whether it can find FILE. If both the client and the server are running a current version of CVS, then there is no need for an external patch program and you should not see this message.  But if either client or server is running CVS 1.9, then you need patch.

cvs update: could not patch FILE; will refetch
     This means that for whatever reason the client was unable to apply a patch that the server sent.  The message is nothing to be concerned about, because inability to apply the patch only slows things down and has no effect on what CVS does.

dying gasps from SERVER unexpected
     There is a known bug in the server for CVS 1.9.18 and older which can cause this.  For me, this was reproducible if I used the -t global option.  It was fixed by Andy Piper's 14 Nov 1997 change to src/filesubr.c, if anyone is curious. If you see the message, you probably can just retry the operation which failed, or if you have discovered information concerning its cause, please let us know as described in Paus.

end of file from server (consult above messages if any)
     The most common cause for this message is if you are using an external rsh program and it exited with an error.  In this case the rsh program should have printed a message, which will appear before the above message.  For more information on setting up a CVS client and server, see Repositórios remotos.

cvs [update aborted]: EOF in key in RCS file FILE,v
cvs [checkout aborted]: EOF while looking for end of string in RCS file FILE,v
     This means that there is a syntax error in the given RCS file.  Note that this might be true even if RCS can read the file OK; CVS does more error checking of errors in the RCS file.  That is why you may see this message when upgrading from CVS 1.9 to CVS 1.10.  The likely cause for the original corruption is hardware, the operating system, or the like.  Of course, if you find a case in which CVS seems to corrupting the file, by all means report it, (see Paus). There are quite a few variations of this error message, depending on exactly where in the RCS file CVS finds the syntax error.

cvs commit: Executing 'mkmodules'
     This means that your repository is set up for a version of CVS prior to CVS 1.8.  When using CVS 1.8 or later, the above message will be preceded by

          cvs commit: Rebuilding administrative file database

     If you see both messages, the database is being rebuilt twice, which is unnecessary but harmless.  If you wish to avoid the duplication, and you have no versions of CVS 1.7 or earlier in use, remove -i mkmodules every place it appears in your modules file.  For more information on the modules file, see modules.

missing author
     Typically this can happen if you created an RCS file with your username set to empty.  CVS will, bogusly, create an illegal RCS file with no value for the author field.  The solution is to make sure your username is set to a non-empty value and re-create the RCS file.

cvs [checkout aborted]: no such tag TAG
     This message means that CVS isn't familiar with the tag TAG.  Usually this means that you have mistyped a tag name; however there are (relatively obscure) cases in which CVS will require you to try a few other CVS commands involving that tag, before you find one which will cause CVS to update the val-tags file; see discussion of val-tags in Permissões de arquivos.  You only need to worry about this once for a given tag; when a tag is listed in val-tags, it stays there.  Note that using -f to not require tag matches does not override this check; see Opções comuns.

*PANIC* administration files missing
     This typically means that there is a directory named CVS but it does not contain the administrative files which CVS puts in a CVS directory.  If the problem is that you created a CVS directory via some mechanism other than CVS, then the answer is simple, use a name other than CVS.  If not, it indicates a CVS bug (see Paus).

rcs error: Unknown option: -x,v/
     This message will be followed by a usage message for RCS.  It means that you have an old version of RCS (probably supplied with your operating system), as well as an old version of CVS. CVS 1.9.18 and earlier only work with RCS version 5 and later; current versions of CVS do not run RCS programs.

cvs [server aborted]: received broken pipe signal
     This message seems to be caused by a hard-to-track-down bug in CVS or the systems it runs on (we don't know---we haven't tracked it down yet!).  It seems to happen only after a CVS command has completed, and you should be able to just ignore the message. However, if you have discovered information concerning its cause, please let us know as described in Paus.

'root' is not allowed to commit files
     When committing a permanent change, CVS makes a log entry of who committed the change.  If you are committing the change logged in as "root" (not under "su" or other root-priv giving program), CVS cannot determine who is actually making the change. As such, by default, CVS disallows changes to be committed by users logged in as "root".  (You can disable this option by passing the --enable-rootcommit option to configure and recompiling CVS. On some systems this means editing the appropriate config.h file before building CVS.)

Too many arguments!
     This message is typically printed by the log.pl script which is in the contrib directory in the CVS source distribution.  In some versions of CVS, log.pl has been part of the default CVS installation.  The log.pl script gets called from the loginfo administrative file. Check that the arguments passed in loginfo match what your version of log.pl expects.  In particular, the log.pl from CVS 1.3 and older expects the logfile as an argument whereas the log.pl from CVS 1.5 and newer expects the logfile to be specified with a -f option.  Of course, if you don't need log.pl you can just comment it out of loginfo.

cvs [update aborted]: unexpected EOF reading FILE,v
     See EOF in key in RCS file.

cvs [login aborted]: unrecognized auth response from SERVER
     This message typically means that the server is not set up properly.  For example, if inetd.conf points to a nonexistent cvs executable.  To debug it further, find the log file which inetd writes (/var/log/messages or whatever inetd uses on your system).  For details, see Conexão, and Servidor de autenticação por senha.

cvs commit: Up-to-date check failed for `FILE'
     This means that someone else has committed a change to that file since the last time that you did a cvs update.  So before proceeding with your cvs commit you need to cvs update.  CVS will merge the changes that you made and the changes that the other person made.  If it does not detect any conflicts it will report M FILE and you are ready to cvs commit.  If it detects conflicts it will print a message saying so, will report C FILE, and you need to manually resolve the conflict.  For more details on this process see Exemplo de conflitos.

Usage:	diff3 [-exEX3 [-i | -m] [-L label1 -L label3]] file1 file2 file3

          Only one of [exEX3] allowed

     This indicates a problem with the installation of diff3 and rcsmerge.  Specifically rcsmerge was compiled to look for GNU diff3, but it is finding unix diff3 instead.  The exact text of the message will vary depending on the system.  The simplest solution is to upgrade to a current version of CVS, which does not rely on external rcsmerge or diff3 programs.

warning: unrecognized response `TEXT' from cvs server
     If TEXT contains a valid response (such as ok) followed by an extra carriage return character (on many systems this will cause the second part of the message to overwrite the first part), then it probably means that you are using the :ext: access method with a version of rsh, such as most non-unix rsh versions, which does not by default provide a transparent data stream.  In such cases you probably want to try :server: instead of :ext:.  If TEXT is something else, this may signify a problem with your CVS server. Double-check your installation against the instructions for setting up the CVS server.

cvs commit: [TIME] waiting for USER's lock in DIRECTORY
     This is a normal message, not an error.  See Concorrência, for more details.

cvs commit: warning: editor session failed
     This means that the editor which CVS is using exits with a nonzero exit status.  Some versions of vi will do this even when there was not a problem editing the file.  If so, point the CVSEDITOR environment variable to a small script such as:

          #!/bin/sh
          vi $*
          exit 0

Trouble making a connection to a CVS server
===========================================

This section concerns what to do if you are having trouble making a connection to a CVS server.  If you are running the CVS command line client running on Windows, first upgrade the client to CVS 1.9.12 or later.  The error reporting in earlier versions provided much less information about what the problem was.  If the client is non-Windows, CVS 1.9 should be fine.

If the error messages are not sufficient to track down the problem, the next steps depend largely on which access method you are using.

:ext:
     Try running the rsh program from the command line.  For example: "rsh servername cvs -v" should print CVS version information.  If this doesn't work, you need to fix it before you can worry about CVS problems.

:server:
     You don't need a command line rsh program to use this access method, but if you have an rsh program around, it may be useful as a debugging tool.  Follow the directions given for :ext:.

:pserver:
     Errors along the lines of "connection refused" typically indicate that inetd isn't even listening for connections on port 2401 whereas errors like "connection reset by peer", "received broken pipe signal", "recv() from server: EOF", or "end of file from server" typically indicate that inetd is listening for connections but is unable to start CVS (this is frequently caused by having an incorrect path in inetd.conf or by firewall software rejecting the connection). "unrecognized auth response" errors are caused by a bad command line in inetd.conf, typically an invalid option or forgetting to put the pserver command at the end of the line. Another less common problem is invisible control characters that your editor "helpfully" added without you noticing.

     One good debugging tool is to "telnet servername 2401".  After connecting, send any text (for example "foo" followed by return).  If CVS is working correctly, it will respond with

          cvs [pserver aborted]: bad auth protocol start: foo

     If instead you get:

          Usage: cvs [cvs-options] command [command-options-and-arguments]
          ...

     then you're missing the pserver command at the end of the line in inetd.conf; check to make sure that the entire command is on one line and that it's complete.

     Likewise, if you get something like:

          Unknown command: `pserved'

          CVS commands are:
                  add          Add a new file/directory to the repository
          ...

     then you've misspelled pserver in some way.  If it isn't obvious, check for invisible control characters (particularly carriage returns) in inetd.conf.

     If it fails to work at all, then make sure inetd is working right.  Change the invocation in inetd.conf to run the echo program instead of cvs.  For example:

          2401  stream  tcp  nowait  root /bin/echo echo hello

     After making that change and instructing inetd to re-read its configuration file, "telnet servername 2401" should show you the text hello and then the server should close the connection.  If this doesn't work, you need to fix it before you can worry about CVS problems.

     On AIX systems, the system will often have its own program trying to use port 2401.  This is AIX's problem in the sense that port 2401 is registered for use with CVS.  I hear that there is an AIX patch available to address this problem.

     Another good debugging tool is the -d (debugging) option to inetd.  Consult your system documentation for more information.

     If you seem to be connecting but get errors like:

          cvs server: cannot open /root/.cvsignore: Permission denied
          cvs [server aborted]: can't chdir(/root): Permission denied

     then you probably haven't specified -f in inetd.conf. (In releases prior to CVS 1.11.1, this problem can be caused by your system setting the $HOME environment variable for programs being run by inetd.  In this case, you can either have inetd run a shell script that unsets $HOME and then runs CVS, or you can use env to run CVS with a pristine environment.)

     If you can connect successfully for a while but then can't, you've probably hit inetd's rate limit. (If inetd receives too many requests for the same service in a short period of time, it assumes that something is wrong and temporarily disables the service.) Check your inetd documentation to find out how to adjust the rate limit (some versions of inetd have a single rate limit, others allow you to set the limit for each service separately.)

Other common problems
=====================

Here is a list of problems which do not fit into the above categories.  They are in no particular order.

  * On Windows, if there is a 30 second or so delay when you run a CVS command, it may mean that you have your home directory set to C:/, for example (see HOMEDRIVE and HOMEPATH in Variáveis de ambiente).  CVS expects the home directory to not end in a slash, for example C: or C:\cvs.

  * If you are running CVS 1.9.18 or older, and cvs update finds a conflict and tries to merge, as described in Exemplo de conflitos, but doesn't tell you there were conflicts, then you may have an old version of RCS.  The easiest solution probably is to upgrade to a current version of CVS, which does not rely on external RCS programs.

Créditos
********

Roland Pesch, then of Cygnus Support <roland@wrs.com> wrote the manual pages which were distributed with CVS 1.3.  Much of their text was copied into this manual.  He also read an early draft of this manual and contributed many ideas and corrections.

The mailing-list info-cvs is sometimes informative. I have included information from postings made by the following persons: David G. Grubbs <dgg@think.com>.

Some text has been extracted from the man pages for RCS.

The CVS FAQ by David G. Grubbs has provided useful material.  The FAQ is no longer maintained, however, and this manual is about the closest thing there is to a successor (with respect to documenting how to use CVS, at least).

In addition, the following persons have helped by telling me about mistakes I've made:

     Roxanne Brunskill <rbrunski@datap.ca>,
     Kathy Dyer <dyer@phoenix.ocf.llnl.gov>,
     Karl Pingle <pingle@acuson.com>,
     Thomas A Peterson <tap@src.honeywell.com>,
     Inge Wallin <ingwa@signum.se>,
     Dirk Koschuetzki <koschuet@fmi.uni-passau.de>
     and Michael Brown <brown@wi.extrel.com>.

The list of contributors here is not comprehensive; for a more complete list of who has contributed to this manual see the file doc/ChangeLog in the CVS source distribution.

Dealing with bugs in CVS or this manual
***************************************

Neither CVS nor this manual is perfect, and they probably never will be.  If you are having trouble using CVS, or think you have found a bug, there are a number of things you can do about it.  Note that if the manual is unclear, that can be considered a bug in the manual, so these problems are often worth doing something about as well as problems with CVS itself.

  * If you want someone to help you and fix bugs that you report, there are companies which will do that for a fee.  One such company is:

          Ximbiot
          319 S. River St.
          Harrisburg, PA  17104-1657
          USA
          Email: info@ximbiot.com
          Phone: (717) 579-6168
          Fax:   (717) 234-3125
          http://ximbiot.com/

  * If you got CVS through a distributor, such as an operating system vendor or a vendor of freeware CD-ROMs, you may wish to see whether the distributor provides support.  Often, they will provide no support or minimal support, but this may vary from distributor to distributor.

  * If you have the skills and time to do so, you may wish to fix the bug yourself.  If you wish to submit your fix for inclusion in future releases of CVS, see the file HACKING in the CVS source distribution.  It contains much more information on the process of submitting fixes.

  * There may be resources on the net which can help.  Two good places to start are:

          http://cvs.nongnu.org/

     If you are so inspired, increasing the information available on the net is likely to be appreciated.  For example, before the standard CVS distribution worked on Windows 95, there was a web page with some explanation and patches for running CVS on Windows 95, and various people helped out by mentioning this page on mailing lists or newsgroups when the subject came up.

  * It is also possible to report bugs to bug-cvs@nongnu.org. Note that someone may or may not want to do anything with your bug report---if you need a solution consider one of the options mentioned above.  People probably do want to hear about bugs which are particularly severe in consequences and/or easy to fix, however.  You can also increase your odds by being as clear as possible about the exact nature of the bug and any other relevant information.  The way to report bugs is to send email to bug-cvs@nongnu.org.  Note that submissions to bug-cvs@nongnu.org may be distributed under the terms of the GNU Public License, so if you don't like this, don't submit them.  There is usually no justification for sending mail directly to one of the CVS maintainers rather than to bug-cvs@nongnu.org; those maintainers who want to hear about such bug reports read bug-cvs@nongnu.org.  Also note that sending a bug report to other mailing lists or newsgroups is not a substitute for sending it to bug-cvs@nongnu.org.  It is fine to discuss CVS bugs on whatever forum you prefer, but there are not necessarily any maintainers reading bug reports sent anywhere except bug-cvs@nongnu.org.

People often ask if there is a list of known bugs or whether a particular bug is a known one.  The file BUGS in the CVS source distribution is one list of known bugs, but it doesn't necessarily try to be comprehensive.  Perhaps there will never be a comprehensive, detailed list of known bugs.