You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by gb...@apache.org on 2013/11/05 11:40:39 UTC
svn commit: r1538929 [1/2] - in
/subversion/branches/invoke-diff-cmd-feature: ./
subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversion/javahl/
subversion/bindings/javahl/src/org/apache/subversion/javahl/util/
subversio...
Author: gbg
Date: Tue Nov 5 10:40:38 2013
New Revision: 1538929
URL: http://svn.apache.org/r1538929
Log:
On the invoke-merge-feature branch: trunk revision 1538925 merged into branch revision 1535411.
Added:
subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_PropLib.cpp
- copied unchanged from r1538927, subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_PropLib.cpp
subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/PropLib.java
- copied unchanged from r1538927, subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/PropLib.java
subversion/branches/invoke-diff-cmd-feature/trunk/
- copied from r1537600, subversion/trunk/
Modified:
subversion/branches/invoke-diff-cmd-feature/ (props changed)
subversion/branches/invoke-diff-cmd-feature/build.conf
subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java
subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java
subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java
subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_repos_private.h
subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_subr_private.h
subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_repos.h
subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_client/iprops.c
subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/authz.c
subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/config_pool.c
subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/repos.c
subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config.c
subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config_file.c
subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config_impl.h
subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/conflicts.c
subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/diff.h
subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/diff_local.c
subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc-queries.sql
subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db.c
subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db_update_move.c
subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/diff_tests.py
subversion/branches/invoke-diff-cmd-feature/subversion/tests/libsvn_repos/repos-test.c
subversion/branches/invoke-diff-cmd-feature/subversion/tests/libsvn_subr/ (props changed)
subversion/branches/invoke-diff-cmd-feature/subversion/tests/libsvn_wc/op-depth-test.c
subversion/branches/invoke-diff-cmd-feature/subversion/tests/libsvn_wc/utils.c
subversion/branches/invoke-diff-cmd-feature/subversion/tests/svn_test_main.c
Propchange: subversion/branches/invoke-diff-cmd-feature/
------------------------------------------------------------------------------
Merged /subversion/trunk:r1538071-1538927
Modified: subversion/branches/invoke-diff-cmd-feature/build.conf
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/build.conf?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/build.conf (original)
+++ subversion/branches/invoke-diff-cmd-feature/build.conf Tue Nov 5 10:40:38 2013
@@ -79,6 +79,7 @@ private-built-includes =
subversion/bindings/javahl/include/org_apache_subversion_javahl_util_ConfigImpl_Category.h
subversion/bindings/javahl/include/org_apache_subversion_javahl_util_ConfigLib.h
subversion/bindings/javahl/include/org_apache_subversion_javahl_util_DiffLib.h
+ subversion/bindings/javahl/include/org_apache_subversion_javahl_util_PropLib.h
subversion/bindings/javahl/include/org_apache_subversion_javahl_util_TunnelChannel.h
subversion/bindings/javahl/include/org_apache_subversion_javahl_util_RequestChannel.h
subversion/bindings/javahl/include/org_apache_subversion_javahl_util_ResponseChannel.h
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java Tue Nov 5 10:40:38 2013
@@ -24,8 +24,10 @@
package org.apache.subversion.javahl;
import org.apache.subversion.javahl.callback.*;
+import org.apache.subversion.javahl.types.*;
import org.apache.subversion.javahl.util.*;
+import java.io.InputStream;
import java.io.OutputStream;
public class SVNUtil
@@ -281,4 +283,61 @@ public class SVNUtil
conflictLatest, conflictSeparator,
conflictStyle, resultStream);
}
+
+ //
+ // Property validation and parsing
+ //
+
+ /**
+ * Validate the value of an <code>svn:</code> property on file or
+ * directory and return a canonical representation of its value.
+ * @param name The name of the property (must be a valid svn: property)
+ * @param value The property's value
+ * @param path The path or URL of the file or directory that
+ * owns the property; only used for error messages
+ * @param kind The node kind of the file or dir that owns the property
+ * @param mimeType If <code>kind</code> is {@link NodeKind.file}, this is
+ * tye file's mime-type, used for extra validation for the
+ * <code>svn:eol-style</code> property. If it is <code>null</code>,
+ * the extra validation will be skipped.
+ * @return a canonicalized representation of the property value
+ * @see http://subversion.apache.org/docs/api/latest/group__svn__wc__properties.html#ga83296313ec59cc825176224ac8282ec2
+ */
+ public static byte[] canonicalizeNodeProperty(
+ String name, byte[] value, String path, NodeKind kind,
+ String mimeType)
+ throws ClientException
+ {
+ return new PropLib().canonicalizeNodeProperty(
+ name, value, path, kind, mimeType, null);
+ }
+
+ /**
+ * Validate the value of an <code>svn:</code> property on file or
+ * directory and return a canonical representation of its value.
+ * @param name The name of the property (must be a valid svn: property)
+ * @param value The property's value
+ * @param path The path or URL of the file or directory that
+ * owns the property; only used for error messages
+ * @param kind The node kind of the file or dir that owns the property
+ * @param mimeType If <code>kind</code> is {@link NodeKind.file}, this is
+ * tye file's mime-type, used for extra validation for the
+ * <code>svn:eol-style</code> property. If it is <code>null</code>,
+ * the extra validation will be skipped.
+ * @param fileContents A stream with the file's contents. Only used
+ * to check for line-ending consistency when validating the
+ * <code>svn:eol-style</code> property, and only when
+ * <code>kind</code> is {@link NodeKind.file} and
+ * <code>mimeType</code> is not <code>null</code>.
+ * @return a canonicalized representation of the property value
+ * @see http://subversion.apache.org/docs/api/latest/group__svn__wc__properties.html#ga83296313ec59cc825176224ac8282ec2
+ */
+ public static byte[] canonicalizeNodeProperty(
+ String name, byte[] value, String path, NodeKind kind,
+ String mimeType, InputStream fileContents)
+ throws ClientException
+ {
+ return new PropLib().canonicalizeNodeProperty(
+ name, value, path, kind, mimeType, fileContents);
+ }
}
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java Tue Nov 5 10:40:38 2013
@@ -43,7 +43,7 @@ public class DiffLib
NativeResources.loadNativeLibrary();
}
- /** @see ISVNUtil.fileDiff */
+ /** @see SVNUtil.fileDiff */
public boolean fileDiff(String originalFile,
String modifiedFile,
SVNUtil.DiffOptions diffOptions,
@@ -88,7 +88,7 @@ public class DiffLib
OutputStream resultStream)
throws ClientException;
- /** @see ISVNUtil.fileMerge */
+ /** @see SVNUtil.fileMerge */
public boolean fileMerge(String originalFile,
String modifiedFile,
String latestFile,
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java Tue Nov 5 10:40:38 2013
@@ -23,7 +23,10 @@
package org.apache.subversion.javahl;
+import org.apache.subversion.javahl.types.NodeKind;
+
import java.io.File;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
@@ -135,4 +138,54 @@ public class UtilTests extends SVNTests
"\nN-3\nN-2\nN-1\nN\n").getBytes();
assertTrue(Arrays.equals(expected, result.toByteArray()));
}
+
+ public void testValidateProp() throws Throwable
+ {
+ File temp = File.createTempFile("propcheck", ".file", localTmp);
+ FileOutputStream out = new FileOutputStream(temp);
+ out.write("normal text\n".getBytes());
+ out.close();
+
+ byte[] prop = SVNUtil.canonicalizeNodeProperty(
+ "svn:eol-style", " native".getBytes(),
+ "propcheck.file", NodeKind.file,
+ "text/plain");
+ assertEquals("native", new String(prop));
+
+ prop = SVNUtil.canonicalizeNodeProperty(
+ "svn:eol-style", " native ".getBytes(),
+ "propcheck.file", NodeKind.file,
+ "text/plain", new FileInputStream(temp));
+ assertEquals("native", new String(prop));
+
+ boolean caught_exception = false;
+ try {
+ prop = SVNUtil.canonicalizeNodeProperty(
+ "svn:eol-style", " weird ".getBytes(),
+ "propcheck.file", NodeKind.file,
+ "text/plain");
+ } catch (ClientException ex) {
+ assertEquals("Unrecognized line ending style",
+ ex.getAllMessages().get(0).getMessage());
+ caught_exception = true;
+ }
+ assertTrue(caught_exception);
+
+ out = new FileOutputStream(temp);
+ out.write("inconsistent\r\ntext\n".getBytes());
+ out.close();
+
+ caught_exception = false;
+ try {
+ prop = SVNUtil.canonicalizeNodeProperty(
+ "svn:eol-style", " native ".getBytes(),
+ "propcheck.file", NodeKind.file,
+ "text/plain", new FileInputStream(temp));
+ } catch (ClientException ex) {
+ assertEquals("Inconsistent line ending style",
+ ex.getAllMessages().get(2).getMessage());
+ caught_exception = true;
+ }
+ assertTrue(caught_exception);
+ }
}
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_repos_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_repos_private.h?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_repos_private.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_repos_private.h Tue Nov 5 10:40:38 2013
@@ -134,7 +134,8 @@ svn_repos__replay_ev2(svn_fs_root_t *roo
*
* If PATH cannot be parsed as a config file then an error is returned. The
* contents of CFG_P is then undefined. If MUST_EXIST is TRUE, a missing
- * authz file is also an error.
+ * authz file is also an error. The CASE_SENSITIVE controls the lookup
+ * behavior for section and option names alike.
*
* REPOS_ROOT points at the root of the repos you are
* going to apply the authz against, can be NULL if you are sure that you
@@ -143,6 +144,7 @@ svn_error_t *
svn_repos__retrieve_config(svn_config_t **cfg_p,
const char *path,
svn_boolean_t must_exist,
+ svn_boolean_t case_sensitive,
apr_pool_t *pool);
/**
@@ -172,6 +174,15 @@ svn_repos__config_pool_create(svn_repos_
* CONFIG_POOL will store the configuration and make further callers use
* the same instance if the content matches.
*
+ * If MUST_EXIST is TRUE, a missing config file is also an error, *CFG
+ * is otherwise simply NULL. The CASE_SENSITIVE controls the lookup
+ * behavior for section and option names alike.
+ *
+ * PREFERRED_REPOS is only used if it is not NULL and PATH is a URL.
+ * If it matches the URL, access the repository through this object
+ * instead of creating a new repo instance. Note that this might not
+ * return the latest content.
+ *
* POOL determines the minimum lifetime of *CFG.
*
* Note: The read-only behavior is not enforced, yet.
@@ -180,6 +191,9 @@ svn_error_t *
svn_repos__config_pool_get(svn_config_t **cfg,
svn_repos__config_pool_t *config_pool,
const char *path,
+ svn_boolean_t must_exist,
+ svn_boolean_t case_sensitive,
+ svn_repos_t *preferred_repos,
apr_pool_t *pool);
/** @} */
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_subr_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_subr_private.h?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_subr_private.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/include/private/svn_subr_private.h Tue Nov 5 10:40:38 2013
@@ -485,6 +485,16 @@ svn_config__is_expanded(svn_config_t *cf
const char *section,
const char *option);
+/* Return a shallow copy of SCR in POOL. If SRC is read-only, different
+ * shallow copies may be used from different threads.
+ *
+ * Any single r/o svn_config_t or shallow copy is not thread-safe because
+ * it contains shared buffers for tempoary data.
+ */
+svn_config_t *
+svn_config__shallow_copy(svn_config_t *src,
+ apr_pool_t *pool);
+
/** @} */
#ifdef __cplusplus
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_repos.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_repos.h?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_repos.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/include/svn_repos.h Tue Nov 5 10:40:38 2013
@@ -558,6 +558,13 @@ svn_repos_capabilities(apr_hash_t **capa
svn_fs_t *
svn_repos_fs(svn_repos_t *repos);
+/** Return the type of filesystem associated with repository object
+ * @a repos allocated in @a pool.
+ *
+ * @since New in 1.9.
+ */
+const char *
+svn_repos_fs_type(svn_repos_t *repos, apr_pool_t *pool);
/** Make a hot copy of the Subversion repository found at @a src_path
* to @a dst_path.
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_client/iprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_client/iprops.c?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_client/iprops.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_client/iprops.c Tue Nov 5 10:40:38 2013
@@ -244,6 +244,8 @@ svn_client__get_inheritable_props(apr_ha
const char *old_session_url;
svn_error_t *err;
+ *wcroot_iprops = NULL;
+
if (!SVN_IS_VALID_REVNUM(revision))
return SVN_NO_ERROR;
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/authz.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/authz.c?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/authz.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/authz.c Tue Nov 5 10:40:38 2013
@@ -773,13 +773,17 @@ authz_validate(svn_authz_t *authz, apr_p
*
* If DIRENT cannot be parsed as a config file then an error is returned. The
* contents of CFG_P is then undefined. If MUST_EXIST is TRUE, a missing
- * authz file is also an error.
+ * authz file is also an error. The CASE_SENSITIVE controls the lookup
+ * behavior for section and option names alike.
*
* SCRATCH_POOL will be used for temporary allocations. */
static svn_error_t *
-authz_retrieve_config_repo(svn_config_t **cfg_p, const char *dirent,
- svn_boolean_t must_exist,
- apr_pool_t *result_pool, apr_pool_t *scratch_pool)
+authz_retrieve_config_repo(svn_config_t **cfg_p,
+ const char *dirent,
+ svn_boolean_t must_exist,
+ svn_boolean_t case_sensitive,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
svn_error_t *err;
svn_repos_t *repos;
@@ -826,7 +830,8 @@ authz_retrieve_config_repo(svn_config_t
{
if (!must_exist)
{
- SVN_ERR(svn_config_create2(cfg_p, TRUE, TRUE, result_pool));
+ SVN_ERR(svn_config_create2(cfg_p, case_sensitive, case_sensitive,
+ result_pool));
return SVN_NO_ERROR;
}
else
@@ -844,7 +849,8 @@ authz_retrieve_config_repo(svn_config_t
}
SVN_ERR(svn_fs_file_contents(&contents, root, fs_path, scratch_pool));
- err = svn_config_parse(cfg_p, contents, TRUE, TRUE, result_pool);
+ err = svn_config_parse(cfg_p, contents, case_sensitive, case_sensitive,
+ result_pool);
/* Add the URL to the error stack since the parser doesn't have it. */
if (err != SVN_NO_ERROR)
@@ -856,8 +862,11 @@ authz_retrieve_config_repo(svn_config_t
}
svn_error_t *
-svn_repos__retrieve_config(svn_config_t **cfg_p, const char *path,
- svn_boolean_t must_exist, apr_pool_t *pool)
+svn_repos__retrieve_config(svn_config_t **cfg_p,
+ const char *path,
+ svn_boolean_t must_exist,
+ svn_boolean_t case_sensitive,
+ apr_pool_t *pool)
{
if (svn_path_is_url(path))
{
@@ -868,8 +877,8 @@ svn_repos__retrieve_config(svn_config_t
err = svn_uri_get_dirent_from_file_url(&dirent, path, scratch_pool);
if (err == SVN_NO_ERROR)
- err = authz_retrieve_config_repo(cfg_p, dirent, must_exist, pool,
- scratch_pool);
+ err = authz_retrieve_config_repo(cfg_p, dirent, must_exist,
+ case_sensitive, pool, scratch_pool);
/* Close the repos and streams we opened. */
svn_pool_destroy(scratch_pool);
@@ -879,7 +888,8 @@ svn_repos__retrieve_config(svn_config_t
else
{
/* Outside of repo file or Windows registry*/
- SVN_ERR(svn_config_read3(cfg_p, path, must_exist, TRUE, TRUE, pool));
+ SVN_ERR(svn_config_read3(cfg_p, path, must_exist, case_sensitive,
+ case_sensitive, pool));
}
return SVN_NO_ERROR;
@@ -930,9 +940,11 @@ svn_repos__authz_read(svn_authz_t **auth
/* Load the authz file */
if (accept_urls)
- SVN_ERR(svn_repos__retrieve_config(&authz->cfg, path, must_exist, pool));
+ SVN_ERR(svn_repos__retrieve_config(&authz->cfg, path, must_exist, TRUE,
+ pool));
else
- SVN_ERR(svn_config_read3(&authz->cfg, path, must_exist, TRUE, TRUE, pool));
+ SVN_ERR(svn_config_read3(&authz->cfg, path, must_exist, TRUE, TRUE,
+ pool));
if (groups_path)
{
@@ -942,7 +954,7 @@ svn_repos__authz_read(svn_authz_t **auth
/* Load the groups file */
if (accept_urls)
SVN_ERR(svn_repos__retrieve_config(&groups_cfg, groups_path,
- must_exist, pool));
+ must_exist, TRUE, pool));
else
SVN_ERR(svn_config_read3(&groups_cfg, groups_path, must_exist,
TRUE, TRUE, pool));
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/config_pool.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/config_pool.c?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/config_pool.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/config_pool.c Tue Nov 5 10:40:38 2013
@@ -54,8 +54,14 @@ typedef struct config_ref_t
* This is a SHA1 checksum of the parsed textual representation of CFG. */
svn_checksum_t *key;
- /* Parsed and expanded configuration */
- svn_config_t *cfg;
+ /* Parsed and expanded configuration. At least one of the following
+ * must not be NULL. */
+
+ /* Case-sensitive config. May be NULL */
+ svn_config_t *cs_cfg;
+
+ /* Case-insensitive config. May be NULL */
+ svn_config_t *ci_cfg;
/* private pool. This instance and its other members got allocated in it.
* Will be destroyed when this instance is cleaned up. */
@@ -217,21 +223,27 @@ config_ref_cleanup(void *baton)
}
/* Return an automatic reference to the CFG member in CONFIG that will be
- * released when POOL gets cleaned up.
+ * released when POOL gets cleaned up. CASE_SENSITIVE controls option and
+ * section name matching.
*/
static svn_config_t *
return_config_ref(config_ref_t *config,
+ svn_boolean_t case_sensitive,
apr_pool_t *pool)
{
if (svn_atomic_inc(&config->ref_count) == 0)
svn_atomic_inc(&config->config_pool->used_config_count);
+
apr_pool_cleanup_register(pool, config, config_ref_cleanup,
apr_pool_cleanup_null);
- return config->cfg;
+ return svn_config__shallow_copy(case_sensitive ? config->cs_cfg
+ : config->ci_cfg,
+ pool);
}
/* Set *CFG to the configuration with a parsed textual matching CHECKSUM.
* Set *CFG to NULL if no such config can be found in CONFIG_POOL.
+ * CASE_SENSITIVE controls option and section name matching.
*
* RESULT_POOL determines the lifetime of the returned reference.
*
@@ -241,12 +253,15 @@ static svn_error_t *
config_by_checksum(svn_config_t **cfg,
svn_repos__config_pool_t *config_pool,
svn_checksum_t *checksum,
+ svn_boolean_t case_sensitive,
apr_pool_t *result_pool)
{
config_ref_t *config_ref = apr_hash_get(config_pool->configs,
checksum->digest,
svn_checksum_size(checksum));
- *cfg = config_ref ? return_config_ref(config_ref, result_pool) : NULL;
+ *cfg = config_ref
+ ? return_config_ref(config_ref, case_sensitive, result_pool)
+ : NULL;
return SVN_NO_ERROR;
}
@@ -283,6 +298,7 @@ remove_unused_configs(svn_repos__config_
/* Cache config_ref* in CONFIG_POOL and return a reference to it in *CFG.
* RESULT_POOL determines the lifetime of that reference.
+ * CASE_SENSITIVE controls option and section name matching.
*
* Requires external serialization on CONFIG_POOL.
*/
@@ -290,6 +306,7 @@ static svn_error_t *
config_add(svn_config_t **cfg,
svn_repos__config_pool_t *config_pool,
config_ref_t *config_ref,
+ svn_boolean_t case_sensitive,
apr_pool_t *result_pool)
{
config_ref_t *config = apr_hash_get(config_ref->config_pool->configs,
@@ -297,8 +314,23 @@ config_add(svn_config_t **cfg,
svn_checksum_size(config_ref->key));
if (config)
{
- /* entry already exists (e.g. race condition)
- * Destroy the new one and return a reference to the existing one
+ /* entry already exists (e.g. race condition) */
+
+ /* Maybe, we created a variant with different case sensitivity? */
+ if (case_sensitive && config->cs_cfg == NULL)
+ {
+ SVN_ERR(svn_config_dup(&config->cs_cfg, config_ref->cs_cfg,
+ config->pool));
+ svn_config__set_read_only(config->cs_cfg, config_ref->pool);
+ }
+ else if (!case_sensitive && config->ci_cfg == NULL)
+ {
+ SVN_ERR(svn_config_dup(&config->ci_cfg, config_ref->ci_cfg,
+ config->pool));
+ svn_config__set_read_only(config->ci_cfg, config_ref->pool);
+ }
+
+ /* Destroy the new one and return a reference to the existing one
* because the existing one may already have references on it.
*/
svn_pool_destroy(config_ref->pool);
@@ -320,14 +352,14 @@ config_add(svn_config_t **cfg,
config_ref);
}
- *cfg = return_config_ref(config_ref, result_pool);
+ *cfg = return_config_ref(config_ref, case_sensitive, result_pool);
return SVN_NO_ERROR;
}
/* Set *CFG to the configuration passed in as text in CONTENTS. If no such
* configuration exists in CONFIG_POOL, yet, parse CONTENTS and cache the
- * result.
+ * result. CASE_SENSITIVE controls option and section name matching.
*
* RESULT_POOL determines the lifetime of the returned reference and
* SCRATCH_POOL is being used for temporary allocations.
@@ -336,6 +368,7 @@ static svn_error_t *
auto_parse(svn_config_t **cfg,
svn_repos__config_pool_t *config_pool,
svn_stringbuf_t *contents,
+ svn_boolean_t case_sensitive,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -353,7 +386,7 @@ auto_parse(svn_config_t **cfg,
*cfg = NULL;
SVN_MUTEX__WITH_LOCK(config_pool->mutex,
config_by_checksum(cfg, config_pool, checksum,
- result_pool));
+ case_sensitive, result_pool));
if (*cfg)
return SVN_NO_ERROR;
@@ -369,16 +402,20 @@ auto_parse(svn_config_t **cfg,
config_ref->pool = cfg_pool;
config_ref->ref_count = 0;
- SVN_ERR(svn_config_parse(&config_ref->cfg,
+ SVN_ERR(svn_config_parse(case_sensitive ? &config_ref->cs_cfg
+ : &config_ref->ci_cfg,
svn_stream_from_stringbuf(contents, scratch_pool),
- TRUE, TRUE, cfg_pool));
+ case_sensitive, case_sensitive, cfg_pool));
/* switch config data to r/o mode to guarantee thread-safe access */
- svn_config__set_read_only(config_ref->cfg, cfg_pool);
+ svn_config__set_read_only(case_sensitive ? config_ref->cs_cfg
+ : config_ref->ci_cfg,
+ cfg_pool);
/* add config in pool, handle loads races and return the right config */
SVN_MUTEX__WITH_LOCK(config_pool->mutex,
- config_add(cfg, config_pool, config_ref, result_pool));
+ config_add(cfg, config_pool, config_ref,
+ case_sensitive, result_pool));
return SVN_NO_ERROR;
}
@@ -439,7 +476,9 @@ add_checksum(svn_repos__config_pool_t *c
}
/* Set *CFG to the configuration stored in URL@HEAD and cache it in
- * CONFIG_POOL. ### Always returns a NULL CFG.
+ * CONFIG_POOL. ### Always returns a NULL CFG. CASE_SENSITIVE controls
+ * option and section name matching. If PREFERRED_REPOS is given,
+ * use that if it also matches URL.
*
* RESULT_POOL determines the lifetime of the returned reference and
* SCRATCH_POOL is being used for temporary allocations.
@@ -448,10 +487,12 @@ static svn_error_t *
find_repos_config(svn_config_t **cfg,
svn_repos__config_pool_t *config_pool,
const char *url,
+ svn_boolean_t case_sensitive,
+ svn_repos_t *preferred_repos,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
- svn_repos_t *repos;
+ svn_repos_t *repos = NULL;
svn_fs_t *fs;
svn_fs_root_t *root;
svn_revnum_t youngest_rev;
@@ -466,11 +507,29 @@ find_repos_config(svn_config_t **cfg,
*cfg = NULL;
SVN_ERR(svn_uri_get_dirent_from_file_url(&dirent, url, scratch_pool));
- /* Search for a repository in the full path. */
- repos_root_dirent = svn_repos_find_root_path(dirent, scratch_pool);
+ /* maybe we can use the preferred repos instance instead of creating a
+ * new one */
+ if (preferred_repos)
+ {
+ repos_root_dirent = svn_repos_path(preferred_repos, scratch_pool);
+ if (!svn_dirent_is_absolute(repos_root_dirent))
+ SVN_ERR(svn_dirent_get_absolute(&repos_root_dirent,
+ repos_root_dirent,
+ scratch_pool));
+
+ if (svn_dirent_is_ancestor(repos_root_dirent, dirent))
+ repos = preferred_repos;
+ }
+
+ /* open repos if no suitable preferred repos was provided. */
+ if (!repos)
+ {
+ /* Search for a repository in the full path. */
+ repos_root_dirent = svn_repos_find_root_path(dirent, scratch_pool);
- /* Attempt to open a repository at repos_root_dirent. */
- SVN_ERR(svn_repos_open2(&repos, repos_root_dirent, NULL, scratch_pool));
+ /* Attempt to open a repository at repos_root_dirent. */
+ SVN_ERR(svn_repos_open2(&repos, repos_root_dirent, NULL, scratch_pool));
+ }
fs_path = &dirent[strlen(repos_root_dirent)];
@@ -487,7 +546,7 @@ find_repos_config(svn_config_t **cfg,
if (checksum)
SVN_MUTEX__WITH_LOCK(config_pool->mutex,
config_by_checksum(cfg, config_pool, checksum,
- result_pool));
+ case_sensitive, result_pool));
/* not parsed, yet? */
if (!*cfg)
@@ -505,8 +564,8 @@ find_repos_config(svn_config_t **cfg,
(apr_size_t)length, scratch_pool));
/* handle it like ordinary file contents and cache it */
- SVN_ERR(auto_parse(cfg, config_pool, contents, result_pool,
- scratch_pool));
+ SVN_ERR(auto_parse(cfg, config_pool, contents, case_sensitive,
+ result_pool, scratch_pool));
}
/* store the (path,rev) -> checksum mapping as well */
@@ -520,7 +579,7 @@ find_repos_config(svn_config_t **cfg,
/* Set *CFG to the configuration cached in CONFIG_POOL for URL. If no
* suitable config has been cached or if it is potentially outdated, set
- * *CFG to NULL.
+ * *CFG to NULL. CASE_SENSITIVE controls option and section name matching.
*
* RESULT_POOL determines the lifetime of the returned reference and
* SCRATCH_POOL is being used for temporary allocations.
@@ -531,6 +590,7 @@ static svn_error_t *
config_by_url(svn_config_t **cfg,
svn_repos__config_pool_t *config_pool,
const char *url,
+ svn_boolean_t case_sensitive,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -541,7 +601,7 @@ config_by_url(svn_config_t **cfg,
/* hash lookup url -> sha1 -> config */
in_repo_config_t *config = svn_hash_gets(config_pool->in_repo_configs, url);
- *cfg = 0;
+ *cfg = NULL;
if (config)
config_ref = apr_hash_get(config_pool->configs,
config->key->digest,
@@ -549,6 +609,12 @@ config_by_url(svn_config_t **cfg,
if (!config_ref)
return SVN_NO_ERROR;
+ /* available with the desired case sensitivity? */
+ if (case_sensitive && config_ref->cs_cfg == NULL)
+ return SVN_NO_ERROR;
+ if (!case_sensitive && config_ref->ci_cfg == NULL)
+ return SVN_NO_ERROR;
+
/* found *some* configuration.
* Verify that it is still current. Will fail for BDB repos. */
err = svn_stringbuf_from_file2(&contents,
@@ -561,7 +627,7 @@ config_by_url(svn_config_t **cfg,
if (err)
svn_error_clear(err);
else if (current == config->revision)
- *cfg = return_config_ref(config_ref, result_pool);
+ *cfg = return_config_ref(config_ref, case_sensitive, result_pool);
return SVN_NO_ERROR;
}
@@ -600,6 +666,9 @@ svn_error_t *
svn_repos__config_pool_get(svn_config_t **cfg,
svn_repos__config_pool_t *config_pool,
const char *path,
+ svn_boolean_t must_exist,
+ svn_boolean_t case_sensitive,
+ svn_repos_t *preferred_repos,
apr_pool_t *pool)
{
svn_error_t *err = SVN_NO_ERROR;
@@ -610,18 +679,24 @@ svn_repos__config_pool_get(svn_config_t
/* Read config file from repository.
* Attempt a quick lookup first. */
SVN_MUTEX__WITH_LOCK(config_pool->mutex,
- config_by_url(cfg, config_pool, path, pool,
+ config_by_url(cfg, config_pool, path,
+ case_sensitive, pool,
scratch_pool));
if (*cfg)
- return SVN_NO_ERROR;
+ {
+ svn_pool_destroy(scratch_pool);
+ return SVN_NO_ERROR;
+ }
/* Read and cache the configuration. This may fail. */
- err = find_repos_config(cfg, config_pool, path, pool, scratch_pool);
+ err = find_repos_config(cfg, config_pool, path, case_sensitive,
+ preferred_repos, pool, scratch_pool);
if (err || !*cfg)
{
/* let the standard implementation handle all the difficult cases */
svn_error_clear(err);
- err = svn_repos__retrieve_config(cfg, path, TRUE, pool);
+ err = svn_repos__retrieve_config(cfg, path, must_exist,
+ case_sensitive, pool);
}
}
else
@@ -633,12 +708,14 @@ svn_repos__config_pool_get(svn_config_t
{
/* let the standard implementation handle all the difficult cases */
svn_error_clear(err);
- err = svn_config_read3(cfg, path, TRUE, TRUE, TRUE, pool);
+ err = svn_config_read3(cfg, path, must_exist, case_sensitive,
+ case_sensitive, pool);
}
else
{
/* parsing and caching will always succeed */
- err = auto_parse(cfg, config_pool, contents, pool, scratch_pool);
+ err = auto_parse(cfg, config_pool, contents, case_sensitive,
+ pool, scratch_pool);
}
}
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/repos.c?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_repos/repos.c Tue Nov 5 10:40:38 2013
@@ -1796,6 +1796,11 @@ svn_repos_fs(svn_repos_t *repos)
return repos->fs;
}
+const char *
+svn_repos_fs_type(svn_repos_t *repos, apr_pool_t *pool)
+{
+ return apr_pstrdup(pool, repos->fs_type);
+}
/* For historical reasons, for the Berkeley DB backend, this code uses
* repository locking, which is motivated by the need to support the
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config.c?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config.c Tue Nov 5 10:40:38 2013
@@ -703,11 +703,11 @@ svn_config_get(svn_config_t *cfg, const
}
else
/* before attempting to expand an option, check for the placeholder.
- * If none is there, there is no point in calling expand_option_value.
+ * If there is none, there is no point in calling expand_option_value.
*/
if (default_value && strchr(default_value, '%'))
{
- apr_pool_t *tmp_pool = svn_pool_create(cfg->x_pool);
+ apr_pool_t *tmp_pool = svn_pool_create(cfg->pool);
const char *x_default;
expand_option_value(cfg, sec, default_value, &x_default, tmp_pool);
if (x_default)
@@ -985,7 +985,7 @@ svn_config_enumerate(svn_config_t *cfg,
if (sec == NULL)
return 0;
- subpool = svn_pool_create(cfg->x_pool);
+ subpool = svn_pool_create(cfg->pool);
count = 0;
for (opt_ndx = apr_hash_first(subpool, sec->options);
opt_ndx != NULL;
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config_file.c?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config_file.c Tue Nov 5 10:40:38 2013
@@ -469,6 +469,26 @@ svn_config__is_read_only(svn_config_t *c
return cfg->read_only;
}
+svn_config_t *
+svn_config__shallow_copy(svn_config_t *src,
+ apr_pool_t *pool)
+{
+ svn_config_t *cfg = apr_palloc(pool, sizeof(*cfg));
+
+ cfg->sections = src->sections;
+ cfg->pool = pool;
+
+ /* r/o configs are fully expanded and don't need the x_pool anymore */
+ cfg->x_pool = src->read_only ? NULL : svn_pool_create(pool);
+ cfg->x_values = src->x_values;
+ cfg->tmp_key = svn_stringbuf_create_empty(pool);
+ cfg->tmp_value = svn_stringbuf_create_empty(pool);
+ cfg->section_names_case_sensitive = src->section_names_case_sensitive;
+ cfg->option_names_case_sensitive = src->option_names_case_sensitive;
+ cfg->read_only = src->read_only;
+
+ return cfg;
+}
svn_error_t *
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config_impl.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config_impl.h?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config_impl.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_subr/config_impl.h Tue Nov 5 10:40:38 2013
@@ -47,7 +47,8 @@ struct svn_config_t
/* Table of cfg_section_t's. */
apr_hash_t *sections;
- /* Pool for hash tables, table entries and unexpanded values */
+ /* Pool for hash tables, table entries and unexpanded values.
+ Also, parent pool for temporary pools. */
apr_pool_t *pool;
/* Pool for expanded values -- this is separate, so that we can
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/conflicts.c?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/conflicts.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/conflicts.c Tue Nov 5 10:40:38 2013
@@ -2709,12 +2709,17 @@ resolve_prop_conflict_on_node(svn_boolea
* existed and was resolved, set *DID_RESOLVE to TRUE, else set it to FALSE.
*
* It is not an error if there is no tree conflict.
+ *
+ * If the conflict can't be resolved yet because another tree conflict is
+ * blocking a storage location, store the tree conflict in the RESOLVE_LATER
+ * hash.
*/
static svn_error_t *
resolve_tree_conflict_on_node(svn_boolean_t *did_resolve,
svn_wc__db_t *db,
const char *local_abspath,
svn_wc_conflict_choice_t conflict_choice,
+ apr_hash_t *resolve_later,
svn_wc_notify_func2_t notify_func,
void *notify_baton,
svn_cancel_func_t cancel_func,
@@ -2748,6 +2753,7 @@ resolve_tree_conflict_on_node(svn_boolea
if (operation == svn_wc_operation_update
|| operation == svn_wc_operation_switch)
{
+ svn_error_t *err;
if (reason == svn_wc_conflict_reason_deleted ||
reason == svn_wc_conflict_reason_replaced)
{
@@ -2766,10 +2772,26 @@ resolve_tree_conflict_on_node(svn_boolea
* this directory, and leave this directory deleted.
* The newly conflicted moved-away children will be updated
* if they are resolved with 'mine_conflict' as well. */
- SVN_ERR(svn_wc__db_resolve_delete_raise_moved_away(
+ err = svn_wc__db_resolve_delete_raise_moved_away(
db, local_abspath, notify_func, notify_baton,
- scratch_pool));
- *did_resolve = TRUE;
+ scratch_pool);
+
+ if (err)
+ {
+ const char *dup_abspath;
+ if (err && err->apr_err != SVN_ERR_WC_OBSTRUCTED_UPDATE)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+ dup_abspath = apr_pstrdup(apr_hash_pool_get(resolve_later),
+ local_abspath);
+
+ svn_hash_sets(resolve_later, dup_abspath, dup_abspath);
+
+ return SVN_NO_ERROR; /* Retry after other conflicts */
+ }
+ else
+ *did_resolve = TRUE;
}
else
return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
@@ -2789,12 +2811,28 @@ resolve_tree_conflict_on_node(svn_boolea
* move (theirs-conflict). */
if (conflict_choice == svn_wc_conflict_choose_mine_conflict)
{
- SVN_ERR(svn_wc__db_update_moved_away_conflict_victim(
+ err = svn_wc__db_update_moved_away_conflict_victim(
db, local_abspath,
notify_func, notify_baton,
cancel_func, cancel_baton,
- scratch_pool));
- *did_resolve = TRUE;
+ scratch_pool);
+
+ if (err)
+ {
+ const char *dup_abspath;
+ if (err && err->apr_err != SVN_ERR_WC_OBSTRUCTED_UPDATE)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+ dup_abspath = apr_pstrdup(apr_hash_pool_get(resolve_later),
+ local_abspath);
+
+ svn_hash_sets(resolve_later, dup_abspath, dup_abspath);
+
+ return SVN_NO_ERROR; /* Retry after other conflicts */
+ }
+ else
+ *did_resolve = TRUE;
}
else if (conflict_choice == svn_wc_conflict_choose_merged)
{
@@ -2822,20 +2860,27 @@ resolve_tree_conflict_on_node(svn_boolea
}
}
- if (! *did_resolve && conflict_choice != svn_wc_conflict_choose_merged)
+ if (! *did_resolve)
{
- /* For other tree conflicts, there is no way to pick
- * theirs-full or mine-full, etc. Throw an error if the
- * user expects us to be smarter than we really are. */
- return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
- NULL,
- _("Tree conflict can only be "
- "resolved to 'working' state; "
- "'%s' not resolved"),
- svn_dirent_local_style(local_abspath,
- scratch_pool));
+ if (conflict_choice != svn_wc_conflict_choose_merged)
+ {
+ /* For other tree conflicts, there is no way to pick
+ * theirs-full or mine-full, etc. Throw an error if the
+ * user expects us to be smarter than we really are. */
+ return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE,
+ NULL,
+ _("Tree conflict can only be "
+ "resolved to 'working' state; "
+ "'%s' not resolved"),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+ }
+ else
+ *did_resolve = TRUE;
}
+ SVN_ERR_ASSERT(*did_resolve);
+
SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath, FALSE, FALSE, TRUE,
NULL, scratch_pool));
SVN_ERR(svn_wc__wq_run(db, local_abspath, cancel_func, cancel_baton,
@@ -2888,6 +2933,7 @@ struct conflict_status_walker_baton
void *cancel_baton;
svn_wc_notify_func2_t notify_func;
void *notify_baton;
+ apr_hash_t *resolve_later;
};
/* Implements svn_wc_status4_t to walk all conflicts to resolve.
@@ -2957,13 +3003,15 @@ conflict_status_walker(void *baton,
db,
local_abspath,
my_choice,
+ cswb->resolve_later,
cswb->notify_func,
cswb->notify_baton,
cswb->cancel_func,
cswb->cancel_baton,
iterpool));
- resolved = TRUE;
+ if (did_resolve)
+ resolved = TRUE;
break;
case svn_wc_conflict_kind_text:
@@ -3045,6 +3093,8 @@ svn_wc__resolve_conflicts(svn_wc_context
svn_node_kind_t kind;
svn_boolean_t conflicted;
struct conflict_status_walker_baton cswb;
+ apr_pool_t *iterpool = NULL;
+ svn_error_t *err;
/* ### the underlying code does NOT support resolving individual
### properties. bail out if the caller tries it. */
@@ -3084,6 +3134,8 @@ svn_wc__resolve_conflicts(svn_wc_context
cswb.notify_func = notify_func;
cswb.notify_baton = notify_baton;
+ cswb.resolve_later = apr_hash_make(scratch_pool);
+
if (notify_func)
notify_func(notify_baton,
svn_wc_create_notify(local_abspath,
@@ -3091,16 +3143,66 @@ svn_wc__resolve_conflicts(svn_wc_context
scratch_pool),
scratch_pool);
- SVN_ERR(svn_wc_walk_status(wc_ctx,
- local_abspath,
- depth,
- FALSE /* get_all */,
- FALSE /* no_ignore */,
- TRUE /* ignore_text_mods */,
- NULL /* ignore_patterns */,
- conflict_status_walker, &cswb,
- cancel_func, cancel_baton,
- scratch_pool));
+ err = svn_wc_walk_status(wc_ctx,
+ local_abspath,
+ depth,
+ FALSE /* get_all */,
+ FALSE /* no_ignore */,
+ TRUE /* ignore_text_mods */,
+ NULL /* ignore_patterns */,
+ conflict_status_walker, &cswb,
+ cancel_func, cancel_baton,
+ scratch_pool);
+
+ while (!err && apr_hash_count(cswb.resolve_later))
+ {
+ apr_hash_index_t *hi;
+ svn_boolean_t cleared_one = FALSE;
+ const char *tc_abspath = NULL;
+
+ if (iterpool)
+ svn_pool_clear(iterpool);
+ else
+ iterpool = svn_pool_create(scratch_pool);
+
+ for (hi = apr_hash_first(scratch_pool, cswb.resolve_later);
+ hi && !err;
+ hi = apr_hash_next(hi))
+ {
+ tc_abspath = svn__apr_hash_index_key(hi);
+ svn_pool_clear(iterpool);
+
+ svn_hash_sets(cswb.resolve_later, tc_abspath, NULL);
+
+ err = svn_wc_walk_status(wc_ctx, tc_abspath, depth, FALSE, FALSE,
+ TRUE, NULL, conflict_status_walker, &cswb,
+ cancel_func, cancel_baton,
+ iterpool);
+
+ if (!err && !svn_hash_gets(cswb.resolve_later, tc_abspath))
+ cleared_one = TRUE;
+ }
+
+ if (!cleared_one && !err)
+ {
+ /* Return the error on one of the paths: The last one. */
+ err = svn_error_createf(
+ SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+ _("Unable to resolve pending conflict on '%s'"),
+ svn_dirent_local_style(tc_abspath, scratch_pool));
+ }
+ }
+
+ if (iterpool)
+ svn_pool_destroy(iterpool);
+
+ if (err && err->apr_err != SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE)
+ err = svn_error_createf(
+ SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, err,
+ _("Unable to resolve conflicts on '%s'"),
+ svn_dirent_local_style(local_abspath, scratch_pool));
+
+ SVN_ERR(err);
if (notify_func)
notify_func(notify_baton,
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/diff.h
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/diff.h?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/diff.h (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/diff.h Tue Nov 5 10:40:38 2013
@@ -38,7 +38,9 @@
extern "C" {
#endif /* __cplusplus */
-/* Reports the file LOCAL_ABSPATH as ADDED file with relpath RELPATH to
+/* A function to diff locally added and locally copied files.
+
+ Reports the file LOCAL_ABSPATH as ADDED file with relpath RELPATH to
PROCESSOR with as parent baton PROCESSOR_PARENT_BATON.
The node is expected to have status svn_wc__db_status_normal, or
@@ -61,7 +63,9 @@ svn_wc__diff_local_only_file(svn_wc__db_
void *cancel_baton,
apr_pool_t *scratch_pool);
-/* Reports the directory LOCAL_ABSPATH and everything below it (limited by
+/* A function to diff locally added and locally copied directories.
+
+ Reports the directory LOCAL_ABSPATH and everything below it (limited by
DEPTH) as added with relpath RELPATH to PROCESSOR with as parent baton
PROCESSOR_PARENT_BATON.
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/diff_local.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/diff_local.c?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/diff_local.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/diff_local.c Tue Nov 5 10:40:38 2013
@@ -390,7 +390,7 @@ diff_status_callback(void *baton,
}
}
- if (local_only)
+ if (local_only && (db_status != svn_wc__db_status_deleted))
{
if (db_kind == svn_node_file)
SVN_ERR(svn_wc__diff_local_only_file(db, child_abspath,
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc-queries.sql?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc-queries.sql Tue Nov 5 10:40:38 2013
@@ -198,7 +198,7 @@ WHERE wc_id = ?1
-- STMT_DELETE_NODE
DELETE
FROM NODES
-WHERE wc_id = ?1 AND local_relpath = ?2
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
-- STMT_DELETE_ACTUAL_FOR_BASE_RECURSIVE
/* The ACTUAL_NODE applies to BASE, unless there is in at least one op_depth
@@ -718,7 +718,7 @@ WHERE wc_id = ?1 AND local_relpath = ?2
WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3)
AND presence = MAP_BASE_DELETED
--- STMT_DELETE_ALL_LAYERS
+-- STMT_DELETE_NODE_ALL_LAYERS
DELETE FROM nodes
WHERE wc_id = ?1 AND local_relpath = ?2
@@ -1576,17 +1576,18 @@ UPDATE nodes SET moved_to = NULL
/* This statement returns pairs of move-roots below the path ?2 in WC_ID ?1,
- * where the source of the move is within the subtree rooted at path ?2, and
- * the destination of the move is outside the subtree rooted at path ?2. */
--- STMT_SELECT_MOVED_PAIR2
-SELECT local_relpath, moved_to, op_depth FROM nodes
+ * where the original source of the move is within the subtree rooted at path
+ * ?2 at op_depth ?3. (The move is recorded immediately above op_depth ?3) */
+-- STMT_SELECT_MOVED_PAIRS_DEPTH
+SELECT local_relpath, moved_to, op_depth FROM nodes n
WHERE wc_id = ?1
AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
AND moved_to IS NOT NULL
- AND NOT IS_STRICT_DESCENDANT_OF(moved_to, ?2)
- AND op_depth >= (SELECT MAX(op_depth) FROM nodes o
- WHERE o.wc_id = ?1
- AND o.local_relpath = ?2)
+ AND op_depth > ?3
+ AND op_depth = (SELECT MIN(op_depth) FROM nodes o
+ WHERE o.wc_id = ?1
+ AND o.local_relpath = n.local_relpath
+ AND o.op_depth > ?3)
-- STMT_SELECT_MOVED_PAIR3
SELECT local_relpath, moved_to, op_depth, kind FROM nodes
@@ -1604,12 +1605,17 @@ WHERE wc_id = ?1
AND NOT IS_STRICT_DESCENDANT_OF(moved_to, ?2)
-- STMT_SELECT_OP_DEPTH_MOVED_PAIR
-SELECT n.local_relpath, n.moved_to,
- (SELECT o.repos_path FROM nodes AS o
- WHERE o.wc_id = n.wc_id
- AND o.local_relpath = n.local_relpath
- AND o.op_depth < ?3 ORDER BY o.op_depth DESC LIMIT 1)
+SELECT n.local_relpath, p.kind, n.moved_to, p.repos_path
FROM nodes AS n
+JOIN (SELECT local_relpath, kind, repos_path
+ FROM nodes AS o
+ WHERE o.wc_id = ?1
+ AND o.op_depth=(SELECT MAX(d.op_depth)
+ FROM nodes AS d
+ WHERE d.wc_id = ?1
+ AND d.local_relpath = o.local_relpath
+ AND d.op_depth < ?3)) AS p
+ ON n.local_relpath = p.local_relpath
WHERE n.wc_id = ?1
AND IS_STRICT_DESCENDANT_OF(n.local_relpath, ?2)
AND n.op_depth = ?3
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db.c?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db.c Tue Nov 5 10:40:38 2013
@@ -627,6 +627,10 @@ svn_wc__db_extend_parent_delete(svn_wc__
When removing a node if the parent has a higher working node then
the parent node and this node are both deleted or replaced and any
delete over this node must be removed.
+
+ This function (like most wcroot functions) assumes that its caller
+ only uses this function within an sqlite transaction if atomic
+ behavior is needed.
*/
svn_error_t *
svn_wc__db_retract_parent_delete(svn_wc__db_wcroot_t *wcroot,
@@ -635,12 +639,41 @@ svn_wc__db_retract_parent_delete(svn_wc_
apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
+ svn_boolean_t have_row;
+ int working_depth;
+ svn_wc__db_status_t presence;
+ const char *moved_to;
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_DELETE_LOWEST_WORKING_NODE));
+ STMT_SELECT_LOWEST_WORKING_NODE));
SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
op_depth));
- SVN_ERR(svn_sqlite__step_done(stmt));
+ SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+ if (!have_row)
+ return svn_error_trace(svn_sqlite__reset(stmt));
+
+ working_depth = svn_sqlite__column_int(stmt, 0);
+ presence = svn_sqlite__column_token(stmt, 1, presence_map);
+ moved_to = svn_sqlite__column_text(stmt, 3, scratch_pool);
+
+ SVN_ERR(svn_sqlite__reset(stmt));
+
+ if (moved_to)
+ {
+ /* ### TODO: Turn the move into a copy to keep the NODES table
+ valid */
+ }
+
+ if (presence == svn_wc__db_status_base_deleted)
+ {
+ SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_DELETE_NODE));
+
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
+ working_depth));
+
+ SVN_ERR(svn_sqlite__update(NULL, stmt));
+ }
return SVN_NO_ERROR;
}
@@ -7180,7 +7213,7 @@ remove_node_txn(svn_boolean_t *left_chan
if (local_relpath[0] != '\0')
{
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_DELETE_NODE));
+ STMT_DELETE_NODE_ALL_LAYERS));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__step_done(stmt));
}
@@ -10878,7 +10911,7 @@ commit_node(svn_wc__db_wcroot_t *wcroot,
if we need to remove shadowed layers below our descendants. */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_DELETE_ALL_LAYERS));
+ STMT_DELETE_NODE_ALL_LAYERS));
SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db_update_move.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db_update_move.c?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db_update_move.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/libsvn_wc/wc_db_update_move.c Tue Nov 5 10:40:38 2013
@@ -251,11 +251,14 @@ mark_tree_conflict(const char *local_rel
: NULL;
if (!new_repos_relpath)
- new_repos_relpath
- = svn_relpath_join(new_version->path_in_repos,
- svn_relpath_skip_ancestor(move_root_dst_relpath,
- local_relpath),
- scratch_pool);
+ {
+ const char *child_relpath = svn_relpath_skip_ancestor(
+ move_root_dst_relpath,
+ local_relpath);
+ SVN_ERR_ASSERT(child_relpath != NULL);
+ new_repos_relpath = svn_relpath_join(new_version->path_in_repos,
+ child_relpath, scratch_pool);
+ }
err = svn_wc__db_read_conflict_internal(&conflict, wcroot, local_relpath,
scratch_pool, scratch_pool);
@@ -303,7 +306,7 @@ mark_tree_conflict(const char *local_rel
&& strcmp(move_src_op_root_relpath,
svn_dirent_skip_ancestor(wcroot->abspath,
existing_abspath))))
- return svn_error_createf(SVN_ERR_WC_CONFLICT_RESOLVER_FAILURE, NULL,
+ return svn_error_createf(SVN_ERR_WC_OBSTRUCTED_UPDATE, NULL,
_("'%s' already in conflict"),
svn_dirent_local_style(local_relpath,
scratch_pool));
@@ -835,6 +838,7 @@ tc_editor_alter_directory(void *baton,
apr_hash_t *actual_props;
apr_array_header_t *propchanges;
+ /* ### TODO: Only do this when there is no higher WORKING layer */
SVN_ERR(update_working_props(&prop_state, &conflict_skel,
&propchanges, &actual_props,
b->db, dst_abspath,
@@ -905,6 +909,7 @@ update_working_file(const char *local_re
svn_wc_notify_state_t prop_state, content_state;
svn_skel_t *work_item, *work_items = NULL;
+ /* ### TODO: Only do this when there is no higher WORKING layer */
SVN_ERR(update_working_props(&prop_state, &conflict_skel, &propchanges,
&actual_props, db, local_abspath,
old_version, new_version,
@@ -1407,9 +1412,9 @@ get_tc_info(svn_wc_operation_t *operatio
/* Return *PROPS, *CHECKSUM, *CHILDREN and *KIND for LOCAL_RELPATH at
OP_DEPTH provided the row exists. Return *KIND of svn_node_none if
- the row does not exist. *CHILDREN is a sorted array of basenames of
- type 'const char *', rather than a hash, to allow the driver to
- process children in a defined order. */
+ the row does not exist, or only describes a delete of a lower op-depth.
+ *CHILDREN is a sorted array of basenames of type 'const char *', rather
+ than a hash, to allow the driver to process children in a defined order. */
static svn_error_t *
get_info(apr_hash_t **props,
const svn_checksum_t **checksum,
@@ -1424,16 +1429,36 @@ get_info(apr_hash_t **props,
apr_hash_t *hash_children;
apr_array_header_t *sorted_children;
svn_error_t *err;
+ svn_wc__db_status_t status;
+ const char *repos_relpath;
int i;
- err = svn_wc__db_depth_get_info(NULL, kind, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, checksum, NULL, NULL, props,
+ err = svn_wc__db_depth_get_info(&status, kind, NULL, &repos_relpath, NULL,
+ NULL, NULL, NULL, NULL, checksum, NULL,
+ NULL, props,
wcroot, local_relpath, op_depth,
result_pool, scratch_pool);
- if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+
+ /* If there is no node at this depth, or only a node that describes a delete
+ of a lower layer we report this node as not existing.
+
+ But when a node is reported as DELETED, but has a repository location it
+ is really a not-present node that must be reported as being there */
+ if ((err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+ || (!err && status == svn_wc__db_status_deleted))
{
svn_error_clear(err);
- *kind = svn_node_none;
+
+ if (kind && (err || !repos_relpath))
+ *kind = svn_node_none;
+ if (checksum)
+ *checksum = NULL;
+ if (props)
+ *props = NULL;
+ if (children)
+ *children = apr_array_make(result_pool, 0, sizeof(const char *));
+
+ return SVN_NO_ERROR;
}
else
SVN_ERR(err);
@@ -2324,7 +2349,6 @@ resolve_delete_raise_moved_away(svn_wc__
{
svn_sqlite__stmt_t *stmt;
svn_boolean_t have_row;
- int op_depth = relpath_depth(local_relpath);
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
SVN_ERR(svn_sqlite__exec_statements(wcroot->sdb,
@@ -2333,26 +2357,31 @@ resolve_delete_raise_moved_away(svn_wc__
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
STMT_SELECT_OP_DEPTH_MOVED_PAIR));
SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
- op_depth));
+ relpath_depth(local_relpath)));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
while(have_row)
{
- const char *moved_relpath = svn_sqlite__column_text(stmt, 0, NULL);
- const char *move_root_dst_relpath = svn_sqlite__column_text(stmt, 1,
- NULL);
- const char *moved_dst_repos_relpath = svn_sqlite__column_text(stmt, 2,
- NULL);
+ svn_error_t *err;
+ const char *src_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+ svn_node_kind_t src_kind = svn_sqlite__column_token(stmt, 1, kind_map);
+ const char *dst_relpath = svn_sqlite__column_text(stmt, 2, NULL);
+ const char *src_repos_relpath = svn_sqlite__column_text(stmt, 3, NULL);
svn_pool_clear(iterpool);
- SVN_ERR(mark_tree_conflict(moved_relpath,
- wcroot, db, old_version, new_version,
- move_root_dst_relpath, operation,
- svn_node_dir /* ### ? */,
- svn_node_dir /* ### ? */,
- moved_dst_repos_relpath,
- svn_wc_conflict_reason_moved_away,
- action, local_relpath,
- iterpool));
+ SVN_ERR_ASSERT(src_repos_relpath != NULL);
+
+ err = mark_tree_conflict(src_relpath,
+ wcroot, db, old_version, new_version,
+ dst_relpath, operation,
+ src_kind /* ### old kind */,
+ src_kind /* ### new kind */,
+ src_repos_relpath,
+ svn_wc_conflict_reason_moved_away,
+ action, local_relpath,
+ iterpool);
+
+ if (err)
+ return svn_error_compose_create(err, svn_sqlite__reset(stmt));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
}
@@ -2411,7 +2440,6 @@ break_move(svn_wc__db_wcroot_t *wcroot,
const char *src_relpath,
int src_op_depth,
const char *dst_relpath,
- int dst_op_depth,
apr_pool_t *scratch_pool)
{
svn_sqlite__stmt_t *stmt;
@@ -2422,11 +2450,12 @@ break_move(svn_wc__db_wcroot_t *wcroot,
src_op_depth));
SVN_ERR(svn_sqlite__step_done(stmt));
- /* This statement clears moved_here. */
+ /* The destination is always an op-root, so we can calculate the depth
+ from there. */
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_UPDATE_OP_DEPTH_RECURSIVE));
- SVN_ERR(svn_sqlite__bindf(stmt, "isdd", wcroot->wc_id,
- dst_relpath, dst_op_depth, dst_op_depth));
+ STMT_CLEAR_MOVED_HERE_RECURSIVE));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id,
+ dst_relpath, relpath_depth(dst_relpath)));
SVN_ERR(svn_sqlite__step_done(stmt));
return SVN_NO_ERROR;
@@ -2455,7 +2484,6 @@ svn_wc__db_resolve_break_moved_away_inte
SVN_ERR(break_move(wcroot, local_relpath,
relpath_depth(move_src_op_root_relpath),
move_dst_op_root_relpath,
- relpath_depth(move_dst_op_root_relpath),
scratch_pool));
return SVN_NO_ERROR;
@@ -2474,8 +2502,9 @@ break_moved_away_children_internal(svn_w
STMT_CREATE_UPDATE_MOVE_LIST));
SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
- STMT_SELECT_MOVED_PAIR2));
- SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
+ STMT_SELECT_MOVED_PAIRS_DEPTH));
+ SVN_ERR(svn_sqlite__bindf(stmt, "isd", wcroot->wc_id, local_relpath,
+ relpath_depth(local_relpath)));
SVN_ERR(svn_sqlite__step(&have_row, stmt));
iterpool = svn_pool_create(scratch_pool);
@@ -2488,7 +2517,7 @@ break_moved_away_children_internal(svn_w
svn_pool_clear(iterpool);
SVN_ERR(break_move(wcroot, src_relpath, src_op_depth, dst_relpath,
- relpath_depth(dst_relpath), iterpool));
+ iterpool));
SVN_ERR(update_move_list_add(wcroot, src_relpath,
svn_wc_notify_move_broken,
svn_node_unknown,
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/diff_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/diff_tests.py?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/diff_tests.py (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/tests/cmdline/diff_tests.py Tue Nov 5 10:40:38 2013
@@ -4696,6 +4696,26 @@ def diff_local_missing_obstruction(sbox)
'diff', wc_dir)
+@Issue(4444)
+def diff_move_inside_copy(sbox):
+ "diff copied-along child that contains a moved file"
+ sbox.build(read_only=True)
+ wc_dir = sbox.wc_dir
+
+ d_path = 'A/D'
+ d_copy = 'A/D-copy'
+ h_path = 'A/D-copy/H'
+ chi_path = '%s/chi' % h_path
+ chi_moved = '%s/chi-moved' % h_path
+
+ sbox.simple_copy(d_path, d_copy)
+ sbox.simple_move(chi_path, chi_moved)
+ sbox.simple_append(chi_moved, 'a new line')
+
+ # Bug: Diffing the copied-along parent directory asserts
+ svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [],
+ 'diff', sbox.ospath(h_path))
+
########################################################################
#Run the tests
@@ -4778,6 +4798,7 @@ test_list = [ None,
diff_repos_empty_file_addition,
diff_missing_tree_conflict_victim,
diff_local_missing_obstruction,
+ diff_move_inside_copy,
]
if __name__ == '__main__':
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/tests/libsvn_repos/repos-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/tests/libsvn_repos/repos-test.c?rev=1538929&r1=1538928&r2=1538929&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/tests/libsvn_repos/repos-test.c Tue Nov 5 10:40:38 2013
@@ -39,6 +39,9 @@
#include "svn_version.h"
#include "private/svn_repos_private.h"
+/* be able to look into svn_config_t */
+#include "../../libsvn_subr/config_impl.h"
+
#include "../svn_test_fs.h"
#include "dir-delta-editor.h"
@@ -3311,7 +3314,8 @@ test_config_pool(const svn_test_opts_t *
const char *repo_name = "test-repo-config-pool";
svn_repos_t *repos;
svn_stringbuf_t *cfg_buffer1, *cfg_buffer2;
- svn_config_t *cfg, *cfg1, *cfg2;
+ svn_config_t *cfg;
+ apr_hash_t *sections1, *sections2;
int i;
svn_boolean_t bvalue;
svn_fs_txn_t *txn;
@@ -3367,7 +3371,7 @@ test_config_pool(const svn_test_opts_t *
/* requesting a config over and over again should return the same
(even though it is not being referenced) */
- cfg1 = NULL;
+ sections1 = NULL;
for (i = 0; i < 4; ++i)
{
SVN_ERR(svn_repos__config_pool_get(
@@ -3375,12 +3379,12 @@ test_config_pool(const svn_test_opts_t *
svn_dirent_join(wrk_dir,
"config-pool-test1.cfg",
pool),
- subpool));
+ TRUE, TRUE, NULL, subpool));
- if (cfg1 == NULL)
- cfg1 = cfg;
+ if (sections1 == NULL)
+ sections1 = cfg->sections;
else
- SVN_TEST_ASSERT(cfg == cfg1);
+ SVN_TEST_ASSERT(cfg->sections == sections1);
svn_pool_clear(subpool);
}
@@ -3394,15 +3398,15 @@ test_config_pool(const svn_test_opts_t *
svn_dirent_join(wrk_dir,
"config-pool-test2.cfg",
pool),
- subpool));
+ TRUE, TRUE, NULL, subpool));
- SVN_TEST_ASSERT(cfg == cfg1);
+ SVN_TEST_ASSERT(cfg->sections == sections1);
svn_pool_clear(subpool);
}
/* reading a different configuration should return a different pointer */
- cfg2 = NULL;
+ sections2 = NULL;
for (i = 0; i < 2; ++i)
{
SVN_ERR(svn_repos__config_pool_get(
@@ -3410,14 +3414,14 @@ test_config_pool(const svn_test_opts_t *
svn_dirent_join(wrk_dir,
"config-pool-test3.cfg",
pool),
- subpool));
+ TRUE, TRUE, NULL, subpool));
- if (cfg2 == NULL)
- cfg2 = cfg;
+ if (sections2 == NULL)
+ sections2 = cfg->sections;
else
- SVN_TEST_ASSERT(cfg == cfg2);
+ SVN_TEST_ASSERT(cfg->sections == sections2);
- SVN_TEST_ASSERT(cfg1 != cfg2);
+ SVN_TEST_ASSERT(sections1 != sections2);
svn_pool_clear(subpool);
}
@@ -3440,8 +3444,8 @@ test_config_pool(const svn_test_opts_t *
svn_path_url_add_component2(
repo_root_url,
"dir/config", pool),
- subpool));
- SVN_TEST_ASSERT(cfg == cfg1);
+ TRUE, TRUE, NULL, subpool));
+ SVN_TEST_ASSERT(cfg->sections == sections1);
svn_pool_clear(subpool);
/* create another in-repo config */
@@ -3458,8 +3462,8 @@ test_config_pool(const svn_test_opts_t *
svn_path_url_add_component2(
repo_root_url,
"dir/config", pool),
- subpool));
- SVN_TEST_ASSERT(cfg == cfg2);
+ TRUE, TRUE, NULL, subpool));
+ SVN_TEST_ASSERT(cfg->sections == sections2);
svn_pool_clear(subpool);
/* reading the copied config should still give cfg1 */
@@ -3468,8 +3472,8 @@ test_config_pool(const svn_test_opts_t *
repo_root_url,
"another-dir/config",
pool),
- subpool));
- SVN_TEST_ASSERT(cfg == cfg1);
+ TRUE, TRUE, NULL, subpool));
+ SVN_TEST_ASSERT(cfg->sections == sections1);
svn_pool_clear(subpool);
/* once again: repeated reads. This triggers a different code path. */
@@ -3477,46 +3481,67 @@ test_config_pool(const svn_test_opts_t *
svn_path_url_add_component2(
repo_root_url,
"dir/config", pool),
- subpool));
- SVN_TEST_ASSERT(cfg == cfg2);
+ TRUE, TRUE, NULL, subpool));
+ SVN_TEST_ASSERT(cfg->sections == sections2);
SVN_ERR(svn_repos__config_pool_get(&cfg, config_pool,
svn_path_url_add_component2(
repo_root_url,
"another-dir/config",
pool),
- subpool));
- SVN_TEST_ASSERT(cfg == cfg1);
+ TRUE, TRUE, NULL, subpool));
+ SVN_TEST_ASSERT(cfg->sections == sections1);
svn_pool_clear(subpool);
/* access paths that don't exist */
SVN_TEST_ASSERT_ERROR(svn_repos__config_pool_get(&cfg, config_pool,
svn_path_url_add_component2(repo_root_url, "X",
pool),
- subpool),
+ TRUE, TRUE, NULL, subpool),
SVN_ERR_ILLEGAL_TARGET);
- err = svn_repos__config_pool_get(&cfg, config_pool, "X.cfg", subpool);
+ err = svn_repos__config_pool_get(&cfg, config_pool, "X.cfg", TRUE, TRUE,
+ NULL, subpool);
SVN_TEST_ASSERT(err && APR_STATUS_IS_ENOENT(err->apr_err));
svn_error_clear(err);
svn_pool_clear(subpool);
/* as long as we keep a reference to a config, clearing the config pool
should not invalidate that reference */
- SVN_ERR(svn_repos__config_pool_get(&cfg1, config_pool,
+ SVN_ERR(svn_repos__config_pool_get(&cfg, config_pool,
svn_dirent_join(wrk_dir,
"config-pool-test1.cfg",
pool),
- pool));
+ TRUE, TRUE, NULL, pool));
svn_pool_clear(config_pool_pool);
for (i = 0; i < 64000; ++i)
apr_pcalloc(config_pool_pool, 80);
- SVN_ERR(svn_config_get_bool(cfg1, &bvalue, "booleans", "true3", FALSE));
+ SVN_ERR(svn_config_get_bool(cfg, &bvalue, "booleans", "true3", FALSE));
SVN_TEST_ASSERT(bvalue);
return SVN_NO_ERROR;
}
-
+
+static svn_error_t *
+test_repos_fs_type(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_repos_t *repos;
+
+ /* Create test repository. */
+ SVN_ERR(svn_test__create_repos(&repos, "test-repo-repos_fs_type",
+ opts, pool));
+
+ SVN_TEST_STRING_ASSERT(svn_repos_fs_type(repos, pool), opts->fs_type);
+
+ /* Re-open repository and verify fs-type again. */
+ SVN_ERR(svn_repos_open2(&repos, svn_repos_path(repos, pool), NULL, pool));
+
+ SVN_TEST_STRING_ASSERT(svn_repos_fs_type(repos, pool), opts->fs_type);
+
+ return SVN_NO_ERROR;
+}
+
/* The test table. */
struct svn_test_descriptor_t test_funcs[] =
@@ -3566,5 +3591,7 @@ struct svn_test_descriptor_t test_funcs[
"test svn_repos_info_*"),
SVN_TEST_OPTS_PASS(test_config_pool,
"test svn_repos__config_pool_*"),
+ SVN_TEST_OPTS_PASS(test_repos_fs_type,
+ "test test_repos_fs_type"),
SVN_TEST_NULL
};
Propchange: subversion/branches/invoke-diff-cmd-feature/subversion/tests/libsvn_subr/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Nov 5 10:40:38 2013
@@ -22,6 +22,7 @@ opt-test
path-test
revision-test
skel-test
+sqlite-test
stream-test
string-test
string-test.tmp