<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://andromeda.df.lu.lv/wiki/index.php?action=history&amp;feed=atom&amp;title=Change-svn-wc-format.py</id>
	<title>Change-svn-wc-format.py - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://andromeda.df.lu.lv/wiki/index.php?action=history&amp;feed=atom&amp;title=Change-svn-wc-format.py"/>
	<link rel="alternate" type="text/html" href="http://andromeda.df.lu.lv/wiki/index.php?title=Change-svn-wc-format.py&amp;action=history"/>
	<updated>2026-04-13T04:17:51Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>http://andromeda.df.lu.lv/wiki/index.php?title=Change-svn-wc-format.py&amp;diff=1060&amp;oldid=prev</id>
		<title>Girts: New page: &lt;pre&gt; #!/usr/bin/env python # # change-svn-wc-format.py: Change the format of a Subversion working copy. # # ==================================================================== #    Licen...</title>
		<link rel="alternate" type="text/html" href="http://andromeda.df.lu.lv/wiki/index.php?title=Change-svn-wc-format.py&amp;diff=1060&amp;oldid=prev"/>
		<updated>2009-11-15T18:54:19Z</updated>

		<summary type="html">&lt;p&gt;New page: &amp;lt;pre&amp;gt; #!/usr/bin/env python # # change-svn-wc-format.py: Change the format of a Subversion working copy. # # ==================================================================== #    Licen...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/usr/bin/env python&lt;br /&gt;
#&lt;br /&gt;
# change-svn-wc-format.py: Change the format of a Subversion working copy.&lt;br /&gt;
#&lt;br /&gt;
# ====================================================================&lt;br /&gt;
#    Licensed to the Subversion Corporation (SVN Corp.) under one&lt;br /&gt;
#    or more contributor license agreements.  See the NOTICE file&lt;br /&gt;
#    distributed with this work for additional information&lt;br /&gt;
#    regarding copyright ownership.  The SVN Corp. licenses this file&lt;br /&gt;
#    to you under the Apache License, Version 2.0 (the&lt;br /&gt;
#    &amp;quot;License&amp;quot;); you may not use this file except in compliance&lt;br /&gt;
#    with the License.  You may obtain a copy of the License at&lt;br /&gt;
#&lt;br /&gt;
#      http://www.apache.org/licenses/LICENSE-2.0&lt;br /&gt;
#&lt;br /&gt;
#    Unless required by applicable law or agreed to in writing,&lt;br /&gt;
#    software distributed under the License is distributed on an&lt;br /&gt;
#    &amp;quot;AS IS&amp;quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY&lt;br /&gt;
#    KIND, either express or implied.  See the License for the&lt;br /&gt;
#    specific language governing permissions and limitations&lt;br /&gt;
#    under the License.&lt;br /&gt;
# ====================================================================&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
import os&lt;br /&gt;
import getopt&lt;br /&gt;
try:&lt;br /&gt;
  my_getopt = getopt.gnu_getopt&lt;br /&gt;
except AttributeError:&lt;br /&gt;
  my_getopt = getopt.getopt&lt;br /&gt;
&lt;br /&gt;
### The entries file parser in subversion/tests/cmdline/svntest/entry.py&lt;br /&gt;
### handles the XML-based WC entries file format used by Subversion&lt;br /&gt;
### 1.3 and lower.  It could be rolled into this script.&lt;br /&gt;
&lt;br /&gt;
LATEST_FORMATS = { &amp;quot;1.4&amp;quot; : 8,&lt;br /&gt;
                   &amp;quot;1.5&amp;quot; : 9,&lt;br /&gt;
                   &amp;quot;1.6&amp;quot; : 10,&lt;br /&gt;
                   # Do NOT add format 11 here.  See comment in must_retain_fields&lt;br /&gt;
                   # for why.&lt;br /&gt;
                 }&lt;br /&gt;
