2009-06-23 2 views
5

Во-первых, я должен признать, что я немного прикрутил CVS. У меня был тег релиза releaseX, который был сделан некоторое время назад (т. Е. Не HEAD). Тогда я решил, что в этот момент мне нужна ветка обслуживания. Вместо создания тега ветви (branchX) в добавление к releaseX, I удалено тег выпуска и создан тег ветки (ошибочно) с именем releaseX. Затем я приступил к работе над этой отраслью обслуживания, и создал releaseX1, releaseX2 и т.д.Как проверить точку ветвления CVS?

Моей проблемы: когда я проверяю releaseX, я получаю ветви голова, т.е. последний код из этой ветви. Что мне необходимо сейчас код в точке филиала, т. Е. бывшийreleaseX код.

Есть ли способ сделать это?

Возвращение к более ранней версии репозитория из резервной копии не является вариантом.

Редактировать: Я знаю, что могу обойти это, выполнив проверку на основе даты. Я хотел бы знать, можно ли по-прежнему использовать тегов.

Обновление (Re @Philip Derbeko): Я знаю, что CVS не коррелирует между файлами. Но у CVS есть есть информация, где произошла ветка. В ViewVC, я могу даже видеть его:

File X - Revision 1.y - Branch: MAIN - Branch point for: releaseX

Следующая редакция файла:

File X - Revision 1.y.2.1 - Branch: releaseX - CVS Tags: releaseX1

метаданные, по-видимому там. Поэтому мой вопрос: Можно проверить филиал , а не филиал HEAD?

ответ

9

Поскольку вы не устанавливали тег при ветвлении, единственный способ, которым я вижу, - использовать подход с датой. Но вы все равно можете установить этот тег. Предположим, вы хотите назвать этот начальный выпуск «ReleaseX0», потому что, к сожалению, имя «ReleaseX» уже занято для ветки. В зависимости от того, хотите ли вы, чтобы установить метку на ветке или на основной ветке вы можете использовать любого из этих команд кассы:

cvs co -r releaseX -D "2008-12-30" modulename 
cvs co -D "2008-12-30" modulename 

Затем установите тег:

cvs tag releaseX0 

Теперь вы можете проверьте этот выпуск так же, как и другие выпуски.


Как вы отметили в своем комментарии к моему первоначальному ответу, переименовав ветвь от releaseX к releaseX_branch как этот не работает:

cvs rtag -r releaseX releaseX_branch modulename 
cvs rtag -d releaseX modulename 

Чтобы переименовать филиал «CVS администратор -N < старый>: < новый> "необходимо использовать. Но переименование ветки - это плохая идея. (Прошу прощения за то, что вы его подняли в первую очередь ;-).), Renaming испортит рабочие копии других пользователей. Поэтому лучше всего придерживаться оригинального названия.

+0

Хммм ... плохая идея?Первая команда установит тег, но не ветку, поэтому я не уверен, что сделает вторая команда (удаление тега ветви). Добавление -b к первой команде создаст ветку * new *, и снова будет догадаться, что сделает вторая команда ... Опять же, вы уверены, что это сработает? У меня очень ограниченные возможности тестирования/отката. – DevSolar

+0

Вы правы, переименовывая ветку, не работает так. Я отредактирую свой ответ. – Ralph

+0

Отличное предложение о «cvs admin», я полностью забыл об этом: поскольку я также являюсь администратором CVS и единственным, кто сейчас работает над этим модулем, это действительно жизнеспособный вариант. Благодаря! – DevSolar

2

Я не эксперт по CVS. Вот что я сделал бы, если бы был на вашем месте. CVS маркирует версии файлов в ветке HEAD как 1.N, когда вы делите файл в версии X, фиксируется в этой ветви, отмеченной как 1.X.B.M. Поэтому после проверки releaseX, я бы написал сценарий, который будет обновлять файлы, которые были изменены в ветке, на версию 1.X, а затем пометить мою рабочую копию. Может быть, есть более простой способ, но я не знаю об этом.

+0

Чтобы решить подобные проблемы несколько раз на работе, мой коллега закончил создание сценария Python для этого автоматически на основе вывода cvs rlog. У меня больше нет сценария, но я просто хочу сказать, что это жизнеспособный подход. – olsner

1

