You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ar...@apache.org on 2012/07/30 08:39:38 UTC

svn commit: r1367002 [2/21] - in /subversion/branches/svn-bisect: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/client-side/emacs/ contrib/server-side/mod_dontdothat/ notes/ notes/api-errata/1.7/ notes/http-and-webdav/ ...

Modified: subversion/branches/svn-bisect/notes/dump-load-format.txt
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/notes/dump-load-format.txt?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/notes/dump-load-format.txt (original)
+++ subversion/branches/svn-bisect/notes/dump-load-format.txt Mon Jul 30 06:39:28 2012
@@ -1,139 +1,375 @@
-This file describes the format produced by 'svnadmin dump' and
-consumed by 'svnadmin load'.  
+= How to interpret Subversion dumpfiles =
 
-The format has undergone revisions over time.  They are presented in
-reverse chronological order here.  You may wish to start with the
-VERSION 1 description in order to get a baseline understanding first.
+Version 1.0, 2012-01-18
 
-===== SVN DUMPFILE VERSION 3 FORMAT =====
+== Introduction ==
 
-(generated by SVN versions 1.1.0-present, if requested by the user)
+The Subversion dumpfile format is a serialized description of the
+actions required to (re)build a version history. from scratch.
 
-This format is equivalent to the VERSION 2 format except for the
-following:
+The goal of this document is that it be sufficient for people writing
+dumpfile interpreters to emulate the actions the dumpfile describes on
+a versioned filesystem-like store, such as another version-control
+system.  It derives from and incorporates some incomplete notes from 
+before r39883.
 
-1.) The format starts with the new version number of the dump format
-    ("SVN-fs-dump-format-version: 3\n").
+1. In interpreting a Node record which has both a copyfrom source and
+a property section, it is possible that the copy source node itself
+has a property section.  How are they to be combined?
 
-2.) There are several new optional headers for node changes:
+Also note that the section on the semantics of kinds of operations 
+documents a minor bug at r39883 in the behavior of "add", which 
+should be fixed.
 
-[Text-delta: true|false]
-[Prop-delta: true|false]
-[Text-delta-base-md5: blob]
-[Text-delta-base-sha1: blob]
-[Text-copy-source-sha1: blob]
-[Text-content-sha1: blob]
+== Syntax ==
 
-    The default value for the boolean headers is "false".  If the value is
-    set to "true", then the text and property contents will be treated
-    as deltas against the previous contents of the node (as determined
-    by copy history for adds with history, or by the value in the
-    previous revision for changes--just as with commits).
+=== Encoding and delimiters ===
 
-Property deltas have the same format as regular property lists except
-that (1) properties with the same value as in the previous contents of
-the node are not printed, and (2) deleted properties will be written
-out as
+Subversion dumpfiles are plain byte streams. The structural parts are
+ASCII.  Text sections and property key/value pairs may be interpreted
+as binary data in any encoding by client tools.
 
-D <name length>
-<name>
+A dumpfile consists of four kinds of records.  A record is a group of
+RFC822-style header lines (each consisting of a key, followed by a
+colon, followed by text data to end of line), followed by an empty
+spacer line, followed optionally by a body section.  If the body
+section is present, another empty spacer line separates it from the
+following record.
 
-just as a regular property is printed, but with the "K " changed to a
-"D " and with no value part.
+For forward compatibility, unrecognized headers are ignored.
 
-Text deltas are written out as a series of svndiff0 windows.  If
-Text-delta-base-md5 is provided, it is the checksum of the base to
-which the text delta is applied; note that older versions (pre-1.5) of
-'svnadmin load' may ignore the checksum.
+=== Record types ===
 
-Text-delta-base-sha1, Text-copy-source-sha1, and Text-content-sha1 are not
-currently used by the loader.  They are written by 1.6-and-later versions of
-Subversion so that future loaders can optionally choose which checksum to
-use for checking for corruption.
+Dumpfiles include four record types.  Two, the version stamp and UUID
+record, consist of single header lines. The bulk of a dumpfile
+consists of Revision and Node records.
+
+A version stamp record is always the first line of the file and
+looks like this:
+
+-------------------------------------------------------------------
+SVN-fs-dump-format-version: <N>\n
+-------------------------------------------------------------------
+
+where <N> is replaced by the dump format version. Except where 
+specified, the descriptions in this document aapply to all
+versions of the format.
+
+Versions 2 and later may have a UUID record following the version
+stamp. It is of the form 
 
-===== SVN DUMPFILE VERSION 2 FORMAT =====
+-------------------------------------------------------------------
+UUID: <hex-string>
+-------------------------------------------------------------------
 
-(generated by SVN versions 0.18.0-present, by default)
+where the <hex-string> is the UUID of the originating repository.
+An example UUID is "7bf7a5ef-cabf-0310-b7d4-93df341afa7e".
 
-This format is equivalent to the VERSION 1 format in every respect,
-except for the following:
+A Revision record has three headers and is always followed by a
+property section.  Expect the following form and sequence:
+
+-------------------------------------------------------------------
+Revision-number: <N>
+Prop-content-length: <P>
+Content-length: <L>
+!
+-------------------------------------------------------------------
+
+with the Revision-number header always first and the '!' indicating
+a mandatory empty spacer line.  <P> gives the length in bytes of the
+following property section. <L> gives the body length of the entire
+Revision record.  These two numbers will be *identical* for a Revision
+record; the Content-length header is added for the benefit of software
+that can parse RFC-822 messages.
+
+A revision record is followed by one or more Node records (see below).
+
+=== Property sections ==
+
+A Revision record *must* have a property section, and a Node record *may*
+have a property section. Every record with a property section has 
+a Prop-content-length header.
+
+A property section consists of pairs of key and value records and
+is ended by a fixed trailer.  Here is an example attached to a
+Revision record:
+
+-------------------------------------------------------------------
+Revision-number: 1422
+Prop-content-length: 80
+Content-length: 80
+
+K 6
+author
+V 7
+sussman
+K 3
+log
+V 33
+Added two files, changed a third.
+PROPS-END
+-------------------------------------------------------------------
+
+The fixed trailer is "PROPS-END\n" and its length is included in the
+Prop-content-length. Before it, each K and V record consists of a
+header line giving the length of the key or value content in bytes.  
+The content follows.  The content is itself always followed by \n.
+
+In version 3 of the format, a third type 'D' of property record is
+introduced to describe property deletion. This feature will be
+described later, in the specification of delta dumps.
+
+=== Node records ===
+
+Each Revision record is followed by one or more Node records.
+Node records have the following sequence of header lines:
+
+-------------------------------------------------------------------
+Node-path: <path/to/node/in/filesystem>
+[Node-kind: {file | dir}]
+Node-action: {change | add | delete | replace}
+[Node-copyfrom-rev: <rev>]
+[Node-copyfrom-path: <path> ]
+[Text-copy-source-md5: <blob>]
+[Text-content-md5: <blob>]
+[Text-content-length: <T>]
+[Prop-content-length: <P>]
+[Content-length: Y]
+!
+-------------------------------------------------------------------
+
+Bracketing in [] indicates optional lines; { | } is an alternation group.
+
+Dump decoders should be prepared for the optional lines after
+Node-action to be in any order, except that Content-length is 
+always last if it present.
+
+A Node record describes an action on a path relative to the repository
+root, and always begins with the Node-path specification.
+
+The Node-kind line indicates whether the path is a file or directory.
+The header value will be one of the strings "file" or "dir". 
+This header may be (and usually is) absent if the node action is a delete.  
+
+The Node-action line is always present and specifies the type of
+operation for this node.  The header value is one of the strings
+"change", "add", "delete", or "replace".  These operations will be
+described in detail later in this document.
+
+Either both the Node-copyfrom-rev and Node-copyfrom-path lines will be
+present, or neither will be.  They pair to describe a copy source for
+the node. Copy-source semantics will be described in detail later in
+this document.
+
+The Text-content-md5 and Text-copy-source-md5 lines are hash integrity
+checks and will be present only if Text-content-length and the copfyrom
+pair (respectively) are also present. A decoder may use them to verify
+that the source content they refer to has not been corrupted.
+
+Text-content-length will be present only when there is a text section.
+Zero is a legal value for this length, indicating an empty file.
+
+Prop-content-length will be present only when there is a properties section.
+
+Content-length will be present if there is either a text or a
+properties section.  This is not always the case.  In particular, 
+a delete operation cannot have either.  Some other operations that use
+copyfrom sources may also not have either.
+
+Again, the '!' stands in for a mandatory empty line following the
+RFC822-style headers. A body may follow
+
+== Semantics ==
+
+=== The kinds of things ===
+
+There are four kinds of things described by a dumpfile: paths,
+properties, content, and flows.  The distinctions among content,
+paths, and flows matter for understanding some operations.
+
+A path is a filesystem location (a file or directory).  There are two
+kinds of paths in a dumpfile; node paths and copy sources.
+
+Properties are key-value pairs associated with revisions or paths.
+Subversion interprets and reserves some properties, those beginning
+with "svn:". Others are not interpreted by Subversion; they may 
+may be set and read for the convenience of other applications, such
+as repository browsers or translators.
+
+A flow is a sequence of actions on a file or directory path that is
+considered to be a single history for change-tracking purposes.
+Creating a flow tells Subversion that you want to track the history of
+the path or paths it contains. Destroying a flow breaks the chain of
+history; changes will not be tracked across the break, even if another
+flow is created at the same path.  A copy operation creates a new
+flow connected to the flow from which it was copied.
+
+Content is what file paths point at (one timewise slice of a flow). It
+is the payload of program source code, documents, images, and so forth
+that a version control system actually manages.
+
+A Node record describes a change in properties, the addition or deletion
+of a flow, or a change in content.  It nust do at least one of these things,
+otherwise it would be a no-op and omitted.
+
+When no copyfrom is present, and the action isn't an add or copy, then
+the kind of the thing identified by (PATH, REVISION) must agree with
+the kind of the thing identified by (PATH, -1+REVISION).
+
+Terminological node: in Subversion-speak, the term "node" is
+historically ambiguous.  Sometimes it refers to what this document
+calls a "flow", and sometimes it refers to the internal per-revision
+structure that a Node record represents (that is, just one action in a
+flow).  For clarity, most of this document avoids the term "node" in
+favor of the more specific "flow" and "Node record", but knowing 
+about this issue will help if you read the Ancient History section.
+
+=== The kinds of operations ===
+
+.File operations
+|======================================================================
+|                           |   add    | delete | replace  |  change  |
+|Can have text section?     | optional |   no   | optional | optional |
+|Can have property section? | optional |   no   | optional | optional |
+|Can have copy source?      | optional |   no   | optional |    no    |
+|Fails on existent path     |   yes*   |   no   |    no    |    no    |   
+|Fails on non-existent path |    no    |  yes   |   yes    |   yes    |   
+|======================================================================
+
+* As of December 2011 there is a minor bug: Adding a file with history
+twice _in two different revisions_ succeeds silently.
+
+.Directory operations
+|======================================================================
+|                           |   add    | delete | replace  |  change  |
+|Can have text section?     |    no    |   no   |    no    |    no    |
+|Can have property section? | optional |   no   | optional | required |
+|Can have copy source?      | optional |   no   | optional |    no    |
+|Fails on existent path     |   yes    |   no   |    no    |    no    |   
+|Fails on non-existent path |    no    |  yes   |   yes    |   yes    |   
+|======================================================================
+
+A Node record represents an operation that does one of four things: add,
+delete, change, or replace.
+
+Node records can carry content in one (or both!) of two ways: from a text
+section or from a copy source (that is, a copy-path and copy-revision
+pair).
+
+Giving a copy source appends the node to the flow of which that source
+is part; when you 'add' or 'replace' with a copy source, the content
+at the path becomes a copy of the source (but see below for a
+qualification about directories).
+
+Giving a text section also changes the content of the flow. In the
+(unusual) case that a node has both a copy source and a text section,
+the correct semantics is to attach the path to the source flow and
+then change the content.
+
+An add operation creates a new flow for a file or directory. See the
+table above for possible operand combinations.
+
+A delete operation deletes a flow and its content. If the path is a
+file, the file is deleted.  If the path is a directory, the directory
+and all its children are deleted. A subsequent add at the same path
+will create a new and different flow with its own history.
+
+A change operation changes properties on a file or directory path. See the
+table above for possible operand combinations.
+
+A replace operation behaves exactly like a delete followed by an add
+(destroying an old flow, producing a new one) when it has no copy
+source. When a replace has a copy source, it produces a new flow
+with history extending back through the copy source. A Node record
+representing a replace operation may have a property section.
+
+The main reason "replace" exists is because it helps sequential
+processors of the dump stream avoid possibly notifying about multiple
+actions on the same path.
+
+It is even possible to have a replace with a copyfrom source *and*
+text, such as would result from this on the client side:
+ 
+-------------------------------------------------------------------
+$ svn rm dir/file.txt
+$ svn cp otherdir/otherfile.txt dir/file.txt
+$ echo "Replacement text" > dir/file.txt
+$ svn ci -m "Replace dir/file.txt with a copy of otherdir/otherfile.txt and replace its text, too."
+-------------------------------------------------------------------
+
+$Subversion filesystems do not allow the root directory ("/") to be
+deleted or replaced.
+
+=== Some details about copyfroms ===
+
+The source and target of a copyfrom are always of like kind; that is,
+Subversion dump will never generate a node with a source type of file
+and a target type of directory or vice-versa.
+
+Interpreting copyfrom_path for file copies is straightforward; the
+target pathname gets the contents of the source pathname.
+
+Directory copies (the primitive beneath branching and tagging) are
+tricky.  For each source path under the source directory, a new path
+is generated by removing the head segment of the pathname that is
+the source directory.  That new path under the target directory gets
+the content of the source path.
+
+After this operation:
+
+-------------------------------------------------------------------
+Node-path: x/y/z
+Node-kind: dir
+Node-action: add
+Node-copyfrom-rev: 10
+Node-copyfrom-path: a/b/c
+-------------------------------------------------------------------
 
