Propriedades

Nós já abordamos em detalhes como o Subversion armazena e recupera várias versões de arquivos e diretórios em seu repositório. Capítulos inteiros têm sido focados nesta parte mais fundamental das funcionalidades providas pela ferramenta. E se o suporte a versionamento parar por aí, o Subversion ainda seria completo do ponto de vista do controle de versão.

Mas não pára por aí.

Adicionalmente ao versionamento de seus arquivos e diretórios, o Subversion permite interfaces para adição, modificação e remoção de metadados versionados em cada um de seus arquivos e diretórios sob controle de versão. Chamamos estes metadados de propriedades, e eles podem ser entendidos como tabelas de duas colunas que mapeiam nomes de propriedades a valores arbitrários anexados a cada item em sua cópia de trabalho. Falando de uma forma geral, os nomes e valores das propriedades podem ser quaisquer coisas que você queira, com a restrição de que os nomes devem ser texto legível por humanos. E a melhor parte sobre estas propriedades é que elas, também, são versionadas, tal como o conteúdo textual de seus arquivos. Você pode modificar, submeter, e reverter alterações em propriedades tão facilmente como em qualquer alteração no conteúdo de arquivos. E o envio e recebimento das modificações em propriedades ocorrem como parte de suas operações de submissão (commit) e atualização (update)—você não tem que mudar seus procedimentos básicos para utilizá-los.

Nota

O Subversion reservou um conjunto de propriedades cujos nomes começam com svn: para si próprio. Ainda que haja apenas um conjunto útil de tais propriedades em uso hoje em dia, você deve evitar criar suas propriedades específicas com nomes que comecem com este prefixo. Do contrário, você corre o risco de que uma versão futura do Subversion aumente seu suporte a recursos ou comportamentos a partir de uma propriedade de mesmo nome, mas talvez com um significado completamente diferente.

Propriedades aparecem em qualquer parte no Subversion, também. Da mesma maneira que arquivos e diretórios podem ter nomes de propriedades arbitrários e valores anexados a eles, cada revisão como um todo pode ter propriedades arbitrárias anexadas a si própria. As mesmas restrições se aplicam;mdash;nomes que sejam legíveis por humanos e valores com qualquer coisa que você queira, inclusive dados binários. A principal diferença é que as propriedades de uma revisão não são versionadas. Em outras palavras, se você modificar o valor de, ou excluir uma propriedade de uma revisão, não há uma forma de recuperar seu valor anterior no Subversion.

O Subversion não tem nenhuma política em particular em relação ao uso de propriedades. Ele apenas solicita que você não use nomes de propriedades que comecem com o prefixo svn:. Este é o espaço de nomes (namespace) que ele reserva para uso próprio. E o Subversion, de fato, faz uso de propriedades, tanto do tipo versionadas quando das não-versionadas. Certas propriedades versionadas têm um significado especial ou certos efeitos quando encontradas em arquivos e diretórios, ou carregam alguma pequena informação sobre a revisão na qual estes se encontram. Certas propriedades de revisão são automaticamente anexadas às revisões pelo processo de submissão de alterações do Subversion, e obtém informação sobre a revisão. Muitas dessas propriedades são mencionadas em algum lugar neste ou em outros capítulos como parte de tópicos mais gerais aos quais estão relacionadas. Para uma lista exaustiva das propriedades pré-definidas do Subversion, veja “Propriedades do Subversion”.

Nesta seção, vamos examinar a utilidade—tanto para os usuários quanto para o próprio Subversion—do suporte a propriedades. Você vai aprender sobre os subcomandos de svn que lidam com propriedades, e como alterações nas propriedades afetam seu fluxo de trabalho normal no Subversion.

Por que Propriedades?

Como o Subversion usa propriedades para armazenar informações extras sobre arquivos, diretórios, e revisões que as contém, você também pode usar propriedades de forma semelhante. Você poderia achar útil ter um lugar próximo de seus dados versionados para pendurar metadados personalizados sobre estes dados.

Digamos que você quer elaborar um website que armazene muitas fotos digitais, e as exiba com legendas e a data e hora em que foram tiradas. Só que seu conjunto de fotos está mudando constantemente, e você gostaria de automatizar este site tanto quanto possível. Estas fotos podem ser um pouco grandes, então, como muito comum em sites desse tipo, você quer disponibilizar prévias em miniatura de suas fotos para os visitantes de seu site.

Agora, você pode ter esta funcionalidade usando arquivos tradicionais. Isto é, você pode ter seus arquivos image123.jpg e image123-thumbnail.jpg lado a lado em um diretório. Ou se você quiser manter os mesmos nomes de arquivos, você poderia ter suas miniaturas em um diretório diferente, como thumbnails/image123.jpg. Você também pode armazenar suas legendas e datas e horários de forma parecida, também separadas do arquivo da foto original. Mas o problema aqui é que o conjunto de arquivos aumenta aos múltiplos para cada nova foto adicionada ao site.