Извините, не может быть сделано. Единственный вариант, который у вас есть, - это проверка времени. Проблема в том, что CVS не коррелирует между разными файлами, что делается с использованием тегов. Как только тег исчез, информация, которая связывает разные файлы вместе, ушла навсегда. Это означает, что вам нужно написать скрипт, который найдет точку ветвления для каждого файла.

Как обычная практика, и в случае, если вам не нужны многие теги в репозитории, я бы предложил создать тег на соединительной линии (или ветку, откуда вы разветвляетесь) и на слияние. Эти теги должны следовать соглашению об именах, а затем в сценариях CVS вы можете предотвратить беспорядок с ними.

С CVS вы должны автоматизировать как можно больше :)

+0

Я понимаю, что CVS не коррелирует между файлами. Но ... см. Обновленный вопрос. – DevSolar

4

Это происходит спустя четыре года - это не поможет, но это может помочь кому-то, как я пытаюсь понять эту проблему вне через Google. Недавно я столкнулся с одной и той же проблемой с слиянием, которое я делаю. Мне нужно увидеть родительский предок файлов между ветвью ветви и главной линией - это точка ветвления. Точка ветвления не была помечена и была создана много лет назад - в неопределенное время, поэтому пометка по времени не помогает.

Решение, которое я придумал, вычисляет номер ревизии точки перехода для каждого файла и применяет тег точки ветвления через скрипт PERL. Он очень похож на то, что указано здесь: http://www.cvsnt.org/pipermail/cvsnt/2006-February/024063.html

Небольшой фон CVS: в ветвях CVS отслеживается добавлением .0.x к редакции основной строки файла. Например, если ревизия mainline равна 1,18, то ответвление будет равно 1.18.0.x, X - номер ветки (если уже существовала ветвь из этого номера версии, тогда x будет 2 -> 1.18.0.2). «.0» отбрасывается при изменении файлов в ветви, поэтому в этом примере ветка будет 1.18.0.2, а первая ревизия будет 1.18.2.1, а вторая ревизия будет 1.18.2.2. Много это сделать из этого: http://www.astro.princeton.edu/~rhl/cvs-branches.html#branchnumbers

Я нашел PERL скрипт здесь: https://github.com/effectiveprogramming/ep-cvs/wiki/List-CVS-Tags, которые будут либо перечислить теги CVS, когда дали ключ -t или если дано название филиала тег будет список всех файлов и пересмотр связанных с этим тегом. Этот скрипт использует эту команду: «cvs -q status -R -v filename», которая будет скрывать ветви с «.0», поэтому вы просто удаляете «.x» из номера версии нужного имени ветки. Поэтому я взял сценарий на github и добавил несколько строк. Вы просто выполняете этот скрипт с именем ветки в качестве аргумента, и он будет тегировать точку ветвления с тем же именем ветки с добавленным им _BP.

#!/usr/bin/perl 

# Simple perl script. Given a branch name, determine 
# the file revision a branch was created on for all 
# files in a repository and tag those files with a user defined tag.  
# Created 2013/04/05 CPG 
# $Id: lstag,v 1.1 2002/09/26 10:02:53 ec Exp $ 

use strict; 

$::VERSION = "1.0"; 
$::cvs_ID = '$Id: lstag,v 1.1 2002/09/26 10:02:53 ec Exp $'; #' 