-1.) The format starts with the new version number of the dump format
-    ("SVN-fs-dump-format-version: 2\n").
-
-2.) In addition to "Revision Records", another sort of record is supported:
-    the "UUID" record, which should be of the form:
-
-UUID: 7bf7a5ef-cabf-0310-b7d4-93df341afa7e
-
-    This should be used to indicate the UUID of the originating repository.
-
-===== SVN DUMPFILE VERSION 1 FORMAT =====
-
-(generated by SVN versions prior to 0.18.0)
-
-The binary format starts with the version number of the dump format
-("SVN-fs-dump-format-version: 1\n"), followed by a series of revision
-records.  Each revision record starts with information about the
-revision, followed by a variable number of node changes for that
-revision.  Fields in [braces] are optional, and unknown headers are
-always ignored, for backwards compatibility.
-
-Revision-number: N
-Prop-content-length: P
-Content-length: L
-
-   ...P bytes of property data.  Properties are stored in the same
-   human-readable hashdump format used by working copy property files,
-   except that they end with "PROPS-END\n" for better readability.
-
-Node-path: absolute/path/to/node/in/filesystem
-Node-kind: file | dir  (1)
-Node-action: change | add | delete | replace
-[Node-copyfrom-rev: X]
-[Node-copyfrom-path: path ]
-[Text-copy-source-md5: blob] (2)
-[Text-content-md5: blob]
-[Text-content-length: T]
-[Prop-content-length: P]
-Content-length: Y (3)
-
-   ... Y bytes of content data, divided into P bytes of "property"
-   data and T bytes of "text" data.  The properties come first; their
-   total length (including formatting) is Prop-content-length, and is
-   included in Node-content-length.  The "PROPS-END\n" line always
-   terminates the property section if there are props.  The remainder
-   of the Y bytes (expected to be equivalent to Text-content-length)
-   represent the contents of the node.
-
-
-Notes:
-
-   (1) if the node represents a deletion, this field is optional.
-   
-   (2) this is a checksum of the source of the copy.  a loader process
-       can use this checksum to determine that the copyfrom path/rev
-       already present in a filesystem is really the *correct* one to
-       use.
-   
-   (3) the Content-length header is technically unnecessary, since the
-       information it holds (and more) can be found in the
-       Prop-content-length and Text-content-length fields.  Though
-       Subversion itself does not make use of the header when reading
-       a dumpfile, we include it for compatibility with generic RFC822
-       parsers.
-   
-   (4) There are actually 2 types of version 1 dump streams. The
-       regular ones are generated since r2634 (svn 0.14.0). Older ones
-       also claim to be version 1, but miss the Props-content-length
-       and Text-content-length fields in the block header. In those
-       days there *always* was a properties block.
-   
-EXAMPLE:
+the file a/b/c/d will have been be copied to x/y/z/d.
 
-Here's an example of revision 1422, whereby I added a new directory
+A single revision may include multiple copyfrom Node records, even multiple
+copyfroms to the same directory, even mixed directory and file copies
+to the same directory. 
+
+=== Properties and persistence ===
+
+The properties section of a Revision record consists of some subset
+of the three reserved per-commit properties: svn:author, svn:date,
+and svn.log. These properties do not persist to later revisions.
+
+The key thing to know about Node properties is that they are 
+persistent, once set, until modified by a future property 
+section on the same path.
+
+Normally, a dumpfile re-lists the entire property set for a directory
+or file in every Node record that changes any part of it. (But see
+the material on delta dumps for an exception.)
+
+This implies that to delete a given property from a path, a dumpfile
+generator will issue a Node record with all other properties listed in it;
+to delete all properties from a path, the dumpfile generator will
+simply issue a node with an empty properties section. Note that this
+is different from an *absent* properties section, which will change
+no properties and will be associated with a change to content!
+
+=== Implementation pragmatics ===
+
+Because directory operations with copyfroms don't specify all the file
+paths they modify, an interpreter for this format must build a map of
+the paths in the file store it is manipulating, and update that map as
+it processes each Node record.
+
+On a repository with thousands of commits, the per-revision list of
+maps can become quite large. For space economy, the file map for each 
+revision can be discarded after it is processed *unless it is a source
+revision for a copyfrom*. 
+
+== An example ==
+
+Here's an example of revision 1422, which added a new directory
 "baz", added a new file "bop" inside it, and modified the file "foo.c":
 
+-------------------------------------------------------------------
 Revision-number: 1422
 Prop-content-length: 80
 Content-length: 80
@@ -188,8 +424,79 @@ Content-length: 102
 
 Here is the fulltext of my change to an existing /bar/foo.c.
 Notice that this file has no properties.
