You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2010/01/05 18:32:11 UTC

svn commit: r896142 [1/3] - in /subversion/branches/issue-3242-dev: ./ build/ build/ac-macros/ build/generator/templates/ notes/tree-conflicts/ subversion/bindings/ctypes-python/test/ subversion/bindings/javahl/tests/org/tigris/subversion/javahl/ subve...

Author: cmpilato
Date: Tue Jan  5 17:31:58 2010
New Revision: 896142

URL: http://svn.apache.org/viewvc?rev=896142&view=rev
Log:
Sync the 'issue-3242-dev' branch up with the trunk.
(Merged /subversion/trunk:r890484-896090)

Removed:
    subversion/branches/issue-3242-dev/HACKING
    subversion/branches/issue-3242-dev/TRANSLATING
Modified:
    subversion/branches/issue-3242-dev/   (props changed)
    subversion/branches/issue-3242-dev/CHANGES
    subversion/branches/issue-3242-dev/COMMITTERS
    subversion/branches/issue-3242-dev/INSTALL
    subversion/branches/issue-3242-dev/build/ac-macros/apr.m4
    subversion/branches/issue-3242-dev/build/ac-macros/aprutil.m4
    subversion/branches/issue-3242-dev/build/buildcheck.sh
    subversion/branches/issue-3242-dev/build/generator/templates/vcnet_vcxproj.ezt
    subversion/branches/issue-3242-dev/notes/tree-conflicts/use-cases.txt
    subversion/branches/issue-3242-dev/subversion/bindings/ctypes-python/test/   (props changed)
    subversion/branches/issue-3242-dev/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/BasicTests.java
    subversion/branches/issue-3242-dev/subversion/bindings/swig/python/tests/mergeinfo.py
    subversion/branches/issue-3242-dev/subversion/bindings/swig/python/tests/trac/test.py
    subversion/branches/issue-3242-dev/subversion/bindings/swig/ruby/test/windows_util.rb
    subversion/branches/issue-3242-dev/subversion/include/private/svn_diff_private.h
    subversion/branches/issue-3242-dev/subversion/include/svn_client.h
    subversion/branches/issue-3242-dev/subversion/include/svn_error_codes.h
    subversion/branches/issue-3242-dev/subversion/include/svn_io.h
    subversion/branches/issue-3242-dev/subversion/libsvn_client/add.c
    subversion/branches/issue-3242-dev/subversion/libsvn_client/commit_util.c
    subversion/branches/issue-3242-dev/subversion/libsvn_client/deprecated.c
    subversion/branches/issue-3242-dev/subversion/libsvn_client/export.c
    subversion/branches/issue-3242-dev/subversion/libsvn_client/externals.c
    subversion/branches/issue-3242-dev/subversion/libsvn_client/merge.c
    subversion/branches/issue-3242-dev/subversion/libsvn_client/mergeinfo.c
    subversion/branches/issue-3242-dev/subversion/libsvn_client/patch.c
    subversion/branches/issue-3242-dev/subversion/libsvn_client/url.c
    subversion/branches/issue-3242-dev/subversion/libsvn_diff/parse-diff.c
    subversion/branches/issue-3242-dev/subversion/libsvn_fs_base/dag.c
    subversion/branches/issue-3242-dev/subversion/libsvn_fs_base/dag.h
    subversion/branches/issue-3242-dev/subversion/libsvn_fs_base/obliterate.c
    subversion/branches/issue-3242-dev/subversion/libsvn_fs_base/revs-txns.c
    subversion/branches/issue-3242-dev/subversion/libsvn_fs_base/trail.h
    subversion/branches/issue-3242-dev/subversion/libsvn_fs_fs/fs_fs.c
    subversion/branches/issue-3242-dev/subversion/libsvn_ra_serf/auth.c
    subversion/branches/issue-3242-dev/subversion/libsvn_ra_serf/ra_serf.h
    subversion/branches/issue-3242-dev/subversion/libsvn_ra_serf/serf.c
    subversion/branches/issue-3242-dev/subversion/libsvn_ra_serf/update.c
    subversion/branches/issue-3242-dev/subversion/libsvn_ra_serf/util.c
    subversion/branches/issue-3242-dev/subversion/libsvn_repos/obliterate.c
    subversion/branches/issue-3242-dev/subversion/libsvn_subr/mergeinfo.c
    subversion/branches/issue-3242-dev/subversion/libsvn_subr/opt.c
    subversion/branches/issue-3242-dev/subversion/libsvn_subr/stream.c
    subversion/branches/issue-3242-dev/subversion/libsvn_wc/adm_crawler.c
    subversion/branches/issue-3242-dev/subversion/libsvn_wc/entries.c
    subversion/branches/issue-3242-dev/subversion/libsvn_wc/lock.c
    subversion/branches/issue-3242-dev/subversion/libsvn_wc/props.c
    subversion/branches/issue-3242-dev/subversion/libsvn_wc/update_editor.c
    subversion/branches/issue-3242-dev/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/issue-3242-dev/subversion/libsvn_wc/wc_db.c
    subversion/branches/issue-3242-dev/subversion/libsvn_wc/wc_db.h
    subversion/branches/issue-3242-dev/subversion/mod_dav_svn/merge.c
    subversion/branches/issue-3242-dev/subversion/svn/cl.h
    subversion/branches/issue-3242-dev/subversion/svn/export-cmd.c
    subversion/branches/issue-3242-dev/subversion/svn/main.c
    subversion/branches/issue-3242-dev/subversion/svn/merge-cmd.c
    subversion/branches/issue-3242-dev/subversion/tests/cmdline/basic_tests.py
    subversion/branches/issue-3242-dev/subversion/tests/cmdline/commit_tests.py
    subversion/branches/issue-3242-dev/subversion/tests/cmdline/export_tests.py
    subversion/branches/issue-3242-dev/subversion/tests/cmdline/externals_tests.py
    subversion/branches/issue-3242-dev/subversion/tests/cmdline/getopt_tests.py
    subversion/branches/issue-3242-dev/subversion/tests/cmdline/getopt_tests_data/svn--version_stdout
    subversion/branches/issue-3242-dev/subversion/tests/cmdline/merge_tests.py
    subversion/branches/issue-3242-dev/subversion/tests/cmdline/mergeinfo_tests.py
    subversion/branches/issue-3242-dev/subversion/tests/cmdline/obliterate_tests.py
    subversion/branches/issue-3242-dev/subversion/tests/cmdline/prop_tests.py
    subversion/branches/issue-3242-dev/subversion/tests/cmdline/svntest/actions.py
    subversion/branches/issue-3242-dev/subversion/tests/cmdline/svntest/objects.py
    subversion/branches/issue-3242-dev/subversion/tests/libsvn_diff/parse-diff-test.c
    subversion/branches/issue-3242-dev/subversion/tests/libsvn_fs_fs/   (props changed)
    subversion/branches/issue-3242-dev/subversion/tests/libsvn_subr/stream-test.c
    subversion/branches/issue-3242-dev/tools/dev/gen_junit_report.py
    subversion/branches/issue-3242-dev/tools/dev/wc-ng/gather-data.sh
    subversion/branches/issue-3242-dev/tools/hook-scripts/mailer/mailer.py
    subversion/branches/issue-3242-dev/tools/hook-scripts/svnperms.py

Propchange: subversion/branches/issue-3242-dev/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Jan  5 17:31:58 2010
@@ -32,4 +32,4 @@
 /subversion/branches/tc_url_rev:874351-874483
 /subversion/branches/tree-conflicts:868291-873154
 /subversion/branches/tree-conflicts-notify:873926-874008
-/subversion/trunk:879653-890483
+/subversion/trunk:879653-896090

Modified: subversion/branches/issue-3242-dev/CHANGES
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/CHANGES?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/CHANGES (original)
+++ subversion/branches/issue-3242-dev/CHANGES Tue Jan  5 17:31:58 2010
@@ -1,10 +1,28 @@
 Version 1.6.7
-(?? ??? ????, from /branches/1.6.x)
-http://svn.collab.net/repos/svn/tags/1.6.7
+(29 Dec 2009, from /branches/1.6.x)
+http://svn.apache.org/repos/asf/subversion/tags/1.6.7
 
  User-visible changes:
