0

13,000 件のコミットがあるオンラインのレポがありますが、私はそれらの最後の 1000 件にしか興味がありません。それらをsvnsyncでコピーすることは可能ですか?

このローカル リポジトリから過去 1000 件のコミット以内にチェックアウトできるようにしたいのですが、サーバーからよりも高速である必要があります。

リビジョン番号は保持する必要があります。
svnsync将来のリビジョンをローカル リポジトリに正常に同期できる必要があります。

4

2 に答える 2

1

これらの最後の 1000 のリビジョンをどこにコピーしますか? svnsyncツールは、リビジョンの「コピー」ではなく、リポジトリの複製に使用されます。最新の 1000 リビジョンをリモートで取得する場合は、リビジョン範囲を指定できるsvnrdumpツールを使用してください。

于 2013-11-27T09:00:29.330 に答える
1

次の例では、リポジトリの最後の 45 件のコミットを保存します。ヘルパー python スクリプトは次のとおりです。

# svnsync 1.6.11
# rhel 6 x86_64

# params
svn_baserepourl="http://svn.igniterealtime.org/svn/repos"
svn_subdir="spark/trunk"
reponame=spark
skipuntil=13774


# well-known svnsync preparation
repopath=`pwd`/$reponame.svn
svnadmin create "$repopath"

echo '#!/bin/sh' >"$repopath"/hooks/pre-revprop-change
chmod +x "$repopath"/hooks/pre-revprop-change

svnsync init file://"$repopath" "$svn_baserepourl/$svn_subdir"

expectedfmt="4
layout sharded 1000"

if [ x"$expectedfmt" != x"$(cat "$repopath/db/format")" ]; then
    echo unknown db format
fi

# create database folder structure
( cd "$repopath/db" && echo $(for (( i=0; i<=$((skipuntil / 1000)) ; i++ )) ; do mkdir -p revprops/$i revs/$i; done ) )

# don't create last skipped revision
skipuntil=$((skipuntil - 1))

# create dummy revision files
( cd "$repopath/db" && for (( i=0; i<=$skipuntil; i++ )) ; do echo revprops/$((i/1000))/$i; echo revs/$((i/1000))/$i; done | xargs touch )

# update revision counter
echo $skipuntil >"$repopath/db/current"

# we need a valid revision file
cp "$repopath/db/revs/0/0" "$repopath/db/revs/$((skipuntil/1000))/$skipuntil"

# last skipped revision number
skipuntil=$((skipuntil + 1))

if false; then
    # TODO: if svnrdump available
    # mkdir in local repo
    # svnrdump last skipped revision and subdir
    # svnadmin load --parent-dir subdir
    :
else
    # checkout last skipped revision
    rm -rf temptree
    svn co -r $skipuntil "$svn_baserepourl/$svn_subdir" "temptree/$svn_subdir"
    cd temptree
    pushd "$svn_subdir"

    # save properties
    svn proplist --xml -v -R  | ~/svnprops.py >/tmp/propset.sh

    # remove .svn folders
    find . -name .svn -print0 | xargs -0 rm -rf

    popd

    # checkout our copy
    svn co "file://$repopath" .

    # add the files
    svn add --no-ignore --force .

    # delete automatic props
    for p in $(svn proplist -q -R | sort -u); do svn propdel -q -R $p; done

    # restore original props
    pushd "$svn_subdir"
    sh /tmp/propset.sh
    popd

    # commit the last skipped revision
    svn commit -m"shallow root"

    cd ..
    rm -rf temptree
fi

# update svnsync counters
svn propset --revprop -r 0 svn:sync-last-merged-rev $skipuntil  "file://$repopath"
svn propset --revprop -r 0 svn:sync-currently-copying $((skipuntil+1))  "file://$repopath"

# sync!
svnsync sync "file://$repopath"

これは、リポジトリ間で svn プロパティをコピーするための古い svnprops.py です。

#!/usr/bin/env python

import sys
import xml.sax
import xml.sax.handler

"""
<?xml version="1.0"?>
<properties>
<target
   path="file:///.snapshots/persist/builds/cyg-apt/cyg-apt.svn/trunk">
<property
   name="svn:ignore">build
</property>
</target>
</properties>
"""

class Subhandler:
  def __init__(self, mainHandler, parenthandler):
    self.mainHandler = mainHandler
    self.parenthandler = parenthandler
    self.subhandler = None
    self.lvl = 0
  def startElement(self, name, attributes):
    self.lvl = self.lvl + 1
  def characters(self, data):
    pass
  def endElement(self, name):
    self.lvl = self.lvl - 1

class Subhandler_properties(Subhandler):
  def startElement(self, name, attributes):
    pass
  def characters(self, data):
    pass
  def endElement(self, name):
    pass

class P1ropertiesDocHandler(xml.sax.handler.ContentHandler):
  def __init__(self):
    self.subhandler = None

  def startElement(self, name, attributes):
    if subhandler != None:
      subhandler.startElement(name, attributes)
    elif name == "properties":
      Subhandler_properties(self)

  def endElement(self, name):
    if subhandler != None:
      subhandler.endElement(name)

  def characters(self, data):
    if subhandler != None:
      subhandler.characters(data)


class PropertiesDocHandler(xml.sax.handler.ContentHandler):
  def __init__(self):
    self.target = None
    self.property = None

  def startElement(self, name, attributes):
    if name == "target":
      self.target = attributes["path"]
    elif name == "property":
      self.property = attributes["name"]
      self.propval = ""

  def endElement(self, name):
    if name == "target":
      self.target = None
    elif name == "property":
      print("svn ps \"" + self.property.replace("\"","\\\"") + "\" \"" + self.propval.replace("\"","\\\"") + "\" \"" + self.target.replace("\"","\\\"") + "\"")
      self.property = None
      self.propval = None

  def characters(self, data):
    if self.property != None:
      self.propval += data

parser = xml.sax.make_parser()
handler = PropertiesDocHandler()
parser.setContentHandler(handler)
#print("aa\"ass".replace("\"","\\\""))
parser.parse(sys.stdin)
于 2013-11-27T12:18:41.300 に答える