+-------------------------------------------------------------------
+
+== Format variants ==
+
+=== Version 3 format ===
+
+Version 3 format is a delta dump; text changes are represented 
+as diffs against the original file, and properties as incremental
+changes to a persistent set (that is, a property section does not
+necessarily implcitly clear the property set on a path before the
+new property settings are evaluated).
+
+This change is a space optimization. It requires additional 
+computing time to integrate the diff history.
+
+Version 3 is generated by SVN versions 1.1.0-present, if requested by the user.
+
+This format is equivalent to the VERSION 2 format except for the
+following:
+
+1. The format starts with the new version number of the dump format
+   ("SVN-fs-dump-format-version: 3\n").
+
+2. There are several new optional headers for Node records:
+
+-------------------------------------------------------------------
+[Text-delta: true|false]
+[Prop-delta: true|false]
+[Text-delta-base-md5: blob]
+[Text-delta-base-sha1: blob]
+[Text-copy-source-sha1: blob]
+[Text-content-sha1: blob]
+-------------------------------------------------------------------
 
--*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*- -*-
+The default value for the boolean headers is "false".  If the value is
+set to "true", then the text and property contents will be treated
+as deltas against the previous contents of the flow (as determined
+by copy history for adds with history, or by the value in the
+previous revision for changes--just as with commits).
+
+Property deltas have the same format as regular property lists except
+that (1) properties with the same value as in the previous contents of
+the flow are not printed, and (2) deleted properties will be written
+out as
+
+D <name length>
+<name>
+
+just as a regular property is printed, but with the "K " changed to a
+"D " and with no value part.
+
+Text deltas are written out as a series of svndiff0 windows.  If
+Text-delta-base-md5 is provided, it is the checksum of the base to
+which the text delta is applied; note that older versions (pre-1.5) of
+'svnadmin load' may ignore the checksum.
+
+Text-delta-base-sha1, Text-copy-source-sha1, and Text-content-sha1 are not
+currently used by the loader.  They are written by 1.6-and-later versions of
+Subversion so that future loaders can optionally choose which checksum to
+use for checking for corruption.
+
+=== Archaic version 1 format ===
+
+There are actually two types of version 1 dump streams. The regular ones
+are generated since r2634 (svn 0.14.0). Older ones also claim to be
+version 1, but miss the Props-content-length and Text-content-length
+fields in the block header. In those days there *always* was a
+properties block.
+
+This note is included for historical completeness only, at is it highly
+unlikely that any Subversion instances that old remain in production.
+
+== Ancient history ==
 
 Old discussion: 
 
@@ -197,8 +504,7 @@ Old discussion: 
 
 A proposal for an svn filesystem dump/restore format.
 
-Two problems we want to solve
-=============================
+=== Two problems we want to solve ===
 
  1.  When we change our node-id schema, we need to migrate all of our
      data (by dumping and restoring).
@@ -207,8 +513,7 @@ Two problems we want to solve
      someday.
 
 
-Design Goals
-============
+=== Design Goals ===
 
  A.  Written as two new public functions in svn_fs.h.  To be invoked
      by new 'svnadmin' subcommands.
@@ -221,9 +526,7 @@ Design Goals
      backend.  In other words, we're talking about the basic ideas in
      our original "design spec" from May 2000.
 
-
-Format Semantics
-================
+=== Format Semantics ===
 
 Here are the timeless semantics of our fs design -- the things that
 would be stored in our dump format.
@@ -248,10 +551,9 @@ would be stored in our dump format.
     The history values can be non-existent (meaning the node is
     completely new), or can have a value of {revision, path}.
 
+=== Refinement of proposal #2: ===
 
-------------------------------------------------------------------------
-Refinement of proposal #2:  (after discussion with gstein)
-=========================
+(after discussion with gstein)
 
 Each node starts with RFC822-style headers at the top.  The final
 header is a 'Content-length:', followed by the content, so record
@@ -261,3 +563,5 @@ The content section has two implicit par
 fulltext.  The division between these two sections is implied by the
 "PROPS-END\n" tag at the end of the prophash.  In the case of a
 directory node or a revision, only the prophash is present.
+
+//End of document.

Modified: subversion/branches/svn-bisect/notes/http-and-webdav/webdav-protocol
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/notes/http-and-webdav/webdav-protocol?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/notes/http-and-webdav/webdav-protocol (original)
+++ subversion/branches/svn-bisect/notes/http-and-webdav/webdav-protocol Mon Jul 30 06:39:28 2012
@@ -354,6 +354,7 @@ Request:
     <S:discover-changed-paths/> (optional)
     <S:strict-node-history/> (optional)
     <S:include-merged-revisions/> (optional)
+    <S:encode-binary-props> (optional)
     <S:revprop>REVPROP</S:revprop>... | <S:all-revprops/> | <S:no-revprops/>
       ('revprop', 'all-revprops', and 'no-revprops' are all optional)
     <S:path></S:path>... (optional)
@@ -369,6 +370,7 @@ Response:
       <S:date>2006-02-27T18:44:26.149336Z</S:date>
       <D:comment>Add doo-hickey</D:comment>
       <S:revprop name="REVPROP">value</S:revprop>... (optional)