-
- Developer-visible changes:
+  * allow multiple external updates over ra_svn (issue #3487)
+  * fix a segmentation fault when using FSFS (r881905)
+  * support Berkeley DB 4.8 (r879688)
+  * various autoprop improvements (r880274, -5)
+  * improve usage of svn+ssh:// on Windows (issue #2580)
+  * teach 1.6.x to recognize 1.7 working copies (1.6.x-future-proof branch)
+  * update help text for 'svn update' and 'svn switch' (r886164, -97)
+  * make 'svnadmin load --parent-dir' create valid mergeinfo (r888979, -9081)
+  * tolerate relative merge source paths in mergeinfo (r889840)
+  * teach mod_dav_svn to support the Label header (issue #3519)
+  * fixed: svnsync leaves stale sync-locks on mirrors (r884842)
+  * fix applicability of 'svn resolve --accept=theirs-conflict' (r880525, -6)
+
+ Developer-visible changes:
+  * update ruby bindings test expectation (r880162)
+
+
+[ Note: All revision numbers for versions prior to 1.6.7 reference the
+  original repository on svn.collab.net.  For more information see:
+  http://svn.apache.org/repos/asf/subversion/README ]
 
 
 Version 1.6.6

Modified: subversion/branches/issue-3242-dev/COMMITTERS
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/COMMITTERS?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/COMMITTERS [UTF-8] (original)
+++ subversion/branches/issue-3242-dev/COMMITTERS [UTF-8] Tue Jan  5 17:31:58 2010
@@ -39,7 +39,7 @@
         pburba   Paul Burba <pb...@collab.net>
        glasser   David Glasser <gl...@davidglasser.net>
            lgo   Lieven Govaerts <lg...@mobsol.be>
-       hwright   Hyrum Wright <hy...@mail.utexas.edu>
+       hwright   Hyrum Wright <hy...@wandisco.com>
     vgeorgescu   Vlad Georgescu <vg...@gmail.com>
        kameshj   Kamesh Jayachandran <ka...@collab.net>
       markphip   Mark Phippard <mp...@collab.net>

Modified: subversion/branches/issue-3242-dev/INSTALL
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/INSTALL?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/INSTALL (original)
+++ subversion/branches/issue-3242-dev/INSTALL Tue Jan  5 17:31:58 2010
@@ -700,7 +700,7 @@
       a checkout and see an error like:
 
       subversion/libsvn_ra/ra_loader.c:209: (apr_err=170000)
-      svn: Unrecognized URL scheme 'http://svn.collab.net/repos/svn/trunk'
+      svn: Unrecognized URL scheme 'https://svn.apache.org/repos/asf/subversion/trunk'
 
       It probably means that the dynamic loader/linker can't find all
       of the libsvn_* libraries.
@@ -725,7 +725,7 @@
       It is possible to configure and build Subversion on Unix in a
       directory other than the working copy. For example
 
-          $ svn co http://svn.collab.net/repos/svn/trunk svn
+          $ svn co https://svn.apache.org/repos/asf/subversion/trunk svn
           $ cd svn
           $ # get neon/apr as required
           $ chmod +x autogen.sh
@@ -793,7 +793,7 @@
       "command" from the Start menu's "Run..." menu option), change to
       the directory you installed the executables into, and run:
 
-          C:\test>svn co http://svn.collab.net/repos/svn/trunk svn
+          C:\test>svn co https://svn.apache.org/repos/asf/subversion/trunk svn
 
       This will get the latest Subversion sources and put them into the
       "svn" subdirectory.
@@ -892,7 +892,7 @@
       * Make a directory SVN and cd into it.
       * Either checkout Subversion:
 
-          svn co http://svn.collab.net/repos/svn/trunk/ src-trunk
+          svn co https://svn.apache.org/repos/asf/subversion/trunk src-trunk
 
         or unpack the zip file distribution and rename the directory to
         src-trunk.

Modified: subversion/branches/issue-3242-dev/build/ac-macros/apr.m4
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/build/ac-macros/apr.m4?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/build/ac-macros/apr.m4 (original)
+++ subversion/branches/issue-3242-dev/build/ac-macros/apr.m4 Tue Jan  5 17:31:58 2010
@@ -131,7 +131,7 @@
   echo "get it with SVN and put it in a subdirectory of this source:"
   echo ""
   echo "   svn co \\"
-  echo "    http://svn.apache.org/repos/asf/apr/apr/branches/1.2.x \\"
+  echo "    http://svn.apache.org/repos/asf/apr/apr/branches/1.3.x \\"
   echo "    apr"
   echo ""
   echo "Run that right here in the top level of the Subversion tree."
@@ -144,7 +144,7 @@
   echo "getting both from SVN with:"
   echo ""
   echo "   svn co \\"
-  echo "    http://svn.apache.org/repos/asf/apr/apr-util/branches/1.2.x \\"
+  echo "    http://svn.apache.org/repos/asf/apr/apr-util/branches/1.3.x \\"
   echo "    apr-util"
   echo ""
   AC_MSG_ERROR([no suitable apr found])

Modified: subversion/branches/issue-3242-dev/build/ac-macros/aprutil.m4
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/build/ac-macros/aprutil.m4?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/build/ac-macros/aprutil.m4 (original)
+++ subversion/branches/issue-3242-dev/build/ac-macros/aprutil.m4 Tue Jan  5 17:31:58 2010
@@ -135,7 +135,7 @@
   echo "get it with SVN and put it in a subdirectory of this source:"
   echo ""
   echo "   svn co \\"
-  echo "    http://svn.apache.org/repos/asf/apr/apr-util/branches/1.2.x \\"
+  echo "    http://svn.apache.org/repos/asf/apr/apr-util/branches/1.3.x \\"
   echo "    apr-util"
   echo ""
   echo "Run that right here in the top level of the Subversion tree."

Modified: subversion/branches/issue-3242-dev/build/buildcheck.sh
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/build/buildcheck.sh?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/build/buildcheck.sh (original)
+++ subversion/branches/issue-3242-dev/build/buildcheck.sh Tue Jan  5 17:31:58 2010
@@ -1,3 +1,4 @@
+#! /bin/sh
 #
 #
 # Licensed to the Apache Software Foundation (ASF) under one
@@ -18,8 +19,6 @@
 # under the License.
 #
 #
-#! /bin/sh
-#
 # buildcheck.sh: Inspects the build setup to make detection and
 # correction of problems an easier process.
 

Modified: subversion/branches/issue-3242-dev/build/generator/templates/vcnet_vcxproj.ezt
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/build/generator/templates/vcnet_vcxproj.ezt?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/build/generator/templates/vcnet_vcxproj.ezt (original)
+++ subversion/branches/issue-3242-dev/build/generator/templates/vcnet_vcxproj.ezt Tue Jan  5 17:31:58 2010
@@ -45,7 +45,8 @@
 [for configs][for platforms]    <OutDir Condition="'$(Configuration)|$(Platform)'=='[configs.name]|[platforms]'">$([[]System.IO.Path]::GetFullPath('$(ProjectDir)..\..\..\[configs.name]\[target.output_dir]'))\</OutDir>
     <IntDir Condition="'$(Configuration)|$(Platform)'=='[configs.name]|[platforms]'">..\..\..\[configs.name]\[target.intermediate_dir]\</IntDir>
     <TargetName Condition="'$(Configuration)|$(Platform)'=='[configs.name]|[platforms]'">[target.output_name_without_ext]</TargetName>
-[end][end]  </PropertyGroup>
+[is config_type "DynamicLibrary"][is target.output_ext ".dll"][else]    <TargetExt>[target.output_ext]</TargetExt>
+[end][end][end][end]  </PropertyGroup>
 [for configs][for platforms]  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='[configs.name]|[platforms]'">
     <ClCompile>
 [is configs.name "Debug"]      <Optimization>Disabled</Optimization>
@@ -61,6 +62,7 @@
       <WarningLevel>Level4</WarningLevel>
       <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
       <ProgramDataBaseFileName>$(IntDir)[target.output_pdb]</ProgramDataBaseFileName>
+      <BrowseInformation>true</BrowseInformation>
       <DisableSpecificWarnings>4100;4127;4204;4206;4701;4706;%(DisableSpecificWarnings)</DisableSpecificWarnings>
       <TreatSpecificWarningsAsErrors>4002;4003;4013;4020;4022;4024;4028;4029;4030;4031;4047;4089;4115;%(TreatSpecificWarningsAsErrors)</TreatSpecificWarningsAsErrors>
     </ClCompile>
@@ -68,11 +70,14 @@
       <OutputFile>$(OutDir)[target.output_name]</OutputFile>
       <AdditionalDependencies>[for configs.libs][configs.libs];[end]%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>[for configs.libdirs][configs.libdirs];[end]%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
     </Link>
 [else][is config_type "DynamicLibrary"]    <Link>
       <OutputFile>$(OutDir)[target.output_name]</OutputFile>
       <AdditionalDependencies>[for configs.libs][configs.libs];[end]%(AdditionalDependencies)</AdditionalDependencies>
       <AdditionalLibraryDirectories>[for configs.libdirs][configs.libdirs];[end]%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
 [if-any def_file]      <ModuleDefinitionFile>[def_file]</ModuleDefinitionFile>
 [end]    </Link>
 [else][is config_type "StaticLibrary"]    <Lib>

Modified: subversion/branches/issue-3242-dev/notes/tree-conflicts/use-cases.txt
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/notes/tree-conflicts/use-cases.txt?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/notes/tree-conflicts/use-cases.txt (original)
+++ subversion/branches/issue-3242-dev/notes/tree-conflicts/use-cases.txt Tue Jan  5 17:31:58 2010
@@ -245,7 +245,7 @@
 
    Developer B moves Foo.c to Bar.c and commits it to the repository.
    
-   Developer merges A's new revision into his working copy. The merge
+   Developer B merges A's new revision into his working copy. The merge
    will apply A's modification to Foo.c to the Foo.c in B's working
    copy.
 
@@ -320,11 +320,11 @@
 
 Current Behavior
 
-   Developer A  moves Foo.c to Bar.c and commits it to the repository.
+   Developer A moves Foo.c to Bar.c and commits it to the repository.
 
-   Developer B modifies Foo.cand commits it to the repository.
+   Developer B modifies Foo.c and commits it to the repository.
    
-   Developer merges A's new revision into his working copy.  The merge
+   Developer B merges A's new revision into his working copy.  The merge
    will add Bar.c (with the same content as the original Foo.c) and
    will delete B's Foo.c.
 
@@ -398,7 +398,7 @@
 
    Developer B moves Foo.c to Bix.c and commits it to the repository.
    
-   Developer merges A's new revision into his working copy.  The merge
+   Developer B merges A's new revision into his working copy.  The merge
    will add Bar.c with history in B's working copy.
 
 Problems With Current Behavior

Propchange: subversion/branches/issue-3242-dev/subversion/bindings/ctypes-python/test/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Jan  5 17:31:58 2010
@@ -0,0 +1 @@
+*.pyc

Modified: subversion/branches/issue-3242-dev/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/BasicTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/BasicTests.java?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/BasicTests.java (original)
+++ subversion/branches/issue-3242-dev/subversion/bindings/javahl/tests/org/tigris/subversion/javahl/BasicTests.java Tue Jan  5 17:31:58 2010
@@ -2247,7 +2247,9 @@
     private long[] getMergeinfoRevisions(int kind, String pathOrUrl,
                                          Revision pegRevision,
                                          String mergeSourceUrl,
-                                         Revision srcPegRevision) {
+                                         Revision srcPegRevision) 
+        throws SubversionException
+    {
         class Callback implements LogMessageCallback {
 
             List revList = new ArrayList();
@@ -2268,15 +2270,10 @@
                 return revisions;
             }
         }
-        try {
-            Callback callback = new Callback();
-            client.getMergeinfoLog(kind, pathOrUrl, pegRevision, mergeSourceUrl,
-                                   srcPegRevision, false, null, callback);
-            return callback.getRevisions();
-        } catch (ClientException e) {
-            return null;
-        }
-
+        Callback callback = new Callback();
+        client.getMergeinfoLog(kind, pathOrUrl, pegRevision, mergeSourceUrl,
+                               srcPegRevision, false, null, callback);
+        return callback.getRevisions();
     }
 
     /**

Modified: subversion/branches/issue-3242-dev/subversion/bindings/swig/python/tests/mergeinfo.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/bindings/swig/python/tests/mergeinfo.py?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/bindings/swig/python/tests/mergeinfo.py (original)
+++ subversion/branches/issue-3242-dev/subversion/bindings/swig/python/tests/mergeinfo.py Tue Jan  5 17:31:58 2010
@@ -129,10 +129,10 @@
                                        False, None, None)
     expected_mergeinfo = \
       { '/trunk' :
-          { 'branches/a' : [RevRange(2, 11)],
-            'branches/b' : [RevRange(9, 13)],
-            'branches/c' : [RevRange(2, 16)],
-            'trunk'      : [RevRange(1, 9)],  },
+          { '/branches/a' : [RevRange(2, 11)],
+            '/branches/b' : [RevRange(9, 13)],
+            '/branches/c' : [RevRange(2, 16)],
+            '/trunk'      : [RevRange(1, 9)],  },
       }
     self.compare_mergeinfo_catalogs(mergeinfo, expected_mergeinfo)
 

Modified: subversion/branches/issue-3242-dev/subversion/bindings/swig/python/tests/trac/test.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/bindings/swig/python/tests/trac/test.py?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/bindings/swig/python/tests/trac/test.py (original)
+++ subversion/branches/issue-3242-dev/subversion/bindings/swig/python/tests/trac/test.py Tue Jan  5 17:31:58 2010
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+# -*- coding: utf-8 -*-
 #
 #
 # Licensed to the Apache Software Foundation (ASF) under one
@@ -19,8 +20,6 @@
 # under the License.
 #
 #
-# -*- coding: utf-8 -*-
-#
 # Copyright (C) 2003, 2004, 2005 Edgewall Software
 # Copyright (C) 2003, 2004, 2005 Jonas Borgström <jo...@edgewall.com>
 # Copyright (C) 2005 Christopher Lenz <cm...@gmx.de>

Modified: subversion/branches/issue-3242-dev/subversion/bindings/swig/ruby/test/windows_util.rb
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/bindings/swig/ruby/test/windows_util.rb?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/bindings/swig/ruby/test/windows_util.rb (original)
+++ subversion/branches/issue-3242-dev/subversion/bindings/swig/ruby/test/windows_util.rb Tue Jan  5 17:31:58 2010
@@ -238,6 +238,8 @@
          ["apr-util", build_type],
          ["apr-iconv", build_type],
          ["berkeley-db", "bin"],
+         ["libintl", "bin"],
+         ["sasl", "lib"],
         ].each do |lib, sub_dir|
           lib_dir = Pathname.new(gen_make_opts["--with-#{lib}"])
           dll_dir = lib_dir + sub_dir

Modified: subversion/branches/issue-3242-dev/subversion/include/private/svn_diff_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/include/private/svn_diff_private.h?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/include/private/svn_diff_private.h (original)
+++ subversion/branches/issue-3242-dev/subversion/include/private/svn_diff_private.h Tue Jan  5 17:31:58 2010
@@ -97,23 +97,18 @@
   const char *old_filename;
   const char *new_filename;
 
-  /* EOL string used in patch file. */
-  const char *eol_str;
-
   /* An array containing an svn_hunk_t object for each hunk parsed
    * from the patch. */
   apr_array_header_t *hunks;
 } svn_patch_t;
 
-/* Return the next *PATCH in PATCH_FILE. The patch file is assumed to
- * have consistent EOL-markers as specified in EOL_STR.
+/* Return the next *PATCH in PATCH_FILE.
  * If no patch can be found, set *PATCH to NULL.
  * Allocate results in RESULT_POOL.
  * Use SCRATCH_POOL for all other allocations. */
 svn_error_t *
 svn_diff__parse_next_patch(svn_patch_t **patch,
                            apr_file_t *patch_file,
-                           const char *eol_str,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool);
 

Modified: subversion/branches/issue-3242-dev/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/include/svn_client.h?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/include/svn_client.h (original)
+++ subversion/branches/issue-3242-dev/subversion/include/svn_client.h Tue Jan  5 17:31:58 2010
@@ -4033,6 +4033,9 @@
  * If @a ignore_externals is set, don't process externals definitions
  * as part of this operation.
  *
+ * If @a ignore_keywords is set, don't expand keywords as part of this
+ * operation.
+ *
  * @a native_eol allows you to override the standard eol marker on the platform
  * you are running on.  Can be either "LF", "CR" or "CRLF" or NULL.  If NULL
  * will use the standard eol marker.  Any other value will cause the
@@ -4047,6 +4050,28 @@
  *
  * All allocations are done in @a pool.
  *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_client_export5(svn_revnum_t *result_rev,
+                   const char *from,
+                   const char *to,
+                   const svn_opt_revision_t *peg_revision,
+                   const svn_opt_revision_t *revision,
+                   svn_boolean_t overwrite,
+                   svn_boolean_t ignore_externals,
+                   svn_boolean_t ignore_keywords,
+                   svn_depth_t depth,
+                   const char *native_eol,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *pool);
+
+/**
+ * Similar to svn_client_export5(), but with @a ignore_keywords set
+ * to FALSE.
+ *
+ * @deprecated Provided for backward compatibility with the 1.5 API.
+ *
  * @since New in 1.5.
  */
 svn_error_t *

Modified: subversion/branches/issue-3242-dev/subversion/include/svn_error_codes.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/include/svn_error_codes.h?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/include/svn_error_codes.h (original)
+++ subversion/branches/issue-3242-dev/subversion/include/svn_error_codes.h Tue Jan  5 17:31:58 2010
@@ -293,6 +293,11 @@
              SVN_ERR_STREAM_CATEGORY_START + 3,
              "Stream doesn't support resetting")
 
