Умный экспорт из SVN с помощью консоли

    Использовать svn я начал, работая в windows и соответственно в качестве клиента использовал TortoiseSVN.
    В то время я был очень рад новой возможности, описанной в статье Умный экспорт из SVN при помощи TortoiseSVN.
    Совсем недавно сделал то, что давно не находилось времени сделать — поставил на свой рабочий компьютер linux.
    И вот незадача, ни в одном из графических клиентов, опробованных мной, не обнаружил схожей функциональности.
    Мало того. Почитав svn --help не нашёл опции, дающий такой результат.
    Обидно. Учитывая, что приучил уже отдел делать такие экспорты для плавного обновления проектов.
    В-общем, не буду тянуть: написал на bash скрипт, реализующий сравнение и экспорт отличий между двумя ревизиями.


    Код


    #!/bin/bash
    
    if [ $# -lt 2 ] ; then
     echo "usage: start_revision end_revision [project_name]"
     exit 0
    fi
    
    dir_prefix='!UPDATES/'
    svn_repo='svn://<svn_host>:<svn_port>'
    
    
    if [[ $3 != '' ]]
        then
            project=$svn_repo'/'$3'/'
        fi
    revision_start=$1
    revision_end=$2
    
    files=`svn diff --summarize -r $revision_start:$revision_end $project | awk '{print \$2}'`
    echo "svn diff --summarize -r $revision_start:$revision_end $project | awk '{print \$2}'"
    declare -a filelist
    i=0
    for file in $files;
    do
        dir=''
        filelist[$i]=`echo $file | sed -e 's/\//\n/g'`
        j=0
        declare -a items
        for item in ${filelist[$i]};
        do
            items[$j]=$item
            j=`echo $j+1 | bc`
        done
    
        #create dirs
        j=0
        cur_dir=''
        els_count=`echo ${#items[@]}-1 | bc`
        for ditem in ${items[@]};
        do
            if [[ $j = $els_count ]] #if lat element - it's filename
            then
                #store filename
                file_name=$ditem
                break
            fi
            cur_dir=$cur_dir$ditem'/'
            j=`echo $j+1 | bc`
        done
        dir=${dir_prefix}`date +%Y-%m-%d`'/'${revision_end}'/'$cur_dir
        mkdir -p $dir
    
        #export files in created dirs
        svn export -r $revision_end $project$file ./$dir$file_name
    
        i=`echo $i+1 | bc`
    done


    Настройка


    Прописать хост, на котором находится svn-сервер.

    Использование


    1. Набрать в директории с рабочей копией <имя скрипта> <начальная ревизия> <конечная ревизия>
    2. Либо набрать в произвольной директории <имя скрипта> <начальная ревизия> <конечная ревизия> <путь внутри репозитория>


    В результате в текущей директории появится каталог !UPDATES/текущая дата/номер конечной ревизии/, в котором будут изменившиеся между этими номерами ревизий с учётом вложенности каталогов.

    Пользуйтесь. =)
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 34

      0
      спасибо конечно за скрипт
      но не могли бы вы конкретней описать опцию, дающий такой результат.
      а то не сразу понятно что за результат?

      svn diff [-r N[:M]] --old=OLD-TGT[@OLDREV] [--new=NEW-TGT[@NEWREV]]
      ?

      тк не поставлина задача сложно что-то сказать
      но мне кажется что решение должно быть и по проще =) (с помощь awk и тп)
        0
        Задача описана в статье «Умный экспорт из SVN при помощи TortoiseSVN», ссылка на которую дана в начале.
        Если коротко, то я хочу экспортнуть из репозитория файлы, которые были изменены в промежутке между начальной и конечной ревизиями. Чтобы потом их залить уже на живой проект. Простым копированием.

        svn diff же даёт вывод утилиты diff, применённой к изменившемся файлам.

        Что же касается сложности скрипта, то я его сделал за 2 часа не зная ни bash, ни awk, ни sed. И теперь пользуюсь им каждый день.
        Я уверен, что это можно было бы сделать проще, но у меня вышло так. И на этом остановился, потому как скрипт стал делать то, что я хотел от него получить.
          0
          Держу отдельную рабочую копию для заливки на сервер.
          Для заливки использую rsync -avzC -e ssh…

          Отправляются только измененные файлы, файлы архивируются и упаковываются в блоки большего размера. Все передается через защищенный туннель.

          Рекомендую!
            0
            честно, не знаю что такое «умный экспорт», но в линуксе есть хороший редактор, называется Geany, и у него есть опция показывающая (не в лучшем виде конечно, но все изменения четки и ясны) изменения между текущей и предидущей ревизией… может быть это то чего Вам не хватало?
              0
              Тут штука вот в чём. Изменения между текущей и предыдущей ревизией и без специальных редакторов посмотреть можно.
              Например, просто консольной командой svn diff --summarize
              А скрипт написан для повторения функционала TortoiseSVN, а именно получения изменившейся части дерева проекта с учётом вложенности каталогов.
              Вручную же собирать это дело, глядя на вывод svn diff --summarize надоедает уже на третий раз.
          0
          а че не в тематический блог написано?
            0
            А в какой? Я когда искал, подходящего не нашёл. Как раз думал может кто в комментариях предложит.
              0
              А вот врочем перенёс в «Управление проектами», в котором опубликована родительская статья.
              0
              Кстати если сервер выделенный (можно поставить svn), например тестовый, то можно использовать svn клиент на сервере.
              И командой svn up апдейтить рабочую копию на сервере. А еще можно cruise control поставить…
                0
                В-общем, тоже выход.
                Однако, на продакшене будут лежать «мусорные» каталоги .svn, что мне не нравится.
                Да и к тому же если мне нужно обновить функциональность не просто до какой-то ревизии, а допустим только 3-4 и 9-11 (условно обозначим номера ревизий), при этом нельзя допустить заливку 5-8, то как-то получается неудобно.
                Конечно, дело можно поправить, проводя изменения только в бранчах, а то что нужно залить мержить в транк… Но вот пока я до этого не дошёл. Ну и .svn как-то совсем не радует.

                Да и не стоит забывать, что на девелоперском сервере и боевом в проекте разные ini, которые так же хранятся в svn. При обновлении точно могут возникнуть проблемы.
                  –1
                  Аргумент cleanup команды svn специально чтобы вас обрадовать сделали.
                    +1
                    svn help cleanup
                    cleanup: Recursively clean up the working copy, removing locks, resuming
                    unfinished operations, etc.

                    Видимо не для меня. cleanup не удаляет .svn
                      –1
                      Удаляет, попробуйте сами.
                        0
                        Только что проверил. Не удаляет. Версия svn 1.5.1.
                        Да и судя по описанию команды не должен удалять. Может мы о разном говорим?
                  • НЛО прилетело и опубликовало эту надпись здесь
                      0
                      Попробуйте svn export, вам должно понравиться :)

                      hint: svn help export
                        0
                        О нём и статья =)
                          0
                          чёрт :)
                          Чепуху написал, да
                        0
                        ну а разве сложно сделать так, чтобы сайт подхватывал инишники в зависимости от продакшена/девелопмента? и головная боль с автоматической выкаткой на живой в плане подключения разных инишников отпадет сама собой
                      +1
                      Вообще достаточно странный подход заливать отдельные файлы проекта для релиза. Может стоит пойти в сторону более четко сформулированных релизов? Где релиз есть атомарная единица — четко характеризующася ревизией в репозитории и подразумевающую полную перезаливку файлов из нужной ревизии применяя попутно нужные проперти файлов? А обозначенные варианты — залить кусочек проекта куда то — это не серьезно — у вас в транке всегда должна лежать живая версия, которая находиться в продакшене.
                        0
                        Поддерживаю вашу идею об атомарности релизов: релиз = версия в SVN — правильный подход. Но вот идея о том, что «в транке всегда должна лежать живая версия, которая находиться в продакшене» выглядит несколько странно.
                        В транке традиционно находится головная версия разработки. На сколько она «валидна» определяется процессами автоматической сборки и автоматизированного тестирования.
                        Версии же, находящиеся в production, помечаются соответствующими тегами. А при необходимости внести фикс непосредственно в production, есть смысл сделать branch в svn и исправить там.
                        Так у вас всегда будет доступ как к головной версии разработке, так и к той версии, которая ушла на production, со всеми изменениями, патчами и хотфиксами.
                          +1
                          В нашей организации есть следующий подход релизов и билдов. Каждую неделю у нас выходит билд — в среду заморозка кода для этого билда и в пятницу пуш кода. Есть множество команд которые работают над своими ветками (ветки создаются из транка в момент создания проекта — точнее подпроекта для главного проекта). Что происходит — за месяц — два до намеченного выхода вашей версии — вы создаете бренч из транка и работаете в нем — ближе к релизу все команды мержжатся в ветку для этого релиза — потом релиз морозиться и тестируются, проходя несколько альфа релизов. Затем когда релиз готов — и зарелизин и все эмергенси баги зафикшены код заливается в транк. Идея иметь код в транке следующая — в условиях конкурентных проектов, вы не можете знать что и как происходит. И надо всегда иметь отправную точку.

                          Для справки — у нас порядка 140 девелоперов и десятка три конкурентных проектов для одного большого проекта — и поэтому иметь в транке весь мусор никак нельзя.

                            0
                            Согласен. При разработке продукта такого масштаба — самый разумный подход. Описанный мною процесс работает для небольших команд, скажем, человек по 10-20.

                            Я сталкивался с выносом разработки по каждому релизу в бренч. В добавок, каждый дефект порождал свой бренч. Но все это уже плохо уживается с svn, в качестве инструмента использовался Rational Clear Case.

                            Скажите, у вас не наблюдается крупных проблем с множественным мержем в svn? Например, когда команды начинают сливать свои изменения в ветку релиза?
                              0
                              Сильно больших проблем не замечается, хотя подумываем в сторону дргих систем вроде GIT
                              0
                              А что у вас понимается под конкурентным проектом? это версии одного и того же продукта? тогда почему в транке не лежит самая последняя версия? Ведь идея в том, что в транке должны находиться наиболее поздние версии приложения. Я не прав? может специфика вашего приложения как-то влияет на структуру репозитория, если да, то как именно? Есть ли какие-то особенности кроме вышеописанных? Что имеется в виду под «отправной точкой»? Почему бранчи не могут быть просто по возможности максимально независимыми (если это ведение того, что вы называете «конкурентным проектом»)?

                              Судя по написанному вами, у вас в компании вполне адекватный подход к ведению репозитория. Интересуюсь, может еще что-то полезное могу для себя извлечь.
                            0
                            Ну в проекте 2500 файлов и из-за того что изменилось штук 10 всё перезаливать сильно долго.
                              0
                              Если изменилось 10 файлов, то только 10 файлов и перезальются
                                0
                                релиз — это совокупност файлов
                                  0
                                  А я здесь про релиз и не говорил ничего.
                                  Да и вообще, о чём спор? Я просто реализовал функциональность имеющуюся в TortoiseSVN.
                                  Которую предлагаю тем, кому нехватает. Не более того.
                              0
                              Почему не rsync?
                                0
                                Ну и ещё потому, что есть только ftp.
                                  0
                                  lftp с ключиком R

                                  ИМХО, синхронизация это не дело VCS, хотя бы потому, что оно привязано к конкретной системе.
                                    0
                                    Для синхронизации я пока что использую свой мозг, а скрипт — просто небольшой небольшой вспомогательный инструмент.
                                0
                                SmartSVN + SmartCVS + SmartSynchronize (http://www.syntevo.com/)

                                Прекрасная разработка, правда для нашего проекта оказалась великоватой, — для однократного использования это как танк окупать для проезда в магазин за хлебом :)

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое