Как проверить точку ветвления CVS? - PullRequest
6 голосов
/ 23 июня 2009

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

Моя проблема: когда я проверяю 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 ?

Ответы [ 4 ]

9 голосов
/ 25 июня 2009

Поскольку вы не устанавливали тег при ветвлении, я вижу только один способ - использовать подход даты. Но вы все еще можете установить этот тег сейчас. Предположим, вы хотите назвать этот первоначальный выпуск «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 admin -N : " необходимо использовать. Но переименовать ветку в любом случае плохая идея. (Я извиняюсь за то, что поднял его в первую очередь ;-).), Переименование испортит рабочие копии других пользователей. Так что, вероятно, лучше придерживаться оригинального названия.

4 голосов
/ 07 мая 2013

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

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

Небольшой фон CVS: В ветвях CVS отслеживаются путем добавления .0.x к основной версии файла. Например, если основная ревизия равна 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";
2 голосов
/ 23 июня 2009

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

1 голос
/ 25 июня 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...