+  /** @since New in 1.7. */
+  SVN_ERRDEF(SVN_ERR_STREAM_SEEK_NOT_SUPPORTED,
+             SVN_ERR_STREAM_CATEGORY_START + 4,
+             "Stream doesn't support seeking")
+
   /* node errors */
 
   SVN_ERRDEF(SVN_ERR_NODE_UNKNOWN_KIND,

Modified: subversion/branches/issue-3242-dev/subversion/include/svn_io.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/include/svn_io.h?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/include/svn_io.h (original)
+++ subversion/branches/issue-3242-dev/subversion/include/svn_io.h Tue Jan  5 17:31:58 2010
@@ -702,6 +702,30 @@
  */
 typedef svn_error_t *(*svn_io_reset_fn_t)(void *baton);
 
+/* An opaque type which represents a mark on a stream.
+ *
+ * @see svn_stream_mark().
+ * @since New in 1.7.
+ */
+typedef struct svn_stream_mark_t svn_stream_mark_t;
+
+/** Mark handler function for a generic stream. @see svn_stream_t and
+ * svn_stream_mark().
+ *
+ * @since New in 1.7.
+ */
+typedef svn_error_t *(*svn_io_mark_fn_t)(void *baton,
+                                         svn_stream_mark_t **mark,
+                                         apr_pool_t *pool);
+
+/** Seek handler function for a generic stream. @see svn_stream_t and
+ * svn_stream_seek().
+ *
+ * @since New in 1.7.
+ */
+typedef svn_error_t *(*svn_io_seek_fn_t)(void *baton,
+                                         svn_stream_mark_t *mark);
+
 /** Line-filtering callback function for a generic stream.
  * @a baton is the stream's baton.
  * @see svn_stream_t, svn_stream_set_baton() and svn_stream_readline().
@@ -770,6 +794,22 @@
 svn_stream_set_reset(svn_stream_t *stream,
                      svn_io_reset_fn_t reset_fn);
 
+/** Set @a stream's mark function to @a mark_fn 
+ *
+ * @since New in 1.7.
+ */
+void
+svn_stream_set_mark(svn_stream_t *stream,
+                    svn_io_mark_fn_t mark_fn);
+
+/** Set @a stream's seek function to @a seek_fn 
+ *
+ * @since New in 1.7.
+ */
+void
+svn_stream_set_seek(svn_stream_t *stream,
+                    svn_io_seek_fn_t seek_fn);
+
 /** Set @a stream's line-filtering callback function to @a line_filter_cb
  *
  * @since New in 1.7.
@@ -1028,7 +1068,7 @@
 
 /** Reset a generic stream back to its origin. E.g. On a file this would be
  * implemented as a seek to position 0).  This function returns a
- * @a SVN_ERR_STREAM_RESET_NOT_SUPPORTED error when the stream doesn't
+ * #SVN_ERR_STREAM_RESET_NOT_SUPPORTED error when the stream doesn't
  * implement resetting.
  *
  * @since New in 1.7.
@@ -1036,6 +1076,30 @@
 svn_error_t *
 svn_stream_reset(svn_stream_t *stream);
 
+/** Set a @a mark at the current position of a generic @a stream,
+ * which can later be sought back to using svn_stream_seek().
+ * The @a mark is allocated in @a pool.
+ *
+ * This function returns the #SVN_ERR_STREAM_SEEK_NOT_SUPPORTED error
+ * if the stream doesn't implement seeking.
+ *
+ * @see svn_stream_seek()
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_stream_mark(svn_stream_t *stream,
+                svn_stream_mark_t **mark,
+                apr_pool_t *pool);
+
+/* Seek to a @a mark in a generic @a stream.
+ * This function returns the #SVN_ERR_STREAM_SEEK_NOT_SUPPORTED error
+ * if the stream doesn't implement seeking.
+ *
+ * @see svn_stream_mark()
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_stream_seek(svn_stream_t *stream, svn_stream_mark_t *mark);
 
 /** Return a writable stream which, when written to, writes to both of the
  * underlying streams.  Both of these streams will be closed upon closure of
@@ -1106,6 +1170,20 @@
                     svn_boolean_t *eof,
                     apr_pool_t *pool);
 
+/**
+ * Similar to svn_stream_readline(). The line-terminator is detected
+ * automatically.  If @a eol is not NULL, the detected line-terminator
+ * is returned in @a *eol.  If EOF is reached and the stream does not
+ * end with a newline character, @a *eol will be NULL.
+ *
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_stream_readline_detect_eol(svn_stream_t *stream,
+                               svn_stringbuf_t **stringbuf,
+                               const char **eol,
+                               svn_boolean_t *eof,
+                               apr_pool_t *pool);
 
 /**
  * Read the contents of the readable stream @a from and write them to the

Modified: subversion/branches/issue-3242-dev/subversion/libsvn_client/add.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/libsvn_client/add.c?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/libsvn_client/add.c (original)
+++ subversion/branches/issue-3242-dev/subversion/libsvn_client/add.c Tue Jan  5 17:31:58 2010
@@ -556,6 +556,8 @@
 
   parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
 
+  /* ### Do we need locks here?  Are locks being enforced? 1.6 used to
+         acquire and release locks. */
   SVN_ERR(add_parent_dirs(ctx, parent_abspath, scratch_pool));
   SVN_ERR(svn_wc_add4(ctx->wc_ctx, local_abspath, svn_depth_infinity,
                       NULL, SVN_INVALID_REVNUM,
@@ -595,28 +597,18 @@
   else
     parent_abspath = svn_dirent_dirname(local_abspath, pool);
 
-  SVN_ERR(svn_wc__acquire_write_lock(NULL, ctx->wc_ctx, parent_abspath,
-                                     pool, pool));
-
   if (add_parents)
     {
       apr_pool_t *subpool;
 
       subpool = svn_pool_create(pool);
-      err = add_parent_dirs(ctx, parent_abspath, subpool);
-
-      /* We need to be sure we release our working copy locks if we bump
-         into a situation where we couldn't add the parents. */
-      if (err)
-        return svn_error_return(
-                    svn_error_compose_create(
-                      err,
-                      svn_wc__release_write_lock(ctx->wc_ctx, parent_abspath,
-                                                 pool)));
-
+      SVN_ERR(add_parent_dirs(ctx, parent_abspath, subpool));
       svn_pool_destroy(subpool);
     }
 
+  SVN_ERR(svn_wc__acquire_write_lock(NULL, ctx->wc_ctx, parent_abspath,
+                                     pool, pool));
+
   err = add(local_abspath, depth, force, no_ignore, ctx, pool);
 
   /* ### Currently we rely on the fact that this releases all our write locks

Modified: subversion/branches/issue-3242-dev/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/libsvn_client/commit_util.c?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/libsvn_client/commit_util.c (original)
+++ subversion/branches/issue-3242-dev/subversion/libsvn_client/commit_util.c Tue Jan  5 17:31:58 2010
@@ -430,6 +430,9 @@
          svn_dirent_local_style(path, scratch_pool));
     }
 
+  if (entry->file_external_path && copy_mode)
+    return SVN_NO_ERROR;
+
   if (entry->kind == svn_node_dir)
     {
       /* Read the dir's own entries for use when recursing. */

Modified: subversion/branches/issue-3242-dev/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/libsvn_client/deprecated.c?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/libsvn_client/deprecated.c (original)
+++ subversion/branches/issue-3242-dev/subversion/libsvn_client/deprecated.c Tue Jan  5 17:31:58 2010
@@ -860,6 +860,24 @@
 
 /*** From export.c ***/
 svn_error_t *
+svn_client_export4(svn_revnum_t *result_rev,
+                   const char *from,
+                   const char *to,
+                   const svn_opt_revision_t *peg_revision,
+                   const svn_opt_revision_t *revision,
+                   svn_boolean_t overwrite,
+                   svn_boolean_t ignore_externals,
+                   svn_depth_t depth,
+                   const char *native_eol,
+                   svn_client_ctx_t *ctx,
+                   apr_pool_t *pool)
+{
+  return svn_client_export5(result_rev, from, to, peg_revision, revision,
+                            overwrite, ignore_externals, FALSE, depth,
+                            native_eol, ctx, pool);
+}
+
+svn_error_t *
 svn_client_export3(svn_revnum_t *result_rev,
                    const char *from,
                    const char *to,

Modified: subversion/branches/issue-3242-dev/subversion/libsvn_client/export.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/libsvn_client/export.c?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/libsvn_client/export.c (original)
+++ subversion/branches/issue-3242-dev/subversion/libsvn_client/export.c Tue Jan  5 17:31:58 2010
@@ -101,6 +101,7 @@
                         svn_wc_context_t *wc_ctx,
                         const svn_opt_revision_t *revision,
                         const char *native_eol,
+                        svn_boolean_t ignore_keywords,
                         apr_pool_t *scratch_pool)
 {
   const svn_wc_entry_t *entry;
@@ -245,7 +246,7 @@
                                              eol,
                                              FALSE /* repair */,
                                              kw,
-                                             TRUE /* expand */,
+                                             ! ignore_keywords /* expand */,
                                              scratch_pool);
 
   /* ###: use cancel func/baton in place of NULL/NULL below. */
@@ -271,6 +272,7 @@
                      const svn_opt_revision_t *revision,
                      svn_boolean_t force,
                      svn_boolean_t ignore_externals,
+                     svn_boolean_t ignore_keywords,
                      svn_depth_t depth,
                      const char *native_eol,
                      svn_client_ctx_t *ctx,
@@ -369,7 +371,8 @@
 
                   SVN_ERR(copy_versioned_files(new_from, new_to,
                                                revision, force,
-                                               ignore_externals, depth,
+                                               ignore_externals,
+                                               ignore_keywords, depth,
                                                native_eol, ctx, iterpool));
                 }
             }
@@ -391,7 +394,8 @@
 
               SVN_ERR(copy_one_versioned_file(new_from_abspath, new_to_abspath,
                                               ctx->wc_ctx, revision,
-                                              native_eol, iterpool));
+                                              native_eol, ignore_keywords,
+                                              iterpool));
             }
         }
 
