Edgewall Software

Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#12329 closed defect (fixed)

WARNING: Diff rendering failed for property svnmerge-integrated with renderer SubversionMergePropertyDiffRenderer — at Version 9

Reported by: Ryan J Ollos Owned by: Ryan J Ollos
Priority: normal Milestone: 1.0.12
Component: version control Version:
Severity: normal Keywords: svn
Cc: Branch:
Release Notes:

Fixed ValueError rendering property diff of svnmerge-integrated properties, which were added by the svnmerge.py script.

API Changes:
Internal Changes:

Description

Another issue found in the logs. Probably not too significant, but hopefully we can raise a TracError for invalid input.

2016-01-19 19:12:45,719 Trac[changeset] WARNING: Diff rendering failed for property svnmerge-integrated with renderer SubversionMergePropertyDiffRenderer:
Traceback (most recent call last):
  File "/usr/local/virtualenv/1.0-stable/lib/python2.7/site-packages/trac/versioncontrol/web_ui/changeset.py", line 811, in render_property_diff
    options)
  File "/usr/local/virtualenv/1.0-stable/lib/python2.7/site-packages/tracopt/versioncontrol/svn/svn_prop.py", line 367, in render_property_diff
    old_sources = parse_sources(old_props)
  File "/usr/local/virtualenv/1.0-stable/lib/python2.7/site-packages/tracopt/versioncontrol/svn/svn_prop.py", line 364, in parse_sources
    sources[spath] = (set(Ranges(inheritable)),
  File "/usr/local/virtualenv/1.0-stable/lib/python2.7/site-packages/trac/util/__init__.py", line 982, in __init__
    self.appendrange(r)
  File "/usr/local/virtualenv/1.0-stable/lib/python2.7/site-packages/trac/util/__init__.py", line 1000, in appendrange
    a, b = int(x), int(x)
ValueError: invalid literal for int() with base 10: '7014 /trunk:1-4559'

Change History (10)

comment:1 by Ryan J Ollos, 8 years ago

Owner: set to Ryan J Ollos

comment:2 by Ryan J Ollos, 8 years ago

Similar to #11308.

comment:3 by Ryan J Ollos, 8 years ago

Milestone: 1.0.101.0.11

comment:4 by Ryan J Ollos, 8 years ago

Milestone: 1.0.111.0.12

by Ryan J Ollos, 8 years ago

comment:5 by Jun Omae, 8 years ago

Nice find.

The svnmerge-integrated property is separated by spaces but newlines are used for svn:mergeinfo.

$ svn propget -r7084 svnmerge-integrated https://svn.edgewall.org/repos/trac/trunk
/branches/0.11-stable:1-6940,6942-6971,6973-6979,6981-7012,7014-7036,7077,7080,7082 /trunk:1-4559,5254-5420

According to https://svn.apache.org/repos/asf/subversion/trunk/contrib/client-side/svnmerge/svnmerge.py, svnmerge-* property separated by any whitespace.

def dict_from_revlist_prop(propvalue):
    """Given a property value as a string containing per-source revision
    lists, return a dictionary whose key is a source path identifier
    and whose value is the revisions for that source."""
    prop = {}

    # Multiple sources are separated by any whitespace.
    for L in propvalue.split():
        # We use rsplit to play safe and allow colons in pathids.
        pathid_str, revs = rsplit(L.strip(), ":", 1)

comment:6 by Ryan J Ollos, 8 years ago

The problem is seen in r7084, which has space-delimited svn properties rather than newline delimited properties.

The property changes are:

Index: trunk
===================================================================
--- trunk       (revision 7083)
+++ trunk       (revision 7084)

Property changes on: trunk
___________________________________________________________________
Modified: svnmerge-integrated
## -1 +1 ##
-/branches/0.11-stable:1-6940,6942-6971,6973-6979,6981-7012,7014-7036,7077,7080 /trunk:1-4559,5254-5420
\ No newline at end of property
+/branches/0.11-stable:1-6940,6942-6971,6973-6979,6981-7012,7014-7036,7077,7080,7082 /trunk:1-4559,5254-5420
\ No newline at end of property
$ svn pg svnmerge-integrated -r 7084 https://svn.edgewall.org/repos/trac/trunk
/branches/0.11-stable:1-6940,6942-6971,6973-6979,6981-7012,7014-7036,7077,7080,7082 /trunk:1-4559,5254-5420

The property diff should be rendered like this:

The following patch seems to fix the issue:

  • tracopt/versioncontrol/svn/svn_prop.py

    diff --git a/tracopt/versioncontrol/svn/svn_prop.py b/tracopt/versioncontrol/svn/svn_prop.py
    index eb7d1e0..3edda66 100644
    a b  
    1616# Author: Christopher Lenz <cmlenz@gmx.de>
    1717#         Christian Boos <cboos@edgewall.org>
    1818
     19import re
    1920import posixpath
    2021
    2122from genshi.builder import tag
    class SubversionMergePropertyDiffRenderer(Component):  
    356357        repos = rm.get_repository(old_context.resource.parent.id)
    357358        def parse_sources(props):
    358359            sources = {}
    359             for line in props[name].splitlines():
     360            for line in re.split('\s+', props[name]):
    360361                path, revs = line.split(':', 1)
    361362                spath = _path_within_scope(repos.scope, path)
    362363                if spath is not None:

That's not a good solution though because paths can have whitespace, such as in this little test example that I ran:

$svn pg svn:mergeinfo trunk
/branches/rel 2.0:23

Also, from what I recall properties should be newline delimited, not whitespace delimited. It looks like svnmerge-integrated was probably created by the svnmerge script, which I assume is a tool that was useful prior to the addition of svn:mergeinfo in SVN 1.5.

If the svnmerge-* properties are deprecated, and they are effectively malformed by using whitespace rather than newline delimiters, one possible resolution would be to just turn off rendering of the properties:

hide_properties = svk:merge, svnmerge-integrated, svnmerge-blocked

in reply to:  5 comment:7 by Ryan J Ollos, 8 years ago

Replying to Jun Omae:

According to https://svn.apache.org/repos/asf/subversion/trunk/contrib/client-side/svnmerge/svnmerge.py, svnmerge-* property separated by any whitespace.

def dict_from_revlist_prop(propvalue):
    """Given a property value as a string containing per-source revision
    lists, return a dictionary whose key is a source path identifier
    and whose value is the revisions for that source."""
    prop = {}

    # Multiple sources are separated by any whitespace.
    for L in propvalue.split():
        # We use rsplit to play safe and allow colons in pathids.
        pathid_str, revs = rsplit(L.strip(), ":", 1)

I have to assume then that svnmerge.py would not store a path with whitespace encoding the path. With that information, maybe the proper solution involves parsing svnmerge-* differently from svn:mergeinfo.

comment:8 by Jun Omae, 8 years ago

Yeah. I think we could simply fix it like this:

  • tracopt/versioncontrol/svn/svn_prop.py

    diff --git a/tracopt/versioncontrol/svn/svn_prop.py b/tracopt/versioncontrol/svn/svn_prop.py
    index eb7d1e037..1ac9fcd68 100644
    a b class SubversionMergePropertyDiffRenderer(Component):  
    356356        repos = rm.get_repository(old_context.resource.parent.id)
    357357        def parse_sources(props):
    358358            sources = {}
    359             for line in props[name].splitlines():
     359            value = props[name]
     360            lines = value.splitlines() if name == 'svn:mergeinfo' else \
     361                    value.split()
     362            for line in lines:
    360363                path, revs = line.split(':', 1)
    361364                spath = _path_within_scope(repos.scope, path)
    362365                if spath is not None:

comment:9 by Ryan J Ollos, 8 years ago

Release Notes: modified (diff)
Resolution: fixed
Status: assignedclosed

Committed to 1.0-stable in [14857], merged to trunk in [14858].

Note: See TracTickets for help on using tickets.