Agora considere o mesmo website desenvolvido de forma a fazer uso das propriedades de arquivo do Subversion. Imagine ter um único arquivo de imagem, image123.jpg, e então propriedades definidas neste arquivo chamadas caption, datestamp, ou mesmo thumbnail (respectivamente para a legenda, data e hora, e miniatura da imagem). Agora sua cópia de trabalho parece muito mais gerenciável—de fato, numa primeira visualização, não parece haver nada mais além dos arquivos de imagem lá dentro. Mas seus scripts de automação sabem mais. Eles sabes que podem usar o svn (ou melhor ainda, eles podem usar a linguagem incorporada ao Subversion—veja “Usando as APIs”) para para extrair as informações extras que seu site precisa exibir sem ter que lê-las de um arquivo de índices nem precisar de preocupar em estar manipulando caminhos dos arquivos.

As propriedades personalizadas de revisões também são freqüentemente usadas. Um de seus usos comuns é uma propriedades cujo valor contém um recurso de ID de rastreamento ao qual a revisão está associada, talvez pelo fato de a alteração feita nesta revisão corrigir um problema relatado externamente com aquele ID. Outros usos incluem a inserção de nomes mais amigáveis à revisão—pode ser difícil lembrar que a revisão 1935 foi uma revisão testada completamente. Mas se houver, digamos, uma propriedade resultado-dos-testes nesta revisão com o valor todos passaram, esta á uma informação bem mais significativa de se ter.

Manipulando Propriedades

O comando svn oferece algumas poucas maneiras de se adicionar ou modificar propriedades de arquivos e diretórios. Para propriedades com valores pequenos, legíveis por humanos, talvez a forma mais simples de se adicionar uma nova propriedade é especificar o nome e o valor da propriedade na linha de comando com o subcomando propset.

$ svn propset copyright '(c) 2006 Red-Bean Software' calc/button.c
property 'copyright' set on 'calc/button.c'
$

Mas sempre podemos contar com a flexibilidade que o Subversion oferece para seus valores de propriedades. E se você está planejando ter texto com múltiplas linhas, ou mesmo valores binários para o valor da propriedade, você provavelmente não vai informar este valor pela linha de comando. Então, o subcomando propset leva uma opção --file (-F) para especificar o nome de um arquivo que contém o valor para a nova propriedade.

$ svn propset license -F /path/to/LICENSE calc/button.c
property 'license' set on 'calc/button.c'
$

Há algumas restrições sobre os nomes que você pode usar para propriedades. Um nome de propriedade deve começar com uma letra, dois-pontos (:), ou um caractere sublinha (_); e depois disso, você também pode usar dígitos, hifens (-), e pontos (.). [9]

Além do propset, o programa svn também oferece comando propedit. Este comando usa o editor de texto configurado (veja “Configuração”) para adicionar ou modificar propriedades. Quando você executa este comando, o svn chama seu programa editor em um arquivo temporário que contém o valor atual da propriedade (ou o qual é vazio, se você estiver adicionando uma nova propriedade). Então, você apenas modifica esse valor em seu editor até que ele represente o novo valor que você quer armazenar para a propriedade. Se o Subversion identificar que no momento você está modificando o valor da propriedade existente, ele irá aceitá-lo como novo valor da propriedade. Se você sair de seu editor sem fazer qualquer alteração, nenhuma modificação irá ocorrer:

$ svn propedit copyright calc/button.c  ### sai do editor sem fazer nada
No changes to property 'copyright' on 'calc/button.c'
$

Devemos notar que, como qualquer outro subcomando do svn, estes que são relacionados a propriedades podem agir em diversos caminhos de uma só vez. Isto lhe permite modificar propriedades em todo um conjunto de arquivos com um único comando. Por exemplo, nós poderíamos ter feito:

$ svn propset copyright '(c) 2006 Red-Bean Software' calc/*
property 'copyright' set on 'calc/Makefile'
property 'copyright' set on 'calc/button.c'
property 'copyright' set on 'calc/integer.c'
…
$

Toda esta adição e alteração de propriedades não é realmente muito útil se você não puder obter facilmente o valor armazenado da propriedade. Então o programa svn dispõe de dois subcomando para exibição dos nomes e valores das propriedades armazenadas nos arquivos e diretórios. O comando svn proplist vai listar os nomes das propriedades que existem naquele caminho. Uma vez que você saiba os nomes das propriedades do nó, você pode verificar seus valores individualmente usando svn propget. Este comando mostrará, dado um nome de propriedade e um caminho (ou conjunto de caminhos), o valor da propriedade para a saída padrão.

$ svn proplist calc/button.c
Properties on 'calc/button.c':
  copyright
  license
$ svn propget copyright calc/button.c
(c) 2006 Red-Bean Software

Há ainda uma variação do comando proplist que lista tanto o nome quanto o valor de todas as propriedades. Apenas informe a opção --verbose (-v).

$ svn proplist -v calc/button.c
Properties on 'calc/button.c':
  copyright : (c) 2006 Red-Bean Software
  license : ================================================================
Copyright (c) 2006 Red-Bean Software.  All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions 
are met:

1. Redistributions of source code must retain the above copyright
notice, this list of conditions, and the recipe for Fitz's famous
red-beans-and-rice.
…

O último subcomando relacionado a propriedades é o propdel. Como o Subversion permite armazenar propriedades com valores vazios, você não pode remover uma propriedade usando propedit ou propset. Por exemplo, este comando não vai surtir o efeito desejado:

$ svn propset license '' calc/button.c
property 'license' set on 'calc/button.c'
$ svn proplist -v calc/button.c
Properties on 'calc/button.c':
  copyright : (c) 2006 Red-Bean Software
  license : 
$

Você precisa usar o subcomando propdel para remover propriedades completamente. A sintaxe é semelhante a dos outros comandos de propriedades:

$ svn propdel license calc/button.c
property 'license' deleted from 'calc/button.c'.
$ svn proplist -v calc/button.c
Properties on 'calc/button.c':
  copyright : (c) 2006 Red-Bean Software
$

Lembra das propriedades não-versionadas de revisões? Você pode modificá-las, também, usando os mesmo subcomandos do svn que acabamos de descrever. Apenas adicione o parâmetro --revprop na linha de comando, e especifique a revisão cujas propriedades você quer modificar. Como as revisões são globais, você não precisa especificar um caminho para para estes comandos relacionados a propriedades enquanto estiver em uma cópia de trabalho do repositório cuja propriedade de revisão você queira alterar. Por outro lado, você pode apenas especificar a URL de qualquer caminho de seu interesse no repositório (incluindo a URL raiz do repositório). Por exemplo, você pode querer trocar a mensagem de log de um registro de alteração de uma revisão existente. [10] Se seu diretório atual for parte da cópia de trabalho de seu repositório, você pode simplesmente executar o comando svn propset sem nenhum caminho:

$ svn propset svn:log '* button.c: Fix a compiler warning.' -r11 --revprop
property 'svn:log' set on repository revision '11'
$

Mas mesmo que você não tenha criado uma cópia de trabalho a partir do repositório, você ainda assim pode proceder com modificação de propriedades informando a URL raiz do repositório:

$ svn propset svn:log '* button.c: Fix a compiler warning.' -r11 --revprop \
              http://svn.example.com/repos/project
property 'svn:log' set on repository revision '11'
$

Perceba que a permissão para se alterar estas propriedades não-versionadas deve ser explicitamente concedida pelo administrador do repositório (veja “Corrigindo Mensagens de Log Submetidas”). Isto é porque as propriedades não são versionadas, então você corre o risco de perder informação se não for cuidadoso com suas alterações. O administrador do repositório pode definir formas de proteção contra perda de dados, e por padrão, além de que as modificações de propriedades não-versionadas são desabilitadas por padrão.

Dica

Usuários poderia, quando possível, usar svn propedit ao invés de svn propset. Ainda que o resultado da execução dos comandos seja o mesmo, o primeiro vai lhes permitir visualizar o valor atual da propriedade que querem modificar, o que ajuda a conferir que estão, de fato, fazer a alteração que acham que estão fazendo. Isto é especialmente verdadeiro ao modificar as propriedades não-versionadas de revisão. E ainda, é significativamente modificar valores de propriedades em múltiplas linhas em um editor de texto do que pela linha de comando.

Propriedades e o Fluxo de Trabalho no Subversion

Agora que você está familiarizado com todos os subcomandos svn relacionados a propriedades, vamos ver como as modificações de propriedades afetam o fluxo de trabalho usual do Subversion. Como mencionado anteriormente, as propriedades de arquivos e diretórios são versionadas, tal como os conteúdos de arquivos. Como resultado, o Subversion dispõe dos mesmos recursos para mesclar—de forma limpa ou com conflitos—alterações de terceiros às nossas próprias.

E como com conteúdos de arquivos, suas mudanças de propriedades são modificações locais, que são tornadas permanentes apenas quando submetidas ao repositório com o comando svn commit. Suas alterações de propriedades também podem ser facilmente desfeitas—o comando svn revert vai restaurar seus arquivos e diretórios para seus estados inalterados—conteúdos, propriedades, e tudo. Também, você pode obter informações interessantes sobre o estado de suas propriedades de arquivos e diretórios usando os comandos svn status e svn diff.

$ svn status calc/button.c
 M     calc/button.c
$ svn diff calc/button.c
Property changes on: calc/button.c
___________________________________________________________________
Name: copyright
   + (c) 2006 Red-Bean Software

$

Note como o subcomando status exibe M na segunda coluna ao invés de na primeira. Isto é porque modificamos as propriedades de calc/button.c, mas não seu conteúdo textual. Se tivéssemos modificado ambos, deveríamos ver um M na primeira coluna também (veja “Obtendo uma visão geral de suas alterações”).

Você também deve ter notado a forma não-padrão como o Subversion atualmente exibe diferenças de propriedades. Você ainda pode executar svn diff e redirecionar a saída para criar um arquivo de patch usável. O programa patch vai ignorar patches de propriedades—como regra, ele ignora qualquer coisa que não consiga entender. Isso significa, infelizmente, que para aplicar completamente um patch gerado pelo svn diff, quaisquer alterações em propriedades precisarão ser aplicadas manualmente.

Definição Automática de Propriedades

Propriedades são um poderoso recurso do Subversion, agindo como componentes chave em muitos outros recursos apresentados neste e em outros capítulos—suporte a diferenciação e mesclagem textual, substituição de palavras-chave, conversão de delimitadores de linha, etc. Mas para aproveitar plenamente as propriedades, elas devem ser definidas nos arquivos e diretórios certos. Infelizmente, este passo é facilmente esquecido na rotina de ações de usuário, especialmente pelo fato de que a não atribuição de uma propriedade normalmente não resulta em nenhum erro óbvio (ao menos quando comparado a, digamos, esquecer de adicionar um arquivo ao controle de versão). Para ajudar que suas propriedades sejam aplicadas em seus devidos locais, o Subversion dispõem de uma porção de recursos simples e poderosos.

Sempre que você inclui um arquivo ao controle de versão usando os comando svn add ou svn import, o Subversion tenta ajudar criando algumas propriedades de arquivo automaticamente. Primeiramente, em sistema operacionais cujos sistemas de arquivo suportem bits de permissão de execução, o Subversion automaticamente vai definir a propriedade svn:executable nos arquivos recém adicionados ou importados nos quais o bit de execução esteja ativo. (Veja “Executabilidade de Arquivo” para mais sobre esta propriedade.) Em segundo lugar, ele executa uma heurística bem básica para identificar se o arquivo contém algum conteúdo que seja legível por humanos. Se não, o Subversion automaticamente vai definir a propriedade svn:mime-type naquele arquivo para application/octet-stream (o tipo MIME genérico para “isto é um conjunto de bytes”). Claro que se o Subversion identificou corretamente, ou se você quiser definir a propriedade svn:mime-type para algo mais preciso—talvez image/png ou application/x-shockwave-flash—você sempre pode remover ou editar esta propriedade. (Para mais sobre como o Subversion faz uso dos tipos MIME, veja “Tipo de Conteúdo do Arquivo”.)

O Subversion também oferece, através de seu sistema de configuração em tempo de execução (veja “Área de Configuração do Tempo de Execução”), um mecanismo mais flexível de definição automática de propriedades que permite a você criar mapeamentos de padrões de nome de arquivos para nomes de propriedades e valores. Novamente, estes mapeamentos afetam adições e importações e não apenas podem sobrescrever a identificação sobre o tipo MIME padrão feita pelo Subversion durante suas operações, como pode definir propriedades do Subversion adicionais e personalizadas também. Por exemplo, você poderia criar um mapeamento que dissesse que sempre que você adicionar arquivos JPEG—aqueles cujos nomes casem com o padrão *.jpg—o Subversion deveria automaticamente definir a propriedade svn:mime-type destes arquivos para image/jpeg. Ou talvez quaisquer arquivos que correspondam ao padrão *.cpp deveriam ter a propriedade svn:eol-style definida para native, e svn:keywords atribuída para Id. Suporte a propriedades automáticas talvez seja a ferramenta mais prática no conjunto de ferramentas do Subversion. Veja “Configuração” para mais sobre a configuração deste recurso.



[9] Se você é familiarizado com XML, este é exatamente o subconjunto ASCII da sintaxe de um "Nome" XML.

[10] Correção de erros de ortografia, gramaticais “outros ajustes simples de texto” nas mensagens de log de uma registro talvez seja o uso mais comum da opção --revprop option.