@@ -435,6 +439,7 @@
 
                   SVN_ERR(copy_versioned_files(new_from, new_to,
                                                revision, force, FALSE,
+                                               ignore_keywords,
                                                svn_depth_infinity, native_eol,
                                                ctx, iterpool));
                 }
@@ -446,7 +451,8 @@
   else if (from_kind == svn_node_file)
     {
       SVN_ERR(copy_one_versioned_file(from_abspath, to_abspath, ctx->wc_ctx,
-                                      revision, native_eol, pool));
+                                      revision, native_eol, ignore_keywords,
+                                      pool));
     }
 
   return SVN_NO_ERROR;
@@ -511,6 +517,7 @@
   svn_revnum_t *target_revision;
   apr_hash_t *externals;
   const char *native_eol;
+  svn_boolean_t ignore_keywords;
 
   svn_wc_notify_func2_t notify_func;
   void *notify_baton;
@@ -739,7 +746,8 @@
   if (strcmp(name, SVN_PROP_EOL_STYLE) == 0)
     fb->eol_style_val = svn_string_dup(value, fb->pool);
 
-  else if (strcmp(name, SVN_PROP_KEYWORDS) == 0)
+  else if (! fb->edit_baton->ignore_keywords &&
+           strcmp(name, SVN_PROP_KEYWORDS) == 0)
     fb->keywords_val = svn_string_dup(value, fb->pool);
 
   else if (strcmp(name, SVN_PROP_EXECUTABLE) == 0)
@@ -868,13 +876,14 @@
 /*** Public Interfaces ***/
 
 svn_error_t *
-svn_client_export4(svn_revnum_t *result_rev,
+svn_client_export5(svn_revnum_t *result_rev,
                    const char *from,
                    const char *to,
                    const svn_opt_revision_t *peg_revision,
                    const svn_opt_revision_t *revision,
                    svn_boolean_t overwrite,
                    svn_boolean_t ignore_externals,
+                   svn_boolean_t ignore_keywords,
                    svn_depth_t depth,
                    const char *native_eol,
                    svn_client_ctx_t *ctx,
@@ -915,6 +924,7 @@
       eb->notify_baton = ctx->notify_baton2;
       eb->externals = apr_hash_make(pool);
       eb->native_eol = native_eol;
+      eb->ignore_keywords = ignore_keywords;
 
       SVN_ERR(svn_ra_check_path(ra_session, "", revnum, &kind, pool));
 
@@ -1038,8 +1048,8 @@
       /* This is a working copy export. */
       /* just copy the contents of the working copy into the target path. */
       SVN_ERR(copy_versioned_files(from, to, revision, overwrite,
-                                   ignore_externals, depth, native_eol,
-                                   ctx, pool));
+                                   ignore_externals, ignore_keywords,
+                                   depth, native_eol, ctx, pool));
     }
 
 

Modified: subversion/branches/issue-3242-dev/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/libsvn_client/externals.c?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/issue-3242-dev/subversion/libsvn_client/externals.c Tue Jan  5 17:31:58 2010
@@ -894,51 +894,22 @@
          just be renamed to a new one. */
 
       svn_error_t *err;
-      svn_wc_adm_access_t *adm_access;
-      svn_boolean_t close_access_baton_when_done;
-
       const char *remove_target_abspath;
+      svn_boolean_t lock_existed; 
 