&lt;br /&gt;
def usage_and_exit(error_msg=None):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;Write usage information and exit.  If ERROR_MSG is provide, that&lt;br /&gt;
  error message is printed first (to stderr), the usage info goes to&lt;br /&gt;
  stderr, and the script exits with a non-zero status.  Otherwise,&lt;br /&gt;
  usage info goes to stdout and the script exits with a zero status.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  progname = os.path.basename(sys.argv[0])&lt;br /&gt;
&lt;br /&gt;
  stream = error_msg and sys.stderr or sys.stdout&lt;br /&gt;
  if error_msg:&lt;br /&gt;
    stream.write(&amp;quot;ERROR: %s\n\n&amp;quot; % error_msg)&lt;br /&gt;
  stream.write(&amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
usage: %s WC_PATH SVN_VERSION [--verbose] [--force] [--skip-unknown-format]&lt;br /&gt;
       %s --help&lt;br /&gt;
&lt;br /&gt;
Change the format of a Subversion working copy to that of SVN_VERSION.&lt;br /&gt;
&lt;br /&gt;
  --skip-unknown-format    : skip directories with unknown working copy&lt;br /&gt;
                             format and continue the update&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot; % (progname, progname))&lt;br /&gt;
  stream.flush()&lt;br /&gt;
  sys.exit(error_msg and 1 or 0)&lt;br /&gt;
&lt;br /&gt;
def get_adm_dir():&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;Return the name of Subversion&amp;#039;s administrative directory,&lt;br /&gt;
  adjusted for the SVN_ASP_DOT_NET_HACK environment variable.  See&lt;br /&gt;
  &amp;lt;http://svn.collab.net/repos/svn/trunk/notes/asp-dot-net-hack.txt&amp;gt;&lt;br /&gt;
  for details.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  return &amp;quot;SVN_ASP_DOT_NET_HACK&amp;quot; in os.environ and &amp;quot;_svn&amp;quot; or &amp;quot;.svn&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class WCFormatConverter:&lt;br /&gt;
  &amp;quot;Performs WC format conversions.&amp;quot;&lt;br /&gt;
  root_path = None&lt;br /&gt;
  error_on_unrecognized = True&lt;br /&gt;
  force = False&lt;br /&gt;
  verbosity = 0&lt;br /&gt;
&lt;br /&gt;
  def write_dir_format(self, format_nbr, dirname, paths):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Attempt to write the WC format FORMAT_NBR to the entries file&lt;br /&gt;
    for DIRNAME.  Throws LossyConversionException when not in --force&lt;br /&gt;
    mode, and unconvertable WC data is encountered.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Avoid iterating in unversioned directories.&lt;br /&gt;
    if not (get_adm_dir() in paths):&lt;br /&gt;
      del paths[:]&lt;br /&gt;
      return&lt;br /&gt;