+      <S:revprop name="REVPROP" encoding="base64">encoded value</S:revprop>... (optional)
       <S:has-children/> (optional)
       <S:added-path( copyfrom-path="PATH" copyfrom-rev="REVNUM">PATH</S:added-path>... (optional)
       <S:replaced-path( copyfrom-path="PATH" copyfrom-rev="REVNUM">PATH</S:replaced-path>... (optional)

Modified: subversion/branches/svn-bisect/notes/knobs
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/notes/knobs?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/notes/knobs (original)
+++ subversion/branches/svn-bisect/notes/knobs Mon Jul 30 06:39:28 2012
@@ -22,6 +22,8 @@ The SVN source code boasts a number of e
 processor enabled tweaks that are mainly aimed at developer support.
 If you introduce new ones, please document them here.
 
+Macros documented in the configure-generated ../subversion/svn_private_config.h
+file are not repeated here.
 
 2 Defines and Environment Variables
 ===================================
@@ -33,6 +35,8 @@ DEFAULT_HTTP_LIBRARY
 MAX_SECS_TO_LINGER
 SUFFIX_LINES_TO_KEEP
 SVN_FS_FS_DEFAULT_MAX_FILES_PER_DIR
+SVN_FS_FS_MAX_LINEAR_DELTIFICATION
+SVN_FS_FS_MAX_DELTIFICATION_WALK
 SVN_UNALIGNED_ACCESS_IS_OK
 
 2.2 Features
@@ -44,6 +48,8 @@ SVN_MERGE__ALLOW_ALL_FORWARD_MERGES_FROM
 SVN_USE_WIN32_CRASHHANDLER
 SVN_DAV_SEND_VTXN_NAME
 SVN_DISABLE_PREFIX_SUFFIX_SCANNING
+SVN_FS_FS_DELTIFY_DIRECTORIES
+SVN_FS_FS_DELTIFY_PROPS
 SVN_SQLITE_MIN_VERSION_NUMBER
 SVN_SQLITE_MIN_VERSION
 
@@ -125,7 +131,25 @@ SVN_I_LIKE_LATENCY_SO_IGNORE_HTTPV2
   Range:     natural integers
   Suggested: 1, 2, 3, 4, 5, 7, 11
 
-3.6 SVN_UNALIGNED_ACCESS_IS_OK
+3.6 SVN_FS_FS_MAX_LINEAR_DELTIFICATION
+
+  Scope:     libsvn_fs_fs
+  Purpose:   max length + 1 of the linear deltification history
+             before skip-deltification kicks in
+  Default:   16
+  Range:     natural integers
+  Suggested: 2, 4, 8, 16, 32, 64
+
+3.7 SVN_FS_FS_MAX_DELTIFICATION_WALK
+
+  Scope:     libsvn_fs_fs
+  Purpose:   max skip deltification range. Change histories
+             longer than that will be restarted with a fulltext.
+  Default:   1023
+  Range:     natural integers
+  Suggested: 1, 2, 3, 4, 5, 7, 11
+
+3.8 SVN_UNALIGNED_ACCESS_IS_OK
 
   Scope:     (global)
   Purpose:   enable data accesss optimizations.
@@ -207,7 +231,27 @@ SVN_I_LIKE_LATENCY_SO_IGNORE_HTTPV2
   Default:   not defined
   Suggested: not defined
 
-4.8 SVN_SQLITE_MIN_VERSION_NUMBER
+4.8 SVN_FS_FS_DELTIFY_DIRECTORIES
+
+  Scope:     libsvn_fs_fs
+  Purpose:   Define this symbol to enable directory deltification in FSFS.
+             When activated, previous versions of Subversion will still be
+             able to read from and write to this repository.
+  Range:     definedness
+  Default:   not defined
+  Suggested: defined
+
+4.9 SVN_FS_FS_DELTIFY_PROPS
+
+  Scope:     libsvn_fs_fs
+  Purpose:   Define this symbol to enable node property deltification in
+             FSFS.  When activated, previous versions of Subversion will
+             still be able to read from and write to this repository.
+  Range:     definedness
+  Default:   not defined
+  Suggested: not defined
+
+4.10 SVN_SQLITE_MIN_VERSION_NUMBER
 
   Scope:     libsvn_subr
   Purpose:   The minimum SQLite version to have run-time support for.
@@ -215,7 +259,7 @@ SVN_I_LIKE_LATENCY_SO_IGNORE_HTTPV2
   Default:   SQLITE_VERSION_NUMBER (i.e., the compile-time-sqlite version)
   Suggested: not defined (to use default)
 
-4.9 SVN_SQLITE_MIN_VERSION
+4.11 SVN_SQLITE_MIN_VERSION
 
   Scope:     libsvn_subr
   Purpose:   See SVN_SQLITE_MIN_VERSION_NUMBER.  The two must be overridden

Modified: subversion/branches/svn-bisect/notes/repos-dictated-config
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/notes/repos-dictated-config?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/notes/repos-dictated-config (original)
+++ subversion/branches/svn-bisect/notes/repos-dictated-config Mon Jul 30 06:39:28 2012
@@ -1,58 +1,2 @@
-Some thoughts on repository-dictated configuration
-
-Introduction
-============
-Many software development shops of non-trivial size desire to have an enforce
-a uniform configuration environment among the various clients which commit
-to their repositories.  Although these shops my have the ability to control
-the environment on the client machines (dictating software versions, etc),
-relying up on the client for setting various configuration parameters can
-be time-consuming and problematic.
-
-Subversion already provides the means of enforcing much (but not all) of this
-configuration through the hook script mechanism.  What our users desire is
-some way of having the server dictate a default or recommended configuration
-to clients.  The parameters of interest typically come from the standard
-client-side config: things like global-excludes or auto-props.  Allowing the
-administrator to store a default config on the server, which then gets pushed
-to the clients, would save both time and frustration.
-
-
-Behavioral specification
-========================
-The high-level behavior for repository-dictated configuration is relatively
-simple: the repository maintains a list of configuration parameters and
-values, and upon request, provides these to the client who then applies them
-appropriately.
-
-It should be noted that the configuration the server dictates is only a
-*suggestion* to the client.  Clients may choose to override the suggestion
-with a configuration of their own, so appropriate server-side enforcement
-(often via hook scripts) is still recommended.
-
-
-Server-client transmission mechanism
-====================================
-As part of the OPTIONS request, the client will send to the server the 
-sha1 hash of the version of the server-dictated config that it current has
-cached.  If the server has a different version, it will send that to the
-client in the OPTIONS response.
-
-
-Server-side storage
-===================
-[TODO]
-
-
-Client-side storage
-===================
-The client current maintains a global configuration file in
-~/.subversion/config  This feature will introduce the ~/.subversion/repos/
-directory, which will hold additional subdirectories keyed on the UUID of the
-repository.  It is in this subdirectory that the cached version of the
-repository configuration will be stored.
-
-
-Configuration Hierarchy
-=======================
-[TODO]
+[  The contents and further evolution of this document have been moved to  ]
+[  http://wiki.apache.org/subversion/ServerDictatedConfiguration           ]

Propchange: subversion/branches/svn-bisect/subversion/bindings/javahl/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Mon Jul 30 06:39:28 2012
@@ -3,3 +3,4 @@ classes
 include
 svn-javahl.jar
 test-work
+Manifest

Modified: subversion/branches/svn-bisect/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/javahl/native/SVNClient.cpp?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/branches/svn-bisect/subversion/bindings/javahl/native/SVNClient.cpp Mon Jul 30 06:39:28 2012
@@ -829,10 +829,11 @@ jbyteArray SVNClient::propertyGet(const 
         return NULL;
 
     apr_hash_t *props;
-    SVN_JNI_ERR(svn_client_propget3(&props, name,
+    SVN_JNI_ERR(svn_client_propget4(&props, name,
                                     intPath.c_str(), pegRevision.revision(),
                                     revision.revision(), NULL, svn_depth_empty,
-                                    NULL, ctx, subPool.getPool()),
+                                    NULL, ctx, subPool.getPool(),
+                                    subPool.getPool()),
                 NULL);
 
     apr_hash_index_t *hi;
@@ -935,7 +936,7 @@ void SVNClient::diff(const char *target1
                      OutputStream &outputStream, svn_depth_t depth,
                      StringArray &changelists,
                      bool ignoreAncestry, bool noDiffDelete, bool force,
-                     bool showCopiesAsAdds)
+                     bool showCopiesAsAdds, bool ignoreProps)
 {
     SVN::Pool subPool(pool);
     const char *c_relToDir = relativeToDir ?
@@ -971,7 +972,8 @@ void SVNClient::diff(const char *target1
                                    noDiffDelete,
                                    showCopiesAsAdds,
                                    force,
-                                   FALSE,
+                                   ignoreProps,
+                                   FALSE, /* use_git_diff_format */
                                    SVN_APR_LOCALE_CHARSET,
                                    outputStream.getStream(subPool),
                                    NULL /* error file */,
@@ -997,7 +999,8 @@ void SVNClient::diff(const char *target1
                                noDiffDelete,
                                showCopiesAsAdds,
                                force,
-                               FALSE,
+                               ignoreProps,
+                               FALSE, /* use_git_diff_format */
                                SVN_APR_LOCALE_CHARSET,
                                outputStream.getStream(subPool),
                                NULL /* error stream */,
@@ -1013,11 +1016,11 @@ void SVNClient::diff(const char *target1
                      const char *relativeToDir, OutputStream &outputStream,
                      svn_depth_t depth, StringArray &changelists,
                      bool ignoreAncestry, bool noDiffDelete, bool force,
-                     bool showCopiesAsAdds)
+                     bool showCopiesAsAdds, bool ignoreProps)
 {
     diff(target1, revision1, target2, revision2, NULL, relativeToDir,
          outputStream, depth, changelists, ignoreAncestry, noDiffDelete, force,
-         showCopiesAsAdds);
+         showCopiesAsAdds, ignoreProps);
 }
 
 void SVNClient::diff(const char *target, Revision &pegRevision,
@@ -1025,11 +1028,12 @@ void SVNClient::diff(const char *target,
                      const char *relativeToDir, OutputStream &outputStream,
                      svn_depth_t depth, StringArray &changelists,
                      bool ignoreAncestry, bool noDiffDelete, bool force,
-                     bool showCopiesAsAdds)
+                     bool showCopiesAsAdds, bool ignoreProps)
 {
     diff(target, startRevision, NULL, endRevision, &pegRevision,
          relativeToDir, outputStream, depth, changelists,
-         ignoreAncestry, noDiffDelete, force, showCopiesAsAdds);
+         ignoreAncestry, noDiffDelete, force, showCopiesAsAdds,
+         ignoreProps);
 }
 
 void

Modified: subversion/branches/svn-bisect/subversion/bindings/javahl/native/SVNClient.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/javahl/native/SVNClient.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/javahl/native/SVNClient.h (original)
+++ subversion/branches/svn-bisect/subversion/bindings/javahl/native/SVNClient.h Mon Jul 30 06:39:28 2012
@@ -177,13 +177,13 @@ class SVNClient :public SVNBase
             const char *relativeToDir, OutputStream &outputStream,
             svn_depth_t depth, StringArray &changelists,
             bool ignoreAncestry, bool noDiffDelete, bool force,
-            bool showCopiesAsAdds);
+            bool showCopiesAsAdds, bool ignoreProps);
   void diff(const char *target, Revision &pegevision,
             Revision &startRevision, Revision &endRevision,
             const char *relativeToDir, OutputStream &outputStream,
             svn_depth_t depth, StringArray &changelists,
             bool ignoreAncestry, bool noDiffDelete, bool force,
-            bool showCopiesAsAdds);
+            bool showCopiesAsAdds, bool ignoreProps);
   void diffSummarize(const char *target1, Revision &revision1,
                      const char *target2, Revision &revision2,
                      svn_depth_t depth, StringArray &changelists,
@@ -212,7 +212,7 @@ class SVNClient :public SVNBase
             OutputStream &outputStream, svn_depth_t depth,
             StringArray &changelists,
             bool ignoreAncestry, bool noDiffDelete, bool force,
-            bool showCopiesAsAdds);
+            bool showCopiesAsAdds, bool ignoreProps);
 
   Path m_lastPath;
   ClientContext context;

Modified: subversion/branches/svn-bisect/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp (original)
+++ subversion/branches/svn-bisect/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp Mon Jul 30 06:39:28 2012
@@ -1171,12 +1171,12 @@ JNIEXPORT void JNICALL Java_org_apache_s
 }
 
 JNIEXPORT void JNICALL
-Java_org_apache_subversion_javahl_SVNClient_diff__Ljava_lang_String_2Lorg_apache_subversion_javahl_types_Revision_2Ljava_lang_String_2Lorg_apache_subversion_javahl_types_Revision_2Ljava_lang_String_2Ljava_io_OutputStream_2Lorg_apache_subversion_javahl_types_Depth_2Ljava_util_Collection_2ZZZZ
+Java_org_apache_subversion_javahl_SVNClient_diff__Ljava_lang_String_2Lorg_apache_subversion_javahl_types_Revision_2Ljava_lang_String_2Lorg_apache_subversion_javahl_types_Revision_2Ljava_lang_String_2Ljava_io_OutputStream_2Lorg_apache_subversion_javahl_types_Depth_2Ljava_util_Collection_2ZZZZZ
 (JNIEnv *env, jobject jthis, jstring jtarget1, jobject jrevision1,
  jstring jtarget2, jobject jrevision2, jstring jrelativeToDir,
  jobject jstream, jobject jdepth, jobject jchangelists,
  jboolean jignoreAncestry, jboolean jnoDiffDeleted, jboolean jforce,
- jboolean jcopiesAsAdds)
+ jboolean jcopiesAsAdds, jboolean jignoreProps)
 {
   JNIEntry(SVNClient, diff);
   SVNClient *cl = SVNClient::getCppObject(jthis);
@@ -1217,16 +1217,16 @@ Java_org_apache_subversion_javahl_SVNCli
            EnumMapper::toDepth(jdepth), changelists,
            jignoreAncestry ? true:false,
            jnoDiffDeleted ? true:false, jforce ? true:false,
-           jcopiesAsAdds ? true:false);
+           jcopiesAsAdds ? true:false, jignoreProps ? true:false);
 }
 
 JNIEXPORT void JNICALL