-      /* Determine if a directory or file external is being removed.
-         Try to handle the case when the user deletes the external by
-         hand or it is missing.  First try to open the directory for a
-         directory external.  If that doesn't work, get the access
-         baton for the parent directory and remove the entry for the
-         external. */
-      err = svn_wc__adm_open_in_context(&adm_access, ib->ctx->wc_ctx, path,
-                                        TRUE, -1, ib->ctx->cancel_func,
-                                        ib->ctx->cancel_baton, ib->iter_pool);
-      if (err)
-        {
-          const char *anchor;
-          const char *target;
-          svn_error_t *err2;
-
-          SVN_ERR(svn_wc_get_actual_target2(&anchor, &target, ib->ctx->wc_ctx,
-                                            path, ib->iter_pool,
-                                            ib->iter_pool));
+      SVN_ERR(svn_dirent_get_absolute(&remove_target_abspath,
+                                      path,
+                                      ib->iter_pool));
 
-          err2 = svn_wc_adm_retrieve(&adm_access, ib->adm_access, anchor,
-                                     ib->iter_pool);
-          if (err2)
-            {
-              svn_error_clear(err2);
-              return svn_error_return(err);
-            }
-          else
-            {
-              svn_error_clear(err);
-            }
-          close_access_baton_when_done = FALSE;
-          SVN_ERR(svn_dirent_get_absolute(&remove_target_abspath, target,
-                                          ib->iter_pool));
-        }
-      else
+      SVN_ERR(svn_wc_locked2(&lock_existed, NULL, ib->ctx->wc_ctx,
+                             remove_target_abspath, ib->iter_pool));
+
+      if (! lock_existed)
         {
-          close_access_baton_when_done = TRUE;
-          SVN_ERR(svn_dirent_get_absolute(&remove_target_abspath,
-                                          svn_wc_adm_access_path(adm_access),
-                                          ib->iter_pool));
+          SVN_ERR(svn_wc__acquire_write_lock(NULL, ib->ctx->wc_ctx,
+                                             remove_target_abspath, 
+                                             ib->iter_pool,
+                                             ib->iter_pool));
         }
 
       /* We don't use relegate_dir_external() here, because we know that
@@ -965,13 +936,15 @@
         }
 
       /* ### Ugly. Unlock only if not going to return an error. Revisit */
-      if (close_access_baton_when_done &&
-          (!err || err->apr_err == SVN_ERR_WC_LEFT_LOCAL_MOD))
+      if (! lock_existed
+          && (! err || err->apr_err == SVN_ERR_WC_LEFT_LOCAL_MOD))
         {
-          svn_error_t *err2 = svn_wc_adm_close2(adm_access, ib->iter_pool);
+          svn_error_t *err2 = svn_wc__release_write_lock(ib->ctx->wc_ctx, 
+                                                         remove_target_abspath,
+                                                         ib->iter_pool);
           if (err2)
             {
-              if (!err)
+              if (! err)
                 err = err2;
               else
                 svn_error_clear(err2);

Modified: subversion/branches/issue-3242-dev/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/libsvn_client/merge.c?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/issue-3242-dev/subversion/libsvn_client/merge.c Tue Jan  5 17:31:58 2010
@@ -8561,6 +8561,9 @@
    path@TARGET_REV.  Effectively this is the mergeinfo catalog on the
    reintegrate target.
 
+   YC_ANCESTOR_REV is the revision of the youngest common ancestor of the
+   reintegrate source and the reintegrate target.
+
    SOURCE_REPOS_REL_PATH is the path of the reintegrate source relative to
    the root of the repository.  TARGET_REPOS_REL_PATH is the path of the
    reintegrate target relative to the root of the repository.
@@ -8594,6 +8597,7 @@
 find_unmerged_mergeinfo(svn_mergeinfo_catalog_t *unmerged_to_source_catalog,
                         svn_boolean_t *never_synched,
                         svn_revnum_t *youngest_merged_rev,
+                        svn_revnum_t yc_ancestor_rev,
                         svn_mergeinfo_catalog_t source_catalog,
                         apr_hash_t *target_segments_hash,
                         const char *source_repos_rel_path,
@@ -8639,6 +8643,16 @@
                                                   segments,
                                                   iterpool));
 
+      /* Remove any target history that is also part of the source's history,
+         i.e. their common ancestry.  By definition this has already been
+         "merged" from the target to the source.  If the source has explict
+         self referential mergeinfo it would intersect with the target's
+         history below, making it appear that some merges had been done from
+         the target to the source, when this might not actually be the case. */
+      SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
+        &target_history_as_mergeinfo, target_history_as_mergeinfo,
+        source_rev, yc_ancestor_rev, iterpool));
+
       /* Look for any explicit mergeinfo on the source path corresponding to
          the target path.  If we find any remove that from SOURCE_CATALOG.
          When this iteration over TARGET_SEGMENTS_HASH is complete all that
@@ -8925,6 +8939,9 @@
   apr_hash_t *segments_hash = apr_hash_make(pool);
   svn_boolean_t never_synced;
   svn_revnum_t youngest_merged_rev;
+  const char *yc_ancestor_path;
+  const char *source_url;
+  const char *target_url;
 
   /* Get the history (segments) for the target and any of its subtrees
      with explicit mergeinfo. */
@@ -8945,6 +8962,26 @@
                    APR_HASH_KEY_STRING, segments);
     }
 
+  /* Check that SOURCE_URL@SOURCE_REV and TARGET_URL@TARGET_REV are
+     actually related, we can't reintegrate if they are not.  Also
+     get an initial value for *REV_LEFT. */
+  source_url = svn_path_url_add_component2(source_repos_root,
+                                           source_repos_rel_path,
+                                           subpool),
+  target_url = svn_path_url_add_component2(source_repos_root,
+                                           target_repos_rel_path,
+                                           subpool);
+  SVN_ERR(svn_client__get_youngest_common_ancestor(&yc_ancestor_path,
+                                                   rev_left,
+                                                   source_url, source_rev,
+                                                   target_url, target_rev,
+                                                   ctx, subpool));
+  if (!(yc_ancestor_path && SVN_IS_VALID_REVNUM(*rev_left)))
+    return svn_error_createf(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
+                             _("'%s@%ld' must be ancestrally related to "
+                               "'%s@%ld'"), source_url, source_rev,
+                             target_url, target_rev);
+
   /* Get the mergeinfo from the source, including its descendants
      with differing explicit mergeinfo. */
   APR_ARRAY_PUSH(source_repos_rel_path_as_array, const char *)
@@ -8962,6 +8999,7 @@
   SVN_ERR(find_unmerged_mergeinfo(&unmerged_catalog,
                                   &never_synced,
                                   &youngest_merged_rev,
+                                  *rev_left,
                                   mergeinfo_catalog,
                                   segments_hash,
                                   source_repos_rel_path,
@@ -8981,24 +9019,6 @@
   if (never_synced)
     {
       /* We never merged to the source.  Just return the branch point. */
-      const char *yc_ancestor_path,
-        *source_url = svn_path_url_add_component2(source_repos_root,
-                                                  source_repos_rel_path,
-                                                  subpool),
-        *target_url = svn_path_url_add_component2(source_repos_root,
-                                                  target_repos_rel_path,
-                                                  subpool);
-
-      SVN_ERR(svn_client__get_youngest_common_ancestor(&yc_ancestor_path,
-                                                       rev_left,
-                                                       source_url, source_rev,
-                                                       target_url, target_rev,
-                                                       ctx, subpool));
-      if (!(yc_ancestor_path && SVN_IS_VALID_REVNUM(*rev_left)))
-        return svn_error_createf(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
-                                 _("'%s@%ld' must be ancestrally related to "
-                                   "'%s@%ld'"), source_url, source_rev,
-                                 target_url, target_rev);
       *url_left = svn_path_url_add_component2(source_repos_root,
                                               yc_ancestor_path, pool);
     }

Modified: subversion/branches/issue-3242-dev/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/libsvn_client/mergeinfo.c?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/issue-3242-dev/subversion/libsvn_client/mergeinfo.c Tue Jan  5 17:31:58 2010
@@ -1011,7 +1011,6 @@
   if (is_url)
     {
       const char *repos_rel_path;
-      const char *local_abspath;
       const char *old_session_url;
 
       SVN_ERR(svn_dirent_get_absolute(&local_abspath, "", scratch_pool));

Modified: subversion/branches/issue-3242-dev/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/libsvn_client/patch.c?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/libsvn_client/patch.c (original)
+++ subversion/branches/issue-3242-dev/subversion/libsvn_client/patch.c Tue Jan  5 17:31:58 2010
@@ -42,6 +42,14 @@
 #include "private/svn_wc_private.h"
 
 typedef struct {
+  /* The hunk. */
+  const svn_hunk_t *hunk;
+
+  /* The line where the hunk matched in the target file. */
+  svn_linenum_t matched_line;
+} hunk_info_t;
+
+typedef struct {
   /* The patch being applied. */
   const svn_patch_t *patch;
 
@@ -98,6 +106,13 @@
   /* EOL-marker used by target file. */
   const char *eol_str;
 
+  /* An array containing stream markers marking the beginning
+   * each line in the target stream. */
+  apr_array_header_t *lines;
+
+  /* An array containing hunk_info_t structures for hunks already matched. */
+  apr_array_header_t *matched_hunks;
+
   /* The node kind of the target as found on disk prior
    * to patch application. */
   svn_node_kind_t kind;
@@ -130,6 +145,9 @@
 
   /* True if the target has the executable bit set. */
   svn_boolean_t executable;
+
+  /* The pool the target is allocated in. */
+  apr_pool_t *pool;
 } patch_target_t;
 
 
@@ -170,6 +188,7 @@
  * which is the path of the target as it appeared in the patch file.
  * Put a canonicalized version of PATH_FROM_PATCHFILE into
  * TARGET->CANON_PATH_FROM_PATCHFILE.
+ * WC_CTX is a context for the working copy the patch is applied to.
  * If possible, determine TARGET->WC_PATH, TARGET->ABS_PATH, and TARGET->KIND.
  * Indicate in TARGET->SKIPPED whether the target should be skipped.
  * STRIP_COUNT specifies the number of leading path components
@@ -180,6 +199,7 @@
                     const char *path_from_patchfile,
                     const char *wc_path,
                     int strip_count,
+                    svn_wc_context_t *wc_ctx,
                     apr_pool_t *result_pool,
                     apr_pool_t *scratch_pool)
 {
@@ -264,6 +284,33 @@
         break;
     }
 
+  if (! target->skipped)
+    {
+      const svn_wc_entry_t *entry;
+
+      /* If the target is versioned, we should be able to get an entry. */
+      SVN_ERR(svn_wc__maybe_get_entry(&entry, wc_ctx,
+                                      target->abs_path,
+                                      svn_node_unknown,
+                                      TRUE, FALSE,
+                                      result_pool,
+                                      scratch_pool));
+      if (entry)
+        {
+          if (entry->schedule == svn_wc_schedule_delete)
+            {
+              /* The target is versioned and scheduled for deletion,
+               * skip it. */
+              target->skipped = TRUE;
+            }
+        }
+      else if (target->kind == svn_node_file)
+        {
+          /* The target is an unversioned file, skip it. */
+           target->skipped = TRUE;
+        }
+    }
+
   return SVN_NO_ERROR;
 }
 
@@ -316,26 +363,8 @@
   new_target = apr_pcalloc(result_pool, sizeof(*new_target));
 
   SVN_ERR(resolve_target_path(new_target, patch->new_filename,
-                              base_dir, strip_count, result_pool,
-                              scratch_pool));
-  if (! new_target->skipped)
-    {
-      const svn_wc_entry_t *entry;
-
-      /* If the target is versioned, we should be able to get an entry. */
-      SVN_ERR(svn_wc__maybe_get_entry(&entry, ctx->wc_ctx,
-                                      new_target->abs_path,
-                                      svn_node_unknown,
-                                      TRUE, FALSE,
-                                      result_pool,
-                                      scratch_pool));
-
-      if (entry && entry->schedule == svn_wc_schedule_delete)
-        {
-          /* The target is versioned and scheduled for deletion, so skip it. */
-          new_target->skipped = TRUE;
-        }
-    }
+                              base_dir, strip_count, ctx->wc_ctx,
+                              result_pool, scratch_pool));
 
   if (new_target->kind == svn_node_file && ! new_target->skipped)
     {
@@ -411,11 +440,84 @@
   new_target->added = FALSE;
   new_target->deleted = FALSE;
   new_target->eof = FALSE;
-
+  new_target->pool = result_pool;
+  new_target->lines = apr_array_make(result_pool, 0,
+                                     sizeof(svn_stream_mark_t *));
+  new_target->matched_hunks = apr_array_make(result_pool, 0,
+                                             sizeof(hunk_info_t *));
   *target = new_target;
   return SVN_NO_ERROR;
 }
 
