Как искать все изменения файла в репозитории SubVersion?

Я хотел бы grep все изменения файла для строки. например найти, когда функция была добавлена ​​или удалена.

Есть ли "простой" способ сделать это? (т.е. простая командная строка bash была бы приятной.) Выполнение ручного двоичного поиска путем проверки ревизий и тестирования по отдельности кажется слишком утомительным и подверженным ошибкам.

Если бы я был достаточно умен, чтобы совершить изменение с полезным описанием, я могу grep создать журнал с чем-то вроде:

svn log myfile.c | grep my_func

Это не дает номер версии, поэтому я подозреваю, что есть лучший способ сделать это.

Ответ 1

Я написал script, чтобы сделать это

Типичное использование:

perl searchrev.pl Import.php setImportStatus

----------------------------------------------------------------------
r19565 | johnf | 2009-06-24 14:33:00 +0100 (Wed, 24 Jun 2009) | 1 line
----------------------------------------------------------------------
line 60 $this->setImportStatus($entity_id, $entity_attr_id);
---------------------------------------------------------------------
r13722 | john | 2008-03-10 17:06:14 +0000 (Mon, 10 Mar 2008) | 1 line
---------------------------------------------------------------------
line 70 $this->setImportStatus($entity_id, $entity_attr_id);
---------------------------------------------------------------------
r11692 | paul | 2007-05-23 10:55:45 +0100 (Wed, 23 May 2007) | 1 line
---------------------------------------------------------------------
Not found
---------------------------------------------------------------------
r11691 | paul | 2007-05-23 10:36:26 +0100 (Wed, 23 May 2007) | 1 line
---------------------------------------------------------------------
Not found
---------------------------------------------------------------------
r11683 | paul | 2007-05-23 09:04:29 +0100 (Wed, 23 May 2007) | 1 line
---------------------------------------------------------------------
Not found

Здесь script, легко взломать для ваших целей

#!/usr/bin/perl -w

my $file=$ARGV[0];
my $pattern=$ARGV[1];

my @history=`svn log $file`;
foreach (@history)
{
    chomp;
    if (m/^r(\d+)/)
    {
        my $revision=$1;
        my $sep='-' x length($_);

        print "$sep\n$_\n$sep\n";

        my @code=`svn cat -r $revision $file`;
        my $lineno=0;
        my $found=0;
        foreach my $line (@code)
        {
            $lineno++;
            if ($line=~m/$pattern/)
            {
                $line=~s/^\s+//;
                print "line $lineno $line";
                 $found=1;
            }
        }

        print "Not found\n" unless ($found);
    }
}

Ответ 2

Команда "аннотировать/винить" не делает именно то, что вы хотите, но это может помочь:

svn blame - Показывать информацию об авторе и ревизии в строке для указанных файлов или URL-адресов.

 $ svn blame http://svn.red-bean.com/repos/test/readme.txt
 3      sally This is a README file.
 5      harry You should read this.

Итак, вы должны узнать, кто добавил функцию. Что касается выяснения, кто удалил функцию, не знаю.

Ответ 3

С сервером Subversion 1.6 и его mod_dav_svn вы можете указать номер версии с помощью параметра GET:

http://host/repos/path?r=20

Таким образом, вы можете легко wget ваши файлы во всех версиях, а затем diff их.

Источник: SVN 1.6 changelog

Ответ 4

Это команда для поиска исправлений файла, содержащего строку:

svn log -l 30 -q FILENAME | grep ^r | cut -d ' ' -f 1 | while read rev; do
    svn cat -$rev FILENAME | grep -c PATTERN && svn info [email protected]$rev
done

Ответ 5

Первое, что вы хотите сделать, будет сложно. Обычно я предлагаю использовать svn diff или svn cat, но есть (насколько мне известно) никакого способа получить номер версии, встроенный в вывод кода.

Во втором вопросе, если вы ищете конкретного пользователя, вы можете использовать

svn log | grep -A 2 username

который даст вам две дополнительные строки после каждой согласованной строки (-A = "after" ). Если у вас очень мало сообщений журнала, вы можете использовать

svn log | grep -B 2 search_string

который будет аналогичным образом печатать две строки перед (-B) каждой согласованной линией. (Надеюсь, этого достаточно, чтобы дать вам номер версии.) Я абсолютно уверен, что с AWK есть лучший способ дать вам номера ревизий в соответствии с сообщениями журнала, но я устал, и я не могу думать это прямо сейчас.: D

Ответ 6

Насколько я знаю, это нелегко. Я бы написал небольшой script, который извлекает каждый набор изменений для рассматриваемого файла, а затем grep через diff для строки. Тогда это так же просто, как распечатать текущий номер версии:)

Ответ 7

Вы можете использовать pySVN + python diff tools, в то время как это не bash, возможно, стоит подумать, используете ли вы эту функцию на более регулярной основе. Это версия решения wget, но будет иметь более удобный интерфейс, если вы его построите:)