Jak poprawnie utworzyć tag SVN z pnia?

282

Mój pierwszy projekt tworzę w Subversion . Do tej pory mam

 branches
 tags
 trunk

Myślę, że od razu muszę uczynić gałęzie osobnymi i zacząć od nowa. Aktualizacja oddziałów jest normą.

Pracowałem w bagażniku i przenosiłem zawartość do znaczników w następujący sposób.

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

Mój żołądek mówi mi, że jest to całkowicie błędne i powinienem zachować pewien związek między używanymi plikami svn copy. Pliki, które utworzę w ten sposób, nie będą ze sobą powiązane i jestem pewien, że przegapię funkcje Subversion. Mam rację?

Czy powinienem używać kopii svn dla poszczególnych plików?

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"

Czy powinienem używać kopii svn w całym katalogu?

svn copy cp -rf trunk tags/1.0
svn commit -m " create a first tagged version"
ojblass
źródło
10
Niestety nie wybieram wszystkich opcji w tym przypadku ... git jest dość cholerną magią.
ojblass

Odpowiedzi:

186

Masz rację, ponieważ dodawanie plików do folderu znaczników jest „niewłaściwe”.

Prawidłowo zgadłeś, copyz której operacji należy skorzystać; pozwala Subversion śledzić historię tych plików, a także (zakładam) przechowywać je znacznie wydajniej.

Z mojego doświadczenia wynika, że ​​najlepiej jest wykonywać kopie („migawki”) całych projektów, tj. Wszystkich plików z głównego miejsca wyewidencjonowania. W ten sposób migawka może działać samodzielnie, jako prawdziwa reprezentacja stanu całego projektu w określonym momencie.

Ta część „książki” pokazuje, w jaki sposób komenda jest zwykle używana.

rozwijać
źródło
15
Wersja 1.1 książki jest strasznie nieaktualna. Oto lepszy link: svnbook.red-bean.com/nightly/en/svn.branchmerge.tags.html
Quinn Taylor
1
skopiowane pliki nie wydają dodatkowego miejsca
Carlos
424

Posługiwać się:

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

Stenografia:

cd /path/to/project
svn copy ^/trunk ^/tags/1.0 -m "Release 1.0"
Wiktor Hugo
źródło
36
Oznacziłem to jako odpowiedź. Tylko jedna dodatkowa uwaga. Możesz pobrać poprzednią wersję pnia i „oznaczyć” ją również. polecenie: svn copy -r 123 " svn.example.com/project/trunk " " svn.example.com/project/tags/1.0 " -m "Tagowanie, ale przy użyciu starszej wersji (123)."
granadaCoder
7
Dostaję svn: lokalne operacje bez zatwierdzenia nie biorą wiadomości dziennika ani właściwości wersji , więc po prostu usuwam opcję -m.
Jonny
4
Tylko do Twojej wiadomości, upewnij się, że Twój adres URL pasuje do repozytorium, w tym http lub https.
Norman H
2
Dlaczego \ na końcu pierwszego wiersza?
Fractaliste
1
@Jonny Nie mogę uruchomić powyższej komendy bez opcji „-m”. Używam terminala na komputerze Mac.
Abdurrahman Mubeen Ali
14

Jak zauważył @victor hugo, „właściwym” sposobem jest użycie kopii svn. Jest jednak jedno zastrzeżenie. Tak utworzony „tag” nie będzie prawdziwym tagiem, będzie dokładną kopią określonej wersji, ale sama będzie inną wersją. Jeśli więc system kompilacji w jakiś sposób korzysta z wersji svn (np. Uwzględnia liczbę uzyskaną za pomocą „svn info” w wersji produktu, który budujesz), to nie będziesz w stanie zbudować dokładnie tego samego produktu z tagu ( wynik będzie miał poprawkę znacznika zamiast oryginalnego kodu).

Wygląda na to, że zgodnie z projektem svn nie ma możliwości stworzenia naprawdę poprawnego metatagu.

