Как клонировать часть хранилища SVN? - PullRequest
3 голосов
/ 03 июля 2010

У меня есть SVN-репозиторий, в котором много каталогов.Теперь я хотел бы клонировать этот репозиторий, оставив в нем только один конкретный каталог.И, конечно, мне не нужны какие-либо изменения, связанные с другими каталогами в этом новом хранилище.Как мне это сделать?Спасибо.

Ответы [ 3 ]

5 голосов
/ 03 июля 2010

Вам нужно будет создать дамп своего хранилища и отфильтровать нужные вам каталоги и ревизии. svndumpfilter - универсальный инструмент для этого. См. эту главу подрывной книги для примера.

0 голосов
/ 27 апреля 2016

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

Все становится немного сложнее, когда в хранилище содержатся файлы и копии.

Давайте рассмотрим простейший пример, когда папка проекта с именем MyProject была переименована в истории в TheProject.Другой файл с именем TheProject/copiedfile.txt был впоследствии скопирован в TheProject из папки AnotherLocation.Элементарная древовидная структура может выглядеть следующим образом.

...
+ AnotherLocation
|--- copiedfile.txt
|--- unwantedfile.txt
+ TheProject
|--- copiedfile.txt
|--- otherfile.txt 
...

Вы бы хотели, чтобы TheProject имел свой новый репозиторий.Таким образом, вы выгружаете свой репозиторий в файл и используете svndumpfilter для включения только TheProject, поскольку это имя проекта, которое вы видите в ревизии HEAD.

svndumpfilter include /TheProject < input.dump > output.dump

К сожалению, вы получаете эту ошибку от svndumpfilter

svndumpfilter: E200003: Invalid copy source path '/MyProject'

Это потому, что раньше TheProject назывался MyProject, и в прошлом он был переименован.Поскольку переименование - это, по сути, удаление и копирование, svndumpfilter не может найти источник копии, которая создает TheProject, и правильно выводит сообщение об ошибке.Поэтому мы снова пытаемся выполнить следующую команду, включающую также MyProject

svndumpfilter include /TheProject /MyProject < input.dump > output.dump

Svndumfilter теперь появляется с другой ошибкой.

svndumpfilter: E200003: Invalid copy source path '/AnotherLocation/copiedfile.txt'

Да, это потому, что copiedfile.txt былоскопировано с AnotherLocation на TheProject.Поэтому мы должны также включить этот файл, так как иначе мы не смогли бы скопировать его в `TheProject '.Попробуем еще раз.

svndumpfilter include /TheProject /MyProject /AnotherLocation/copiedfile.txt < input.dump > output.dump

Операция прошла успешно!В третий раз повезло, кажется!

Давайте попробуем загрузить наш отфильтрованный файл дампа в хранилище.

svnadmin create newrepo
svnadmin load newrepo < output.dump

Не так уж повезло в конце концов!Следующая ошибка возникает при загрузке

* editing path : AnotherLocation/copiedfile.txt ...svnadmin: E160013: File not found: transaction '1-1', path '/AnotherLocation/copiedfile.txt'

А!это потому, что мы забыли включить AnotherLocation, что необходимо, поскольку это родительская папка copiedfile.txt

svndumpfilter include /TheProject /MyProject /AnotherLocation < input.dump > output.dump

Хорошо, эта команда работает и загрузка также работает.К сожалению, теперь мы включили /AnotherLocation/unwantedfile.txt.Отсюда делается вывод, что использование svndumpfilter include на самом деле не работает, поскольку не дает нам детализации, к которой мы стремимся.Мы должны сделать все, используя svndumpfilter exclude, чтобы исключить все, что нам не нужно, и в результате мы получим репозиторий с необходимыми нам файлами.Достаточно сказать, что изобилует собственным набором проблем.Например, довольно легко исключить файлы, которые действительно требуются в хранилище.Если люди хотят пример этого, я могу расширить этот ответ.

Должен быть лучший путь.Оказывается, есть, но это коммерческое предложение.Мы разработали инструмент под названием Subdivision , который специализируется на извлечении файлов и папок из хранилища Subversion.Он также может удалять (или стирать) файлы из хранилища Subversion, а также разбивать хранилище на две части, гарантируя, что ни один из этих двух хранилищ не пропущен.Что делает Subdivision сияющим, так это тот факт, что он хранит в памяти представление всего хранилища и запускает алгоритмы, необходимые для решения всех проблем, с которыми мы столкнулись в приведенном выше примере.Это означает, что вы получаете необходимую степень детализации при извлечении нужных файлов только при сохранении времени пользователя, поскольку операция завершается за один проход.

0 голосов
/ 31 марта 2016

Другая возможность - это git svn clone, который извлекает только интересующий каталог. Затем его можно отправить в новый репозиторий SVN. Это легко? Нет, но если у вас нет доступа к серверу, это удобно. Я уверен, что есть лучший способ - но этот способ гарантирует, что вы случайно не перейдете к исходному репозиторию SVN.


    # original svn path
    git svn clone http://server/path/to/clone orig
    # SVN to put just your branch in
    svnadmin create new
    # add one entry, or git svn errors out...
    svn co file:///path/to/new new.wd
    mkdir new.wd/null
    svn add new.wd/null
    svn ci -m"add null" new.wd/null
    # clone our clone
    git clone file:///path/to/orig abc
    cd abc
    # set up svn path to the svn repo
    git svn init file:///path/to/new
    # pull data in (our one commit)
    git svn fetch
    # show the branches
    git branch -a
    # Prep the git repot for the push
    git rebase --onto remotes/git-svn --root master
    # finally push to the new svn repo.
    git svn dcommit

Нет, где я мог узнать, как это сделать, поэтому я придумал это. Вам может понадобиться возиться с файлами SVN Donf, например так:


    svn_repo="$(pwd)/new"
    user="myusername"
    echo '[/]' >> $svn_repo/conf/authz
    echo "$user = rw" >> $svn_repo/conf/authz
    echo '[users]' >> $svn_repo/conf/passwd
    echo "$user = test" >> $svn_repo/conf/passwd
    echo 'password-db = passwd' >> $svn_repo/conf/svnserve.conf
    echo "svn repo is file://$svn_repo"
    svn co file://$svn_repo svn.wd

В приведенном выше примере myusername будет иметь пароль test.

...