+/* Read a line from TARGET. If this line has not been read before
+ * mark the line in TARGET->LINES.
+ * Return the line in *STRINGBUF, allocated in RESULT_POOL.
+ * Do temporary allocations in SCRATCH_POOL.
+ */
+static svn_error_t *
+read_line(patch_target_t *target,
+          svn_stringbuf_t **stringbuf,
+          apr_pool_t *scratch_pool,
+          apr_pool_t *result_pool)
+{
+  if (target->eof)
+    {
+      *stringbuf = svn_stringbuf_create_ensure(0, result_pool);
+      return SVN_NO_ERROR;
+    }
+
+  SVN_ERR_ASSERT(target->current_line <= target->lines->nelts + 1);
+  if (target->current_line == target->lines->nelts + 1)
+    {
+      svn_stream_mark_t *mark;
+      SVN_ERR(svn_stream_mark(target->stream, &mark, target->pool));
+      APR_ARRAY_PUSH(target->lines, svn_stream_mark_t *) = mark;
+    }
+
+  SVN_ERR(svn_stream_readline(target->stream, stringbuf, target->eol_str,
+                              &target->eof, result_pool));
+  target->current_line++;
+
+  return SVN_NO_ERROR;
+}
+
+/* Seek to the specified LINE in TARGET.
+ * Mark any lines not read before in TARGET->LINES.
+ * Do temporary allocations in SCRATCH_POOL.
+ */
+static svn_error_t *
+seek_to_line(patch_target_t *target, svn_linenum_t line,
+             apr_pool_t *scratch_pool)
+{
+  SVN_ERR_ASSERT(line > 0);
+
+  if (line == target->current_line)
+    return SVN_NO_ERROR;
+
+  if (line <= target->lines->nelts)
+    {
+      svn_stream_mark_t *mark;
+
+      mark = APR_ARRAY_IDX(target->lines, line - 1, svn_stream_mark_t *);
+      SVN_ERR(svn_stream_seek(target->stream, mark));
+      target->current_line = line;
+    }
+  else
+    {
+      svn_stringbuf_t *dummy;
+      apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+      while (target->current_line < line)
+        {
+          svn_pool_clear(iterpool);
+          SVN_ERR(read_line(target, &dummy, iterpool, iterpool));
+        }
+      svn_pool_destroy(iterpool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* Indicate in *MATCHED whether the original text of HUNK matches
  * the patch TARGET at its current line.
  * When this function returns, neither TARGET->CURRENT_LINE nor the
@@ -427,187 +529,173 @@
 {
   svn_stringbuf_t *hunk_line;
   svn_stringbuf_t *target_line;
+  svn_linenum_t saved_line;
   svn_boolean_t hunk_eof;
   svn_boolean_t lines_matched;
-  apr_off_t pos;
   apr_pool_t *iterpool;
 
   *matched = FALSE;
 
-  pos = 0;
-  SVN_ERR(svn_io_file_seek(target->file, APR_CUR, &pos, pool));
-
-  SVN_ERR(svn_stream_reset(hunk->original_text));
+  if (target->eof)
+    return SVN_NO_ERROR;
 
+  saved_line = target->current_line;
   lines_matched = FALSE;
+  SVN_ERR(svn_stream_reset(hunk->original_text));
   iterpool = svn_pool_create(pool);
   do
     {
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_stream_readline(hunk->original_text, &hunk_line,
-                                  target->patch->eol_str, &hunk_eof, iterpool));
-      SVN_ERR(svn_stream_readline(target->stream, &target_line, target->eol_str,
-                                  &target->eof, iterpool));
-      if (! hunk_eof && hunk_line->len > 0)
+      SVN_ERR(svn_stream_readline_detect_eol(hunk->original_text, &hunk_line,
+                                             NULL, &hunk_eof, iterpool));
+      SVN_ERR(read_line(target, &target_line, iterpool, iterpool));
+      if (! hunk_eof)
         {
           lines_matched = (hunk_line->len == target_line->len &&
                            ! strcmp(hunk_line->data, target_line->data));
         }
     }
   while (lines_matched && ! (hunk_eof || target->eof));
-  svn_pool_destroy(iterpool);
 
-  /* Determine whether we had a match. */
   if (hunk_eof)
     *matched = lines_matched;
   else if (target->eof)
-    *matched = FALSE;
-
-  SVN_ERR(svn_stream_reset(hunk->original_text));
-  SVN_ERR(svn_io_file_seek(target->file, APR_SET, &pos, pool));
+    {
+      /* If the target has no newline at end-of-file, we get an EOF
+       * indication for the target earlier than we do get it for the hunk. */
+      SVN_ERR(svn_stream_readline_detect_eol(hunk->original_text, &hunk_line,
+                                             NULL, &hunk_eof, iterpool));
+      if (hunk_line->len == 0 && hunk_eof)
+        *matched = lines_matched;
+      else
+        *matched = FALSE;
+    }
+  SVN_ERR(seek_to_line(target, saved_line, iterpool));
   target->eof = FALSE;
 
+  svn_pool_destroy(iterpool);
+
   return SVN_NO_ERROR;
 }
 
 /* Scan lines of TARGET for a match of the original text of HUNK,
  * up to but not including the specified UPPER_LINE.
  * If UPPER_LINE is zero scan until EOF occurs when reading from TARGET.
- * Indicate in *MATCHED whether HUNK was matched during the scan.
- * If the hunk matched exactly once, return the line number at which
- * the hunk matched in *MATCHED_LINE.
+ * Return the line at which HUNK was matched in *MATCHED_LINE.
+ * If the hunk did not match at all, set *MATCHED_LINE to zero.
  * If the hunk matched multiple times, and MATCH_FIRST is TRUE,
  * return the line number at which the first match occured in *MATCHED_LINE.
  * If the hunk matched multiple times, and MATCH_FIRST is FALSE,
  * return the line number at which the last match occured in *MATCHED_LINE.
  * Do all allocations in POOL. */
 static svn_error_t *
-scan_for_match(svn_boolean_t *match, svn_linenum_t *matched_line,
-               patch_target_t *target, const svn_hunk_t *hunk,
-               svn_boolean_t match_first, svn_linenum_t upper_line,
-               apr_pool_t *pool)
+scan_for_match(svn_linenum_t *matched_line, patch_target_t *target,
+               const svn_hunk_t *hunk, svn_boolean_t match_first,
+               svn_linenum_t upper_line, apr_pool_t *pool)
 {
-  svn_boolean_t matched;
   apr_pool_t *iterpool;
 
-  *match = FALSE;
+  *matched_line = 0;
   iterpool = svn_pool_create(pool);
   while ((target->current_line < upper_line || upper_line == 0) &&
          ! target->eof)
     {
-      svn_stringbuf_t *buf;
+      svn_boolean_t matched;
+      int i;
 
       svn_pool_clear(iterpool);
 
       SVN_ERR(match_hunk(&matched, target, hunk, iterpool));
       if (matched)
         {
-          *match = TRUE;
-          *matched_line = target->current_line;
-          if (match_first)
-            break;
+          svn_boolean_t taken = FALSE;
+
+          /* Don't allow hunks to match at overlapping locations. */
+          for (i = 0; i < target->matched_hunks->nelts; i++)
+            {
+              const hunk_info_t *hi;
+              
+              hi = APR_ARRAY_IDX(target->matched_hunks, i, hunk_info_t *);
+              taken = (target->current_line >= hi->matched_line &&
+                       target->current_line < hi->matched_line +
+                                              hi->hunk->original_length);
+              if (taken)
+                break;
+            }
+
+          if (! taken)
+            {
+              *matched_line = target->current_line;
+              if (match_first)
+                break;
+            }
         }
 
-      SVN_ERR(svn_stream_readline(target->stream, &buf, target->eol_str,
-                                  &target->eof, iterpool));
-      if (! target->eof)
-        target->current_line++;
+      SVN_ERR(seek_to_line(target, target->current_line + 1, iterpool));
     }
   svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;
 }
 
-/* Determine the *LINE at which a HUNK applies to the TARGET file.
- * If no correct line can be determined, set *LINE to zero.
+/* Determine the line at which a HUNK applies to the TARGET file,
+ * and return an appropriate hunk_info object in *HI, allocated from
+ * RESULT_POOL. If no correct line can be determined,
+ * set HI->MATCHED_LINE to zero.
  * When this function returns, neither TARGET->CURRENT_LINE nor the
  * file offset in the target file will have changed.
  * Do temporary allocations in POOL. */
 static svn_error_t *
-determine_hunk_line(svn_linenum_t *line, patch_target_t *target,
-                    const svn_hunk_t *hunk, apr_pool_t *pool)
+get_hunk_info(hunk_info_t **hi, patch_target_t *target,
+              const svn_hunk_t *hunk, apr_pool_t *result_pool,
+              apr_pool_t *scratch_pool)
 {
-  svn_linenum_t hunk_start;
-  svn_boolean_t early_match;
-  svn_linenum_t early_matched_line;
-  svn_boolean_t match;
   svn_linenum_t matched_line;
-  svn_linenum_t saved_line;
-  apr_off_t saved_pos;
-
-  saved_line = target->current_line;
-  saved_pos = 0;
-  SVN_ERR(svn_io_file_seek(target->file, APR_CUR, &saved_pos, pool));
 
-  /* If the file didn't originally exist, the starting line is zero,
-   * but we're counting lines starting from 1 so fix that up. */
-  hunk_start = hunk->original_start == 0 ? 1 : hunk->original_start;
-
-  /* Scan forward towards the hunk's line and look for a line where the
-   * hunk matches, in case there are local changes in the target which
-   * cause the hunk to match early. */
-  SVN_ERR(scan_for_match(&early_match, &early_matched_line, target, hunk,
-                         FALSE, hunk_start, pool));
-
-  /* Scan for a match at the line where the hunk thinks it should be going. */
-  SVN_ERR(scan_for_match(&match, &matched_line, target, hunk, TRUE,
-                         hunk_start + 1, pool));
-  if (match)
-    {
-      /* Neat, an exact match. */
-      SVN_ERR_ASSERT(matched_line == hunk_start);
-      *line = hunk_start;
-    }
-  else
-    {
-      /* Scan forward towards the end of the file and look for a line where
-       * the hunk matches, in case there are local changes in the target
-       * which cause the hunk to match late. */
-      SVN_ERR(scan_for_match(&match, &matched_line, target, hunk, TRUE, 0,
-                             pool));
-      if (match && ! early_match)
-        {
-          /* We have a late match only, so use it. */
-          *line = matched_line;
-        }
-      else if (! match && early_match)
-        {
-          /* We have a early match only, so use it. */
-          *line = early_matched_line;
-        }
-      else if (match && early_match)
-        {
-          apr_off_t early_offset;
-          apr_off_t late_offset;
-
-          /* We have both a late and an early match. Use whichever is
-           * closest to where the hunk thinks it should be going. */
-          SVN_ERR_ASSERT(early_matched_line < hunk_start);
-          SVN_ERR_ASSERT(matched_line > hunk_start);
-          early_offset = hunk_start - early_matched_line;
-          late_offset = matched_line - hunk_start;
-
-          if (early_offset < late_offset)
-            *line = early_matched_line;
-          else if (early_offset > late_offset)
-            *line = matched_line;
-          else if (early_offset == late_offset)
+  /* An original offset of zero means that this hunk wants to create
+   * a new file, potentially overwriting all content of an existing
+   * file in the WC. Don't bother matching hunks in that case, since
+   * the hunk applies at line 1. */
+  matched_line = 1;
+  if (hunk->original_start > 0 && target->kind == svn_node_file)
+    {
+      svn_linenum_t saved_line = target->current_line;
+      svn_boolean_t saved_eof = target->eof;
+
+      /* Scan for a match at the line where the hunk thinks it
+       * should be going. */
+      SVN_ERR(seek_to_line(target, hunk->original_start, scratch_pool));
+      SVN_ERR(scan_for_match(&matched_line, target, hunk, TRUE,
+                             hunk->original_start + 1, scratch_pool));
+      if (matched_line != hunk->original_start)
+        {
+          /* Scan the whole file again from the start. */
+          SVN_ERR(seek_to_line(target, 1, scratch_pool));
+
+          /* Scan forward towards the hunk's line and look for a line
+           * where the hunk matches. */
+          SVN_ERR(scan_for_match(&matched_line, target, hunk, FALSE,
+                                 hunk->original_start, scratch_pool));
+
+          /* In tie-break situations, we arbitrarily prefer early matches
+           * to save us from scanning the rest of the file. */
+          if (matched_line == 0)
             {
-              /* But don't try to be smart about breaking a tie. */
-              *line = 0;
+              /* Scan forward towards the end of the file and look
+               * for a line where the hunk matches. */
+              SVN_ERR(scan_for_match(&matched_line, target, hunk, TRUE, 0,
+                                     scratch_pool));
             }
         }
-      else
-        {
-          /* We found no match at all. */
-          *line = 0;
-        }
+
+      SVN_ERR(seek_to_line(target, saved_line, scratch_pool));
+      target->eof = saved_eof;
     }
 
-  target->current_line = saved_line;
-  SVN_ERR(svn_io_file_seek(target->file, APR_SET, &saved_pos, pool));
-  target->eof = FALSE;
+  (*hi) = apr_palloc(result_pool, sizeof(hunk_info_t));
+  (*hi)->matched_line = matched_line;
+  (*hi)->hunk = hunk;
 
   return SVN_NO_ERROR;
 }
@@ -644,50 +732,16 @@
   iterpool = svn_pool_create(pool);
   while ((target->current_line < line || line == 0) && ! target->eof)
     {
-      svn_stringbuf_t *buf;
+      svn_stringbuf_t *target_line;
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_stream_readline(target->stream, &buf, target->eol_str,
-                                  &target->eof, iterpool));
+      SVN_ERR(read_line(target, &target_line, iterpool, iterpool));
       if (! target->eof)
-        {
-          svn_stringbuf_appendcstr(buf, target->eol_str);
-          target->current_line++;
-        }
+        svn_stringbuf_appendcstr(target_line, target->eol_str);
 
       SVN_ERR(try_stream_write(target->patched, target->patched_path,
-                               buf->data, buf->len, pool));
-    }
-  svn_pool_destroy(iterpool);
-
-  return SVN_NO_ERROR;
-}
-
-/* Read at most NLINES from the TARGET file, separated by the EOL sequence
- * specified in TARGET->eol_str, and discard any lines read.
- * The caller is responsible for closing *LINES.
- * Use SCRATCH_POOL for all other allocations. */
-static svn_error_t *
-skip_lines_from_target(patch_target_t *target, svn_linenum_t nlines,
-                       apr_pool_t *scratch_pool)
-{
-  apr_pool_t *iterpool;
-  svn_linenum_t i;
-
-  iterpool = svn_pool_create(scratch_pool);
-  for (i = 0; i < nlines; i++)
-    {
-      svn_stringbuf_t *line;
-
-      svn_pool_clear(iterpool);
-
-      SVN_ERR(svn_stream_readline(target->stream, &line, target->eol_str,
-                                  &target->eof, iterpool));
-      if (target->eof)
-        break;
-      else
-        target->current_line++;
+                               target_line->data, target_line->len, pool));
     }
   svn_pool_destroy(iterpool);
 
@@ -697,12 +751,10 @@
 /* Copy HUNK_TEXT into TARGET, line by line, such that the line filter
  * and transformation callbacks set on HUNK_TEXT by the diff parsing
  * code in libsvn_diff will trigger. ABSPATH is the absolute path to the
- * file underlying TARGET. Use EOL_STR as EOL indicator when
- * reading from HUNK_TEXT and when writing to TARGET. */
+ * file underlying TARGET. */
 static svn_error_t *
 copy_hunk_text(svn_stream_t *hunk_text, svn_stream_t *target,
-               const char *abspath, const char *eol_str,
-               apr_pool_t *scratch_pool)
+               const char *abspath, apr_pool_t *scratch_pool)
 {
   svn_boolean_t eof;
   apr_pool_t *iterpool;
@@ -711,18 +763,20 @@
   do
     {
       svn_stringbuf_t *line;
+      const char *eol_str;
 
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_stream_readline(hunk_text, &line, eol_str, &eof, iterpool));
+      SVN_ERR(svn_stream_readline_detect_eol(hunk_text, &line, &eol_str,
+                                             &eof, iterpool));
       if (! eof)
         {
           if (line->len >= 1)
             SVN_ERR(try_stream_write(target, abspath, line->data, line->len,
                                      iterpool));
-          /* Add newline. */
-          SVN_ERR(try_stream_write(target, abspath, eol_str, strlen(eol_str),
-                                   iterpool));
+          if (eol_str)
+            SVN_ERR(try_stream_write(target, abspath, eol_str, strlen(eol_str),
+                                     iterpool));
         }
     }
   while (! eof);