-Java_org_apache_subversion_javahl_SVNClient_diff__Ljava_lang_String_2Lorg_apache_subversion_javahl_types_Revision_2Lorg_apache_subversion_javahl_types_Revision_2Lorg_apache_subversion_javahl_types_Revision_2Ljava_lang_String_2Ljava_io_OutputStream_2Lorg_apache_subversion_javahl_types_Depth_2Ljava_util_Collection_2ZZZZ
+Java_org_apache_subversion_javahl_SVNClient_diff__Ljava_lang_String_2Lorg_apache_subversion_javahl_types_Revision_2Lorg_apache_subversion_javahl_types_Revision_2Lorg_apache_subversion_javahl_types_Revision_2Ljava_lang_String_2Ljava_io_OutputStream_2Lorg_apache_subversion_javahl_types_Depth_2Ljava_util_Collection_2ZZZZZ
 (JNIEnv *env, jobject jthis, jstring jtarget, jobject jpegRevision,
  jobject jstartRevision, jobject jendRevision, jstring jrelativeToDir,
  jobject jstream, jobject jdepth, jobject jchangelists,
  jboolean jignoreAncestry, jboolean jnoDiffDeleted, jboolean jforce,
- jboolean jcopiesAsAdds)
+ jboolean jcopiesAsAdds, jboolean jignoreProps)
 {
   JNIEntry(SVNClient, diff);
   SVNClient *cl = SVNClient::getCppObject(jthis);
@@ -1267,7 +1267,7 @@ Java_org_apache_subversion_javahl_SVNCli
            dataOut, EnumMapper::toDepth(jdepth), changelists,
            jignoreAncestry ? true:false,
            jnoDiffDeleted ? true:false, jforce ? true:false,
-           jcopiesAsAdds ? true:false);
+           jcopiesAsAdds ? true:false, jignoreProps ? true:false);
 }
 
 JNIEXPORT void JNICALL

Modified: subversion/branches/svn-bisect/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java (original)
+++ subversion/branches/svn-bisect/subversion/bindings/javahl/src/org/apache/subversion/javahl/ClientNotifyInformation.java Mon Jul 30 06:39:28 2012
@@ -541,7 +541,10 @@ public class ClientNotifyInformation ext
         failed_locked ("failed by lock"),
 
         /** Operation failed because the operation was forbidden */
-        failed_forbidden_by_server ("failed forbidden by server");
+        failed_forbidden_by_server ("failed forbidden by server"),
+
+        /** Operation skipped the path because it was conflicted */
+        skip_conflicted ("skipped conflicted path");
 
         /**
          * The description of the action.

Modified: subversion/branches/svn-bisect/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java (original)
+++ subversion/branches/svn-bisect/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java Mon Jul 30 06:39:28 2012
@@ -521,13 +521,14 @@ public interface ISVNClient
      * @param force         diff even on binary files
      * @param copiesAsAdds  if set, copied files will be shown in their
      *                      entirety, not as diffs from their sources
+     * @param ignoreProps   don't show property diffs
      * @throws ClientException
      */
     void diff(String target1, Revision revision1, String target2,
               Revision revision2, String relativeToDir, OutputStream outStream,
               Depth depth, Collection<String> changelists,
               boolean ignoreAncestry, boolean noDiffDeleted, boolean force,
-              boolean copiesAsAdds)
+              boolean copiesAsAdds, boolean ignoreProps)
             throws ClientException;
 
     void diff(String target1, Revision revision1, String target2,
@@ -552,6 +553,7 @@ public interface ISVNClient
      * @param force         diff even on binary files
      * @param copiesAsAdds  if set, copied files will be shown in their
      *                      entirety, not as diffs from their sources
+     * @param ignoreProps   don't show property diffs
      * @throws ClientException
      */
     void diff(String target, Revision pegRevision, Revision startRevision,
@@ -559,7 +561,7 @@ public interface ISVNClient
               OutputStream outStream,
               Depth depth, Collection<String> changelists,
               boolean ignoreAncestry, boolean noDiffDeleted, boolean force,
-              boolean copiesAsAdds)
+              boolean copiesAsAdds, boolean ignoreProps)
             throws ClientException;
 
     void diff(String target, Revision pegRevision, Revision startRevision,

Modified: subversion/branches/svn-bisect/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/svn-bisect/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java Mon Jul 30 06:39:28 2012
@@ -278,7 +278,7 @@ public class SVNClient implements ISVNCl
             OutputStream stream = new FileOutputStream(outFileName);
             diff(target1, revision1, target2, revision2, relativeToDir,
                  stream, depth, changelists, ignoreAncestry, noDiffDeleted,
-                 force, copiesAsAdds);
+                 force, copiesAsAdds, false);
         } catch (FileNotFoundException ex) {
             throw ClientException.fromException(ex);
         }
@@ -289,7 +289,8 @@ public class SVNClient implements ISVNCl
                             OutputStream stream, Depth depth,
                             Collection<String> changelists,
                             boolean ignoreAncestry, boolean noDiffDeleted,
-                            boolean force, boolean copiesAsAdds)
+                            boolean force, boolean copiesAsAdds,
+                            boolean ignoreProps)
             throws ClientException;
 
     public void diff(String target, Revision pegRevision,
@@ -304,7 +305,7 @@ public class SVNClient implements ISVNCl
             OutputStream stream = new FileOutputStream(outFileName);
             diff(target, pegRevision, startRevision, endRevision,
                  relativeToDir, stream, depth, changelists, ignoreAncestry,
-                 noDiffDeleted, force, copiesAsAdds);
+                 noDiffDeleted, force, copiesAsAdds, false);
         } catch (FileNotFoundException ex) {
             throw ClientException.fromException(ex);
         }
@@ -315,7 +316,8 @@ public class SVNClient implements ISVNCl
                             String relativeToDir, OutputStream stream,
                             Depth depth, Collection<String> changelists,
                             boolean ignoreAncestry, boolean noDiffDeleted,