undef ($::repo); 
# Try #1 to get CVS repository location 
if (-r "CVS/Root") { 
    open (INF, "<CVS/Root") || die "Failed to read CVS/Root file!\n"; 
    ###chop ($::repo = <INF>); 
    $::repo = <INF>; 
    close (INF); 
} else { 
    # Try #2 to get CVS repository location 
    if (!$::ENV{"CVSROOT"}) { 
     print "CVSROOT environment variable not found!\n"; 
     print "CVS not detected...\n"; 
     exit (10); 
    } 
} 
$::repo =~ s/\n$//g; 
$::repo =~ s/\r$//g; 
($::repo) = $::repo =~ /([^:]+)$/; 
$::repo =~ s/\/*$/\//; 

### print "CVS repository at $::repo\n"; 


# Check commandline arguments 
if ($#ARGV < 0) { 
    print "Missing argument!\n"; 
    print "Usage: $0 [ tag]\n\n"; 
    print "Where: tag is number of "; 
    print "  each file this tag was created.\n"; 
    print "  tag shows list of files with this tag\n"; 
    print "\n"; 
    exit (1); 
} 

# Get desired tagname 
$::tag = $ARGV[0]; 
$::taglist = 0; 
if ($::tag eq "-l") { 
    $::taglist = 1; 
} 



# Run cvs status and catch output 
open (INF, "cvs -q status -R -v |") || die "Failed to run cvs status command!\n"; 
chop (@::STATUS = <INF>); 
close (INF); 

# Parse status 
$::state = 0; 
$::fpath = $::frpath = $::fname = $::fstatus = $::ftag = $::ftagrev = "!UNINITIALIZED VARIABLE!"; 
undef (%::TAGS); 
$::found = 0; 
for $::lc (0 .. $#::STATUS) { 
    $_ = $::STATUS[$::lc]; 
    if ($::state == 0) { 
     if (/^File:/) { 
      ($::fname, $::fstatus) = /^File:\s+(\S+\s*\S+)\s+Status:\s+(\S+)/; 
      $::state = 1; 
     } 
     next; 
    } 
    if ($::state == 1) { 
     if (/^\s+Repository revision:/) { 
      ($::frpath) = /(\/.*),v/; 
      ($::fpath) = $::frpath =~ /^$::repo(.*)$/; 
      push @::INFOL, ($::fpath); 
      $::current = $::fpath; 
      $::INFO{$::current}->{"rpath"} = $::frpath; 
      $::INFO{$::current}->{"name"} = $::fname; 
      $::INFO{$::current}->{"status"} = $::fstatus; 
      $::fpath = $::frpath = $::fname = $::fstatus = "!UNINITIALIZED VARIABLE!"; 
      $::state = 2; 
     } 
     next; 
    } 
    if ($::state == 2) { 
     if (/^\s+Existing Tags:/) { 
      $::state = 3; 
     } 
     next; 
    } 
    if (/^\s+\S+\s+\([^:]+:/) { 
     ($::ftag, $::ftagrev) = /^\s+(\S+)\s+\([^:]+:\s+([^\)]+)\)/; 
     if ($::taglist) { 
      $::TAGL{$::ftag}++; 
     } 
     if ($::ftag eq $::tag) { 
      $::found++; 
      $::INFO{$::current}->{"tag"} = $::ftag; 
      $::INFO{$::current}->{"tagrev"} = $::ftagrev; 
      $::ftag = $::ftagrev = "!UNINITIALIZED VARIABLE!"; 
     } 
    } else { $::state = 0; } 
} 

# Print results 
print "$0 - CVS tag and file lister version $::VERSION\n"; 
print "ID: $::cvs_ID\n\n"; 
if ($::taglist) { 
    print "List of all known tags:\n\n"; 
    foreach $::key (sort {uc($a) cmp uc($b)} keys %::TAGL) { 
     print "$::key\n"; 
    } 
} else { 
    print "Files with tag \"$::tag\":"; 
    if ($::found > 0) { 
     print "\n\n"; 
    } else { 
     print " NONE\n"; 
    } 
    for $::i (0 .. $#::INFOL) { 
     if (!defined($::INFO{$::INFOL[$::i]}->{"tag"})) { 
      next; 
     } 
     $::name = $::INFOL[$::i]; 
     $::status = $::INFO{$::name}->{"status"}; 
     $::tagrev = $::INFO{$::name}->{"tagrev"}; 

     # Code added to apply a tag to a branch point: 
     # regex to strip from last '.' to end of revision #. 
     $::ge = '\.[^\.]*$'; 

     $::branchPtRev = $::tagrev; 
     $_ = $::branchPtRev; 
     s/$::ge//; 
     $::cmd = "cvs tag -r".$_." ".$::tag."_BP " . $::name . " xst"; 

     #printf "%10s %s\n", ($_, $::name); 

     # printf "%10s %10s\n", ($::branchPtRev, $_); 

     #printf $::cmd; 
     # printf "\n"; 

     # Run cvs command 
     open (INF, $::cmd) || die "Failed to run cvs status command!\n"; 
     close (INF); 
    } 
} 

print "Script Completed Successfully\n"; 
Смежные вопросы