@@ -746,8 +800,7 @@
   SVN_ERR(svn_stream_write(target->reject, hunk_header, &len));
 
   SVN_ERR(copy_hunk_text(hunk->diff_text, target->reject,
-                         target->reject_path,
-                         target->patch->eol_str, pool));
+                         target->reject_path, pool));
 
   target->had_rejects = TRUE;
   return SVN_NO_ERROR;
@@ -755,48 +808,28 @@
 
 /* Apply a HUNK to a patch TARGET. Do all allocations in POOL. */
 static svn_error_t *
-apply_one_hunk(const svn_hunk_t *hunk, patch_target_t *target, apr_pool_t *pool)
+apply_one_hunk(const hunk_info_t *hi, patch_target_t *target, apr_pool_t *pool)
 {
-  svn_linenum_t hunk_line;
-
   if (target->kind == svn_node_file)
     {
-      /* Determine the line the hunk should be applied at. */
-      SVN_ERR(determine_hunk_line(&hunk_line, target, hunk, pool));
-      if (hunk_line == 0)
-        {
-          /* The hunk does not apply, reject it. */
-          SVN_ERR(reject_hunk(target, hunk, pool));
-          return SVN_NO_ERROR;
-        }
-
-      if (target->current_line > hunk_line)
-        {
-          /* If we already passed the line that the hunk should be applied to,
-           * the hunks in the patch file are out of order. */
-          SVN_ERR(reject_hunk(target, hunk, pool));
-          return SVN_NO_ERROR;
-        }
-
       /* Move forward to the hunk's line, copying data as we go. */
-      if (target->current_line < hunk_line)
-        SVN_ERR(copy_lines_to_target(target, hunk_line, pool));
+      SVN_ERR(copy_lines_to_target(target, hi->matched_line, pool));
       if (target->eof)
         {
           /* File is shorter than it should be. */
-          SVN_ERR(reject_hunk(target, hunk, pool));
+          SVN_ERR(reject_hunk(target, hi->hunk, pool));
           return SVN_NO_ERROR;
         }
-    }
 
-  /* Target file is at the hunk's line.
-   * Skip the target's version of the hunk.
-   * We assume the target hunk has the same length as the original hunk. */
-  SVN_ERR(skip_lines_from_target(target, hunk->original_length, pool));
+      /* Skip the target's version of the hunk. */
+      SVN_ERR(seek_to_line(target,
+                           target->current_line + hi->hunk->original_length,
+                           pool));
+    }
 
   /* Copy the patched hunk text into the patched stream. */