Alexander Amelkin
źródło
4
Możliwe jest użycie „Last Changed Rev”: echo "{ 'svnRev': \"`svn info | awk '/Last Changed Rev:/{print $4}'`\" }" >svnver.txt`
18446744073709551615
W ten sposób dwie gałęzie z (oczywiście) różnymi numerami wersji nadal wytwarzają tę samą wersję oprogramowania.
18446744073709551615
1
Tak, masz rację co do ostatniej zmiany Rev, ale to nie zmienia faktu, że z założenia w Subversion nie ma żadnych prawdziwych tagów.
Alexander Amelkin
@ 18446744073709551615: Możesz uniknąć korzystania z awktych informacji i uzyskać je bezpośrednio z svn, korzystając z --show-itemopcji:svn info --show-item last-changed-revision
Luchostein
12

Po prostu użyj tego:

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

(wszystko w jednym wierszu, oczywiście.) Zawsze należy utworzyć gałąź całego folderu głównego i zawartości. Oczywiście można rozgałęzić części pnia, ale prawie nigdy nie będzie to dobra praktyka. Chcesz, aby gałąź zachowywała się dokładnie tak samo jak teraz pień, a żeby tak się stało, musisz rozgałęzić cały pień.

Zobacz lepsze podsumowanie wykorzystania SVN na moim blogu: SVN Essentials i SVN Essentials 2

AgilePro
źródło
Czy możesz opracować sposób, w jaki powinien on wyglądać, jeśli sprawdzam tylko z pnia i jestem w środku z moim skryptem.
aholbreich
Jeśli sprawdziłeś folder trunk, musisz użyć adresu http repozytorium. Zaktualizowałem odpowiedź, aby to reprezentować, ponieważ sprawdzanie folderu głównego jest zalecanym wzorcem.
AgilePro,
Czym różni się ta odpowiedź od przyjętej?
Daniel W.
7

@victor hugo i @unwind są poprawne, a rozwiązanie zwycięzcy jest zdecydowanie najprostsze. Należy jednak uważać na efekty zewnętrzne w swoim projekcie SVN. Jeśli odwołujesz się do bibliotek zewnętrznych, odniesienie do wersji zewnętrznej (niezależnie od tego, czy jest to znacznik, HEAD, czy liczba) pozostanie niezmienione, gdy dodasz znaczniki do katalogów, które mają odniesienia zewnętrzne.

Możliwe jest utworzenie skryptu do obsługi tego aspektu znakowania. Aby uzyskać dyskusję na ten temat, zobacz ten artykuł SO: Oznaczanie kasy SVN za pomocą elementów zewnętrznych

MOK9
źródło
5

Inną opcją oznaczenia repozytorium Subversion jest dodanie znacznika do właściwości svn: log w następujący sposób:

   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

Ostatnio zacząłem myśleć, że jest to najbardziej „właściwy” sposób na tagowanie. W ten sposób nie tworzysz dodatkowych wersji (jak w przypadku „svn cp”) i nadal możesz łatwo wyodrębnić wszystkie tagi, używając grep na wyjściu „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;
                  }'

W ten sposób możesz w razie potrzeby bezproblemowo usuwać tagi. Tagi stają się kompletną meta-informacją i podoba mi się to.

Alexander Amelkin
źródło
0
svn copy http://URL/svn/trukSource http://URL/svn/tagDestination -m "Test tag code" 
  $error[0].Exception | Select-object Data

Wszystko, co musisz zrobić, zmienić ścieżkę URL. To polecenie utworzy nowy katalog „tagDestination”. Drugi wiersz poinformuje Cię o szczegółach błędu, jeśli wystąpią. Utwórz zmienną env svn, jeśli nie została utworzona. Można sprawdzić (Cmd: - set, Powershell: - Env Get-ChildItem :) Domyślna ścieżka to „C: \ Program Files \ TortoiseSVN \ bin \ TortoiseProc.exe”

Ashu
źródło
-4

Spróbuj tego. Mi to pasuje:

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
źródło
1
To zdecydowanie zła droga. Tag (Release 1.0) powinien być kopią katalogu źródłowego (trunk), a nie katalogiem utworzonym arbitralnie. Jeśli zrobisz to w ten sam sposób, stracisz historię samego katalogu źródłowego i zachowasz tylko historię węzłów potomnych (plików i katalogów).
Alexander Amelkin,