Pergunta

Recentemente perguntei sobre expansão de palavras-chave no Git e estou disposto a aceitar o design para não apoiar realmente essa ideia no Git.

Para o bem ou para o mal, o projeto em que estou trabalhando no momento requer uma expansão de palavras-chave SVN como esta:

svn propset svn:keywords "Id" expl3.dtx

para manter esta string atualizada:

$Id: expl3.dtx 803 2008-09-11 14:01:58Z will $

Mas eu gostaria bastante de usar o Git para fazer meu controle de versão.Infelizmente, o git-svn não suporta isso, de acordo com os documentos:

"Ignoramos todas as propriedades do SVN, exceto svn:executable"

Mas não parece muito complicado ter essas palavras-chave emuladas por alguns ganchos pré/pós commit.Sou a primeira pessoa a querer isso?Alguém tem algum código para fazer isso?

Foi útil?

Solução

O que está acontecendo aqui:O Git é otimizado para alternar entre ramificações o mais rápido possível.Em particular, git checkout foi projetado para não tocar em nenhum arquivo idêntico em ambas as ramificações.

Infelizmente, a substituição de palavras-chave RCS quebra isso.Por exemplo, usando $Date$ exigiria git checkout para tocar em todos os arquivos da árvore ao trocar de ramificação.Para um repositório do tamanho do kernel do Linux, isso paralisaria tudo.

Em geral, sua melhor aposta é marcar pelo menos uma versão:

$ git tag v0.5.whatever

...e então chame o seguinte comando do seu Makefile:

$ git describe --tags
v0.5.15.1-6-g61cde1d

Aqui, o git está me dizendo que estou trabalhando em um commit anônimo da versão 6 anterior à v0.5.15.1, com um hash SHA1 começando com g61cde1d.Se você colar a saída deste comando em um *.h arquivo em algum lugar, você está no negócio e não terá problemas em vincular o software lançado de volta ao código-fonte.Esta é a maneira preferida de fazer as coisas.

Se não for possível evitar o uso de palavras-chave RCS, você pode começar com isto explicação de Lars Hjemli.Basicamente, $Id$ é muito fácil, e você, se estiver usando git archive, você também pode usar $Format$.

Mas, se você absolutamente não pode evitar palavras-chave RCS, o seguinte deve ajudá-lo a começar:

git config filter.rcs-keyword.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"'
git config filter.rcs-keyword.smudge 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date: `date`\\\$/"'

echo '$Date$' > test.html
echo 'test.html filter=rcs-keyword' >> .gitattributes
git add test.html .gitattributes
git commit -m "Experimental RCS keyword support for git"

rm test.html
git checkout test.html
cat test.html

No meu sistema, recebo:

$Date: Tue Sep 16 10:15:02 EDT 2008$

Se você tiver problemas para fazer o shell escapar no smudge e clean Para que os comandos funcionem, basta escrever seus próprios scripts Perl para expandir e remover palavras-chave RCS, respectivamente, e usar esses scripts como seu filtro.

Observe que você realmente não queira fazer isso para mais arquivos do que o absolutamente necessário, ou o git perderá a maior parte de sua velocidade.

Outras dicas

Infelizmente, a substituição da palavra -chave RCS quebra isso.Por exemplo, o uso de $ Date $ exigiria a finalização da compra Git para tocar em todos os arquivos da árvore ao alternar as ramificações.

Isso não é verdade.$Data$ etc.expanda para o valor válido no momento do check-in.De qualquer forma, isso é muito mais útil.Portanto, isso não muda em outras revisões ou ramificações, a menos que o arquivo seja realmente verificado novamente.Do manual RCS:

   $Date$ The  date  and  time the revision was checked in.  With -zzone a
          numeric time zone offset is appended;  otherwise,  the  date  is
          UTC.

Isso também significa que a resposta sugerida acima, com o filtro rcs-keyword.smudge, está incorreta.Ele insere a hora/data do checkout, ou o que quer que faça com que ele seja executado.

Aqui está um projeto de exemplo contendo a configuração e o código de filtro necessários para adicionar suporte a palavras-chave RCS a um projeto git:

https://github.com/turon/git-rcs-keywords

Não é tão simples de configurar como gostaríamos, mas parece funcionar.Ele usa um par de filtros borrados/limpos escrito em perl (semelhante ao que a resposta do emk descreveu) e, sim, tocará todos os arquivos com as extensões definidas em .gitattributes, geralmente retardando um pouco as coisas.

Você poderia definir o atributo ident em seus arquivos, mas isso produziria strings como

$Id: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef$

onde deadbeef... é o sha1 do blob correspondente a esse arquivo.Se você realmente precisa dessa expansão de palavras-chave e precisa dela no repositório git (em oposição a um arquivo exportado), acho que você terá que usar o ident gitattribute com um script personalizado que faz a expansão para você.O problema de usar apenas um gancho é que o arquivo na árvore de trabalho não corresponde ao índice e o git pensaria que foi modificado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top