-  SVN_ERR(copy_hunk_text(hunk->modified_text, target->patched,
-                         target->patched_path, target->patch->eol_str, pool));
+  SVN_ERR(copy_hunk_text(hi->hunk->modified_text, target->patched,
+                         target->patched_path, pool));
 
   return SVN_NO_ERROR;
 }
@@ -886,16 +919,37 @@
       apr_finfo_t patched_file;
       int i;
 
-      /* Apply hunks. */
       iterpool = svn_pool_create(pool);
+      /* Match hunks. */
       for (i = 0; i < patch->hunks->nelts; i++)
         {
           svn_hunk_t *hunk;
+          hunk_info_t *hi;
 
           svn_pool_clear(iterpool);
 
           hunk = APR_ARRAY_IDX(patch->hunks, i, svn_hunk_t *);
-          SVN_ERR(apply_one_hunk(hunk, target, iterpool));
+
+          /* Determine the line the hunk should be applied at. */
+          SVN_ERR(get_hunk_info(&hi, target, hunk, pool, iterpool));
+          if (hi->matched_line == 0)
+            {
+              /* The hunk does not apply, reject it. */
+              SVN_ERR(reject_hunk(target, hunk, iterpool));
+            }
+          else
+            APR_ARRAY_PUSH(target->matched_hunks, hunk_info_t *) = hi;
+        }
+
+      /* Apply hunks. */
+      for (i = 0; i < target->matched_hunks->nelts; i++)
+        {
+          const hunk_info_t *hi;
+
+          svn_pool_clear(iterpool);
+
+          hi = APR_ARRAY_IDX(target->matched_hunks, i, const hunk_info_t *);
+          SVN_ERR(apply_one_hunk(hi, target, iterpool));
         }
       svn_pool_destroy(iterpool);
 
@@ -1058,8 +1112,8 @@
       if (ctx->cancel_func)
         SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
-      SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, patch_eol_str,
-                                         iterpool, iterpool));
+      SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, iterpool,
+                                         iterpool));
       if (patch)
         {
           SVN_ERR(apply_one_patch(patch, wc_path, dry_run, ctx, strip_count,

Modified: subversion/branches/issue-3242-dev/subversion/libsvn_client/url.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/libsvn_client/url.c?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/libsvn_client/url.c (original)
+++ subversion/branches/issue-3242-dev/subversion/libsvn_client/url.c Tue Jan  5 17:31:58 2010
@@ -93,9 +93,17 @@
      it into a URL. */
   if (! svn_path_is_url(abspath_or_url))
     {
-      SVN_ERR(svn_client__entry_location(url, peg_revnum, ctx->wc_ctx,
-                                         abspath_or_url, peg_revision->kind,
-                                         result_pool, scratch_pool));
+      /* If we need to contact the repository for *PEG_REVNUM just get
+         the *URL now.  Otherwise the working copy has all the information
+         we need. */
+      if (peg_revision->kind == svn_opt_revision_date
+          || peg_revision->kind == svn_opt_revision_head)
+        SVN_ERR(svn_wc__node_get_url(url, ctx->wc_ctx, abspath_or_url,
+                                     result_pool, scratch_pool));
+      else
+        SVN_ERR(svn_client__entry_location(url, peg_revnum, ctx->wc_ctx,
+                                           abspath_or_url, peg_revision->kind,
+                                           result_pool, scratch_pool));
     }
   else
     {

Modified: subversion/branches/issue-3242-dev/subversion/libsvn_diff/parse-diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3242-dev/subversion/libsvn_diff/parse-diff.c?rev=896142&r1=896141&r2=896142&view=diff
==============================================================================
--- subversion/branches/issue-3242-dev/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/branches/issue-3242-dev/subversion/libsvn_diff/parse-diff.c Tue Jan  5 17:31:58 2010
@@ -22,6 +22,7 @@
  */
 
 #include <limits.h>  /* for ULONG_MAX */
+#include <stdlib.h>
 #include <string.h>
 
 #include "svn_types.h"
@@ -238,7 +239,7 @@
 
   /* Get current seek position -- APR has no ftell() :( */
   pos = 0;
-  apr_file_seek(patch->patch_file, APR_CUR, &pos);
+  SVN_ERR(svn_io_file_seek(patch->patch_file, APR_CUR, &pos, scratch_pool));
 
   iterpool = svn_pool_create(scratch_pool);
   do
@@ -249,22 +250,22 @@
 
       /* Remember the current line's offset, and read the line. */
       last_line = pos;
-      SVN_ERR(svn_stream_readline(stream, &line, patch->eol_str, &eof,
-                                  iterpool));
-
-      /* Lines starting with a backslash are comments, such as
-       * "\ No newline at end of file". */
-      if (line->data[0] == '\\')
-        continue;
+      SVN_ERR(svn_stream_readline_detect_eol(stream, &line, NULL, &eof,
+                                             iterpool));
 
       if (! eof)
         {
           /* Update line offset for next iteration.
            * APR has no ftell() :( */
           pos = 0;
-          apr_file_seek(patch->patch_file, APR_CUR, &pos);
+          SVN_ERR(svn_io_file_seek(patch->patch_file, APR_CUR, &pos, iterpool));
         }
 
+      /* Lines starting with a backslash are comments, such as
+       * "\ No newline at end of file". */
+      if (line->data[0] == '\\')
+        continue;
+
       if (in_hunk)
         {
           char c;
@@ -324,7 +325,8 @@
     /* Rewind to the start of the line just read, so subsequent calls
      * to this function or svn_diff__parse_next_patch() don't end
      * up skipping the line -- it may contain a patch or hunk header. */
-    apr_file_seek(patch->patch_file, APR_SET, &last_line);
+    SVN_ERR(svn_io_file_seek(patch->patch_file, APR_SET, &last_line,
+                             scratch_pool));
 
   if (hunk_seen && start < end)
     {
@@ -369,6 +371,21 @@
   return SVN_NO_ERROR;
 }
 
+/* Compare function for sorting hunks after parsing.
+ * We sort hunks by their original line offset. */
+static int
+compare_hunks(const void *a, const void *b)
+{
+  const svn_hunk_t *ha = *((const svn_hunk_t **)a);
+  const svn_hunk_t *hb = *((const svn_hunk_t **)b);
+
+  if (ha->original_start < hb->original_start)
+    return -1;
+  if (ha->original_start > hb->original_start)
+    return 1;
+  return 0;
+}
+
 /*
  * Ensure that all streams which were opened for HUNK are closed.
  */
@@ -384,7 +401,6 @@
 svn_error_t *
 svn_diff__parse_next_patch(svn_patch_t **patch,
                            apr_file_t *patch_file,
-                           const char *eol_str,
                            apr_pool_t *result_pool,
                            apr_pool_t *scratch_pool)
 {
@@ -393,7 +409,6 @@
   const char *indicator;
   const char *fname;
   svn_stream_t *stream;
-  apr_off_t pos;
   svn_boolean_t eof, in_header;
   svn_hunk_t *hunk;
   apr_pool_t *iterpool;
@@ -408,14 +423,9 @@
   /* Get the patch's filename. */
   SVN_ERR(svn_io_file_name_get(&fname, patch_file, result_pool));
 
-  /* Get current seek position -- APR has no ftell() :( */
-  pos = 0;
-  apr_file_seek(patch_file, APR_CUR, &pos);
-
   /* Record what we already know about the patch. */
   *patch = apr_pcalloc(result_pool, sizeof(**patch));
   (*patch)->patch_file = patch_file;
-  (*patch)->eol_str = eol_str;
   (*patch)->path = fname;
 
   /* Get a stream to read lines from the patch file.
@@ -433,7 +443,8 @@
       svn_pool_clear(iterpool);
 
       /* Read a line from the stream. */
-      SVN_ERR(svn_stream_readline(stream, &line, eol_str, &eof, iterpool));
+      SVN_ERR(svn_stream_readline_detect_eol(stream, &line, NULL, &eof,
+                                             iterpool));
 
       /* See if we have a diff header. */
       if (line->len > strlen(indicator) && starts_with(line->data, indicator))
@@ -501,6 +512,16 @@
   svn_pool_destroy(iterpool);
   SVN_ERR(svn_stream_close(stream));
 
+  if (*patch)
+    {
+      /* Usually, hunks appear in the patch sorted by their original line
+       * offset. But just in case they weren't parsed in this order for
+       * some reason, we sort them so that our caller can assume that hunks
+       * are sorted as if parsed from a usual patch. */
+      qsort((*patch)->hunks->elts, (*patch)->hunks->nelts,
+            (*patch)->hunks->elt_size, compare_hunks);
+    }
+
   return SVN_NO_ERROR;
 }