-                            boolean force, boolean copiesAsAdds)
+                            boolean force, boolean copiesAsAdds,
+                            boolean ignoreProps)
             throws ClientException;
 
     public native void diffSummarize(String target1, Revision revision1,

Modified: subversion/branches/svn-bisect/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java (original)
+++ subversion/branches/svn-bisect/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java Mon Jul 30 06:39:28 2012
@@ -2737,7 +2737,7 @@ public class BasicTests extends SVNTests
             "## -0,0 +1 ##" + NL +
             "+Test property value." + NL;
 
-        setprop(aPath, "testprop", "Test property value.");
+        setprop(aPath, "testprop", "Test property value." + NL);
         client.diff(aPath, Revision.BASE, aPath, Revision.WORKING, wcPath,
                     diffOutput.getPath(), Depth.infinity, null, true, true,
                     false, false);
@@ -2755,7 +2755,7 @@ public class BasicTests extends SVNTests
             "## -0,0 +1 ##" + NL +
             "+Test property value." + NL;
 
-        setprop(aPath, "testprop", "Test property value.");
+        setprop(aPath, "testprop", "Test property value." + NL);
         client.diff(aPath, Revision.BASE, aPath, Revision.WORKING, aPath,
                     diffOutput.getPath(), Depth.infinity, null, true, true,
                     false, false);

Modified: subversion/branches/svn-bisect/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/BasicTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/BasicTests.java?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/BasicTests.java (original)
+++ subversion/branches/svn-bisect/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/BasicTests.java Mon Jul 30 06:39:28 2012
@@ -2674,7 +2674,8 @@ public class BasicTests extends SVNTests
             "## -0,0 +1 ##" + NL +
             "+Test property value." + NL;
 
-        client.propertySet(aPath, "testprop", "Test property value.", false);
+        client.propertySet(aPath, "testprop", "Test property value." + NL,
+                           false);
         client.diff(aPath, Revision.BASE, aPath, Revision.WORKING, wcPath,
                     diffOutput.getPath(), Depth.infinity, null, true, true,
                     false);
@@ -2692,7 +2693,8 @@ public class BasicTests extends SVNTests
             "## -0,0 +1 ##" + NL +
             "+Test property value." + NL;
 
-        client.propertySet(aPath, "testprop", "Test property value.", false);
+        client.propertySet(aPath, "testprop", "Test property value." + NL,
+                           false);
         client.diff(aPath, Revision.BASE, aPath, Revision.WORKING, aPath,
                     diffOutput.getPath(), Depth.infinity, null, true, true,
                     false);

Modified: subversion/branches/svn-bisect/subversion/bindings/swig/INSTALL
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/swig/INSTALL?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/swig/INSTALL (original)
+++ subversion/branches/svn-bisect/subversion/bindings/swig/INSTALL Mon Jul 30 06:39:28 2012
@@ -80,7 +80,7 @@ Step 1:  Install a suitable version of S
 
              --with-python=/path/to/correct/python/binary
 
-        to the configure script.  You need Python 2.4 or above.
+        to the configure script.  You need Python 2.5 or above.
 
         If you plan to build the Perl bindings, and have a system
         with more than one version of perl installed, you may need
@@ -109,7 +109,7 @@ Step 2:  Build and Install Subversion.
   python executable you used to configure SWIG as above.  If it does not then
   you can specify the correct path by adding PYTHON=/path/to/python or
   PERL=/path/to/perl onto the command line for configure.  For example:
-       ./configure PYTHON=/usr/bin/python2.4 PERL=/usr/bin/perl5.8.0
+       ./configure PYTHON=/usr/bin/python2.5 PERL=/usr/bin/perl5.8.0
 
   If Subversion's ./configure finds a SWIG that it's happy with, then
   it will build special glue libraries to link svn to the swig bindings:

Modified: subversion/branches/svn-bisect/subversion/bindings/swig/core.i
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/swig/core.i?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/swig/core.i (original)
+++ subversion/branches/svn-bisect/subversion/bindings/swig/core.i Mon Jul 30 06:39:28 2012
@@ -698,6 +698,7 @@ svn_swig_pl_set_current_pool (apr_pool_t
 %authprompt_callback_typemap(ssl_server_trust)
 %authprompt_callback_typemap(ssl_client_cert)
 %authprompt_callback_typemap(ssl_client_cert_pw)
+%authprompt_callback_typemap(gnome_keyring_unlock)
 
 /* -----------------------------------------------------------------------
  * For all the various functions that set a callback baton create a reference
@@ -781,6 +782,34 @@ svn_swig_pl_set_current_pool (apr_pool_t
 %include svn_mergeinfo_h.swg
 %include svn_io_h.swg
 
+
+
+#ifdef SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC
+%inline %{
+/* Helper function to set the gnome-keyring unlock prompt function. This
+ * C function accepts an auth baton, a function and a prompt baton, but
+ * the below callback_typemap uses both the function and the prompt
+ * baton, so the resulting binding has just two arguments: The auth
+ * baton and the prompt function.
+ * The prompt function should again have two arguments: The keyring name
+ * (string) and a pool (except for the ruby version, which doesn't have
+ * the pool argument). It should return the entered password (string).
+ * This binding generated for this function generates a reference to the
+ * prompt function that was passed into this. The caller should store
+ * that reference somewhere, to prevent the function from being garbage
+ * collected...
+ */
+static void svn_auth_set_gnome_keyring_unlock_prompt_func(svn_auth_baton_t *ab,
+                                                          svn_auth_gnome_keyring_unlock_prompt_func_t prompt_func,
+                                                          void *prompt_baton) {
+    svn_auth_set_parameter(ab, SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_FUNC,
+                           prompt_func);
+    svn_auth_set_parameter(ab, SVN_AUTH_PARAM_GNOME_KEYRING_UNLOCK_PROMPT_BATON,
+                           prompt_baton);
+}
+%}
+#endif
+
 #if defined(SWIGPERL) || defined(SWIGRUBY)
 %include svn_md5_h.swg
 #endif

Modified: subversion/branches/svn-bisect/subversion/bindings/swig/include/svn_containers.swg
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/swig/include/svn_containers.swg?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/swig/include/svn_containers.swg (original)
+++ subversion/branches/svn-bisect/subversion/bindings/swig/include/svn_containers.swg Mon Jul 30 06:39:28 2012
@@ -482,6 +482,16 @@
    svn_wc_parse_externals_description3()
 */
 
+#ifdef SWIGPYTHON
+%typemap(argout) apr_array_header_t **externals_p {
+  %append_output
+    (svn_swig_py_pointerlist_to_list(*$1, $descriptor(svn_wc_external_item2_t *),
+                                     _global_py_pool));
+  if (PyErr_Occurred()) {
+    SWIG_fail;
+  }
+}
+#endif
 #ifdef SWIGRUBY
 %typemap(argout) apr_array_header_t **externals_p {
   %append_output(svn_swig_rb_apr_array_to_array_external_item2(*$1));
@@ -825,8 +835,8 @@
 #ifdef SWIGPYTHON
 %typemap(argout) apr_array_header_t **RANGELIST {
   %append_output
-    (svn_swig_py_rangelist_to_list(*$1, $descriptor(svn_merge_range_t *),
-                                   _global_py_pool));
+    (svn_swig_py_pointerlist_to_list(*$1, $descriptor(svn_merge_range_t *),
+                                     _global_py_pool));
   if (PyErr_Occurred()) {
     SWIG_fail;
   }
@@ -873,3 +883,20 @@
                     $descriptor(svn_auth_provider_object_t *)));
 }
 #endif
+
+#ifdef SWIGPYTHON
+%typemap(argout) apr_array_header_t **providers {
+  %append_output
+    (svn_swig_py_pointerlist_to_list(*$1, $descriptor(svn_auth_provider_object_t *),
+                                     _global_py_pool));
+  if (PyErr_Occurred()) {
+    SWIG_fail;
+  }
+}
+#endif
+
+#ifdef SWIGRUBY
+%typemap(argout) apr_array_header_t **providers {
+  %append_output(svn_swig_rb_apr_array_to_array_auth_provider_object(*$1));
+}
+#endif

Modified: subversion/branches/svn-bisect/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c (original)
+++ subversion/branches/svn-bisect/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.c Mon Jul 30 06:39:28 2012
@@ -984,6 +984,34 @@ svn_error_t *svn_ra_make_callbacks(svn_r
     return SVN_NO_ERROR;
 }
 
