Como criar corretamente uma tag SVN a partir do tronco?

282

Estou criando meu primeiro projeto no Subversion . Até agora eu tenho

 branches
 tags
 trunk

Acho que preciso imediatamente tornar os galhos singulares e começar de novo. Atualizar ramificações é a norma.

Venho trabalhando no porta-malas e movendo o conteúdo para as tags da seguinte maneira.

mkdir tags/1.0
cp -rf trunk/* tags/1.0
svn add tags/1.0
svn commit -m " create a first tagged version"

Meu intestino me diz que isso está totalmente errado, e eu devo manter algum relacionamento entre os arquivos usando svn copy. Os arquivos que eu criar dessa maneira não terão relação um com o outro, e tenho certeza de que vou perder os recursos do Subversion. Estou correcto?

Devo usar svn copy para os arquivos individuais?

mkdir tags/1.0
svn add tags/1.0
svn copy trunk/file1 tags/1.0
svn copy trunk/file2 tags/1.0
svn copy trunk/file3 tags/1.0
svn commit -m " create a first tagged version"

Devo usar svn copy em todo o diretório?

svn copy cp -rf trunk tags/1.0
svn commit -m " create a first tagged version"
ojblass
fonte
10
Infelizmente eu não faço todas as escolhas neste caso ... git é uma maldita mágica.
ojblass

Respostas:

186

Você está certo, pois não é "correto" adicionar arquivos à pasta de tags.

Você adivinhou corretamente que copyé a operação a ser usada; Ele permite ao Subversion acompanhar o histórico desses arquivos e também (eu assumo) armazená-los com muito mais eficiência.

Na minha experiência, é melhor fazer cópias ("snapshots") de projetos inteiros, ou seja, todos os arquivos do local de check-out raiz. Dessa forma, o instantâneo pode se sustentar por si só, como uma verdadeira representação do estado do projeto inteiro em um determinado momento.

Esta parte do "livro" mostra como o comando é normalmente usado.

descontrair
fonte
15
A versão 1.1 do livro está terrivelmente desatualizada. Aqui está um link melhor: svnbook.red-bean.com/nightly/en/svn.branchmerge.tags.html
Quinn Taylor
1
arquivos copiados não gastam espaço extra
Carlos
424

Usar:

svn copy http://svn.example.com/project/trunk \
      http://svn.example.com/project/tags/1.0 -m "Release 1.0"

Forma abreviada:

cd /path/to/project
svn copy ^/trunk ^/tags/1.0 -m "Release 1.0"
Victor Hugo
fonte
36
Marquei isso como resposta. Apenas uma nota extra. Você pode obter uma revisão anterior do tronco e "marcá-lo" também. o comando: svn copy -r 123 " svn.example.com/project/trunk " " svn.example.com/project/tags/1.0 " -m "Marcando, mas usando a revisão mais antiga (123)."
granadaCoder
7
Recebo svn: Operações locais sem confirmação não recebem uma mensagem de log ou propriedades de revisão , portanto, apenas removo a opção -m.
Jonny
4
Apenas um FYI, verifique se o seu URL corresponde ao seu repositório, incluindo http ou https.
Norman H
2
Por que o \ no final da primeira linha?
Fractaliste
1
@ Jonny Não consigo executar o comando acima sem a opção "-m". Estou usando o terminal no mac.
Abdurrahman Mubeen Ali 10/11/16
14

Como observado por @victor hugo, a maneira "adequada" é usar o svn copy. Há uma ressalva. A "tag" criada dessa maneira não será uma tag verdadeira, será uma cópia exata da revisão especificada, mas será uma revisão diferente. Portanto, se o seu sistema de compilação usa a revisão svn de alguma forma (por exemplo, incorpora o número obtido com 'svn info' na versão do produto que você constrói), você não poderá criar exatamente o mesmo produto a partir de uma tag (a tag O resultado terá a revisão da tag em vez da do código original).

Parece que, por design, não há como o svn criar uma meta tag realmente adequada.

Alexander Amelkin
fonte
4
É possível usar o "Last Changed Rev": echo "{ 'svnRev': \"`svn info | awk '/Last Changed Rev:/{print $4}'`\" }" >svnver.txt`
18446744073709551615
Dessa forma, duas ramificações com (obviamente) números de revisão diferentes ainda produzem a mesma versão do software.
18446744073709551615
1
Sim, você está certo sobre a Última alteração, mas isso não muda o fato de que, por design, não há tags reais no Subversion.
Alexander Amelkin
@ 18446744073709551615: Você pode evitar o uso awke obter essas informações diretamente do svn usando a --show-itemopção:svn info --show-item last-changed-revision
Luchostein 22/16
12

Apenas use isto:

svn  copy  http://svn.example.com/project/trunk  
           http://svn.example.com/project/branches/release-1
           -m  "branch for release 1.0"

(tudo em uma linha, é claro.) Você deve sempre criar uma ramificação de toda a pasta e conteúdo do tronco. É claro que é possível ramificar sub-partes do tronco, mas isso quase nunca será uma boa prática. Você quer que o ramo se comporte exatamente como o tronco agora e, para que isso aconteça, é necessário ramificar o tronco inteiro.

Veja um resumo melhor do uso do SVN no meu blog: SVN Essentials e SVN Essentials 2

AgilePro
fonte
Você pode elaborar como deve ficar se eu apenas fizer check-out do trunk e estiver dentro do meu script.
aholbreich
Se você fez check-out da pasta de tronco, precisará usar o endereço http do repositório. Atualizei a resposta para representar isso, pois verificar a pasta de tronco é o padrão recomendado.
AgilePro
Como essa resposta é diferente da resposta aceita?
Daniel W.
7

@victor hugo e @unwind estão corretos, e a solução da victor é de longe a mais simples. No entanto, tenha cuidado com os fatores externos no seu projeto SVN. Se você referenciar bibliotecas externas, a referência de revisão externa (seja uma marca, HEAD ou número) permanecerá inalterada quando você marcar os diretórios que possuem referências externas.

É possível criar um script para lidar com esse aspecto da marcação, para uma discussão sobre esse tópico, consulte este artigo da SO: Marcando um check-out do SVN com externos

MOK9
fonte
5

Outra opção para marcar um repositório do Subversion é adicionar a marca à propriedade svn: log da seguinte forma:

   echo "TAG: your_tag_text" > newlog
   svn propget $REPO --revprop -r $tagged_revision >> newlog
   svn propset $REPO --revprop -r $tagged_revision -F newlog
   rm newlog

Recentemente, comecei a pensar que essa é a maneira mais "correta" de marcar. Dessa forma, você não cria revisões extras (como faz com "svn cp") e ainda pode extrair facilmente todas as tags usando grep na saída "svn log":

   svn log | awk '/----/ {
                      expect_rev=1;
                      expect_tag=0;
                  }
                  /^r[[:digit:]]+/ {
                      if(expect_rev) {
                          rev=$1;
                          expect_tag=1;
                          expect_rev=0;
                      }
                  }
                  /^TAG:/ {
                      if(expect_tag) {
                          print "Revision "rev", Tag: "$2;
                      }
                      expect_tag=0;
                  }'

Além disso, dessa forma, você pode excluir tags de forma transparente, se necessário. Então, as tags se tornam uma meta-informação completa, e eu gosto.

Alexander Amelkin
fonte
0
svn copy http://URL/svn/trukSource http://URL/svn/tagDestination -m "Test tag code" 
  $error[0].Exception | Select-object Data

Tudo o que você precisa fazer é alterar o caminho da URL. Este comando criará um novo diretório "tagDestination". A segunda linha informará todos os detalhes do erro, se houver algum. Crie uma variável svn env se não for criada. Pode verificar (Cmd: - set, Powershell: - Get-ChildItem Env :) O caminho padrão é "C: \ Arquivos de Programas \ TortoiseSVN \ bin \ TortoiseProc.exe"

Ashu
fonte
-4

Tente isso. Funciona para mim:

mkdir <repos>/tags/Release1.0
svn commit <repos>/tags/Release1.0 
svn copy <repos>/trunk/* <repos>/tag/Release1.0
svn commit <repos/tags/Release1.0 -m "Tagging Release1.0"
iboubuntu
fonte
1
Este é definitivamente um caminho errado. A tag (Release1.0) deve ser uma cópia do diretório de origem (tronco), não um diretório criado arbitrariamente. Se você fizer da maneira que fez, você perde o histórico do próprio diretório de origem e mantém apenas o histórico dos nós descendentes (arquivos e diretórios).
Alexander Amelkin