&lt;br /&gt;
    # Process the entries file for this versioned directory.&lt;br /&gt;
    if self.verbosity:&lt;br /&gt;
      print(&amp;quot;Processing directory &amp;#039;%s&amp;#039;&amp;quot; % dirname)&lt;br /&gt;
    entries = Entries(os.path.join(dirname, get_adm_dir(), &amp;quot;entries&amp;quot;))&lt;br /&gt;
    entries_parsed = True&lt;br /&gt;
    if self.verbosity:&lt;br /&gt;
      print(&amp;quot;Parsing file &amp;#039;%s&amp;#039;&amp;quot; % entries.path)&lt;br /&gt;
    try:&lt;br /&gt;
      entries.parse(self.verbosity)&lt;br /&gt;
    except UnrecognizedWCFormatException, e:&lt;br /&gt;
      if self.error_on_unrecognized:&lt;br /&gt;
        raise&lt;br /&gt;
      sys.stderr.write(&amp;quot;%s, skipping\n&amp;quot; % e)&lt;br /&gt;
      sys.stderr.flush()&lt;br /&gt;
      entries_parsed = False&lt;br /&gt;
&lt;br /&gt;
    if entries_parsed:&lt;br /&gt;
      format = Format(os.path.join(dirname, get_adm_dir(), &amp;quot;format&amp;quot;))&lt;br /&gt;
      if self.verbosity:&lt;br /&gt;
        print(&amp;quot;Updating file &amp;#039;%s&amp;#039;&amp;quot; % format.path)&lt;br /&gt;
      format.write_format(format_nbr, self.verbosity)&lt;br /&gt;
    else:&lt;br /&gt;
      if self.verbosity:&lt;br /&gt;
        print(&amp;quot;Skipping file &amp;#039;%s&amp;#039;&amp;quot; % format.path)&lt;br /&gt;
&lt;br /&gt;
    if self.verbosity:&lt;br /&gt;
      print(&amp;quot;Checking whether WC format can be converted&amp;quot;)&lt;br /&gt;
    try:&lt;br /&gt;
      entries.assert_valid_format(format_nbr, self.verbosity)&lt;br /&gt;
    except LossyConversionException, e:&lt;br /&gt;
      # In --force mode, ignore complaints about lossy conversion.&lt;br /&gt;
      if self.force:&lt;br /&gt;
        print(&amp;quot;WARNING: WC format conversion will be lossy. Dropping &amp;quot;\&lt;br /&gt;
              &amp;quot;field(s) %s &amp;quot; % &amp;quot;, &amp;quot;.join(e.lossy_fields))&lt;br /&gt;
      else:&lt;br /&gt;
        raise&lt;br /&gt;
&lt;br /&gt;
    if self.verbosity:&lt;br /&gt;
      print(&amp;quot;Writing WC format&amp;quot;)&lt;br /&gt;
    entries.write_format(format_nbr)&lt;br /&gt;
&lt;br /&gt;
  def change_wc_format(self, format_nbr):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Walk all paths in a WC tree, and change their format to&lt;br /&gt;
    FORMAT_NBR.  Throw LossyConversionException or NotImplementedError&lt;br /&gt;
    if the WC format should not be converted, or is unrecognized.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    for dirpath, dirs, files in os.walk(self.root_path):&lt;br /&gt;
      self.write_dir_format(format_nbr, dirpath, dirs + files)&lt;br /&gt;
&lt;br /&gt;
class Entries:&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;Represents a .svn/entries file.&lt;br /&gt;
&lt;br /&gt;
  &amp;#039;The entries file&amp;#039; section in subversion/libsvn_wc/README is a&lt;br /&gt;
  useful reference.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # The name and index of each field composing an entry&amp;#039;s record.&lt;br /&gt;
  entry_fields = (&lt;br /&gt;
    &amp;quot;name&amp;quot;,&lt;br /&gt;
    &amp;quot;kind&amp;quot;,&lt;br /&gt;
    &amp;quot;revision&amp;quot;,&lt;br /&gt;
    &amp;quot;url&amp;quot;,&lt;br /&gt;
    &amp;quot;repos&amp;quot;,&lt;br /&gt;
    &amp;quot;schedule&amp;quot;,&lt;br /&gt;
    &amp;quot;text-time&amp;quot;,&lt;br /&gt;
    &amp;quot;checksum&amp;quot;,&lt;br /&gt;
    &amp;quot;committed-date&amp;quot;,&lt;br /&gt;
    &amp;quot;committed-rev&amp;quot;,&lt;br /&gt;
    &amp;quot;last-author&amp;quot;,&lt;br /&gt;
    &amp;quot;has-props&amp;quot;,&lt;br /&gt;
    &amp;quot;has-prop-mods&amp;quot;,&lt;br /&gt;
    &amp;quot;cachable-props&amp;quot;,&lt;br /&gt;
    &amp;quot;present-props&amp;quot;,&lt;br /&gt;
    &amp;quot;conflict-old&amp;quot;,&lt;br /&gt;
    &amp;quot;conflict-new&amp;quot;,&lt;br /&gt;
    &amp;quot;conflict-wrk&amp;quot;,&lt;br /&gt;
    &amp;quot;prop-reject-file&amp;quot;,&lt;br /&gt;
    &amp;quot;copied&amp;quot;,&lt;br /&gt;
    &amp;quot;copyfrom-url&amp;quot;,&lt;br /&gt;
    &amp;quot;copyfrom-rev&amp;quot;,&lt;br /&gt;
    &amp;quot;deleted&amp;quot;,&lt;br /&gt;
    &amp;quot;absent&amp;quot;,&lt;br /&gt;
    &amp;quot;incomplete&amp;quot;,&lt;br /&gt;
    &amp;quot;uuid&amp;quot;,&lt;br /&gt;
    &amp;quot;lock-token&amp;quot;,&lt;br /&gt;
    &amp;quot;lock-owner&amp;quot;,&lt;br /&gt;
    &amp;quot;lock-comment&amp;quot;,&lt;br /&gt;
    &amp;quot;lock-creation-date&amp;quot;,&lt;br /&gt;
    &amp;quot;changelist&amp;quot;,&lt;br /&gt;
    &amp;quot;keep-local&amp;quot;,&lt;br /&gt;
    &amp;quot;working-size&amp;quot;,&lt;br /&gt;
    &amp;quot;depth&amp;quot;,&lt;br /&gt;
    &amp;quot;tree-conflicts&amp;quot;,&lt;br /&gt;
    &amp;quot;file-external&amp;quot;,&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
  # The format number.&lt;br /&gt;
  format_nbr = -1&lt;br /&gt;
&lt;br /&gt;
  # How many bytes the format number takes in the file.  (The format number&lt;br /&gt;
  # may have leading zeroes after using this script to convert format 10 to&lt;br /&gt;
  # format 9 -- which would write the format number as &amp;#039;09&amp;#039;.)&lt;br /&gt;
  format_nbr_bytes = -1&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, path):&lt;br /&gt;
    self.path = path&lt;br /&gt;
    self.entries = []&lt;br /&gt;
&lt;br /&gt;
  def parse(self, verbosity=0):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Parse the entries file.  Throw NotImplementedError if the WC&lt;br /&gt;
    format is unrecognized.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    input = open(self.path, &amp;quot;r&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # Read WC format number from INPUT.  Validate that it&lt;br /&gt;
    # is a supported format for conversion.&lt;br /&gt;
    format_line = input.readline()&lt;br /&gt;
    try:&lt;br /&gt;
      self.format_nbr = int(format_line)&lt;br /&gt;
      self.format_nbr_bytes = len(format_line.rstrip()) # remove &amp;#039;\n&amp;#039;&lt;br /&gt;
    except ValueError:&lt;br /&gt;
      self.format_nbr = -1&lt;br /&gt;
      self.format_nbr_bytes = -1&lt;br /&gt;
    if not self.format_nbr in LATEST_FORMATS.values():&lt;br /&gt;
      raise UnrecognizedWCFormatException(self.format_nbr, self.path)&lt;br /&gt;
&lt;br /&gt;
    # Parse file into individual entries, to later inspect for&lt;br /&gt;
    # non-convertable data.&lt;br /&gt;
    entry = None&lt;br /&gt;
    while True:&lt;br /&gt;
      entry = self.parse_entry(input, verbosity)&lt;br /&gt;
      if entry is None:&lt;br /&gt;
        break&lt;br /&gt;
      self.entries.append(entry)&lt;br /&gt;
&lt;br /&gt;
    input.close()&lt;br /&gt;
&lt;br /&gt;
  def assert_valid_format(self, format_nbr, verbosity=0):&lt;br /&gt;
    if verbosity &amp;gt;= 2:&lt;br /&gt;
      print(&amp;quot;Validating format for entries file &amp;#039;%s&amp;#039;&amp;quot; % self.path)&lt;br /&gt;
    for entry in self.entries:&lt;br /&gt;
      if verbosity &amp;gt;= 3:&lt;br /&gt;
        print(&amp;quot;Validating format for entry &amp;#039;%s&amp;#039;&amp;quot; % entry.get_name())&lt;br /&gt;
      try:&lt;br /&gt;
        entry.assert_valid_format(format_nbr)&lt;br /&gt;
      except LossyConversionException:&lt;br /&gt;
        if verbosity &amp;gt;= 3:&lt;br /&gt;
          sys.stderr.write(&amp;quot;Offending entry:\n%s\n&amp;quot; % entry)&lt;br /&gt;
          sys.stderr.flush()&lt;br /&gt;
        raise&lt;br /&gt;
&lt;br /&gt;
  def parse_entry(self, input, verbosity=0):&lt;br /&gt;
    &amp;quot;Read an individual entry from INPUT stream.&amp;quot;&lt;br /&gt;
    entry = None&lt;br /&gt;
&lt;br /&gt;
    while True:&lt;br /&gt;
      line = input.readline()&lt;br /&gt;
      if line in (&amp;quot;&amp;quot;, &amp;quot;\x0c\n&amp;quot;):&lt;br /&gt;
        # EOF or end of entry terminator encountered.&lt;br /&gt;
        break&lt;br /&gt;
&lt;br /&gt;
      if entry is None:&lt;br /&gt;
        entry = Entry()&lt;br /&gt;
&lt;br /&gt;
      # Retain the field value, ditching its field terminator (&amp;quot;\x0a&amp;quot;).&lt;br /&gt;
      entry.fields.append(line[:-1])&lt;br /&gt;
&lt;br /&gt;
    if entry is not None and verbosity &amp;gt;= 3:&lt;br /&gt;
      sys.stdout.write(str(entry))&lt;br /&gt;
      print(&amp;quot;-&amp;quot; * 76)&lt;br /&gt;
    return entry&lt;br /&gt;
&lt;br /&gt;
  def write_format(self, format_nbr):&lt;br /&gt;
    # Overwrite all bytes of the format number (which are the first bytes in&lt;br /&gt;
    # the file).  Overwrite format &amp;#039;10&amp;#039; by format &amp;#039;09&amp;#039;, which will be converted&lt;br /&gt;
    # to &amp;#039;9&amp;#039; by Subversion when it rewrites the file.  (Subversion 1.4 and later&lt;br /&gt;
    # ignore leading zeroes in the format number.)&lt;br /&gt;
    assert len(str(format_nbr)) &amp;lt;= self.format_nbr_bytes&lt;br /&gt;
    format_string = &amp;#039;%0&amp;#039; + str(self.format_nbr_bytes) + &amp;#039;d&amp;#039;&lt;br /&gt;
&lt;br /&gt;
    os.chmod(self.path, 0600)&lt;br /&gt;
    output = open(self.path, &amp;quot;r+&amp;quot;, 0)&lt;br /&gt;
    output.write(format_string % format_nbr)&lt;br /&gt;
    output.close()&lt;br /&gt;
    os.chmod(self.path, 0400)&lt;br /&gt;
&lt;br /&gt;
class Entry:&lt;br /&gt;
  &amp;quot;Describes an entry in a WC.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  # Maps format numbers to indices of fields within an entry&amp;#039;s record that must&lt;br /&gt;
  # be retained when downgrading to that format.&lt;br /&gt;
  must_retain_fields = {&lt;br /&gt;
      # Not in 1.4: changelist, keep-local, depth, tree-conflicts, file-externals&lt;br /&gt;
      8  : (30, 31, 33, 34, 35),&lt;br /&gt;
      # Not in 1.5: tree-conflicts, file-externals&lt;br /&gt;
      9  : (34, 35),&lt;br /&gt;
      10 : (),&lt;br /&gt;
      # Downgrading from format 11 (1.7-dev) to format 10 is not possible,&lt;br /&gt;
      # because 11 does not use has-props and cachable-props (but 10 does).&lt;br /&gt;
      # Naively downgrading in that situation causes properties to disappear&lt;br /&gt;
      # from the wc.&lt;br /&gt;
      #&lt;br /&gt;
      # Downgrading from the 1.7 SQLite-based format to format 10 is not&lt;br /&gt;
      # implemented.&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
  def __init__(self):&lt;br /&gt;
    self.fields = []&lt;br /&gt;
&lt;br /&gt;
  def assert_valid_format(self, format_nbr):&lt;br /&gt;
    &amp;quot;Assure that conversion will be non-lossy by examining fields.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # Check whether lossy conversion is being attempted.&lt;br /&gt;
    lossy_fields = []&lt;br /&gt;
    for field_index in self.must_retain_fields[format_nbr]:&lt;br /&gt;
      if len(self.fields) - 1 &amp;gt;= field_index and self.fields[field_index]:&lt;br /&gt;
        lossy_fields.append(Entries.entry_fields[field_index])&lt;br /&gt;
    if lossy_fields:&lt;br /&gt;
      raise LossyConversionException(lossy_fields,&lt;br /&gt;
        &amp;quot;Lossy WC format conversion requested for entry &amp;#039;%s&amp;#039;\n&amp;quot;&lt;br /&gt;
        &amp;quot;Data for the following field(s) is unsupported by older versions &amp;quot;&lt;br /&gt;
        &amp;quot;of\nSubversion, and is likely to be subsequently discarded, and/or &amp;quot;&lt;br /&gt;
        &amp;quot;have\nunexpected side-effects: %s\n\n&amp;quot;&lt;br /&gt;
        &amp;quot;WC format conversion was cancelled, use the --force option to &amp;quot;&lt;br /&gt;
        &amp;quot;override\nthe default behavior.&amp;quot;&lt;br /&gt;
        % (self.get_name(), &amp;quot;, &amp;quot;.join(lossy_fields)))&lt;br /&gt;
&lt;br /&gt;
  def get_name(self):&lt;br /&gt;
    &amp;quot;Return the name of this entry.&amp;quot;&lt;br /&gt;
    return len(self.fields) &amp;gt; 0 and self.fields[0] or &amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  def __str__(self):&lt;br /&gt;
    &amp;quot;Return all fields from this entry as a multi-line string.&amp;quot;&lt;br /&gt;
    rep = &amp;quot;&amp;quot;&lt;br /&gt;
    for i in range(0, len(self.fields)):&lt;br /&gt;
      rep += &amp;quot;[%s] %s\n&amp;quot; % (Entries.entry_fields[i], self.fields[i])&lt;br /&gt;
    return rep&lt;br /&gt;
&lt;br /&gt;
class Format:&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;Represents a .svn/format file.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  def __init__(self, path):&lt;br /&gt;
    self.path = path&lt;br /&gt;
&lt;br /&gt;
  def write_format(self, format_nbr, verbosity=0):&lt;br /&gt;
    format_string = &amp;#039;%d\n&amp;#039;&lt;br /&gt;
    if os.path.exists(self.path):&lt;br /&gt;
      if verbosity &amp;gt;= 1:&lt;br /&gt;
        print(&amp;quot;%s will be updated.&amp;quot; % self.path)&lt;br /&gt;
      os.chmod(self.path,0600)&lt;br /&gt;
    else:&lt;br /&gt;
      if verbosity &amp;gt;= 1:&lt;br /&gt;
        print(&amp;quot;%s does not exist, creating it.&amp;quot; % self.path)&lt;br /&gt;
    format = open(self.path, &amp;quot;w&amp;quot;)&lt;br /&gt;
    format.write(format_string % format_nbr)&lt;br /&gt;
    format.close()&lt;br /&gt;
    os.chmod(self.path, 0400)&lt;br /&gt;
&lt;br /&gt;
class LocalException(Exception):&lt;br /&gt;
  &amp;quot;&amp;quot;&amp;quot;Root of local exception class hierarchy.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  pass&lt;br /&gt;
&lt;br /&gt;
class LossyConversionException(LocalException):&lt;br /&gt;
  &amp;quot;Exception thrown when a lossy WC format conversion is requested.&amp;quot;&lt;br /&gt;
  def __init__(self, lossy_fields, str):&lt;br /&gt;
    self.lossy_fields = lossy_fields&lt;br /&gt;
    self.str = str&lt;br /&gt;
  def __str__(self):&lt;br /&gt;
    return self.str&lt;br /&gt;
&lt;br /&gt;
class UnrecognizedWCFormatException(LocalException):&lt;br /&gt;
  def __init__(self, format, path):&lt;br /&gt;
    self.format = format&lt;br /&gt;
    self.path = path&lt;br /&gt;
  def __str__(self):&lt;br /&gt;
    return (&amp;quot;Unrecognized WC format %d in &amp;#039;%s&amp;#039;; &amp;quot;&lt;br /&gt;
            &amp;quot;only formats 8, 9, and 10 can be supported&amp;quot;) % (self.format, self.path)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
  try:&lt;br /&gt;
    opts, args = my_getopt(sys.argv[1:], &amp;quot;vh?&amp;quot;,&lt;br /&gt;
                           [&amp;quot;debug&amp;quot;, &amp;quot;force&amp;quot;, &amp;quot;skip-unknown-format&amp;quot;,&lt;br /&gt;
                            &amp;quot;verbose&amp;quot;, &amp;quot;help&amp;quot;])&lt;br /&gt;
  except:&lt;br /&gt;
    usage_and_exit(&amp;quot;Unable to process arguments/options&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  converter = WCFormatConverter()&lt;br /&gt;
&lt;br /&gt;
  # Process arguments.&lt;br /&gt;
  if len(args) == 2:&lt;br /&gt;
    converter.root_path = args[0]&lt;br /&gt;
    svn_version = args[1]&lt;br /&gt;
  else:&lt;br /&gt;
    usage_and_exit()&lt;br /&gt;
&lt;br /&gt;
  # Process options.&lt;br /&gt;
  debug = False&lt;br /&gt;
  for opt, value in opts:&lt;br /&gt;
    if opt in (&amp;quot;--help&amp;quot;, &amp;quot;-h&amp;quot;, &amp;quot;-?&amp;quot;):&lt;br /&gt;
      usage_and_exit()&lt;br /&gt;
    elif opt == &amp;quot;--force&amp;quot;:&lt;br /&gt;
      converter.force = True&lt;br /&gt;
    elif opt == &amp;quot;--skip-unknown-format&amp;quot;:&lt;br /&gt;
      converter.error_on_unrecognized = False&lt;br /&gt;
    elif opt in (&amp;quot;--verbose&amp;quot;, &amp;quot;-v&amp;quot;):&lt;br /&gt;
      converter.verbosity += 1&lt;br /&gt;
    elif opt == &amp;quot;--debug&amp;quot;:&lt;br /&gt;
      debug = True&lt;br /&gt;
    else:&lt;br /&gt;
      usage_and_exit(&amp;quot;Unknown option &amp;#039;%s&amp;#039;&amp;quot; % opt)&lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    new_format_nbr = LATEST_FORMATS[svn_version]&lt;br /&gt;
  except KeyError:&lt;br /&gt;
    usage_and_exit(&amp;quot;Unsupported version number &amp;#039;%s&amp;#039;; &amp;quot;&lt;br /&gt;
                   &amp;quot;only 1.4, 1.5, and 1.6 can be supported&amp;quot; % svn_version)&lt;br /&gt;
&lt;br /&gt;
  try:&lt;br /&gt;
    converter.change_wc_format(new_format_nbr)&lt;br /&gt;
  except LocalException, e:&lt;br /&gt;
    if debug:&lt;br /&gt;
      raise&lt;br /&gt;
    sys.stderr.write(&amp;quot;%s\n&amp;quot; % e)&lt;br /&gt;
    sys.stderr.flush()&lt;br /&gt;
    sys.exit(1)&lt;br /&gt;
&lt;br /&gt;
  print(&amp;quot;Converted WC at &amp;#039;%s&amp;#039; into format %d for Subversion %s&amp;quot; % \&lt;br /&gt;
        (converter.root_path, new_format_nbr, svn_version))&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
  main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Girts</name></author>
		
	</entry>
</feed>