You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2011/08/17 20:25:09 UTC
svn commit: r1158860 [1/2] - in /subversion/branches/issue-3975: ./
subversion/bindings/ctypes-python/test/ subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversion/javahl/
subversion/bindings/javahl/src/org/tigris/subver...
Author: pburba
Date: Wed Aug 17 18:25:07 2011
New Revision: 1158860
URL: http://svn.apache.org/viewvc?rev=1158860&view=rev
Log:
On the issue-3975 branch: Sync with ^/subversion/trunk.
Added:
subversion/branches/issue-3975/subversion/bindings/javahl/src/org/apache/subversion/javahl/JNIError.java
- copied unchanged from r1158857, subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/JNIError.java
Removed:
subversion/branches/issue-3975/subversion/bindings/javahl/src/org/tigris/subversion/javahl/JNIError.java
Modified:
subversion/branches/issue-3975/ (props changed)
subversion/branches/issue-3975/CHANGES
subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/setup_path.py
subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/svntypes.py
subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNClient.cpp
subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNClient.h
subversion/branches/issue-3975/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
subversion/branches/issue-3975/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
subversion/branches/issue-3975/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
subversion/branches/issue-3975/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java
subversion/branches/issue-3975/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
subversion/branches/issue-3975/subversion/bindings/swig/python/svn/repos.py
subversion/branches/issue-3975/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py
subversion/branches/issue-3975/subversion/include/svn_client.h
subversion/branches/issue-3975/subversion/include/svn_ra.h
subversion/branches/issue-3975/subversion/include/svn_wc.h
subversion/branches/issue-3975/subversion/libsvn_client/cat.c
subversion/branches/issue-3975/subversion/libsvn_client/client.h
subversion/branches/issue-3975/subversion/libsvn_client/merge.c
subversion/branches/issue-3975/subversion/libsvn_client/repos_diff.c
subversion/branches/issue-3975/subversion/libsvn_client/status.c
subversion/branches/issue-3975/subversion/libsvn_ra_serf/locks.c
subversion/branches/issue-3975/subversion/libsvn_wc/adm_ops.c
subversion/branches/issue-3975/subversion/libsvn_wc/questions.c
subversion/branches/issue-3975/subversion/libsvn_wc/status.c
subversion/branches/issue-3975/subversion/libsvn_wc/wc-metadata.sql
subversion/branches/issue-3975/subversion/libsvn_wc/wc-queries.sql
subversion/branches/issue-3975/subversion/libsvn_wc/wc.h
subversion/branches/issue-3975/subversion/libsvn_wc/wc_db.c
subversion/branches/issue-3975/subversion/libsvn_wc/wc_db.h
subversion/branches/issue-3975/subversion/libsvn_wc/wc_db_wcroot.c
subversion/branches/issue-3975/subversion/libsvn_wc/workqueue.c
subversion/branches/issue-3975/subversion/svn/main.c
subversion/branches/issue-3975/subversion/svn/status.c
subversion/branches/issue-3975/subversion/svnversion/main.c
subversion/branches/issue-3975/subversion/tests/cmdline/depth_tests.py
subversion/branches/issue-3975/subversion/tests/cmdline/merge_tests.py
subversion/branches/issue-3975/subversion/tests/cmdline/revert_tests.py
subversion/branches/issue-3975/subversion/tests/cmdline/special_tests.py
subversion/branches/issue-3975/subversion/tests/cmdline/svntest/main.py
subversion/branches/issue-3975/subversion/tests/cmdline/svnversion_tests.py
subversion/branches/issue-3975/tools/dev/benchmarks/suite1/run
Propchange: subversion/branches/issue-3975/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Aug 17 18:25:07 2011
@@ -54,4 +54,4 @@
/subversion/branches/tree-conflicts:868291-873154
/subversion/branches/tree-conflicts-notify:873926-874008
/subversion/branches/uris-as-urls:1060426-1064427
-/subversion/trunk:1152931-1157415
+/subversion/trunk:1152931-1158857
Modified: subversion/branches/issue-3975/CHANGES
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/CHANGES?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/CHANGES (original)
+++ subversion/branches/issue-3975/CHANGES Wed Aug 17 18:25:07 2011
@@ -2,6 +2,9 @@ Version 1.8.0
(?? ??? 2011, from /branches/1.8.x)
http://svn.apache.org/repos/asf/subversion/tags/1.8.0
+ User-visible changes:
+ * don't leave unversioned files when reverting copies (issue #3101)
+
Developer-visible changes:
- API changes:
* fix inconsistent handling of log revs without changed paths (issue #3694)
@@ -182,6 +185,7 @@ the 1.6 release: http://subversion.apac
* notifications sent when mergeinfo changes (r877588)
* add information on text and property mods in log APIs (r877688)
* fixed: svn_ra_local__get_file() leaks file descriptors (issue #3290)
+ * swig-py: always set ChangedPath.path (issue #2630)
- Bindings:
* New JavaHL package: org.apache.subversion
Modified: subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/setup_path.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/setup_path.py?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/setup_path.py (original)
+++ subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/setup_path.py Wed Aug 17 18:25:07 2011
@@ -25,8 +25,8 @@
import sys
import os
-src_swig_python_tests_dir = os.path.dirname(os.path.dirname(__file__))
-sys.path[0:0] = [ src_swig_python_tests_dir ]
+src_ctypes_python_tests_dir = os.path.dirname(os.path.dirname(__file__))
+sys.path[0:0] = [ src_ctypes_python_tests_dir ]
import csvn.core
csvn.core.svn_cmdline_init("", csvn.core.stderr)
Modified: subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/svntypes.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/svntypes.py?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/svntypes.py (original)
+++ subversion/branches/issue-3975/subversion/bindings/ctypes-python/test/svntypes.py Wed Aug 17 18:25:07 2011
@@ -21,8 +21,24 @@ import setup_path
import unittest
from csvn.core import *
import csvn.types as _types
+from csvn.types import SvnDate, Hash, Array, APRFile, Stream, SvnStringPtr
-class TypesTestCase(unittest.TestCase):
+class SvnDateTestCase(unittest.TestCase):
+
+ def test_as_apr_time_t(self):
+ d1 = SvnDate('1999-12-31T23:59:59.000000Z')
+ d2 = SvnDate('2000-01-01T00:00:00.000000Z')
+ t1 = d1.as_apr_time_t().value
+ t2 = d2.as_apr_time_t().value
+ self.assertEqual(t1 + 1000000, t2)
+
+ def test_as_human_string(self):
+ d1 = SvnDate('1999-12-31T23:59:59.000000Z')
+ s1 = d1.as_human_string()
+ self.assertEqual(s1[:27], '1999-12-31 23:59:59 +0000 (')
+
+
+class HashTestCase(unittest.TestCase):
def test_hash(self):
self.pydict = {"bruce":"batman", "clark":"superman",
@@ -35,6 +51,34 @@ class TypesTestCase(unittest.TestCase):
self.assertNotEqual(self.svnhash["clark"].value,
self.pydict["bruce"])
+ def test_insert_delete(self):
+ h = Hash(c_char_p)
+ h['foo'] = 'f'
+ h['bar'] = 'b'
+ self.assertEqual(len(h), 2)
+ self.assertEqual(h['foo'].value, 'f')
+ self.assertEqual(h['bar'].value, 'b')
+ h['bar'] = 'b'
+ self.assertEqual(len(h), 2)
+ del h['foo']
+ self.assertEqual(len(h), 1)
+ self.assertEqual(h['bar'].value, 'b')
+
+ def test_iter(self):
+ h = Hash(c_char_p, { 'foo': 'f', 'bar': 'b' })
+ keys = sorted(h.keys())
+ self.assertEqual(keys, ['bar', 'foo'])
+ vals = []
+ for k in h:
+ vals += [ h[k].value ]
+ self.assertEqual(sorted(vals), ['b', 'f'])
+ vals = []
+ for k,v in h.items():
+ vals += [ v.value ]
+ self.assertEqual(sorted(vals), ['b', 'f'])
+
+class ArrayTestCase(unittest.TestCase):
+
def test_array(self):
self.pyarray = ["vini", "vidi", "vici"]
self.svnarray = _types.Array(c_char_p, self.pyarray)
@@ -43,7 +87,11 @@ class TypesTestCase(unittest.TestCase):
self.assertEqual(self.svnarray[1], "vidi")
def suite():
- return unittest.makeSuite(TypesTestCase, 'test')
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(SvnDateTestCase, 'test'))
+ suite.addTest(unittest.makeSuite(HashTestCase, 'test'))
+ suite.addTest(unittest.makeSuite(ArrayTestCase, 'test'))
+ return suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNClient.cpp?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNClient.cpp (original)
+++ subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNClient.cpp Wed Aug 17 18:25:07 2011
@@ -898,7 +898,9 @@ void SVNClient::propertySetLocal(Targets
ctx, subPool.getPool()), );
}
-void SVNClient::propertySetRemote(const char *path, const char *name,
+void SVNClient::propertySetRemote(const char *path, long base_rev,
+ const char *name,
+ CommitMessage *message,
JNIByteArray &value, bool force,
RevpropTable &revprops,
CommitCallback *callback)
@@ -916,12 +918,12 @@ void SVNClient::propertySetRemote(const
Path intPath(path, subPool);
SVN_JNI_ERR(intPath.error_occured(), );
- svn_client_ctx_t *ctx = context.getContext(NULL, subPool);
+ svn_client_ctx_t *ctx = context.getContext(message, subPool);
if (ctx == NULL)
return;
SVN_JNI_ERR(svn_client_propset_remote(name, val, intPath.c_str(),
- force, SVN_INVALID_REVNUM,
+ force, base_rev,
revprops.hash(subPool),
CommitCallback::callback, callback,
ctx, subPool.getPool()), );
Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNClient.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNClient.h?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNClient.h (original)
+++ subversion/branches/issue-3975/subversion/bindings/javahl/native/SVNClient.h Wed Aug 17 18:25:07 2011
@@ -81,7 +81,8 @@ class SVNClient :public SVNBase
void propertySetLocal(Targets &targets, const char *name, JNIByteArray &value,
svn_depth_t depth, StringArray &changelists,
bool force);
- void propertySetRemote(const char *path, const char *name,
+ void propertySetRemote(const char *path, long base_rev, const char *name,
+ CommitMessage *message,
JNIByteArray &value, bool force,
RevpropTable &revprops, CommitCallback *callback);
void properties(const char *path, Revision &revision,
Modified: subversion/branches/issue-3975/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp (original)
+++ subversion/branches/issue-3975/subversion/bindings/javahl/native/org_apache_subversion_javahl_SVNClient.cpp Wed Aug 17 18:25:07 2011
@@ -922,8 +922,9 @@ Java_org_apache_subversion_javahl_SVNCli
JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_SVNClient_propertySetRemote
-(JNIEnv *env, jobject jthis, jstring jpath, jstring jname,
- jbyteArray jvalue, jboolean jforce, jobject jrevpropTable, jobject jcallback)
+(JNIEnv *env, jobject jthis, jstring jpath, jlong jbaseRev, jstring jname,
+ jbyteArray jvalue, jobject jmessage, jboolean jforce, jobject jrevpropTable,
+ jobject jcallback)
{
JNIEntry(SVNClient, propertySet);
SVNClient *cl = SVNClient::getCppObject(jthis);
@@ -940,6 +941,10 @@ Java_org_apache_subversion_javahl_SVNCli
if (JNIUtil::isExceptionThrown())
return;
+ CommitMessage message(jmessage);
+ if (JNIUtil::isExceptionThrown())
+ return;
+
JNIByteArray value(jvalue);
if (JNIUtil::isExceptionThrown())
return;
@@ -949,8 +954,9 @@ Java_org_apache_subversion_javahl_SVNCli
return;
CommitCallback callback(jcallback);
- cl->propertySetRemote(path, name, value, jforce ? true:false, revprops,
- jcallback ? &callback : NULL);
+ cl->propertySetRemote(path, jbaseRev, name, &message, value,
+ jforce ? true:false,
+ revprops, jcallback ? &callback : NULL);
}
JNIEXPORT void JNICALL
Modified: subversion/branches/issue-3975/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java (original)
+++ subversion/branches/issue-3975/subversion/bindings/javahl/src/org/apache/subversion/javahl/ISVNClient.java Wed Aug 17 18:25:07 2011
@@ -649,7 +649,8 @@ public interface ISVNClient
boolean force)
throws ClientException;
- void propertySetRemote(String path, String name, byte[] value,
+ void propertySetRemote(String path, long baseRev, String name,
+ byte[] value, CommitMessageCallback handler,
boolean force, Map<String, String> revpropTable,
CommitCallback callback)
throws ClientException;
Modified: subversion/branches/issue-3975/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/issue-3975/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNClient.java Wed Aug 17 18:25:07 2011
@@ -307,7 +307,9 @@ public class SVNClient implements ISVNCl
boolean force)
throws ClientException;
- public native void propertySetRemote(String path, String name, byte[] value,
+ public native void propertySetRemote(String path, long baseRev,
+ String name, byte[] value,
+ CommitMessageCallback handler,
boolean force,
Map<String, String> revpropTable,
CommitCallback callback)
Modified: subversion/branches/issue-3975/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java (original)
+++ subversion/branches/issue-3975/subversion/bindings/javahl/src/org/tigris/subversion/javahl/SVNClient.java Wed Aug 17 18:25:07 2011
@@ -1878,8 +1878,12 @@ public class SVNClient implements SVNCli
{
if (Path.isURL(path))
{
- aSVNClient.propertySetRemote(path, name,
+ Info2[] infos = info2(path, Revision.HEAD, Revision.HEAD,
+ false);
+
+ aSVNClient.propertySetRemote(path, infos[0].getRev(), name,
value == null ? null : value.getBytes(),
+ cachedHandler,
force, revpropTable, null);
}
else
Modified: subversion/branches/issue-3975/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java (original)
+++ subversion/branches/issue-3975/subversion/bindings/javahl/tests/org/apache/subversion/javahl/BasicTests.java Wed Aug 17 18:25:07 2011
@@ -130,6 +130,35 @@ public class BasicTests extends SVNTests
}
/**
+ * Test the JNIError class functionality
+ * @throws Throwable
+ */
+ public void testJNIError() throws Throwable
+ {
+ // build the test setup.
+ OneTest thisTest = new OneTest();
+
+ // Create a client, dispose it, then try to use it later
+ ISVNClient tempclient = new SVNClient();
+ tempclient.dispose();
+
+ // create Y and Y/Z directories in the repository
+ addExpectedCommitItem(null, thisTest.getUrl().toString(), "Y", NodeKind.none,
+ CommitItemStateFlags.Add);
+ Set<String> urls = new HashSet<String>(1);
+ urls.add(thisTest.getUrl() + "/Y");
+ try
+ {
+ tempclient.mkdir(urls, false, null, new ConstMsg("log_msg"), null);
+ }
+ catch(JNIError e)
+ {
+ return; // Test passes!
+ }
+ fail("A JNIError should have been thrown here.");
+ }
+
+ /**
* Tests Mergeinfo and RevisionRange classes.
* @since 1.5
*/
@@ -3081,6 +3110,53 @@ public class BasicTests extends SVNTests
}
/**
+ * Test the basic SVNClient.propertySetRemote functionality.
+ * @throws Throwable
+ */
+ public void testPropEdit() throws Throwable
+ {
+ final String PROP = "abc";
+ final byte[] VALUE = new String("def").getBytes();
+ final byte[] NEWVALUE = new String("newvalue").getBytes();
+ // create the test working copy
+ OneTest thisTest = new OneTest();
+
+ Set<String> pathSet = new HashSet<String>();
+ // set a property on A/D/G/rho file
+ pathSet.clear();
+ pathSet.add(thisTest.getWCPath()+"/A/D/G/rho");
+ client.propertySetLocal(pathSet, PROP, VALUE,
+ Depth.infinity, null, false);
+ thisTest.getWc().setItemPropStatus("A/D/G/rho", Status.Kind.modified);
+
+ // test the status of the working copy
+ thisTest.checkStatus();
+
+ // commit the changes
+ checkCommitRevision(thisTest, "wrong revision number from commit", 2,
+ thisTest.getWCPathSet(), "log msg", Depth.infinity,
+ false, false, null, null);
+
+ thisTest.getWc().setItemPropStatus("A/D/G/rho", Status.Kind.normal);
+
+ // check the status of the working copy
+ thisTest.checkStatus();
+
+ // now edit the propval directly in the repository
+ long baseRev = 2L;
+ client.propertySetRemote(thisTest.getUrl()+"/A/D/G/rho", baseRev, PROP, NEWVALUE,
+ new ConstMsg("edit prop"), false, null, null);
+
+ // update the WC and verify that the property was changed
+ client.update(thisTest.getWCPathSet(), Revision.HEAD, Depth.infinity, false, false,
+ false, false);
+ byte[] propVal = client.propertyGet(thisTest.getWCPath()+"/A/D/G/rho", PROP, null, null);
+
+ assertEquals(new String(propVal), new String(NEWVALUE));
+
+ }
+
+ /**
* Test tolerance of unversioned obstructions when adding paths with
* {@link org.apache.subversion.javahl.SVNClient#checkout()},
* {@link org.apache.subversion.javahl.SVNClient#update()}, and
Modified: subversion/branches/issue-3975/subversion/bindings/swig/python/svn/repos.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/swig/python/svn/repos.py?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/swig/python/svn/repos.py (original)
+++ subversion/branches/issue-3975/subversion/bindings/swig/python/svn/repos.py Wed Aug 17 18:25:07 2011
@@ -72,12 +72,28 @@ class ChangedPath:
class ChangeCollector(_svndelta.Editor):
- """Available Since: 1.2.0
+ """An editor that, when driven, walks a revision or a transaction and
+ incrementally invokes a callback with ChangedPath instances corresponding to
+ paths changed in that revision.
+
+ Available Since: 1.2.0
"""
# BATON FORMAT: [path, base_path, base_rev]
def __init__(self, fs_ptr, root, pool=None, notify_cb=None):
+ """Construct a walker over the svn_fs_root_t ROOT, which must
+ be in the svn_fs_t FS_PTR. Invoke NOTIFY_CB with a single argument
+ of type ChangedPath for each change under ROOT.
+
+ At this time, two ChangedPath objects will be passed for a path that had
+ been replaced in the revision/transaction. This may change in the future.
+
+ ### Can't we deduce FS_PTR from ROOT?
+
+ ### POOL is unused
+ """
+
self.fs_ptr = fs_ptr
self.changes = { } # path -> ChangedPathEntry()
self.roots = { } # revision -> svn_svnfs_root_t
@@ -136,9 +152,9 @@ class ChangeCollector(_svndelta.Editor):
self.changes[path] = ChangedPath(item_type,
False,
False,
- base_path,
+ base_path, # base_path
parent_baton[2], # base_rev
- None, # (new) path
+ path, # path
False, # added
CHANGE_ACTION_DELETE,
)
Modified: subversion/branches/issue-3975/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py (original)
+++ subversion/branches/issue-3975/subversion/bindings/swig/python/tests/trac/versioncontrol/svn_fs.py Wed Aug 17 18:25:07 2011
@@ -407,7 +407,7 @@ class SubversionChangeset(Changeset):
else:
base_path = None
action = ''
- if not change.path:
+ if change.action == repos.CHANGE_ACTION_DELETE:
action = Changeset.DELETE
deletions[change.base_path] = idx
elif change.added:
Modified: subversion/branches/issue-3975/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/include/svn_client.h?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/include/svn_client.h (original)
+++ subversion/branches/issue-3975/subversion/include/svn_client.h Wed Aug 17 18:25:07 2011
@@ -2207,18 +2207,38 @@ typedef struct svn_client_status_t
const void *backwards_compatibility_baton;
/** Set to the local absolute path that this node was moved from, if this
- * file or directory has been moved here locally. */
+ * file or directory has been moved here locally and is the root of that
+ * move. Otherwise set to NULL.
+ *
+ * This will be NULL for moved-here nodes that are just part of a subtree
+ * that was moved along (and are not themselves a root of a different move
+ * operation).
+ *
+ * @since New in 1.8. */
const char *moved_from_abspath;
/** Set to the local absolute path that this node was moved to, if this file
- * or directory has been moved away locally. */
+ * or directory has been moved away locally and corresponds to the root
+ * of the destination side of the move. Otherwise set to NULL.
+ *
+ * Note: Saying just "root" here could be misleading. For example:
+ * svn mv A AA;
+ * svn mv AA/B BB;
+ * creates a situation where A/B is moved-to BB, but one could argue that
+ * the move source's root actually was AA/B. Note that, as far as the
+ * working copy is concerned, above case is exactly identical to:
+ * svn mv A/B BB;
+ * svn mv A AA;
+ * In both situations, @a moved_to_abspath would be set for nodes A (moved
+ * to AA) and A/B (moved to BB), only.
+ *
+ * This will be NULL for moved-away nodes that were just part of a subtree
+ * that was moved along (and are not themselves a root of a different move
+ * operation).
+ *
+ * @since New in 1.8. */
const char *moved_to_abspath;
- /* If this file or directory has been moved away locally, set this to the
- * local absolute path that was the root of the move-away, i.e. to the
- * op-root of the delete-half of the move operation. */
- const char *moved_to_op_root_abspath;
-
/* NOTE! Please update svn_client_status_dup() when adding new fields here. */
} svn_client_status_t;
Modified: subversion/branches/issue-3975/subversion/include/svn_ra.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/include/svn_ra.h?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/include/svn_ra.h (original)
+++ subversion/branches/issue-3975/subversion/include/svn_ra.h Wed Aug 17 18:25:07 2011
@@ -1695,7 +1695,8 @@ svn_ra_get_file_revs(svn_ra_session_t *s
/**
* Lock each path in @a path_revs, which is a hash whose keys are the
* paths to be locked, and whose values are the corresponding base
- * revisions for each path.
+ * revisions for each path. The keys are (const char *) and the
+ * revisions are (svn_revnum_t *).
*
* Note that locking is never anonymous, so any server implementing
* this function will have to "pull" a username from the client, if
Modified: subversion/branches/issue-3975/subversion/include/svn_wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/include/svn_wc.h?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/include/svn_wc.h (original)
+++ subversion/branches/issue-3975/subversion/include/svn_wc.h Wed Aug 17 18:25:07 2011
@@ -1755,7 +1755,7 @@ typedef struct svn_wc_conflict_descripti
/** Info on the "merge-right source" or "their" version of incoming change. */
const svn_wc_conflict_version_t *src_right_version;
- /* Remember to adjust svn_wc__conflict_description_dup()
+ /* Remember to adjust svn_wc__conflict_description2_dup()
* if you add new fields to this struct. */
} svn_wc_conflict_description2_t;
@@ -1849,8 +1849,6 @@ typedef struct svn_wc_conflict_descripti
* @since New in 1.6. */
svn_wc_conflict_version_t *src_right_version;
- /* Remember to adjust svn_wc__conflict_description_dup()
- * if you add new fields to this struct. */
} svn_wc_conflict_description_t;
/**
@@ -3620,18 +3618,38 @@ typedef struct svn_wc_status3_t
/** @} */
/** Set to the local absolute path that this node was moved from, if this
- * file or directory has been moved here locally. */
+ * file or directory has been moved here locally and is the root of that
+ * move. Otherwise set to NULL.
+ *
+ * This will be NULL for moved-here nodes that are just part of a subtree
+ * that was moved along (and are not themselves a root of a different move
+ * operation).
+ *
+ * @since New in 1.8. */
const char *moved_from_abspath;
/** Set to the local absolute path that this node was moved to, if this file
- * or directory has been moved away locally. */
+ * or directory has been moved away locally and corresponds to the root
+ * of the destination side of the move. Otherwise set to NULL.
+ *
+ * Note: Saying just "root" here could be misleading. For example:
+ * svn mv A AA;
+ * svn mv AA/B BB;
+ * creates a situation where A/B is moved-to BB, but one could argue that
+ * the move source's root actually was AA/B. Note that, as far as the
+ * working copy is concerned, above case is exactly identical to:
+ * svn mv A/B BB;
+ * svn mv A AA;
+ * In both situations, @a moved_to_abspath would be set for nodes A (moved
+ * to AA) and A/B (moved to BB), only.
+ *
+ * This will be NULL for moved-away nodes that were just part of a subtree
+ * that was moved along (and are not themselves a root of a different move
+ * operation).
+ *
+ * @since New in 1.8. */
const char *moved_to_abspath;
- /* If this file or directory has been moved away locally, set this to the
- * local absolute path that was the root of the move-away, i.e. to the
- * op-root of the delete-half of the move operation. */
- const char *moved_to_op_root_abspath;
-
/* NOTE! Please update svn_wc_dup_status3() when adding new fields here. */
} svn_wc_status3_t;
Modified: subversion/branches/issue-3975/subversion/libsvn_client/cat.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_client/cat.c?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_client/cat.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_client/cat.c Wed Aug 17 18:25:07 2011
@@ -50,6 +50,7 @@ svn_client__get_normalized_stream(svn_st
const char *local_abspath,
const svn_opt_revision_t *revision,
svn_boolean_t expand_keywords,
+ svn_boolean_t normalize_eols,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *result_pool,
@@ -163,8 +164,10 @@ svn_client__get_normalized_stream(svn_st
/* Wrap the output stream if translation is needed. */
if (eol != NULL || kw != NULL)
- input = svn_subst_stream_translated(input, eol, FALSE, kw, expand_keywords,
- result_pool);
+ input = svn_subst_stream_translated(
+ input,
+ (eol_style && normalize_eols) ? SVN_SUBST_NATIVE_EOL_STR : eol,
+ FALSE, kw, expand_keywords, result_pool);
*normal_stream = input;
@@ -211,7 +214,7 @@ svn_client_cat2(svn_stream_t *out,
SVN_ERR(svn_dirent_get_absolute(&local_abspath, path_or_url, pool));
SVN_ERR(svn_client__get_normalized_stream(&normal_stream, ctx->wc_ctx,
- local_abspath, revision, TRUE,
+ local_abspath, revision, TRUE, FALSE,
ctx->cancel_func, ctx->cancel_baton,
pool, pool));
Modified: subversion/branches/issue-3975/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_client/client.h?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_client/client.h (original)
+++ subversion/branches/issue-3975/subversion/libsvn_client/client.h Wed Aug 17 18:25:07 2011
@@ -1051,13 +1051,21 @@ svn_client__ensure_revprop_table(apr_has
/* Return a potentially translated version of local file LOCAL_ABSPATH
in NORMAL_STREAM. REVISION must be one of the following: BASE, COMMITTED,
- WORKING. Uses SCRATCH_POOL for temporary allocations. */
+ WORKING.
+
+ EXPAND_KEYWORDS operates as per the EXPAND argument to
+ svn_subst_stream_translated, which see. If NORMALIZE_EOLS is TRUE and
+ LOCAL_ABSPATH requires translation, then normalize the line endings in
+ *NORMAL_STREAM.
+
+ Uses SCRATCH_POOL for temporary allocations. */
svn_error_t *
svn_client__get_normalized_stream(svn_stream_t **normal_stream,
svn_wc_context_t *wc_ctx,
const char *local_abspath,
const svn_opt_revision_t *revision,
svn_boolean_t expand_keywords,
+ svn_boolean_t normalize_eols,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *result_pool,
Modified: subversion/branches/issue-3975/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_client/merge.c?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_client/merge.c Wed Aug 17 18:25:07 2011
@@ -1854,7 +1854,7 @@ files_same_p(svn_boolean_t *same,
/* Compare the file content, translating 'mine' to 'normal' form. */
SVN_ERR(svn_client__get_normalized_stream(&mine_stream, wc_ctx,
mine_abspath, &working_rev,
- FALSE, NULL, NULL,
+ FALSE, TRUE, NULL, NULL,
scratch_pool, scratch_pool));
SVN_ERR(svn_stream_open_readonly(&older_stream, older_abspath,
Modified: subversion/branches/issue-3975/subversion/libsvn_client/repos_diff.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_client/repos_diff.c?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_client/repos_diff.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_client/repos_diff.c Wed Aug 17 18:25:07 2011
@@ -1086,7 +1086,13 @@ close_file(void *file_baton,
return SVN_NO_ERROR;
}
-/* An svn_delta_editor_t function. */
+/* Report any accumulated prop changes via the 'dir_props_changed' callback,
+ * and then call the 'dir_closed' callback. Notify about any deleted paths
+ * within this directory that have not already been notified, and then about
+ * this directory itself (unless it was added, in which case the notification
+ * was done at that time).
+ *
+ * An svn_delta_editor_t function. */
static svn_error_t *
close_directory(void *dir_baton,
apr_pool_t *pool)
@@ -1110,6 +1116,7 @@ close_directory(void *dir_baton,
if (!b->added && b->propchanges->nelts > 0)
remove_non_prop_changes(b->pristine_props, b->propchanges);
+ /* Report any prop changes. */
if (b->propchanges->nelts > 0)
{
svn_boolean_t tree_conflicted = FALSE;
@@ -1134,8 +1141,8 @@ close_directory(void *dir_baton,
b->edit_baton->diff_cmd_baton,
scratch_pool));
- /* Don't notify added directories as they triggered notification
- in add_directory. */
+ /* Notify about any deleted paths within this directory that have not
+ * already been notified. */
if (!skipped && !b->added && eb->notify_func)
{
apr_hash_index_t *hi;
@@ -1157,6 +1164,8 @@ close_directory(void *dir_baton,
}
}
+ /* Notify about this directory itself (unless it was added, in which
+ * case the notification was done at that time). */
if (!b->added && eb->notify_func)
{
svn_wc_notify_t *notify;
@@ -1188,7 +1197,9 @@ close_directory(void *dir_baton,
}
-/* An svn_delta_editor_t function. */
+/* Record a prop change, which we will report later in close_file().
+ *
+ * An svn_delta_editor_t function. */
static svn_error_t *
change_file_prop(void *file_baton,
const char *name,
@@ -1209,7 +1220,9 @@ change_file_prop(void *file_baton,
return SVN_NO_ERROR;
}
-/* An svn_delta_editor_t function. */
+/* Make a note of this prop change, to be reported when the dir is closed.
+ *
+ * An svn_delta_editor_t function. */
static svn_error_t *
change_dir_prop(void *dir_baton,
const char *name,
@@ -1243,7 +1256,8 @@ close_edit(void *edit_baton,
return SVN_NO_ERROR;
}
-/* An svn_delta_editor_t function. */
+/* Notify that the node at PATH is 'missing'.
+ * An svn_delta_editor_t function. */
static svn_error_t *
absent_directory(const char *path,
void *parent_baton,
@@ -1272,7 +1286,8 @@ absent_directory(const char *path,
}
-/* An svn_delta_editor_t function. */
+/* Notify that the node at PATH is 'missing'.
+ * An svn_delta_editor_t function. */
static svn_error_t *
absent_file(const char *path,
void *parent_baton,
Modified: subversion/branches/issue-3975/subversion/libsvn_client/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_client/status.c?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_client/status.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_client/status.c Wed Aug 17 18:25:07 2011
@@ -570,10 +570,6 @@ svn_client_status_dup(const svn_client_s
if (status->moved_to_abspath)
st->moved_to_abspath = apr_pstrdup(result_pool, status->moved_to_abspath);
- if (status->moved_to_op_root_abspath)
- st->moved_to_op_root_abspath =
- apr_pstrdup(result_pool, status->moved_to_op_root_abspath);
-
return st;
}
@@ -680,7 +676,6 @@ svn_client__create_status(svn_client_sta
(*cst)->moved_from_abspath = status->moved_from_abspath;
(*cst)->moved_to_abspath = status->moved_to_abspath;
- (*cst)->moved_to_op_root_abspath = status->moved_to_op_root_abspath;
return SVN_NO_ERROR;
}
Modified: subversion/branches/issue-3975/subversion/libsvn_ra_serf/locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_ra_serf/locks.c?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_ra_serf/locks.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_ra_serf/locks.c Wed Aug 17 18:25:07 2011
@@ -580,6 +580,8 @@ svn_ra_serf__lock(svn_ra_session_t *ra_s
subpool = svn_pool_create(pool);
+ /* ### TODO for issue 2263: Send all the locks over the wire at once. This
+ loop is just a temporary shim. */
for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi))
{
svn_ra_serf__handler_t *handler;
@@ -683,6 +685,8 @@ svn_ra_serf__unlock(svn_ra_session_t *ra
subpool = svn_pool_create(pool);
+ /* ### TODO for issue 2263: Send all the locks over the wire at once. This
+ loop is just a temporary shim. */
for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi))
{
svn_ra_serf__handler_t *handler;
Modified: subversion/branches/issue-3975/subversion/libsvn_wc/adm_ops.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_wc/adm_ops.c?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_wc/adm_ops.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_wc/adm_ops.c Wed Aug 17 18:25:07 2011
@@ -29,6 +29,7 @@
#include <string.h>
+#include <stdlib.h>
#include <apr_pools.h>
#include <apr_tables.h>
@@ -1291,6 +1292,186 @@ remove_conflict_file(svn_boolean_t *noti
}
+/* Remove the reverted copied file at LOCAL_ABSPATH from disk if it was
+ * not modified after being copied. Use FILESIZE and PRISTINE_CHECKSUM to
+ * detect modification.
+ * If NEW_KIND is not NULL, return the resulting on-disk kind of the node
+ * at LOCAL_ABSPATH in *NEW_KIND. */
+static svn_error_t *
+revert_restore_handle_copied_file(svn_node_kind_t *new_kind,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ svn_filesize_t filesize,
+ const svn_checksum_t *pristine_checksum,
+ apr_pool_t *scratch_pool)
+{
+ svn_stream_t *pristine_stream;
+ svn_filesize_t pristine_size;
+ svn_boolean_t has_text_mods;
+
+ if (new_kind)
+ *new_kind = svn_node_file;
+
+ SVN_ERR(svn_wc__db_pristine_read(&pristine_stream, &pristine_size,
+ db, local_abspath, pristine_checksum,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_wc__compare_file_with_pristine(&has_text_mods, db,
+ local_abspath,
+ filesize,
+ pristine_stream,
+ pristine_size,
+ FALSE, FALSE, FALSE,
+ scratch_pool));
+
+ if (!has_text_mods)
+ {
+ SVN_ERR(svn_io_remove_file2(local_abspath, FALSE, scratch_pool));
+ if (new_kind)
+ *new_kind = svn_node_none;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+/* Sort copied children obtained from the revert list based on
+ * their paths in descending order (longest paths first). */
+static int
+compare_revert_list_copied_children(const void *a, const void *b)
+{
+ const svn_wc__db_revert_list_copied_child_info_t *ca = a;
+ const svn_wc__db_revert_list_copied_child_info_t *cb = b;
+ int i;
+
+ i = svn_path_compare_paths(ca->abspath, cb->abspath);
+
+ /* Reverse the result of svn_path_compare_paths() to achieve
+ * descending order. */
+ return -i;
+}
+
+
+/* Remove as many reverted copied children as possible from the directory at
+ * LOCAL_ABSPATH. If REMOVE_SELF is TRUE, also remove LOCAL_ABSPATH itself
+ * if possible (REMOVE_SELF should be set if LOCAL_ABSPATH is itself a
+ * reverted copy).
+ *
+ * All reverted copied file children not modified after being copied are
+ * removed from disk. Reverted copied directories left empty as a result
+ * are also removed from disk.
+ *
+ * If NEW_KIND is not NULL, return the resulting on-disk kind of the node
+ * at LOCAL_ABSPATH in *NEW_KIND. */
+static svn_error_t *
+revert_restore_handle_copied_dirs(svn_node_kind_t *new_kind,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ svn_boolean_t remove_self,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool)
+{
+ const apr_array_header_t *copied_children;
+ svn_wc__db_revert_list_copied_child_info_t *child_info;
+ int i;
+ apr_finfo_t finfo;
+ apr_pool_t *iterpool;
+ svn_error_t *err;
+
+ if (new_kind)
+ *new_kind = svn_node_dir;
+
+ SVN_ERR(svn_wc__db_revert_list_read_copied_children(&copied_children,
+ db, local_abspath,
+ scratch_pool,
+ scratch_pool));
+ iterpool = svn_pool_create(scratch_pool);
+
+ /* Remove all file children, if possible. */
+ for (i = 0; i < copied_children->nelts; i++)
+ {
+ child_info = APR_ARRAY_IDX(
+ copied_children, i,
+ svn_wc__db_revert_list_copied_child_info_t *);
+
+ if (cancel_func)
+ SVN_ERR(cancel_func(cancel_baton));
+
+ if (child_info->kind != svn_wc__db_kind_file)
+ continue;
+
+ svn_pool_clear(iterpool);
+
+ err = svn_io_stat(&finfo, child_info->abspath,
+ APR_FINFO_TYPE | APR_FINFO_SIZE,
+ iterpool);
+ if (err && (APR_STATUS_IS_ENOENT(err->apr_err)
+ || SVN__APR_STATUS_IS_ENOTDIR(err->apr_err)))
+ {
+ svn_error_clear(err);
+ continue;
+ }
+ else
+ SVN_ERR(err);
+
+ if (finfo.filetype != APR_REG)
+ continue;
+
+ SVN_ERR(revert_restore_handle_copied_file(NULL, db, child_info->abspath,
+ finfo.size,
+ child_info->pristine_checksum,
+ iterpool));
+ }
+
+ /* Try to delete every child directory, ignoring errors.
+ * This is a bit crude but good enough for our purposes.
+ *
+ * We cannot delete children recursively since we want to keep any files
+ * that still exist on disk. So sort the children list such that longest
+ * paths come first and try to remove each child directory in order. */
+ qsort(copied_children->elts, copied_children->nelts,
+ sizeof(svn_wc__db_revert_list_copied_child_info_t *),
+ compare_revert_list_copied_children);
+ for (i = 0; i < copied_children->nelts; i++)
+ {
+ child_info = APR_ARRAY_IDX(
+ copied_children, i,
+ svn_wc__db_revert_list_copied_child_info_t *);
+
+ if (cancel_func)
+ SVN_ERR(cancel_func(cancel_baton));
+
+ if (child_info->kind != svn_wc__db_kind_dir)
+ continue;
+
+ svn_pool_clear(iterpool);
+
+ svn_error_clear(svn_io_dir_remove_nonrecursive(child_info->abspath,
+ iterpool));
+ }
+
+ if (remove_self)
+ {
+ apr_hash_t *remaining_children;
+
+ /* Delete LOCAL_ABSPATH itself if no children are left. */
+ SVN_ERR(svn_io_get_dirents3(&remaining_children, local_abspath, TRUE,
+ iterpool, iterpool));
+ if (apr_hash_count(remaining_children) == 0)
+ {
+ SVN_ERR(svn_io_remove_dir2(local_abspath, FALSE, NULL, NULL,
+ iterpool));
+ if (new_kind)
+ *new_kind = svn_node_none;
+ }
+ }
+
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
+
+
/* Make the working tree under LOCAL_ABSPATH to depth DEPTH match the
versioned tree. This function is called after svn_wc__db_op_revert
has done the database revert and created the revert list. Notifies
@@ -1321,6 +1502,9 @@ revert_restore(svn_wc__db_t *db,
#ifdef HAVE_SYMLINK
svn_boolean_t special;
#endif
+ svn_boolean_t copied_here;
+ svn_wc__db_kind_t reverted_kind;
+ const svn_checksum_t *pristine_checksum;
if (cancel_func)
SVN_ERR(cancel_func(cancel_baton));
@@ -1328,6 +1512,8 @@ revert_restore(svn_wc__db_t *db,
SVN_ERR(svn_wc__db_revert_list_read(¬ify_required,
&conflict_old, &conflict_new,
&conflict_working, &prop_reject,
+ &copied_here, &reverted_kind,
+ &pristine_checksum,
db, local_abspath,
scratch_pool, scratch_pool));
@@ -1342,17 +1528,21 @@ revert_restore(svn_wc__db_t *db,
{
svn_error_clear(err);
- if (notify_func && notify_required)
- notify_func(notify_baton,
- svn_wc_create_notify(local_abspath, svn_wc_notify_revert,
- scratch_pool),
- scratch_pool);
-
- if (notify_func)
- SVN_ERR(svn_wc__db_revert_list_notify(notify_func, notify_baton,
- db, local_abspath,
- scratch_pool));
- return SVN_NO_ERROR;
+ if (!copied_here)
+ {
+ if (notify_func && notify_required)
+ notify_func(notify_baton,
+ svn_wc_create_notify(local_abspath,
+ svn_wc_notify_revert,
+ scratch_pool),
+ scratch_pool);
+
+ if (notify_func)
+ SVN_ERR(svn_wc__db_revert_list_notify(notify_func, notify_baton,
+ db, local_abspath,
+ scratch_pool));
+ return SVN_NO_ERROR;
+ }
}
else if (err)
return svn_error_trace(err);
@@ -1387,6 +1577,21 @@ revert_restore(svn_wc__db_t *db,
#endif
}
+ if (copied_here)
+ {
+ /* The revert target itself is the op-root of a copy. */
+ if (reverted_kind == svn_wc__db_kind_file && on_disk == svn_node_file)
+ SVN_ERR(revert_restore_handle_copied_file(&on_disk, db, local_abspath,
+ finfo.size,
+ pristine_checksum,
+ scratch_pool));
+ else if (reverted_kind == svn_wc__db_kind_dir && on_disk == svn_node_dir)
+ SVN_ERR(revert_restore_handle_copied_dirs(&on_disk, db, local_abspath,
+ TRUE,
+ cancel_func, cancel_baton,
+ scratch_pool));
+ }
+
/* If we expect a versioned item to be present then check that any
item on disk matches the versioned item, if it doesn't match then
fix it or delete it. */
@@ -1567,6 +1772,10 @@ revert_restore(svn_wc__db_t *db,
const apr_array_header_t *children;
int i;
+ SVN_ERR(revert_restore_handle_copied_dirs(NULL, db, local_abspath, FALSE,
+ cancel_func, cancel_baton,
+ iterpool));
+
SVN_ERR(svn_wc__db_read_children_of_working_node(&children, db,
local_abspath,
scratch_pool,
Modified: subversion/branches/issue-3975/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_wc/questions.c?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_wc/questions.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_wc/questions.c Wed Aug 17 18:25:07 2011
@@ -79,38 +79,17 @@
*/
-/* Set *MODIFIED_P to TRUE if (after translation) VERSIONED_FILE_ABSPATH
- * (of VERSIONED_FILE_SIZE bytes) differs from PRISTINE_STREAM (of
- * PRISTINE_SIZE bytes), else to FALSE if not.
- *
- * If EXACT_COMPARISON is FALSE, translate VERSIONED_FILE_ABSPATH's EOL
- * style and keywords to repository-normal form according to its properties,
- * and compare the result with PRISTINE_STREAM. If EXACT_COMPARISON is
- * TRUE, translate PRISTINE_STREAM's EOL style and keywords to working-copy
- * form according to VERSIONED_FILE_ABSPATH's properties, and compare the
- * result with VERSIONED_FILE_ABSPATH.
- *
- * HAS_PROPS should be TRUE if the file had properties when it was not
- * modified, otherwise FALSE.
- *
- * PROPS_MOD should be TRUE if the file's properties have been changed,
- * otherwise FALSE.
- *
- * PRISTINE_STREAM will be closed before a successful return.
- *
- * DB is a wc_db; use SCRATCH_POOL for temporary allocation.
- */
-static svn_error_t *
-compare_and_verify(svn_boolean_t *modified_p,
- svn_wc__db_t *db,
- const char *versioned_file_abspath,
- svn_filesize_t versioned_file_size,
- svn_stream_t *pristine_stream,
- svn_filesize_t pristine_size,
- svn_boolean_t has_props,
- svn_boolean_t props_mod,
- svn_boolean_t exact_comparison,
- apr_pool_t *scratch_pool)
+svn_error_t *
+svn_wc__compare_file_with_pristine(svn_boolean_t *modified_p,
+ svn_wc__db_t *db,
+ const char *versioned_file_abspath,
+ svn_filesize_t versioned_file_size,
+ svn_stream_t *pristine_stream,
+ svn_filesize_t pristine_size,
+ svn_boolean_t has_props,
+ svn_boolean_t props_mod,
+ svn_boolean_t exact_comparison,
+ apr_pool_t *scratch_pool)
{
svn_boolean_t same;
svn_subst_eol_style_t eol_style;
@@ -337,12 +316,12 @@ svn_wc__internal_file_modified_p(svn_boo
/* Check all bytes, and verify checksum if requested. */
{
svn_error_t *err;
- err = compare_and_verify(modified_p, db,
- local_abspath, dirent->filesize,
- pristine_stream, pristine_size,
- has_props, props_mod,
- exact_comparison,
- scratch_pool);
+ err = svn_wc__compare_file_with_pristine(modified_p, db,
+ local_abspath, dirent->filesize,
+ pristine_stream, pristine_size,
+ has_props, props_mod,
+ exact_comparison,
+ scratch_pool);
/* At this point we already opened the pristine file, so we know that
the access denied applies to the working copy path */
Modified: subversion/branches/issue-3975/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_wc/status.c?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_wc/status.c Wed Aug 17 18:25:07 2011
@@ -273,6 +273,68 @@ read_info(const struct svn_wc__db_info_t
&mtb->lock, NULL, NULL,
db, local_abspath,
result_pool, scratch_pool));
+
+ if (mtb->status == svn_wc__db_status_deleted)
+ {
+ const char *moved_to_abspath;
+ const char *moved_to_op_root_abspath;
+
+ /* NOTE: we can't use op-root-ness as a condition here since a base
+ * node can be the root of a move and still not be an explicit
+ * op-root (having a working node with op_depth == pathelements).
+ *
+ * Both these (almost identical) situations showcase this:
+ * svn mv a/b bb
+ * svn del a
+ * and
+ * svn mv a aa
+ * svn mv aa/b bb
+ * In both, 'bb' is moved from 'a/b', but 'a/b' has no op_depth>0
+ * node at all, as its parent 'a' is locally deleted. */
+
+ SVN_ERR(svn_wc__db_scan_deletion(NULL,
+ &moved_to_abspath,
+ NULL,
+ &moved_to_op_root_abspath,
+ db, local_abspath,
+ scratch_pool, scratch_pool));
+ if (moved_to_abspath != NULL
+ && moved_to_op_root_abspath != NULL
+ && strcmp(moved_to_abspath, moved_to_op_root_abspath) == 0)
+ {
+ mtb->moved_to_abspath = apr_pstrdup(result_pool,
+ moved_to_abspath);
+ }
+ /* ### ^^^ THIS SUCKS. For at least two reasons:
+ * 1) We scan the node deletion and that's technically not necessary.
+ * We'd be fine to know if this is an actual root of a move.
+ * 2) From the elaborately calculated results, we backwards-guess
+ * whether this is a root.
+ * It works ok, and this code only gets called when a node is an
+ * explicit target of a 'status'. But it would be better to do this
+ * differently.
+ * We could return moved-to via svn_wc__db_base_get_info() (called
+ * just above), but as moved-to is only intended to be returned for
+ * roots of a move, that doesn't fit too well. */
+ }
+ }
+
+ /* ### svn_wc__db_read_info() could easily return the moved-here flag. But
+ * for now... (The per-dir query for recursive status is far more optimal.)
+ * Note that this actually scans around to get the full path, for a bool.
+ * This bool then gets returned, later is evaluated, and if true leads to
+ * the same paths being scanned again. We'd want to obtain this bool here as
+ * cheaply as svn_wc__db_read_children_info() does. */
+ if (mtb->status == svn_wc__db_status_added)
+ {
+ const char *moved_from_abspath = NULL;
+ SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ &moved_from_abspath,
+ NULL,
+ db, local_abspath,
+ result_pool, scratch_pool));
+ mtb->moved_here = (moved_from_abspath != NULL);
}
mtb->has_checksum = (checksum != NULL);
@@ -404,8 +466,6 @@ assemble_status(svn_wc_status3_t **statu
const char *repos_root_url;
const char *repos_uuid;
const char *moved_from_abspath = NULL;
- const char *moved_to_abspath = NULL;
- const char *moved_to_op_root_abspath = NULL;
svn_filesize_t filesize = (dirent && (dirent->kind == svn_node_file))
? dirent->filesize
: SVN_INVALID_FILESIZE;
@@ -426,17 +486,13 @@ assemble_status(svn_wc_status3_t **statu
/* A node is switched if it doesn't have the implied repos_relpath */
const char *name = svn_relpath_skip_ancestor(parent_repos_relpath,
info->repos_relpath);
- switched_p = !name || (strcmp(name, svn_dirent_basename(local_abspath, NULL)) != 0);
+ switched_p = !name || (strcmp(name,
+ svn_dirent_basename(local_abspath, NULL))
+ != 0);
}
- /* Examine whether our target is missing or obstructed.
-
- While we are not completely in single-db mode yet, data about
- obstructed or missing nodes might be incomplete here. This is
- reported by svn_wc_db_status_obstructed_XXXX. In single-db
- mode these obstructions are no longer reported and we have
- to detect obstructions by looking at the on disk status in DIRENT.
- */
+ /* Examine whether our target is missing or obstructed. To detect
+ * obstructions, we have to look at the on-disk status in DIRENT. */
if (info->kind == svn_wc__db_kind_dir)
{
if (info->status == svn_wc__db_status_incomplete)
@@ -608,26 +664,20 @@ assemble_status(svn_wc_status3_t **statu
else if (schedule == svn_wc_schedule_replace)
node_status = svn_wc_status_replaced;
}
+
+ /* Get moved-from info (only for potential op-roots of a move). */
+ if (node_status == svn_wc_status_added
+ && info->moved_here
+ && info->op_root)
+ SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ &moved_from_abspath,
+ NULL,
+ db, local_abspath,
+ result_pool, scratch_pool));
}
}
- /* Get moved-to info. */
- if (info->status == svn_wc__db_status_deleted)
- SVN_ERR(svn_wc__db_scan_deletion(NULL,
- &moved_to_abspath,
- NULL,
- &moved_to_op_root_abspath,
- db, local_abspath,
- result_pool, scratch_pool));
-
- /* Get moved-from info. */
- if (info->status == svn_wc__db_status_added)
- SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- &moved_from_abspath,
- NULL,
- db, local_abspath,
- result_pool, scratch_pool));
if (node_status == svn_wc_status_normal)
node_status = text_status;
@@ -722,8 +772,7 @@ assemble_status(svn_wc_status3_t **statu
stat->repos_uuid = repos_uuid;
stat->moved_from_abspath = moved_from_abspath;
- stat->moved_to_abspath = moved_to_abspath;
- stat->moved_to_op_root_abspath = moved_to_op_root_abspath;
+ stat->moved_to_abspath = info->moved_to_abspath;
*status = stat;
@@ -1082,8 +1131,8 @@ get_dir_status(const struct walk_status_
don't all map the same types, but only the keys of the result
hash are subsequently used. */
SVN_ERR(svn_wc__db_read_children_info(&nodes, &conflicts,
- wb->db, local_abspath,
- subpool, iterpool));
+ wb->db, local_abspath,
+ subpool, iterpool));
all_children = apr_hash_overlay(subpool, nodes, dirents);
if (apr_hash_count(conflicts) > 0)
@@ -2624,10 +2673,6 @@ svn_wc_dup_status3(const svn_wc_status3_
new_stat->moved_to_abspath
= apr_pstrdup(pool, orig_stat->moved_to_abspath);
- if (orig_stat->moved_to_op_root_abspath)
- new_stat->moved_to_op_root_abspath
- = apr_pstrdup(pool, orig_stat->moved_to_op_root_abspath);
-
/* Return the new hotness. */
return new_stat;
}
Modified: subversion/branches/issue-3975/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_wc/wc-metadata.sql?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/issue-3975/subversion/libsvn_wc/wc-metadata.sql Wed Aug 17 18:25:07 2011
@@ -316,8 +316,8 @@ CREATE TABLE NODES (
BASE node, the location of the initial checkout.
When op_depth != 0, they indicate where this node was copied/moved from.
- In this case, the fields are set only on the root of the operation,
- and are NULL for all children. */
+ In this case, the fields are set for the root of the operation and for all
+ children. */
repos_id INTEGER REFERENCES REPOSITORY (id),
repos_path TEXT,
revision INTEGER,
Modified: subversion/branches/issue-3975/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_wc/wc-queries.sql?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/issue-3975/subversion/libsvn_wc/wc-queries.sql Wed Aug 17 18:25:07 2011
@@ -119,7 +119,7 @@ WHERE wc_id = ?1 AND local_relpath = ?2
SELECT op_depth, nodes.repos_id, nodes.repos_path, presence, kind, revision,
checksum, translated_size, changed_revision, changed_date, changed_author,
depth, symlink_target, last_mod_time, properties, lock_token, lock_owner,
- lock_comment, lock_date, local_relpath
+ lock_comment, lock_date, local_relpath, moved_here, moved_to
FROM nodes
LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
AND nodes.repos_path = lock.repos_relpath
@@ -1112,14 +1112,20 @@ CREATE TEMPORARY TABLE revert_list (
conflict_working TEXT,
prop_reject TEXT,
notify INTEGER, /* 1 if an actual row had props or tree conflict */
+ op_depth INTEGER,
+ repos_id INTEGER,
+ kind TEXT,
+ checksum TEXT,
PRIMARY KEY (local_relpath, actual)
);
DROP TRIGGER IF EXISTS trigger_revert_list_nodes;
CREATE TEMPORARY TRIGGER trigger_revert_list_nodes
BEFORE DELETE ON nodes
BEGIN
- INSERT OR REPLACE INTO revert_list(local_relpath, actual)
- SELECT OLD.local_relpath, 0;
+ INSERT OR REPLACE INTO revert_list(local_relpath, actual, op_depth,
+ repos_id, kind, checksum)
+ SELECT OLD.local_relpath, 0, OLD.op_depth, OLD.repos_id, OLD.kind,
+ OLD.checksum;
END;
DROP TRIGGER IF EXISTS trigger_revert_list_actual_delete;
CREATE TEMPORARY TRIGGER trigger_revert_list_actual_delete
@@ -1156,11 +1162,20 @@ DROP TRIGGER IF EXISTS trigger_revert_li
DROP TRIGGER IF EXISTS trigger_revert_list_actual_update
-- STMT_SELECT_REVERT_LIST
-SELECT conflict_old, conflict_new, conflict_working, prop_reject, notify, actual
+SELECT conflict_old, conflict_new, conflict_working, prop_reject, notify,
+ actual, op_depth, repos_id, kind, checksum
FROM revert_list
WHERE local_relpath = ?1
ORDER BY actual DESC
+-- STMT_SELECT_REVERT_LIST_COPIED_CHILDREN
+SELECT local_relpath, kind, checksum
+FROM revert_list
+WHERE local_relpath LIKE ?1 ESCAPE '#'
+ AND op_depth >= ?2
+ AND repos_id IS NOT NULL
+ORDER BY local_relpath
+
-- STMT_DELETE_REVERT_LIST
DELETE FROM revert_list WHERE local_relpath = ?1
Modified: subversion/branches/issue-3975/subversion/libsvn_wc/wc.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_wc/wc.h?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_wc/wc.h (original)
+++ subversion/branches/issue-3975/subversion/libsvn_wc/wc.h Wed Aug 17 18:25:07 2011
@@ -725,6 +725,39 @@ svn_wc__perform_file_merge(svn_skel_t **
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* Set *MODIFIED_P to TRUE if (after translation) VERSIONED_FILE_ABSPATH
+ * (of VERSIONED_FILE_SIZE bytes) differs from PRISTINE_STREAM (of
+ * PRISTINE_SIZE bytes), else to FALSE if not.
+ *
+ * If EXACT_COMPARISON is FALSE, translate VERSIONED_FILE_ABSPATH's EOL
+ * style and keywords to repository-normal form according to its properties,
+ * and compare the result with PRISTINE_STREAM. If EXACT_COMPARISON is
+ * TRUE, translate PRISTINE_STREAM's EOL style and keywords to working-copy
+ * form according to VERSIONED_FILE_ABSPATH's properties, and compare the
+ * result with VERSIONED_FILE_ABSPATH.
+ *
+ * HAS_PROPS should be TRUE if the file had properties when it was not
+ * modified, otherwise FALSE.
+ *
+ * PROPS_MOD should be TRUE if the file's properties have been changed,
+ * otherwise FALSE.
+ *
+ * PRISTINE_STREAM will be closed before a successful return.
+ *
+ * DB is a wc_db; use SCRATCH_POOL for temporary allocation.
+ */
+svn_error_t *
+svn_wc__compare_file_with_pristine(svn_boolean_t *modified_p,
+ svn_wc__db_t *db,
+ const char *versioned_file_abspath,
+ svn_filesize_t versioned_file_size,
+ svn_stream_t *pristine_stream,
+ svn_filesize_t pristine_size,
+ svn_boolean_t has_props,
+ svn_boolean_t props_mod,
+ svn_boolean_t exact_comparison,
+ apr_pool_t *scratch_pool);
+
#ifdef __cplusplus
}
Modified: subversion/branches/issue-3975/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_wc/wc_db.c?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_wc/wc_db.c Wed Aug 17 18:25:07 2011
@@ -5471,6 +5471,9 @@ struct revert_list_read_baton {
const char **conflict_new;
const char **conflict_working;
const char **prop_reject;
+ svn_boolean_t *copied_here;
+ svn_wc__db_kind_t *kind;
+ const svn_checksum_t **pristine_checksum;
apr_pool_t *result_pool;
};
@@ -5487,6 +5490,9 @@ revert_list_read(void *baton,
*(b->reverted) = FALSE;
*(b->conflict_new) = *(b->conflict_old) = *(b->conflict_working) = NULL;
*(b->prop_reject) = NULL;
+ *(b->copied_here) = FALSE;
+ *(b->pristine_checksum) = NULL;
+ *(b->kind) = svn_wc__db_kind_unknown;
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_REVERT_LIST));
@@ -5527,10 +5533,30 @@ revert_list_read(void *baton,
SVN_ERR(svn_sqlite__step(&another_row, stmt));
if (another_row)
- *(b->reverted) = TRUE;
+ {
+ *(b->reverted) = TRUE;
+ *(b->kind) = svn_sqlite__column_token(stmt, 8,
+ kind_map);
+ if (!svn_sqlite__column_is_null(stmt, 9))
+ SVN_ERR(svn_sqlite__column_checksum(b->pristine_checksum,
+ stmt, 9,
+ b->result_pool));
+ }
}
else
- *(b->reverted) = TRUE;
+ {
+ *(b->reverted) = TRUE;
+ if (!svn_sqlite__column_is_null(stmt, 7))
+ {
+ apr_int64_t op_depth = svn_sqlite__column_int64(stmt, 6);
+ *(b->copied_here) = (op_depth == relpath_depth(local_relpath));
+ }
+ *(b->kind) = svn_sqlite__column_token(stmt, 8, kind_map);
+ if (!svn_sqlite__column_is_null(stmt, 9))
+ SVN_ERR(svn_sqlite__column_checksum(b->pristine_checksum,
+ stmt, 9, b->result_pool));
+ }
+
}
SVN_ERR(svn_sqlite__reset(stmt));
@@ -5551,6 +5577,9 @@ svn_wc__db_revert_list_read(svn_boolean_
const char **conflict_new,
const char **conflict_working,
const char **prop_reject,
+ svn_boolean_t *copied_here,
+ svn_wc__db_kind_t *kind,
+ const svn_checksum_t **pristine_checksum,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *result_pool,
@@ -5560,6 +5589,7 @@ svn_wc__db_revert_list_read(svn_boolean_
const char *local_relpath;
struct revert_list_read_baton b = {reverted, conflict_old, conflict_new,
conflict_working, prop_reject,
+ copied_here, kind, pristine_checksum,
result_pool};
SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
@@ -5571,6 +5601,85 @@ svn_wc__db_revert_list_read(svn_boolean_
return SVN_NO_ERROR;
}
+
+struct revert_list_read_copied_children_baton {
+ const apr_array_header_t **children;
+ apr_pool_t *result_pool;
+};
+
+static svn_error_t *
+revert_list_read_copied_children(void *baton,
+ svn_wc__db_wcroot_t *wcroot,
+ const char *local_relpath,
+ apr_pool_t *scratch_pool)
+{
+ struct revert_list_read_copied_children_baton *b = baton;
+ svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+ apr_array_header_t *children;
+
+ children =
+ apr_array_make(b->result_pool, 0,
+ sizeof(svn_wc__db_revert_list_copied_child_info_t *));
+
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+ STMT_SELECT_REVERT_LIST_COPIED_CHILDREN));
+ SVN_ERR(svn_sqlite__bindf(stmt, "si",
+ construct_like_arg(local_relpath, scratch_pool),
+ relpath_depth(local_relpath)));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ while (have_row)
+ {
+ svn_wc__db_revert_list_copied_child_info_t *child_info;
+ const char *child_relpath;
+
+ child_info = apr_palloc(b->result_pool, sizeof(*child_info));
+
+ child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+ child_info->abspath = svn_dirent_join(wcroot->abspath, child_relpath,
+ b->result_pool);
+ child_info->kind = svn_sqlite__column_token(stmt, 1, kind_map);
+ if (svn_sqlite__column_is_null(stmt, 2))
+ child_info->pristine_checksum = NULL;
+ else
+ SVN_ERR(svn_sqlite__column_checksum(&child_info->pristine_checksum,
+ stmt, 2, b->result_pool));
+ APR_ARRAY_PUSH(
+ children,
+ svn_wc__db_revert_list_copied_child_info_t *) = child_info;
+
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+ }
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ *b->children = children;
+
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_wc__db_revert_list_read_copied_children(const apr_array_header_t **children,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_wc__db_wcroot_t *wcroot;
+ const char *local_relpath;
+ struct revert_list_read_copied_children_baton b = {children, result_pool};
+
+ SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
+ db, local_abspath, scratch_pool, scratch_pool));
+ VERIFY_USABLE_WCROOT(wcroot);
+
+ SVN_ERR(svn_wc__db_with_txn(wcroot, local_relpath,
+ revert_list_read_copied_children, &b,
+ scratch_pool));
+ return SVN_NO_ERROR;
+}
+
+
svn_error_t *
svn_wc__db_revert_list_notify(svn_wc_notify_func2_t notify_func,
void *notify_baton,
@@ -7038,18 +7147,27 @@ read_children_info(void *baton,
if (op_depth == 0)
{
+ const char *moved_to_relpath;
+
child_item->info.have_base = TRUE;
- /* Get the lock info. The query only reports lock info in the row at
- * op_depth 0. */
- if (op_depth == 0)
- child_item->info.lock = lock_from_columns(stmt, 15, 16, 17, 18,
- result_pool);
+ /* Get the lock info, available only at op_depth 0. */
+ child_item->info.lock = lock_from_columns(stmt, 15, 16, 17, 18,
+ result_pool);
+
+ /* Moved-to is only stored at op_depth 0. */
+ moved_to_relpath = svn_sqlite__column_text(stmt, 21, NULL);
+ if (moved_to_relpath)
+ child_item->info.moved_to_abspath =
+ svn_dirent_join(wcroot->abspath, moved_to_relpath, result_pool);
}
else
{
child_item->nr_layers++;
child_item->info.have_more_work = (child_item->nr_layers > 1);
+
+ /* Moved-here can only exist at op_depth > 0. */
+ child_item->info.moved_here = svn_sqlite__column_boolean(stmt, 20);
}
err = svn_sqlite__step(&have_row, stmt);
@@ -9580,7 +9698,7 @@ svn_wc__db_scan_addition(svn_wc__db_stat
const char **original_uuid,
svn_revnum_t *original_revision,
const char **moved_from_abspath,
- const char **delete_op_root_abspath,
+ const char **moved_from_op_root_abspath,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *result_pool,
@@ -9632,14 +9750,15 @@ svn_wc__db_scan_addition(svn_wc__db_stat
*moved_from_abspath = NULL;
}
- if (delete_op_root_abspath)
+ if (moved_from_op_root_abspath)
{
if (moved_from_op_root_relpath)
- *delete_op_root_abspath = svn_dirent_join(wcroot->abspath,
- moved_from_op_root_relpath,
- result_pool);
+ *moved_from_op_root_abspath =
+ svn_dirent_join(wcroot->abspath,
+ moved_from_op_root_relpath,
+ result_pool);
else
- *delete_op_root_abspath = NULL;
+ *moved_from_op_root_abspath = NULL;
}
return SVN_NO_ERROR;
@@ -9668,6 +9787,7 @@ scan_deletion_txn(void *baton,
svn_wc__db_status_t child_presence;
svn_boolean_t child_has_base = FALSE;
apr_int64_t local_op_depth, op_depth;
+ svn_boolean_t found_moved_to = FALSE;
/* Initialize all the OUT parameters. */
if (sd_baton->base_del_relpath != NULL)
@@ -9794,9 +9914,12 @@ scan_deletion_txn(void *baton,
gimmick, not a real node that may have been deleted. */
}
- if ((sd_baton->moved_to_relpath != NULL
- || sd_baton->moved_to_op_root_relpath != NULL
- || sd_baton->base_del_relpath != NULL)
+ /* Evaluate moved-to information. Once moved-to info has been found, it
+ * must not be overwritten with ancestors' moved-to info. */
+ if ((! found_moved_to)
+ && (sd_baton->moved_to_relpath != NULL
+ || sd_baton->moved_to_op_root_relpath != NULL
+ || sd_baton->base_del_relpath != NULL)
&& !svn_sqlite__column_is_null(stmt, 2 /* moved_to */))
{
const char *moved_to_op_root_relpath;
@@ -9887,6 +10010,13 @@ scan_deletion_txn(void *baton,
*sd_baton->moved_to_op_root_relpath = moved_to_op_root_relpath ?
apr_pstrdup(sd_baton->result_pool, moved_to_op_root_relpath)
: NULL;
+
+ /* If all other out parameters are irrelevant, stop scanning.
+ * Happens to be only WORK_DEL_RELPATH. */
+ if (sd_baton->work_del_relpath == NULL)
+ break;
+
+ found_moved_to = TRUE;
}
op_depth = svn_sqlite__column_int64(stmt, 3);
Modified: subversion/branches/issue-3975/subversion/libsvn_wc/wc_db.h
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_wc/wc_db.h?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/issue-3975/subversion/libsvn_wc/wc_db.h Wed Aug 17 18:25:07 2011
@@ -1506,6 +1506,13 @@ svn_wc__db_op_revert(svn_wc__db_t *db,
* path was reverted. Set *CONFLICT_OLD, *CONFLICT_NEW,
* *CONFLICT_WORKING and *PROP_REJECT to the names of the conflict
* files, or NULL if the names are not stored.
+ *
+ * Set *COPIED_HERE if the reverted node was copied here and is the
+ * operation root of the copy.
+ * Set *KIND to the node kind of the reverted node.
+ * If the node was a file, set *PRISTINE_CHECKSUM to the checksum
+ * of the pristine associated with the node. If the file had no
+ * pristine set *PRISTINE_CHECKSUM to NULL.
*
* Removes the row for LOCAL_ABSPATH from the revert list.
*/
@@ -1515,11 +1522,34 @@ svn_wc__db_revert_list_read(svn_boolean_
const char **conflict_new,
const char **conflict_working,
const char **prop_reject,
+ svn_boolean_t *copied_here,
+ svn_wc__db_kind_t *kind,
+ const svn_checksum_t **pristine_checksum,
svn_wc__db_t *db,
const char *local_abspath,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
+/* The type of elements in the array returned by
+ * svn_wc__db_revert_list_read_copied_children(). */
+typedef struct svn_wc__db_revert_list_copied_child_info_t {
+ const char *abspath;
+ svn_wc__db_kind_t kind;
+ const svn_checksum_t *pristine_checksum;
+} svn_wc__db_revert_list_copied_child_info_t ;
+
+/* Return in *CHILDREN a list of reverted copied children within the
+ * reverted tree rooted at LOCAL_ABSPATH.
+ * Allocate *COPIED_CHILDREN and its elements in RESULT_POOL.
+ * The elements are of type svn_wc__db_revert_list_copied_child_info_t. */
+svn_error_t *
+svn_wc__db_revert_list_read_copied_children(const apr_array_header_t **children,
+ svn_wc__db_t *db,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+
/* Make revert notifications for all paths in the revert list that are
* equal to LOCAL_ABSPATH or below LOCAL_ABSPATH.
*
@@ -1842,6 +1872,9 @@ struct svn_wc__db_info_t {
svn_boolean_t locked; /* WC directory lock */
svn_wc__db_lock_t *lock; /* Repository file lock */
+
+ const char *moved_to_abspath; /* Only on op-roots. See svn_wc_status3_t. */
+ svn_boolean_t moved_here; /* On both op-roots and children. */
};
/* Return in *NODES a hash mapping name->struct svn_wc__db_info_t for
Modified: subversion/branches/issue-3975/subversion/libsvn_wc/wc_db_wcroot.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_wc/wc_db_wcroot.c?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_wc/wc_db_wcroot.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_wc/wc_db_wcroot.c Wed Aug 17 18:25:07 2011
@@ -100,11 +100,13 @@ get_old_version(int *version,
of LOCAL_ABSPATH, using DB and SCRATCH_POOL as needed.
This function may do strange things, but at long as it comes up with the
- Right Answer, we should be happy. */
+ Right Answer, we should be happy.
+
+ Sets *KIND to svn_node_dir for symlinks. */
static svn_error_t *
-get_path_kind(svn_wc__db_t *db,
+get_path_kind(svn_node_kind_t *kind,
+ svn_wc__db_t *db,
const char *local_abspath,
- svn_node_kind_t *kind,
apr_pool_t *scratch_pool)
{
svn_boolean_t special;
@@ -132,7 +134,11 @@ get_path_kind(svn_wc__db_t *db,
}
SVN_ERR(svn_io_check_special_path(local_abspath, &db->parse_cache.kind,
- &special /* unused */, scratch_pool));
+ &special, scratch_pool));
+
+ /* The wcroot could be a symlink to a directory. (Issue #2557, #3987) */
+ if (special)
+ db->parse_cache.kind = svn_node_dir;
*kind = db->parse_cache.kind;
return SVN_NO_ERROR;
@@ -395,7 +401,7 @@ svn_wc__db_wcroot_parse_local_abspath(sv
### rid of this stat() call. it is going to happen for EVERY call
### into wc_db which references a file. calls for directories could
### get an early-exit in the hash lookup just above. */
- SVN_ERR(get_path_kind(db, local_abspath, &kind, scratch_pool));
+ SVN_ERR(get_path_kind(&kind, db, local_abspath, scratch_pool));
if (kind != svn_node_dir)
{
/* If the node specified by the path is NOT present, then it cannot
Modified: subversion/branches/issue-3975/subversion/libsvn_wc/workqueue.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/libsvn_wc/workqueue.c?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/libsvn_wc/workqueue.c (original)
+++ subversion/branches/issue-3975/subversion/libsvn_wc/workqueue.c Wed Aug 17 18:25:07 2011
@@ -733,10 +733,7 @@ run_file_install(svn_wc__db_t *db,
cancel_func, cancel_baton,
scratch_pool));
- /* ### post-commit feature: avoid overwrite if same as working file. */
-
/* All done. Move the file into place. */
- /* ### fix this. we should delay the rename. */
{
svn_error_t *err;
@@ -750,7 +747,7 @@ run_file_install(svn_wc__db_t *db,
{
svn_error_t *err2;
- err2 = svn_io_make_dir_recursively(svn_dirent_dirname(dst_abspath,
+ err2 = svn_io_make_dir_recursively(svn_dirent_dirname(local_abspath,
scratch_pool),
scratch_pool);
Modified: subversion/branches/issue-3975/subversion/svn/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/issue-3975/subversion/svn/main.c?rev=1158860&r1=1158859&r2=1158860&view=diff
==============================================================================
--- subversion/branches/issue-3975/subversion/svn/main.c (original)
+++ subversion/branches/issue-3975/subversion/svn/main.c Wed Aug 17 18:25:07 2011
@@ -1184,7 +1184,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
"usage: revert PATH...\n"
"\n"
" Note: this subcommand does not require network access, and resolves\n"
- " any conflicted states. However, it does not restore removed directories.\n"),
+ " any conflicted states.\n"),
{opt_targets, 'R', opt_depth, 'q', opt_changelist} },
{ "status", svn_cl__status, {"stat", "st"}, N_