+svn_error_t *svn_swig_pl_thunk_gnome_keyring_unlock_prompt(char **keyring_password,
+                                                           const char *keyring_name,
+                                                           void *baton,
+                                                           apr_pool_t *pool)
+{
+    SV *result;
+    STRLEN len;
+    /* The baton is the actual prompt function passed from perl, so we
+     * call that one and process the result. */
+    svn_swig_pl_callback_thunk(CALL_SV,
+                               baton, &result,
+                               "sS", keyring_name,
+                               pool, POOLINFO);
+    if (!SvOK(result) || result == &PL_sv_undef) {
+        *keyring_password = NULL;
+    }
+    else if (SvPOK(result)) {
+        *keyring_password = apr_pstrdup(pool, SvPV(result, len));
+    }
+    else {
+        SvREFCNT_dec(result);
+        croak("not a string");
+    }
+
+    SvREFCNT_dec(result);
+    return SVN_NO_ERROR;
+}
+
 svn_error_t *svn_swig_pl_thunk_simple_prompt(svn_auth_cred_simple_t **cred,
                                              void *baton,
                                              const char *realm,

Modified: subversion/branches/svn-bisect/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h (original)
+++ subversion/branches/svn-bisect/subversion/bindings/swig/perl/libsvn_swig_perl/swigutil_pl.h Mon Jul 30 06:39:28 2012
@@ -144,6 +144,11 @@ svn_error_t *svn_ra_make_callbacks(svn_r
 				   SV *perl_callbacks,
 				   apr_pool_t *pool);
 
+/* thunked gnome_keyring_unlock_prompt callback function */
+svn_error_t *svn_swig_pl_thunk_gnome_keyring_unlock_prompt(char **keyring_password,
+                                                           const char *keyring_name,
+                                                           void *baton,
+                                                           apr_pool_t *pool);
 /* thunked simple_prompt callback function */
 svn_error_t *svn_swig_pl_thunk_simple_prompt(svn_auth_cred_simple_t **cred,
                                              void *baton,

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/Base.pm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/Client.pm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/Core.pm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/Delta.pm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/Fs.pm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/Ra.pm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/Repos.pm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/Wc.pm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/t/0use.t
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/t/1repos.t
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/t/2fs.t
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/t/3client.t
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/t/3client.t?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/t/3client.t (original)
+++ subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/t/3client.t Mon Jul 30 06:39:28 2012
@@ -20,7 +20,7 @@
 #
 #
 
-use Test::More tests => 119;
+use Test::More tests => 121;
 use strict;
 
 # shut up about variables that are only used once.
@@ -46,6 +46,11 @@ my $reposurl = 'file://' . (substr($repo
 my $wcpath = catdir($testpath,'wc');
 my $importpath = catdir($testpath,'import');
 
+# Use internal style paths on Windows
+$reposurl =~ s/\\/\//g;
+$wcpath =~ s/\\/\//g;
+$importpath =~ s/\\/\//g;
+
 # track current rev ourselves to test against
 my $current_rev = 0;
 
@@ -53,7 +58,7 @@ my $current_rev = 0;
 $SVN::Error::handler = undef;
 
 # Get username we are running as
-my $username = getpwuid($>);
+my $username = getlogin() || getpwuid($>);
 
 # This is ugly to create the test repo with SVN::Repos, but
 # it seems to be the most reliable way.
@@ -86,36 +91,32 @@ my ($rpgval,$rpgrev) = $ctx->revprop_get
 is($rpgval,$username,'svn:author set to expected username from revprop_get');
 is($rpgrev,$current_rev,'Returned revnum of current rev from revprop_get');
 
-SKIP: {
-    skip 'Difficult to test on Win32', 3 if $^O eq 'MSWin32';
-
+if ($^O eq 'MSWin32') {
+    ok(open(NEW, ">$repospath/hooks/pre-revprop-change.bat"),
+       'Open pre-revprop-change hook for writing');
+    ok(print(NEW 'exit 0'), 'Print to hook');
+    ok(close(NEW), 'Close hook');
+} else {
     ok(rename("$repospath/hooks/pre-revprop-change.tmpl",
               "$repospath/hooks/pre-revprop-change"),
        'Rename pre-revprop-change hook');
     ok(chmod(0700,"$repospath/hooks/pre-revprop-change"),
        'Change permissions on pre-revprop-change hook');
-
-    my ($rps_rev) = $ctx->revprop_set('svn:log','mkdir dir1',
-                                      $reposurl, $current_rev, 0);
-    is($rps_rev,$current_rev,
-       'Returned revnum of current rev from revprop_set');
-
+    is(1, 1, '-')
 }
+my ($rps_rev) = $ctx->revprop_set('svn:log','mkdir dir1',
+                                  $reposurl, $current_rev, 0);
+is($rps_rev,$current_rev,
+   'Returned revnum of current rev from revprop_set');
 
 my ($rph, $rplrev) = $ctx->revprop_list($reposurl,$current_rev);
 isa_ok($rph,'HASH','Returned hash reference form revprop_list');
 is($rplrev,$current_rev,'Returned current rev from revprop_list');
 is($rph->{'svn:author'},$username,
    'svn:author is expected user from revprop_list');
-if ($^O eq 'MSWin32') {
-    # we skip the log change test on win32 so we have to test
-    # for a different var here
-    is($rph->{'svn:log'},'Make dir1',
-       'svn:log is expected value from revprop_list');
-} else {
-    is($rph->{'svn:log'},'mkdir dir1',
-       'svn:log is expected value from revprop_list');
-}
+is($rph->{'svn:log'},'mkdir dir1',
+   'svn:log is expected value from revprop_list');
+
 ok($rph->{'svn:date'},'svn:date is set from revprop_list');
 
 is($ctx->checkout($reposurl,$wcpath,'HEAD',1),$current_rev,
@@ -477,6 +478,28 @@ foreach my $p (@providers) {
 }
 ok($ok, 'svn_auth_get_platform_specific_client_providers returns _p_svn_auth_provider_object_t\'s');
 
+SKIP: {
+  skip 'Gnome-Keyring support not compiled in', 1
+      unless defined &SVN::Core::auth_set_gnome_keyring_unlock_prompt_func;
+
+  # Test setting gnome_keyring prompt function. This just sets the proper
+  # attributes in the auth baton and checks the return value (which should
+  # be a reference to the passed function reference). This does not
+  # actually try the prompt, since that would require setting up a
+  # gnome-keyring-daemon...
+  sub gnome_keyring_unlock_prompt {
+      my $keyring_name = shift;
+      my $pool = shift;
+
+      'test';
+  }
+
+  my $callback = \&gnome_keyring_unlock_prompt;
+  my $result = SVN::Core::auth_set_gnome_keyring_unlock_prompt_func(
+                   $ctx->auth(), $callback);
+  is(${$result}, $callback, 'auth_set_gnome_keyring_unlock_prompt_func result equals paramter');
+}
+
 END {
 diag('cleanup');
 rmtree($testpath);

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/t/3client.t
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/t/4pool.t
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/t/5delta-compat.t
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/svn-bisect/subversion/bindings/swig/perl/native/t/5delta.t
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: subversion/branches/svn-bisect/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (original)
+++ subversion/branches/svn-bisect/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c Mon Jul 30 06:39:28 2012
@@ -650,17 +650,29 @@ PyObject *svn_swig_py_stringhash_to_dict
   return convert_hash(hash, convert_string, NULL, NULL);
 }
 
-static PyObject *convert_rangelist(void *value, void *ctx, PyObject *py_pool)
+static PyObject *convert_pointerlist(void *value, void *ctx, PyObject *py_pool)
 {
   int i;
   PyObject *list;
   apr_array_header_t *array = value;
 
   list = PyList_New(0);
+  if (list == NULL)
+    return NULL;
+
   for (i = 0; i < array->nelts; i++)
     {
-      svn_merge_range_t *range = APR_ARRAY_IDX(array, i, svn_merge_range_t *);
-      if (PyList_Append(list, convert_to_swigtype(range, ctx, py_pool)) == -1)
+      void *ptr = APR_ARRAY_IDX(array, i, void *);
+      PyObject *obj;
+      int result;
+
+      obj = convert_to_swigtype(ptr, ctx, py_pool);
+      if (obj == NULL)
+        goto error;
+
+      result = PyList_Append(list, obj);
+      Py_DECREF(obj);
+      if (result == -1)
         goto error;
     }
   return list;
@@ -669,18 +681,18 @@ static PyObject *convert_rangelist(void 
   return NULL;
 }
 
-PyObject *svn_swig_py_rangelist_to_list(apr_array_header_t *rangelist,
-                                        swig_type_info *type,
-                                        PyObject *py_pool)
+PyObject *svn_swig_py_pointerlist_to_list(apr_array_header_t *list,
+                                          swig_type_info *type,
+                                          PyObject *py_pool)
 {
-  return convert_rangelist(rangelist, type, py_pool);
+  return convert_pointerlist(list, type, py_pool);
 }
 
 PyObject *svn_swig_py_mergeinfo_to_dict(apr_hash_t *hash,
                                         swig_type_info *type,
                                         PyObject *py_pool)
 {
-  return convert_hash(hash, convert_rangelist, type, py_pool);
+  return convert_hash(hash, convert_pointerlist, type, py_pool);
 }
 
 static PyObject *convert_mergeinfo_hash(void *value, void *ctx,
@@ -2792,6 +2804,41 @@ svn_error_t *svn_swig_py_changelist_rece
 }
 
 svn_error_t *
+svn_swig_py_auth_gnome_keyring_unlock_prompt_func(char **keyring_passwd,
+                                                  const char *keyring_name,
+                                                  void *baton,
+                                                  apr_pool_t *pool)
+{
+  /* The baton is the actual prompt function passed from python */
+  PyObject *function = baton;
+  PyObject *result;
+  svn_error_t *err = SVN_NO_ERROR;
+  *keyring_passwd = NULL;
+
+  if ((function == NULL) || (function == Py_None))
+    return SVN_NO_ERROR;
+
+  svn_swig_py_acquire_py_lock();
+
+  if ((result = PyObject_CallFunction(function,
+                                      (char *)"sO&",
+                                      keyring_name,
+                                      make_ob_pool, pool)) == NULL)
+    {
+      err = callback_exception_error();
+    }
+  else
+    {
+      *keyring_passwd = make_string_from_ob(result, pool);
+      Py_DECREF(result);
+    }
+
+  svn_swig_py_release_py_lock();
+  return err;
+}
+
+
+svn_error_t *
 svn_swig_py_auth_simple_prompt_func(svn_auth_cred_simple_t **cred,
                                     void *baton,
                                     const char *realm,

Modified: subversion/branches/svn-bisect/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h (original)
+++ subversion/branches/svn-bisect/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.h Mon Jul 30 06:39:28 2012
@@ -135,9 +135,9 @@ PyObject *svn_swig_py_locationhash_to_di
 /* helper function to convert an apr_array_header_t* (of
    svn_merge_range_t *) to a Python list */
 SVN_SWIG_SWIGUTIL_EXPORT
-PyObject *svn_swig_py_rangelist_to_list(apr_array_header_t *rangelist,
-                                        swig_type_info *type,
-                                        PyObject *py_pool);
+PyObject *svn_swig_py_pointerlist_to_list(apr_array_header_t *list,
+                                          swig_type_info *type,
+                                          PyObject *py_pool);
 
 /* helper function to convert an apr_hash_t* (const char *->array of
    svn_merge_range_t *) to a Python dict */
@@ -423,6 +423,13 @@ svn_error_t *svn_swig_py_changelist_rece
 
 /* auth provider callbacks */
 SVN_SWIG_SWIGUTIL_EXPORT
+svn_error_t * svn_swig_py_auth_gnome_keyring_unlock_prompt_func(
+        char **keyring_passwd,
+        const char *keyring_name,
+        void *baton,
+        apr_pool_t *pool);
+
+SVN_SWIG_SWIGUTIL_EXPORT
 svn_error_t *svn_swig_py_auth_simple_prompt_func(
     svn_auth_cred_simple_t **cred,
     void *baton,

Modified: subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/client.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/client.py?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/client.py (original)
+++ subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/client.py Mon Jul 30 06:39:28 2012
@@ -374,6 +374,29 @@ class SubversionClientTestCase(unittest.
 
     self.assertEqual(readme_text, 'This is a test.\n')
 
+  def test_platform_providers(self):
+    providers = core.svn_auth_get_platform_specific_client_providers(None, None)
+    # Not much more we can test in this minimal environment.
+    self.assert_(isinstance(providers, list))
+    self.assert_(not filter(lambda x:
+                             not isinstance(x, core.svn_auth_provider_object_t),
+                            providers))
+
+  def testGnomeKeyring(self):
+    if not hasattr(core, 'svn_auth_set_gnome_keyring_unlock_prompt_func'):
+      # gnome-keying not compiled in, do nothing
+      return
+
+    # This tests setting the gnome-keyring unlock prompt function as an
+    # auth baton parameter. It doesn't actually call gnome-keyring
+    # stuff, since that would require having a gnome-keyring running. We
+    # just test if this doesn't error out, there's not even a return
+    # value to test.
+    def prompt_func(realm_string, pool):
+      return "Foo"
+
+    core.svn_auth_set_gnome_keyring_unlock_prompt_func(self.client_ctx.auth_baton, prompt_func)
+
 def suite():
     return unittest.defaultTestLoader.loadTestsFromTestCase(
       SubversionClientTestCase)

Modified: subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/mergeinfo.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/mergeinfo.py?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/mergeinfo.py (original)
+++ subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/mergeinfo.py Mon Jul 30 06:39:28 2012
@@ -18,7 +18,7 @@
 # under the License.
 #
 #
-import unittest, os
+import unittest, os, sys, gc
 from svn import core, repos, fs
 import utils
 
@@ -29,6 +29,15 @@ class RevRange:
     self.start = start
     self.end = end
 
+def get_svn_merge_range_t_objects():
+  """Returns a list 'svn_merge_range_t' objects being tracked by the
+     garbage collector, used for detecting memory leaks."""
+  return [
+    o for o in gc.get_objects()
+      if hasattr(o, '__class__') and
+        o.__class__.__name__ == 'svn_merge_range_t'
+  ]
+
 class SubversionMergeinfoTestCase(unittest.TestCase):
   """Test cases for mergeinfo"""
 
@@ -116,6 +125,53 @@ class SubversionMergeinfoTestCase(unitte
       }
     self.compare_mergeinfo_catalogs(mergeinfo, expected_mergeinfo)
 
+  def test_mergeinfo_leakage__incorrect_range_t_refcounts(self):
+    """Ensure that the ref counts on svn_merge_range_t objects returned by
+       svn_mergeinfo_parse() are correct."""
+    # When reference counting is working properly, each svn_merge_range_t in
+    # the returned mergeinfo will have a ref count of 1...
+    mergeinfo = core.svn_mergeinfo_parse(self.TEXT_MERGEINFO1)
+    for (path, rangelist) in mergeinfo.items():
+      # ....and now 2 (incref during iteration of rangelist)
+
+      for (i, r) in enumerate(rangelist):
+        # ....and now 3 (incref during iteration of each range object)
+
+        refcount = sys.getrefcount(r)
+        # ....and finally, 4 (getrefcount() also increfs)
+        expected = 4
+
+        # Note: if path and index are not '/trunk' and 0 respectively, then
+        # only some of the range objects are leaking, which is, as far as
+        # leaks go, even more impressive.
+        self.assertEquals(refcount, expected, (
+          "Memory leak!  Expected a ref count of %d for svn_merge_range_t "
+          "object, but got %d instead (path: %s, index: %d).  Probable "
+          "cause: incorrect Py_INCREF/Py_DECREF usage in libsvn_swig_py/"
+          "swigutil_py.c." % (expected, refcount, path, i)))
+
+    del mergeinfo
+    gc.collect()
+
+  def test_mergeinfo_leakage__lingering_range_t_objects_after_del(self):
+    """Ensure that there are no svn_merge_range_t objects being tracked by
+       the garbage collector after we explicitly `del` the results returned
+       by svn_mergeinfo_parse().  We call gc.collect() to force an explicit
+       garbage collection cycle after the `del`;
+       if our reference counts are correct, the allocated svn_merge_range_t
+       objects will be garbage collected and thus, not appear in the list of
+       objects returned by gc.get_objects()."""
+    mergeinfo = core.svn_mergeinfo_parse(self.TEXT_MERGEINFO1)
+    del mergeinfo
+    gc.collect()
+    lingering = get_svn_merge_range_t_objects()
+    self.assertEquals(lingering, list(), (
+      "Memory leak!  Found lingering svn_merge_range_t objects left over from "
+      "our call to svn_mergeinfo_parse(), even though we explicitly deleted "
+      "the returned mergeinfo object.  Probable cause: incorrect Py_INCREF/"
+      "Py_DECREF usage in libsvn_swig_py/swigutil_py.c.  Lingering objects:\n"
+      "%s" % lingering))
+
   def inspect_mergeinfo_dict(self, mergeinfo, merge_source, nbr_rev_ranges):
     rangelist = mergeinfo.get(merge_source)
     self.inspect_rangelist_tuple(rangelist, nbr_rev_ranges)

Modified: subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/repository.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/repository.py?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/repository.py (original)
+++ subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/repository.py Mon Jul 30 06:39:28 2012
@@ -170,9 +170,11 @@ class SubversionRepositoryTestCase(unitt
     repos.dir_delta(prev_root, '', '', this_root, '', e_ptr, e_baton,
                     _authz_callback, 1, 1, 0, 0)
 
-    # Check results
-    self.assertEqual(editor.textdeltas[0].new_data, "This is a test.\n")
-    self.assertEqual(editor.textdeltas[1].new_data, "A test.\n")
+    # Check results.
+    # Ignore the order in which the editor delivers the two sibling files.
+    self.assertEqual(set([editor.textdeltas[0].new_data,
+                          editor.textdeltas[1].new_data]),
+                     set(["This is a test.\n", "A test.\n"]))
     self.assertEqual(len(editor.textdeltas), 2)
 
   def test_retrieve_and_change_rev_prop(self):

Modified: subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/trac/versioncontrol/tests/svn_fs.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/trac/versioncontrol/tests/svn_fs.py?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/trac/versioncontrol/tests/svn_fs.py (original)
+++ subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/trac/versioncontrol/tests/svn_fs.py Mon Jul 30 06:39:28 2012
@@ -264,30 +264,50 @@ class SubversionRepositoryTestCase(unitt
 
     def test_diff_dir_different_revs(self):
         diffs = self.repos.get_deltas('trunk', 4, 'trunk', 8)
-        self._cmp_diff((None, ('trunk/dir1/dir2', 8),
-                        (Node.DIRECTORY, Changeset.ADD)), diffs.next())
-        self._cmp_diff((None, ('trunk/dir1/dir3', 8),
-                        (Node.DIRECTORY, Changeset.ADD)), diffs.next())
-        self._cmp_diff((None, ('trunk/README2.txt', 6),
-                        (Node.FILE, Changeset.ADD)), diffs.next())
-        self._cmp_diff((('trunk/dir2', 4), None,
-                        (Node.DIRECTORY, Changeset.DELETE)), diffs.next())
-        self._cmp_diff((('trunk/dir3', 4), None,
-                        (Node.DIRECTORY, Changeset.DELETE)), diffs.next())
+        expected = [
+          (None, ('trunk/README2.txt', 6),
+           (Node.FILE, Changeset.ADD)),
+          (None, ('trunk/dir1/dir2', 8),
+           (Node.DIRECTORY, Changeset.ADD)),
+          (None, ('trunk/dir1/dir3', 8),
+           (Node.DIRECTORY, Changeset.ADD)),
+          (('trunk/dir2', 4), None,
+           (Node.DIRECTORY, Changeset.DELETE)),
+          (('trunk/dir3', 4), None,
+           (Node.DIRECTORY, Changeset.DELETE)),
+        ]
+        actual = [diffs.next() for i in range(5)]
+        actual = sorted(actual,
+                        key=lambda diff: ((diff[0] or diff[1]).path,
+                                          (diff[0] or diff[1]).rev))
+        self.assertEqual(len(expected), len(actual))
+        for e,a in zip(expected, actual):
+          self._cmp_diff(e,a)
         self.assertRaises(StopIteration, diffs.next)
 
     def test_diff_dir_different_dirs(self):
         diffs = self.repos.get_deltas('trunk', 1, 'branches/v1x', 12)
-        self._cmp_diff((None, ('branches/v1x/dir1', 12),
-                        (Node.DIRECTORY, Changeset.ADD)), diffs.next())
-        self._cmp_diff((None, ('branches/v1x/dir1/dir2', 12),
-                        (Node.DIRECTORY, Changeset.ADD)), diffs.next())
-        self._cmp_diff((None, ('branches/v1x/dir1/dir3', 12),
-                        (Node.DIRECTORY, Changeset.ADD)), diffs.next())
-        self._cmp_diff((None, ('branches/v1x/README.txt', 12),
-                        (Node.FILE, Changeset.ADD)), diffs.next())
-        self._cmp_diff((None, ('branches/v1x/README2.txt', 12),
-                        (Node.FILE, Changeset.ADD)), diffs.next())
+        expected = [
+          (None, ('branches/v1x/README.txt', 12),
+           (Node.FILE, Changeset.ADD)),
+          (None, ('branches/v1x/README2.txt', 12),
+           (Node.FILE, Changeset.ADD)),
+          (None, ('branches/v1x/dir1', 12),
+           (Node.DIRECTORY, Changeset.ADD)),
+          (None, ('branches/v1x/dir1/dir2', 12),
+           (Node.DIRECTORY, Changeset.ADD)),
+          (None, ('branches/v1x/dir1/dir3', 12),
+           (Node.DIRECTORY, Changeset.ADD)),
+        ]
+        actual = [diffs.next() for i in range(5)]
+        actual = sorted(actual, key=lambda diff: (diff[1].path, diff[1].rev))
+        # for e,a in zip(expected, actual):
+        #   t.write("%r\n" % (e,))
+        #   t.write("%r\n" % ((None, (a[1].path, a[1].rev), (a[2], a[3])),) )
+        #   t.write('\n')
+        self.assertEqual(len(expected), len(actual))
+        for e,a in zip(expected, actual):
+          self._cmp_diff(e,a)
         self.assertRaises(StopIteration, diffs.next)
 
     def test_diff_dir_no_change(self):

Modified: subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/wc.py?rev=1367002&r1=1367001&r2=1367002&view=diff
==============================================================================
--- subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/wc.py (original)
+++ subversion/branches/svn-bisect/subversion/bindings/swig/python/tests/wc.py Mon Jul 30 06:39:28 2012
@@ -216,8 +216,9 @@ class SubversionWorkingCopyTestCase(unit
 
   def test_entries_read(self):
       entries = wc.entries_read(self.wc, True)
-
-      self.assertEqual(['', 'tags', 'branches', 'trunk'], list(entries.keys()))
+      keys = list(entries.keys())
+      keys.sort()
+      self.assertEqual(['', 'branches', 'tags', 'trunk'], keys)
 
   def test_get_ignores(self):
       self.assert_(isinstance(wc.get_ignores(None, self.wc), list))