[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [PATCH] Support format 10 in change-svn-wc-format.py

From: Julian Foad <julianfoad_at_btopenworld.com>
Date: Tue, 07 Oct 2008 17:22:33 +0100

On Tue, 2008-10-07 at 17:46 +0200, Daniel Shahaf wrote:
> The attached patch adds support for wc format 10 (for Subversion 1.6) to
> change-svn-wc-format.py. Review from someone more familiar with this
> area of the code would be welcome.

I'm not familiar but will review anyway.

> [[[
> Support wc format 10 in 'change-svn-wc-format.py':
>
> * tools/client-side/change-svn-wc-format.py
> (re, string.lower, string.upper): Import.

I don't mention imports and includes, only symbols that I'm creating or
modifying or deleting. But no big deal.

> (LATEST_FORMATS): Add format 10 for Subversion 1.6.
> (Entries.entry_fields):
> Add 'tree-conflicts' and 'file-externals' fields.
> (Entry.must_retain_fields):
> Convert to hash of tuples. Extend for format 10.
> (Entry.assert_valid_format):
> Add special-case check for the new URL canonicalization in format 10.
>
> Also, add some infrastructure:
>
> * tools/client-side/change-svn-wc-format.py
> (WCFormatConverter.write_dir_format):
> Pass old format number to write_format().
> (Entries.parse):
> Promote 'format_nbr' to class member (from local variable).
> (Entries.write_format):
> Add 'old_format_nbr' parameter.
> Use it to overwrite all bytes of the old format number (otherwise,
> overwriting format 10 by format 9 would leave format 90).
> ]]]
>
> Index: tools/client-side/change-svn-wc-format.py
> ===================================================================
> --- tools/client-side/change-svn-wc-format.py (revision 33499)
> +++ tools/client-side/change-svn-wc-format.py (working copy)
> @@ -19,6 +19,9 @@
> import sys
> import os
> import getopt
> +import re
> +from string import lower, upper
> +
> try:
> my_getopt = getopt.gnu_getopt
> except AttributeError:
> @@ -36,7 +39,9 @@ except:
> ### 1.3 and lower. It could be rolled into this script.
>
> LATEST_FORMATS = { "1.4" : 8,
> - "1.5" : 9 }
> + "1.5" : 9,
> + "1.6" : 10,
> + }
>
> def usage_and_exit(error_msg=None):
> """Write usage information and exit. If ERROR_MSG is provide, that
> @@ -113,7 +118,7 @@ class WCFormatConverter:
>
> if self.verbosity:
> print "Writing WC format"
> - entries.write_format(format_nbr)
> + entries.write_format(format_nbr, entries.format_nbr)
> break
>
> def change_wc_format(self, format_nbr):
> @@ -164,8 +169,13 @@ class Entries:
> "keep-local",
> "working-size",
> "depth",
> + "tree-conflicts",
> + "file-external",
> )
>
> + # The format number.
> + format_nbr = -1
> +
> def __init__(self, path):
> self.path = path
> self.entries = []
> @@ -176,15 +186,15 @@ class Entries:
>
> input = open(self.path, "r")
>
> - # Read and discard WC format number from INPUT. Validate that it
> + # Read WC format number from INPUT. Validate that it
> # is a supported format for conversion.
> format_line = input.readline()
> try:
> - format_nbr = int(format_line)
> + self.format_nbr = int(format_line)
> except ValueError:
> - format_nbr = -1
> - if not format_nbr in LATEST_FORMATS.values():
> - raise UnrecognizedWCFormatException(format_nbr, self.path)
> + self.format_nbr = -1
> + if not self.format_nbr in LATEST_FORMATS.values():
> + raise UnrecognizedWCFormatException(self.format_nbr, self.path)
>
> # Parse file into individual entries, to later inspect for
> # non-convertable data.
> @@ -232,19 +242,31 @@ class Entries:
> print "-" * 76
> return entry
>
> - def write_format(self, format_nbr):
> + def write_format(self, format_nbr, old_format_nbr):
> + # Overwrite all bytes of the format number (which are the first bytes in
> + # the file). Take advantage of the fact that Subversion 1.4 and later
> + # ignore leading zeroes in the format number.
> + assert(format_nbr <= old_format_nbr)
> + bytes_to_overwrite = len(str(old_format_nbr))
> + format_string = '%0' + str(bytes_to_overwrite) + 'd'
> +
> os.chmod(self.path, 0600)
> output = open(self.path, "r+", 0)
> - output.write("%d" % format_nbr)
> + output.write(format_string % format_nbr)
> output.close()
> os.chmod(self.path, 0400)
>
> class Entry:
> "Describes an entry in a WC."
>
> - # The list of field indices within an entry's record which must be
> - # retained for 1.5 -> 1.4 migration (changelist, keep-local, and depth).
> - must_retain_fields = (30, 31, 33)
> + # Maps format numbers to fields indices within an entry's record that must be
> + # retained when downgrading to that format.

I know you didn't change this, but it looks like these are the indices
that must be _discarded_ rather than those that must be retained.

> + must_retain_fields = {
> + # Not in 1.4: changelist, keep-local, depth, tree-conflicts, file-externals
> + 8 : (30, 31, 33, 34, 35),
> + # Not in 1.5: tree-conflicts, file-externals
> + 9 : (34, 35),
> + }
>
> def __init__(self):
> self.fields = []
> @@ -254,9 +276,25 @@ class Entry:
>
> # Check whether lossy conversion is being attempted.
> lossy_fields = []
> - for field_index in self.must_retain_fields:
> + for field_index in self.must_retain_fields[format_nbr]:
> if len(self.fields) - 1 >= field_index and self.fields[field_index]:
> lossy_fields.append(Entries.entry_fields[field_index])
> +
> + # Special case: format 10 changed the canonicalisation of URLs (r33236).
> + if format_nbr < 10:

Shouldn't this conversion happen only when format_nbr < 10 and the old
format number is >= 10? Not, for example, when downgrading from 9 to 8.

> + url_fields = { 3 : 'url', 4 : 'repos', 20 : 'copyfrom-url'}
> + for field_index in url_fields.keys():
> + if len(self.fields) - 1 >= field_index and self.fields[field_index]:
> + # Check that scheme and hostname are in lowercase.
> + # See also change_case_of_hostname() in copy_tests.py.
> + value = self.fields[field_index]
> + m = re.match(r"^(.*)://([^/@]*@)?([^/]*)(/|$)", value)
> + if m:
> + scheme = m.group(1)
> + host = m.group(3)
> + if host != lower(host) or scheme != lower(scheme):
> + lossy_fields.append(url_fields[field_index])
> +
> if lossy_fields:
> raise LossyConversionException(lossy_fields,
> "Lossy WC format conversion requested for entry '%s'\n"

- Julian

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-10-07 18:22:53 CEST

This is an archived mail posted to the Subversion Dev mailing list.