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 2010/03/16 19:03:41 UTC
svn commit: r923910 [2/9] - in /subversion/branches/1.6.x-issue3432: ./
build/ build/ac-macros/ build/generator/ contrib/cgi/
contrib/client-side/emacs/ contrib/client-side/svn_load_dirs/
contrib/hook-scripts/ contrib/server-side/ doc/user/ notes/ pack...
Modified: subversion/branches/1.6.x-issue3432/subversion/bindings/swig/python/tests/mergeinfo.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/bindings/swig/python/tests/mergeinfo.py?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/bindings/swig/python/tests/mergeinfo.py (original)
+++ subversion/branches/1.6.x-issue3432/subversion/bindings/swig/python/tests/mergeinfo.py Tue Mar 16 18:03:37 2010
@@ -107,10 +107,10 @@ class SubversionMergeinfoTestCase(unitte
False, None, None)
expected_mergeinfo = \
{ '/trunk' :
- { 'branches/a' : [RevRange(2, 11)],
- 'branches/b' : [RevRange(9, 13)],
- 'branches/c' : [RevRange(2, 16)],
- 'trunk' : [RevRange(1, 9)], },
+ { '/branches/a' : [RevRange(2, 11)],
+ '/branches/b' : [RevRange(9, 13)],
+ '/branches/c' : [RevRange(2, 16)],
+ '/trunk' : [RevRange(1, 9)], },
}
self.compare_mergeinfo_catalogs(mergeinfo, expected_mergeinfo)
Modified: subversion/branches/1.6.x-issue3432/subversion/bindings/swig/ruby/test/test_client.rb
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/bindings/swig/ruby/test/test_client.rb?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/bindings/swig/ruby/test/test_client.rb (original)
+++ subversion/branches/1.6.x-issue3432/subversion/bindings/swig/ruby/test/test_client.rb Tue Mar 16 18:03:37 2010
@@ -1013,7 +1013,7 @@ class SvnClientTest < Test::Unit::TestCa
yield(ctx, branch, rev3, rev4, trunk)
ctx.revert(trunk, false)
ctx.resolve(:path=>trunk_path,
- :conflict_choice=>Svn::Wc::CONFLICT_CHOOSE_MINE_FULL)
+ :conflict_choice=>Svn::Wc::CONFLICT_CHOOSE_MERGED)
rev5 = ctx.commit(@wc_path).revision
assert(File.exist?(trunk_path))
ctx.up(@wc_path)
Modified: subversion/branches/1.6.x-issue3432/subversion/bindings/swig/ruby/test/test_core.rb
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/bindings/swig/ruby/test/test_core.rb?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/bindings/swig/ruby/test/test_core.rb (original)
+++ subversion/branches/1.6.x-issue3432/subversion/bindings/swig/ruby/test/test_core.rb Tue Mar 16 18:03:37 2010
@@ -628,9 +628,8 @@ EOM
assert_raises(Svn::Error::BadFilename) do
Svn::Core::MimeType.detect(nonexistent_html_file)
end
- assert_raises(Svn::Error::BadFilename) do
- Svn::Core::MimeType.detect(nonexistent_html_file, type_map)
- end
+ assert_equal("text/html",
+ Svn::Core::MimeType.detect(nonexistent_html_file, type_map))
empty_html_file = File.join(@tmp_path, "empty.html")
FileUtils.touch(empty_html_file)
Modified: subversion/branches/1.6.x-issue3432/subversion/bindings/swig/ruby/test/windows_util.rb
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/bindings/swig/ruby/test/windows_util.rb?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/bindings/swig/ruby/test/windows_util.rb (original)
+++ subversion/branches/1.6.x-issue3432/subversion/bindings/swig/ruby/test/windows_util.rb Tue Mar 16 18:03:37 2010
@@ -67,9 +67,19 @@ module SvnTestUtil
service_control('delete') if service_exists?
FileUtils.rm_rf(svnserve_dir)
end
- targets = %w(svnserve.exe libsvn_subr-1.dll libsvn_repos-1.dll
+
+ config = SetupEnvironment.gen_make_opts
+ apr_version_include = Pathname.new(config["--with-apr"]) +
+ 'include' + 'apr_version.h'
+ %r'^\s*#define\s+APR_MAJOR_VERSION\s+(\d+)' =~ apr_version_include.read
+ apr_major_version = $1 == '0' ? '' : "-#{$1}"
+
+ targets = %W(svnserve.exe libsvn_subr-1.dll libsvn_repos-1.dll
libsvn_fs-1.dll libsvn_delta-1.dll
- libaprutil.dll libapr.dll libapriconv.dll sqlite3.dll libdb44.dll libdb44d.dll)
+ libaprutil#{apr_major_version}.dll
+ libapr#{apr_major_version}.dll
+ libapriconv#{apr_major_version}.dll
+ libdb44.dll libdb44d.dll)
ENV["PATH"].split(";").each do |path|
found_targets = []
targets.each do |target|
@@ -82,6 +92,9 @@ module SvnTestUtil
targets -= found_targets
break if targets.empty?
end
+ # Remove optional targets instead of raising below. If they are really
+ # needed, svnserve won't start anyway.
+ targets -= %W[libapriconv#{apr_major_version}.dll]
unless targets.empty?
raise "can't find libraries to work svnserve: #{targets.join(' ')}"
end
@@ -128,6 +141,7 @@ exit 1
module SetupEnvironment
def setup_test_environment(top_dir, base_dir, ext_dir)
+ @@top_dir = top_dir
build_type = ENV["BUILD_TYPE"] || "Release"
@@ -157,6 +171,30 @@ exit 1
end
end
+ def gen_make_opts
+ @gen_make_opts ||= begin
+ lines = []
+ gen_make_opts = File.join(@@top_dir, "gen-make.opts")
+ lines = File.read(gen_make_opts).to_a if File.exists?(gen_make_opts)
+ config = Hash.new do |hash, key|
+ if /^--with-(.*)$/ =~ key
+ hash[key] = File.join(@@top_dir, $1)
+ end
+ end
+
+ lines.each do |line|
+ name, value = line.chomp.split(/\s*=\s*/, 2)
+ if value
+ config[name] = Pathname.new(value).absolute? ?
+ value :
+ File.join(@@top_dir, value)
+ end
+ end
+ config
+ end
+ end
+ module_function :gen_make_opts
+
private
def setup_dll_wrapper_util(dll_dir, util)
libsvn_swig_ruby_dll_dir = File.join(dll_dir, "libsvn_swig_ruby")
@@ -174,29 +212,18 @@ add_path.call(#{dll_dir.dump})
add_path.call(#{libsvn_swig_ruby_dll_dir.dump})
EOC
end
-
+
def add_depended_dll_path_to_dll_wrapper_util(top_dir, build_type, util)
- lines = []
- gen_make_opts = File.join(top_dir, "gen-make.opts")
- lines = File.read(gen_make_opts).to_a if File.exists?(gen_make_opts)
- config = {}
- lines.each do |line|
- name, value = line.chomp.split(/\s*=\s*/, 2)
- config[name] = value if value
- end
-
[
["apr", build_type],
["apr-util", build_type],
["apr-iconv", build_type],
["berkeley-db", "bin"],
- ["sqlite", "bin"],
+ ["libintl", "bin"],
+ ["sasl", "lib"],
].each do |lib, sub_dir|
- lib_dir = Pathname.new(config["--with-#{lib}"] || lib)
- dll_dir = lib_dir.absolute? ?
- lib_dir :
- Pathname.new(top_dir) + lib_dir
- dll_dir += sub_dir
+ lib_dir = Pathname.new(gen_make_opts["--with-#{lib}"])
+ dll_dir = lib_dir + sub_dir
dll_dir = dll_dir.expand_path
util.puts("add_path.call(#{dll_dir.to_s.dump})")
end
Modified: subversion/branches/1.6.x-issue3432/subversion/bindings/swig/svn_client.i
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/bindings/swig/svn_client.i?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/bindings/swig/svn_client.i (original)
+++ subversion/branches/1.6.x-issue3432/subversion/bindings/swig/svn_client.i Tue Mar 16 18:03:37 2010
@@ -63,9 +63,12 @@
%apply apr_array_header_t *SOURCES {
apr_array_header_t *sources
}
+#endif
+#if defined(SWIGRUBY) || defined(SWIGPYTHON)
%apply apr_array_header_t *REVISION_RANGE_LIST {
- apr_array_header_t *ranges_to_merge
+ const apr_array_header_t *ranges_to_merge,
+ const apr_array_header_t *revision_ranges
}
#endif
Modified: subversion/branches/1.6.x-issue3432/subversion/include/private/svn_mergeinfo_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/include/private/svn_mergeinfo_private.h?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/include/private/svn_mergeinfo_private.h (original)
+++ subversion/branches/1.6.x-issue3432/subversion/include/private/svn_mergeinfo_private.h Tue Mar 16 18:03:37 2010
@@ -93,7 +93,10 @@ svn_mergeinfo__remove_prefix_from_catalo
appropriate newline terminated string. If KEY_PREFIX is not NULL then
prepend KEY_PREFIX to each key (path) in *OUTPUT. if VAL_PREFIX is not
NULL then prepend VAL_PREFIX to each merge source:rangelist line in
- *OUTPUT. */
+ *OUTPUT.
+
+ Any relative merge source paths in the mergeinfo in CATALOG are converted
+ to absolute paths in *OUTPUT. */
svn_error_t *
svn_mergeinfo__catalog_to_formatted_string(svn_string_t **output,
svn_mergeinfo_catalog_t catalog,
@@ -105,7 +108,10 @@ svn_mergeinfo__catalog_to_formatted_stri
Unlike svn_mergeinfo_to_string(), NULL MERGEINFO is tolerated and results
in *OUTPUT set to "\n". If SVN_DEBUG is true, then NULL or empty MERGEINFO
causes *OUTPUT to be set to an appropriate newline terminated string. If
- PREFIX is not NULL then prepend PREFIX to each line in *OUTPUT. */
+ PREFIX is not NULL then prepend PREFIX to each line in *OUTPUT.
+
+ Any relative merge source paths in MERGEINFO are converted to absolute
+ paths in *OUTPUT.*/
svn_error_t *
svn_mergeinfo__to_formatted_string(svn_string_t **output,
svn_mergeinfo_t mergeinfo,
Modified: subversion/branches/1.6.x-issue3432/subversion/include/private/svn_opt_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/include/private/svn_opt_private.h?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/include/private/svn_opt_private.h (original)
+++ subversion/branches/1.6.x-issue3432/subversion/include/private/svn_opt_private.h Tue Mar 16 18:03:37 2010
@@ -32,15 +32,23 @@
extern "C" {
#endif /* __cplusplus */
-/* Extract the peg revision, if any, from UTF8_TARGET. Return the peg
- * revision in *PEG_REVISION and the true target portion in *TRUE_TARGET.
+/* Extract the peg revision, if any, from UTF8_TARGET.
+ *
+ * If PEG_REVISION is not NULL, return the peg revision in *PEG_REVISION.
* *PEG_REVISION will be an empty string if no peg revision is found.
+ * Return the true target portion in *TRUE_TARGET.
*
* UTF8_TARGET need not be canonical. *TRUE_TARGET will not be canonical
* unless UTF8_TARGET is.
*
+ * It is an error if *TRUE_TARGET results in the empty string after the
+ * split, which happens in case UTF8_TARGET has a leading '@' character
+ * with no additional '@' characters to escape the first '@'.
+ *
* Note that *PEG_REVISION will still contain the '@' symbol as the first
- * character if a peg revision was found.
+ * character if a peg revision was found. If a trailing '@' symbol was
+ * used to escape other '@' characters in UTF8_TARGET, *PEG_REVISION will
+ * point to the string "@", containing only a single character.
*
* All allocations are done in POOL.
*/
@@ -106,6 +114,27 @@ svn_opt__args_to_target_array(apr_array_
apr_array_header_t *known_targets,
apr_pool_t *pool);
+/* Return, in @a *true_targets_p, a copy of @a targets with peg revision
+ * specifiers snipped off the end of each element.
+ *
+ * This function is useful for subcommands for which peg revisions
+ * do not make any sense. Such subcommands still need to allow peg
+ * revisions to be specified on the command line so that users of
+ * the command line client can consistently escape '@' characters
+ * in filenames by appending an '@' character, regardless of the
+ * subcommand being used.
+ *
+ * If a peg revision is present but cannot be parsed, an error is thrown.
+ * The user has likely forgotten to escape an '@' character in a filename.
+ *
+ * It is safe to pass the address of @a targets as @a true_targets_p.
+ *
+ * Do all allocations in @a pool. */
+svn_error_t *
+svn_opt__eat_peg_revisions(apr_array_header_t **true_targets_p,
+ apr_array_header_t *targets,
+ apr_pool_t *pool);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/branches/1.6.x-issue3432/subversion/include/svn_mergeinfo.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/include/svn_mergeinfo.h?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/include/svn_mergeinfo.h (original)
+++ subversion/branches/1.6.x-issue3432/subversion/include/svn_mergeinfo.h Tue Mar 16 18:03:37 2010
@@ -152,6 +152,9 @@ typedef apr_hash_t *svn_mergeinfo_catalo
* inheritability are also allowed, but will be combined into a single
* range when placed into @a *mergeinfo.
*
+ * @a input may contain relative merge source paths, but these are
+ * converted to absolute paths in @a *mergeinfo.
+ *
* @since New in 1.5.
*/
svn_error_t *
@@ -363,6 +366,9 @@ svn_mergeinfo_inheritable(svn_mergeinfo_
* mergeinfo in *OUTPUT. If INPUT contains no elements, return the
* empty string.
*
+ * @a mergeinput may contain relative merge source paths, but these are
+ * converted to absolute paths in @a *output.
+ *
* @since New in 1.5.
*/
svn_error_t *
Modified: subversion/branches/1.6.x-issue3432/subversion/include/svn_opt.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/include/svn_opt.h?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/include/svn_opt.h (original)
+++ subversion/branches/1.6.x-issue3432/subversion/include/svn_opt.h Tue Mar 16 18:03:37 2010
@@ -621,11 +621,14 @@ svn_opt_parse_all_args(apr_array_header_
* "foo/bar@1:2" -> error
* "foo/bar@baz" -> error
* "foo/bar@" -> "foo/bar", (base)
+ * "foo/@bar@" -> "foo/@bar", (base)
* "foo/bar/@13" -> "foo/bar/", (number, 13)
* "foo/bar@@13" -> "foo/bar@", (number, 13)
* "foo/@bar@HEAD" -> "foo/@bar", (head)
* "foo@/bar" -> "foo@/bar", (unspecified)
* "foo@HEAD/bar" -> "foo@HEAD/bar", (unspecified)
+ * "@foo/bar" -> error
+ * "@foo/bar@" -> "@foo/bar", (unspecified)
*
* [*] Syntactically valid but probably not semantically useful.
*
Modified: subversion/branches/1.6.x-issue3432/subversion/include/svn_version.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/include/svn_version.h?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/include/svn_version.h (original)
+++ subversion/branches/1.6.x-issue3432/subversion/include/svn_version.h Tue Mar 16 18:03:37 2010
@@ -66,7 +66,7 @@ extern "C" {
*
* @since New in 1.1.
*/
-#define SVN_VER_PATCH 4
+#define SVN_VER_PATCH 10
/** @deprecated Provided for backward compatibility with the 1.0 API. */
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c Tue Mar 16 18:03:37 2010
@@ -248,11 +248,6 @@ password_get_gnome_keyring(const char **
{
char *default_keyring = NULL;
- if (non_interactive)
- {
- return FALSE;
- }
-
if (! dbus_bus_get(DBUS_BUS_SESSION, NULL))
{
return FALSE;
@@ -327,11 +322,6 @@ password_set_gnome_keyring(apr_hash_t *c
{
char *default_keyring = NULL;
- if (non_interactive)
- {
- return FALSE;
- }
-
if (! dbus_bus_get(DBUS_BUS_SESSION, NULL))
{
return FALSE;
@@ -387,6 +377,7 @@ simple_gnome_keyring_first_creds(void **
svn_boolean_t non_interactive = apr_hash_get(parameters,
SVN_AUTH_PARAM_NON_INTERACTIVE,
APR_HASH_KEY_STRING) != NULL;
+ const char *default_keyring = get_default_keyring_name(pool);
if (! non_interactive)
{
svn_auth_gnome_keyring_unlock_prompt_func_t unlock_prompt_func =
@@ -398,7 +389,6 @@ simple_gnome_keyring_first_creds(void **
APR_HASH_KEY_STRING);
char *keyring_password;
- const char *default_keyring = get_default_keyring_name(pool);
if (check_keyring_is_locked(default_keyring))
{
@@ -414,12 +404,22 @@ simple_gnome_keyring_first_creds(void **
}
}
- return svn_auth__simple_first_creds_helper(credentials,
- iter_baton, provider_baton,
- parameters, realmstring,
- password_get_gnome_keyring,
- SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE,
- pool);
+ if (check_keyring_is_locked(default_keyring))
+ {
+ return svn_error_create(SVN_ERR_AUTHN_CREDS_UNAVAILABLE, NULL,
+ _("GNOME Keyring is locked and "
+ "we are non-interactive"));
+ }
+ else
+ {
+ return svn_auth__simple_first_creds_helper
+ (credentials,
+ iter_baton, provider_baton,
+ parameters, realmstring,
+ password_get_gnome_keyring,
+ SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE,
+ pool);
+ }
}
/* Save encrypted credentials to the simple provider's cache. */
@@ -434,6 +434,7 @@ simple_gnome_keyring_save_creds(svn_bool
svn_boolean_t non_interactive = apr_hash_get(parameters,
SVN_AUTH_PARAM_NON_INTERACTIVE,
APR_HASH_KEY_STRING) != NULL;
+ const char *default_keyring = get_default_keyring_name(pool);
if (! non_interactive)
{
svn_auth_gnome_keyring_unlock_prompt_func_t unlock_prompt_func =
@@ -445,7 +446,6 @@ simple_gnome_keyring_save_creds(svn_bool
APR_HASH_KEY_STRING);
char *keyring_password;
- const char *default_keyring = get_default_keyring_name(pool);
if (check_keyring_is_locked(default_keyring))
{
@@ -460,13 +460,22 @@ simple_gnome_keyring_save_creds(svn_bool
}
}
}
-
- return svn_auth__simple_save_creds_helper(saved, credentials,
- provider_baton, parameters,
- realmstring,
- password_set_gnome_keyring,
- SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE,
- pool);
+ if (check_keyring_is_locked(default_keyring))
+ {
+ return svn_error_create(SVN_ERR_AUTHN_CREDS_NOT_SAVED, NULL,
+ _("GNOME Keyring is locked and "
+ "we are non-interactive"));
+ }
+ else
+ {
+ return svn_auth__simple_save_creds_helper
+ (saved, credentials,
+ provider_baton, parameters,
+ realmstring,
+ password_set_gnome_keyring,
+ SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE,
+ pool);
+ }
}
static void
@@ -518,6 +527,7 @@ ssl_client_cert_pw_gnome_keyring_first_c
svn_boolean_t non_interactive = apr_hash_get(parameters,
SVN_AUTH_PARAM_NON_INTERACTIVE,
APR_HASH_KEY_STRING) != NULL;
+ const char *default_keyring = get_default_keyring_name(pool);
if (! non_interactive)
{
svn_auth_gnome_keyring_unlock_prompt_func_t unlock_prompt_func =
@@ -529,7 +539,6 @@ ssl_client_cert_pw_gnome_keyring_first_c
APR_HASH_KEY_STRING);
char *keyring_password;
- const char *default_keyring = get_default_keyring_name(pool);
if (check_keyring_is_locked(default_keyring))
{
@@ -544,14 +553,22 @@ ssl_client_cert_pw_gnome_keyring_first_c
}
}
}
-
- return svn_auth__ssl_client_cert_pw_file_first_creds_helper
- (credentials,
- iter_baton, provider_baton,
- parameters, realmstring,
- password_get_gnome_keyring,
- SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE,
- pool);
+ if (check_keyring_is_locked(default_keyring))
+ {
+ return svn_error_create(SVN_ERR_AUTHN_CREDS_UNAVAILABLE, NULL,
+ _("GNOME Keyring is locked and "
+ "we are non-interactive"));
+ }
+ else
+ {
+ return svn_auth__ssl_client_cert_pw_file_first_creds_helper
+ (credentials,
+ iter_baton, provider_baton,
+ parameters, realmstring,
+ password_get_gnome_keyring,
+ SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE,
+ pool);
+ }
}
/* Save encrypted credentials to the ssl client cert password provider's
@@ -567,6 +584,7 @@ ssl_client_cert_pw_gnome_keyring_save_cr
svn_boolean_t non_interactive = apr_hash_get(parameters,
SVN_AUTH_PARAM_NON_INTERACTIVE,
APR_HASH_KEY_STRING) != NULL;
+ const char *default_keyring = get_default_keyring_name(pool);
if (! non_interactive)
{
svn_auth_gnome_keyring_unlock_prompt_func_t unlock_prompt_func =
@@ -578,7 +596,6 @@ ssl_client_cert_pw_gnome_keyring_save_cr
APR_HASH_KEY_STRING);
char *keyring_password;
- const char *default_keyring = get_default_keyring_name(pool);
if (check_keyring_is_locked(default_keyring))
{
@@ -593,14 +610,22 @@ ssl_client_cert_pw_gnome_keyring_save_cr
}
}
}
-
- return svn_auth__ssl_client_cert_pw_file_save_creds_helper
- (saved, credentials,
- provider_baton, parameters,
- realmstring,
- password_set_gnome_keyring,
- SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE,
- pool);
+ if (check_keyring_is_locked(default_keyring))
+ {
+ return svn_error_create(SVN_ERR_AUTHN_CREDS_UNAVAILABLE, NULL,
+ _("GNOME Keyring is locked and "
+ "we are non-interactive"));
+ }
+ else
+ {
+ return svn_auth__ssl_client_cert_pw_file_save_creds_helper
+ (saved, credentials,
+ provider_baton, parameters,
+ realmstring,
+ password_set_gnome_keyring,
+ SVN_AUTH__GNOME_KEYRING_PASSWORD_TYPE,
+ pool);
+ }
}
static const svn_auth_provider_t gnome_keyring_ssl_client_cert_pw_provider = {
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_client/add.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_client/add.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_client/add.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_client/add.c Tue Mar 16 18:03:37 2010
@@ -82,6 +82,23 @@ trim_string(char **pstr)
str[i] = '\0';
}
+/* Remove leading and trailing single- or double quotes from a C string,
+ * in place. */
+static void
+unquote_string(char **pstr)
+{
+ char *str = *pstr;
+ size_t i = strlen(str);
+
+ if (i > 0 && ((*str == '"' && str[i - 1] == '"') ||
+ (*str == '\'' && str[i - 1] == '\'')))
+ {
+ str[i - 1] = '\0';
+ str++;
+ }
+ *pstr = str;
+}
+
/* Split PROPERTY and store each individual value in PROPS.
Allocates from POOL. */
static void
@@ -163,6 +180,7 @@ auto_props_enumerator(const char *name,
*equal_sign = '\0';
equal_sign++;
trim_string(&equal_sign);
+ unquote_string(&equal_sign);
this_value = equal_sign;
}
else
@@ -291,13 +309,26 @@ add_file(const char *path,
{
const void *pname;
void *pval;
+ svn_error_t *err;
apr_hash_this(hi, &pname, NULL, &pval);
/* It's probably best to pass 0 for force, so that if
the autoprops say to set some weird combination,
we just error and let the user sort it out. */
- SVN_ERR(svn_wc_prop_set3(pname, pval, path, adm_access, FALSE,
- NULL, NULL, pool));
+ err = svn_wc_prop_set3(pname, pval, path, adm_access, FALSE,
+ NULL, NULL, pool);
+ if (err)
+ {
+ /* Don't leave the job half-done. If we fail to set a property,
+ * (try to) un-add the file. */
+ svn_error_clear(svn_wc_revert3(path, adm_access,
+ svn_depth_empty,
+ FALSE /* use_commit_times */,
+ NULL /* changelists */,
+ NULL, NULL, NULL, NULL,
+ pool));
+ return err;
+ }
}
}
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_client/commit_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_client/commit_util.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_client/commit_util.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_client/commit_util.c Tue Mar 16 18:03:37 2010
@@ -314,10 +314,10 @@ bail_on_tree_conflicted_ancestor(svn_wc_
while(1)
{
/* Here, ADM_ACCESS refers to PATH. */
- svn_wc__strictly_is_wc_root(&wc_root,
- path,
- adm_access,
- scratch_pool);
+ SVN_ERR(svn_wc__strictly_is_wc_root(&wc_root,
+ path,
+ adm_access,
+ scratch_pool));
if (adm_access != first_ancestor)
svn_wc_adm_close2(adm_access, scratch_pool);
@@ -335,8 +335,8 @@ bail_on_tree_conflicted_ancestor(svn_wc_
scratch_pool));
/* Now, ADM_ACCESS refers to PARENT_PATH. */
- svn_wc_conflicted_p2(NULL, NULL, &tree_conflicted,
- path, adm_access, scratch_pool);
+ SVN_ERR(svn_wc_conflicted_p2(NULL, NULL, &tree_conflicted,
+ path, adm_access, scratch_pool));
if (tree_conflicted)
return svn_error_createf(
@@ -461,6 +461,9 @@ harvest_committables(apr_hash_t *committ
svn_path_local_style(path, scratch_pool));
}
+ if (entry->file_external_path && copy_mode)
+ return SVN_NO_ERROR;
+
if (entry->kind == svn_node_dir)
{
/* Read the dir's own entries for use when recursing. */
@@ -723,6 +726,14 @@ harvest_committables(apr_hash_t *committ
if (this_entry->depth == svn_depth_exclude)
continue;
+ /* Skip schedule-delete children inside of schedule-replace
+ * directories which were deleted pre-replace.
+ * Attempting to commit such nodes causes an out-of-date error.
+ * See issue #3281. */
+ if (entry->schedule == svn_wc_schedule_replace &&
+ this_entry->schedule == svn_wc_schedule_delete)
+ continue;
+
name_uri = svn_path_uri_encode(name, iterpool);
full_path = svn_path_join(path, name, iterpool);
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_client/copy.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_client/copy.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_client/copy.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_client/copy.c Tue Mar 16 18:03:37 2010
@@ -67,7 +67,7 @@
*TARGET_MERGEINFO. ADM_ACCESS may be NULL, if SRC_PATH_OR_URL is an
URL. If NO_REPOS_ACCESS is set, this function is disallowed from
consulting the repository about anything. RA_SESSION may be NULL but
- only if NO_REPOS_ACCESS is true. */
+ only if NO_REPOS_ACCESS is true. */
static svn_error_t *
calculate_target_mergeinfo(svn_ra_session_t *ra_session,
apr_hash_t **target_mergeinfo,
@@ -109,19 +109,22 @@ calculate_target_mergeinfo(svn_ra_sessio
if (! locally_added)
{
- const char *mergeinfo_path;
-
if (! no_repos_access)
{
- /* Fetch any existing (explicit) mergeinfo. */
- SVN_ERR(svn_client__path_relative_to_root(&mergeinfo_path, src_url,
- entry ? entry->repos : NULL,
- FALSE, ra_session,
- adm_access, pool));
+ /* Fetch any existing (explicit) mergeinfo. We'll temporarily
+ reparent to the target URL here, just to keep the code simple.
+ We could, as an alternative, first see if the target URL was a
+ child of the session URL and use the relative "remainder",
+ falling back to this reparenting as necessary. */
+ const char *old_session_url = NULL;
+ SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url,
+ ra_session, src_url, pool));
SVN_ERR(svn_client__get_repos_mergeinfo(ra_session, &src_mergeinfo,
- mergeinfo_path, src_revnum,
+ "", src_revnum,
svn_mergeinfo_inherited,
TRUE, pool));
+ if (old_session_url)
+ SVN_ERR(svn_ra_reparent(ra_session, old_session_url, pool));
}
else
{
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_client/delete.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_client/delete.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_client/delete.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_client/delete.c Tue Mar 16 18:03:37 2010
@@ -109,7 +109,7 @@ delete_urls(svn_commit_info_t **commit_i
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- svn_ra_session_t *ra_session;
+ svn_ra_session_t *ra_session = NULL;
const svn_delta_editor_t *editor;
void *edit_baton;
void *commit_baton;
@@ -162,30 +162,47 @@ delete_urls(svn_commit_info_t **commit_i
SVN_ERR(svn_client__ensure_revprop_table(&commit_revprops, revprop_table,
log_msg, ctx, pool));
- /* Open an RA session for the URL. Note that we don't have a local
- directory, nor a place to put temp files. */
- SVN_ERR(svn_client__open_ra_session_internal(&ra_session, common, NULL,
- NULL, NULL, FALSE, TRUE,
- ctx, pool));
-
/* Verify that each thing to be deleted actually exists (to prevent
the creation of a revision that has no changes, since the
- filesystem allows for no-op deletes). */
+ filesystem allows for no-op deletes). While here, we'll
+ URI-decode our targets. */
for (i = 0; i < targets->nelts; i++)
{
const char *path = APR_ARRAY_IDX(targets, i, const char *);
+ const char *item_url;
+
svn_pool_clear(subpool);
+ item_url = svn_path_url_add_component2(common, path, subpool);
path = svn_path_uri_decode(path, pool);
APR_ARRAY_IDX(targets, i, const char *) = path;
- SVN_ERR(svn_ra_check_path(ra_session, path, SVN_INVALID_REVNUM,
+
+ /* If we've not yet done so, open an RA session for the
+ URL. Note that we don't have a local directory, nor a place
+ to put temp files. Otherwise, reparent our existing
+ session. */
+ if (! ra_session)
+ {
+ SVN_ERR(svn_client__open_ra_session_internal(&ra_session, item_url,
+ NULL, NULL, NULL, FALSE,
+ TRUE, ctx, pool));
+ }
+ else
+ {
+ SVN_ERR(svn_ra_reparent(ra_session, item_url, subpool));
+ }
+
+ SVN_ERR(svn_ra_check_path(ra_session, "", SVN_INVALID_REVNUM,
&kind, subpool));
if (kind == svn_node_none)
return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,
"URL '%s' does not exist",
- svn_path_local_style(path, pool));
+ svn_path_local_style(item_url, pool));
}
svn_pool_destroy(subpool);
+ /* Reparent the RA_session to the common parent of our deletees. */
+ SVN_ERR(svn_ra_reparent(ra_session, common, pool));
+
/* Fetch RA commit editor */
SVN_ERR(svn_client__commit_get_baton(&commit_baton, commit_info_p, pool));
SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_client/externals.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_client/externals.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_client/externals.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_client/externals.c Tue Mar 16 18:03:37 2010
@@ -769,13 +769,14 @@ handle_external_item_change(const void *
new_item->url, NULL,
&(new_item->peg_revision),
&(new_item->revision), ib->ctx,
- ib->pool));
+ ib->iter_pool));
- SVN_ERR(svn_ra_get_uuid2(ra_session, &ra_cache.repos_uuid, ib->pool));
+ SVN_ERR(svn_ra_get_uuid2(ra_session, &ra_cache.repos_uuid,
+ ib->iter_pool));
SVN_ERR(svn_ra_get_repos_root2(ra_session, &ra_cache.repos_root_url,
- ib->pool));
+ ib->iter_pool));
SVN_ERR(svn_ra_check_path(ra_session, "", ra_cache.ra_revnum, &kind,
- ib->pool));
+ ib->iter_pool));
if (svn_node_none == kind)
return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_client/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_client/log.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_client/log.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_client/log.c Tue Mar 16 18:03:37 2010
@@ -317,6 +317,7 @@ svn_client_log5(const apr_array_header_t
pre_15_receiver_baton_t rb = {0};
apr_pool_t *iterpool;
int i;
+ svn_opt_revision_t peg_rev;
if (revision_ranges->nelts == 0)
{
@@ -325,6 +326,11 @@ svn_client_log5(const apr_array_header_t
_("Missing required revision specification"));
}
+ /* Make a copy of PEG_REVISION, we may need to change it to a
+ default value. */
+ peg_rev.kind = peg_revision->kind;
+ peg_rev.value = peg_revision->value;
+
/* Use the passed URL, if there is one. */
url_or_path = APR_ARRAY_IDX(targets, 0, const char *);
is_url = svn_path_is_url(url_or_path);
@@ -362,7 +368,7 @@ svn_client_log5(const apr_array_header_t
/* Default to any specified peg revision. Otherwise, if the
* first target is an URL, then we default to HEAD:0. Lastly,
* the default is BASE:0 since WC@HEAD may not exist. */
- if (peg_revision->kind == svn_opt_revision_unspecified)
+ if (peg_rev.kind == svn_opt_revision_unspecified)
{
if (svn_path_is_url(url_or_path))
range->start.kind = svn_opt_revision_head;
@@ -370,7 +376,7 @@ svn_client_log5(const apr_array_header_t
range->start.kind = svn_opt_revision_base;
}
else
- range->start = *peg_revision;
+ range->start = peg_rev;
if (range->end.kind == svn_opt_revision_unspecified)
{
@@ -453,6 +459,11 @@ svn_client_log5(const apr_array_header_t
_("When specifying working copy paths, only "
"one target may be given"));
+ /* An unspecified PEG_REVISION for a working copy path defautls
+ to svn_opt_revision_working. */
+ if (peg_rev.kind == svn_opt_revision_unspecified)
+ peg_rev.kind = svn_opt_revision_working;
+
/* Get URLs for each target */
target_urls = apr_array_make(pool, 1, sizeof(const char *));
real_targets = apr_array_make(pool, 1, sizeof(const char *));
@@ -504,14 +515,14 @@ svn_client_log5(const apr_array_header_t
/* If this is a revision type that requires access to the working copy,
* we use our initial target path to figure out where to root the RA
* session, otherwise we use our URL. */
- if (SVN_CLIENT__REVKIND_NEEDS_WC(peg_revision->kind))
+ if (SVN_CLIENT__REVKIND_NEEDS_WC(peg_rev.kind))
SVN_ERR(svn_path_condense_targets(&ra_target, NULL, targets, TRUE, pool));
else
ra_target = url_or_path;
SVN_ERR(svn_client__ra_session_from_path(&ra_session, &ignored_revnum,
&actual_url, ra_target, NULL,
- peg_revision, &session_opt_rev,
+ &peg_rev, &session_opt_rev,
ctx, pool));
SVN_ERR(svn_ra_has_capability(ra_session, &has_log_revprops,
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_client/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_client/merge.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_client/merge.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_client/merge.c Tue Mar 16 18:03:37 2010
@@ -30,6 +30,7 @@
#include "svn_wc.h"
#include "svn_delta.h"
#include "svn_diff.h"
+#include "svn_dirent_uri.h"
#include "svn_mergeinfo.h"
#include "svn_client.h"
#include "svn_string.h"
@@ -441,38 +442,24 @@ obstructed_or_missing(const char *path,
return svn_wc_notify_state_obstructed;
}
-/* Record a tree conflict in the WC, unless this is a dry run or a record-
- * only merge.
- *
- * The tree conflict, with its victim specified by VICTIM_PATH, is
- * assumed to have happened during a merge using merge baton MERGE_B.
- *
- * ADM_ACCESS must correspond to the victim's parent directory (even if
- * the victim is a directory).
- *
- * NODE_KIND must be the node kind of "old" and "theirs" and "mine";
- * this function cannot cope with node kind clashes.
- * ACTION and REASON correspond to the fields
- * of the same names in svn_wc_tree_conflict_description_t.
+/* Create a tree-conflict description in *CONFLICT.
+ * See tree_conflict() for function parameters.
*/
static svn_error_t*
-tree_conflict(merge_cmd_baton_t *merge_b,
- svn_wc_adm_access_t *adm_access,
- const char *victim_path,
- svn_node_kind_t node_kind,
- svn_wc_conflict_action_t action,
- svn_wc_conflict_reason_t reason)
+make_tree_conflict(svn_wc_conflict_description_t **conflict,
+ merge_cmd_baton_t *merge_b,
+ svn_wc_adm_access_t *adm_access,
+ const char *victim_path,
+ svn_node_kind_t node_kind,
+ svn_wc_conflict_action_t action,
+ svn_wc_conflict_reason_t reason)
{
- svn_wc_conflict_description_t *conflict;
const char *src_repos_url; /* root URL of source repository */
const char *left_url;
const char *right_url;
svn_wc_conflict_version_t *left;
svn_wc_conflict_version_t *right;
- if (merge_b->record_only || merge_b->dry_run)
- return SVN_NO_ERROR;
-
SVN_ERR(svn_ra_get_repos_root2(merge_b->ra_session1, &src_repos_url,
merge_b->pool));
@@ -504,17 +491,110 @@ tree_conflict(merge_cmd_baton_t *merge_b
svn_path_is_child(src_repos_url, right_url, merge_b->pool),
merge_b->merge_source.rev2, node_kind, merge_b->pool);
- conflict = svn_wc_conflict_description_create_tree(
+ *conflict = svn_wc_conflict_description_create_tree(
victim_path, adm_access, node_kind, svn_wc_operation_merge,
left, right, merge_b->pool);
- conflict->action = action;
- conflict->reason = reason;
+ (*conflict)->action = action;
+ (*conflict)->reason = reason;
+
+ return SVN_NO_ERROR;
+}
+
+/* Record a tree conflict in the WC, unless this is a dry run or a record-
+ * only merge.
+ *
+ * The tree conflict, with its victim specified by VICTIM_PATH, is
+ * assumed to have happened during a merge using merge baton MERGE_B.
+ *
+ * ADM_ACCESS must correspond to the victim's parent directory (even if
+ * the victim is a directory).
+ *
+ * NODE_KIND must be the node kind of "old" and "theirs" and "mine";
+ * this function cannot cope with node kind clashes.
+ * ACTION and REASON correspond to the fields
+ * of the same names in svn_wc_tree_conflict_description_t.
+ */
+static svn_error_t*
+tree_conflict(merge_cmd_baton_t *merge_b,
+ svn_wc_adm_access_t *adm_access,
+ const char *victim_path,
+ svn_node_kind_t node_kind,
+ svn_wc_conflict_action_t action,
+ svn_wc_conflict_reason_t reason)
+{
+ svn_wc_conflict_description_t *conflict;
+
+ if (merge_b->record_only || merge_b->dry_run)
+ return SVN_NO_ERROR;
+
+ /* Construct the new conflict first to get the proper conflict->path */
+ SVN_ERR(make_tree_conflict(&conflict, merge_b, adm_access, victim_path,
+ node_kind, action, reason));
SVN_ERR(svn_wc__add_tree_conflict(conflict, adm_access, merge_b->pool));
return SVN_NO_ERROR;
}
+/* The same as tree_conflict(), but this one is called from
+ merge_*_added() and possibly collapses a new tree-conflict
+ with an existing one. */
+static svn_error_t*
+tree_conflict_on_add(merge_cmd_baton_t *merge_b,
+ svn_wc_adm_access_t *adm_access,
+ const char *victim_path,
+ svn_node_kind_t node_kind,
+ svn_wc_conflict_action_t action,
+ svn_wc_conflict_reason_t reason)
+{
+ svn_wc_conflict_description_t *existing_conflict;
+ svn_wc_conflict_description_t *conflict;
+
+ if (merge_b->record_only || merge_b->dry_run)
+ return SVN_NO_ERROR;
+
+ /* Construct the new conflict first to get the proper conflict->path,
+ and also to compare the new conflict with a possibly existing one. */
+ SVN_ERR(make_tree_conflict(&conflict, merge_b, adm_access, victim_path,
+ node_kind, action, reason));
+
+ SVN_ERR(svn_wc__get_tree_conflict(&existing_conflict, conflict->path,
+ adm_access, merge_b->pool));
+
+ if (existing_conflict == NULL)
+ {
+ /* There is no existing tree conflict so it is safe to add one. */
+ SVN_ERR(svn_wc__add_tree_conflict(conflict, adm_access, merge_b->pool));
+ }
+ else if (existing_conflict->action == svn_wc_conflict_action_delete &&
+ conflict->action == svn_wc_conflict_action_add)
+ {
+ /* There is already a tree conflict raised by a previous incoming
+ * change that attempted to delete the item (whether in this same
+ * merge operation or not). Change the existing conflict to note
+ * that the incoming change is replacement. */
+
+ /* Remove the existing tree-conflict so we can add a new one.*/
+ SVN_ERR(svn_wc__del_tree_conflict(conflict->path,
+ adm_access,
+ merge_b->pool));
+
+ /* Preserve the reason which caused the first conflict,
+ * re-label the incoming change as 'delete', and update
+ * version info for the left version of the conflict. */
+ conflict->reason = existing_conflict->reason;
+ conflict->action = svn_wc_conflict_action_delete;
+ conflict->src_left_version = svn_wc_conflict_version_dup(
+ existing_conflict->src_left_version,
+ merge_b->pool);
+
+ SVN_ERR(svn_wc__add_tree_conflict(conflict, adm_access, merge_b->pool));
+ }
+
+ /* In any other cases, we don't touch the existing conflict. */
+ return SVN_NO_ERROR;
+}
+
/* Set *HONOR_MERGEINFO and *RECORD_MERGEINFO (if non-NULL) based on the
merge being performed as described in MERGE_B.
@@ -1459,6 +1539,7 @@ merge_file_added(svn_wc_adm_access_t *ad
const char *copyfrom_url = NULL;
svn_revnum_t copyfrom_rev = SVN_INVALID_REVNUM;
svn_stream_t *new_base_contents;
+ svn_wc_conflict_description_t *existing_conflict;
/* If this is a merge from the same repository as our working copy,
we handle adds as add-with-history. Otherwise, we'll use a pure
@@ -1480,20 +1561,39 @@ merge_file_added(svn_wc_adm_access_t *ad
SVN_ERR(svn_stream_open_readonly(&new_base_contents, yours,
subpool, subpool));
- /* Since 'mine' doesn't exist, and this is
- 'merge_file_added', I hope it's safe to assume that
- 'older' is empty, and 'yours' is the full file. Merely
- copying 'yours' to 'mine', isn't enough; we need to get
- the whole text-base and props installed too, just as if
- we had called 'svn cp wc wc'. */
- /* ### would be nice to have cancel/notify funcs to pass */
- SVN_ERR(svn_wc_add_repos_file3(
- mine, adm_access,
- new_base_contents, NULL, new_props, NULL,
- copyfrom_url, copyfrom_rev,
- NULL, NULL, NULL, NULL, subpool));
+ SVN_ERR(svn_wc__get_tree_conflict(&existing_conflict,
+ mine, adm_access,
+ merge_b->pool));
+ if (existing_conflict)
+ {
+ /* Possibly collapse the existing conflict into a 'replace'
+ * tree conflict. The conflict reason is 'added' because
+ * the now-deleted tree conflict victim must have been
+ * added in the history of the merge target. */
+ SVN_ERR(tree_conflict_on_add(merge_b, adm_access, mine,
+ svn_node_file,
+ svn_wc_conflict_action_add,
+ svn_wc_conflict_reason_added));
+ if (tree_conflicted)
+ *tree_conflicted = TRUE;
+ }
+ else
+ {
+ /* Since 'mine' doesn't exist, and this is
+ 'merge_file_added', I hope it's safe to assume that
+ 'older' is empty, and 'yours' is the full file. Merely
+ copying 'yours' to 'mine', isn't enough; we need to get
+ the whole text-base and props installed too, just as if
+ we had called 'svn cp wc wc'. */
+ /* ### would be nice to have cancel/notify funcs to pass */
+ SVN_ERR(svn_wc_add_repos_file3(
+ mine, adm_access,
+ new_base_contents, NULL, new_props, NULL,
+ copyfrom_url, copyfrom_rev,
+ NULL, NULL, NULL, NULL, subpool));
- /* ### delete 'yours' ? */
+ /* ### delete 'yours' ? */
+ }
}
if (content_state)
*content_state = svn_wc_notify_state_changed;
@@ -1507,10 +1607,10 @@ merge_file_added(svn_wc_adm_access_t *ad
* conflict victim.
* See notes about obstructions in notes/tree-conflicts/detection.txt.
*/
- SVN_ERR(tree_conflict(merge_b, adm_access, mine,
- svn_node_file,
- svn_wc_conflict_action_add,
- svn_wc_conflict_reason_obstructed));
+ SVN_ERR(tree_conflict_on_add(merge_b, adm_access, mine,
+ svn_node_file,
+ svn_wc_conflict_action_add,
+ svn_wc_conflict_reason_obstructed));
if (tree_conflicted)
*tree_conflicted = TRUE;
if (content_state)
@@ -1536,14 +1636,14 @@ merge_file_added(svn_wc_adm_access_t *ad
else
{
/* The file add the merge wants to carry out is obstructed by
- * a versioned file, so the file the merge wants to add is a
- * tree conflict victim. See notes about obstructions in
- * notes/tree-conflicts/detection.txt.
- */
- SVN_ERR(tree_conflict(merge_b, adm_access, mine,
- svn_node_file,
- svn_wc_conflict_action_add,
- svn_wc_conflict_reason_obstructed));
+ * a versioned file. This file must have been added in the
+ * history of the merge target, hence we flag a tree conflict
+ * with reason 'added'. */
+ SVN_ERR(tree_conflict_on_add(
+ merge_b, adm_access, mine, svn_node_file,
+ svn_wc_conflict_action_add,
+ svn_wc_conflict_reason_added));
+
if (tree_conflicted)
*tree_conflicted = TRUE;
}
@@ -1879,10 +1979,10 @@ merge_dir_added(svn_wc_adm_access_t *adm
else
{
/* This is a tree conflict. */
- SVN_ERR(tree_conflict(merge_b, adm_access, path,
- svn_node_dir,
- svn_wc_conflict_action_add,
- svn_wc_conflict_reason_added));
+ SVN_ERR(tree_conflict_on_add(merge_b, adm_access, path,
+ svn_node_dir,
+ svn_wc_conflict_action_add,
+ svn_wc_conflict_reason_added));
if (tree_conflicted)
*tree_conflicted = TRUE;
if (state)
@@ -1906,10 +2006,10 @@ merge_dir_added(svn_wc_adm_access_t *adm
{
/* Obstructed: we can't add a dir because there's a file here
* (whatever the entry says should be here). */
- SVN_ERR(tree_conflict(merge_b, adm_access, path,
- svn_node_dir,
- svn_wc_conflict_action_add,
- svn_wc_conflict_reason_obstructed));
+ SVN_ERR(tree_conflict_on_add(merge_b, adm_access, path,
+ svn_node_dir,
+ svn_wc_conflict_action_add,
+ svn_wc_conflict_reason_obstructed));
if (tree_conflicted)
*tree_conflicted = TRUE;
if (state)
@@ -2006,9 +2106,19 @@ merge_dir_deleted(svn_wc_adm_access_t *a
merge_b->ctx, subpool);
if (err)
{
- if (state)
- *state = svn_wc_notify_state_obstructed;
svn_error_clear(err);
+
+ /* If the attempt to delete an existing directory failed,
+ * the directory has local modifications (e.g. locally added
+ * files, or property changes). Flag a tree conflict. */
+ SVN_ERR(tree_conflict(merge_b, adm_access, path,
+ svn_node_dir,
+ svn_wc_conflict_action_delete,
+ svn_wc_conflict_reason_edited));
+ if (tree_conflicted)
+ *tree_conflicted = TRUE;
+ if (state)
+ *state = svn_wc_notify_state_conflicted;
}
else
{
@@ -2742,7 +2852,7 @@ get_full_mergeinfo(svn_mergeinfo_t *reco
svn_boolean_t inherited;
SVN_ERR(svn_client__get_wc_or_repos_mergeinfo(recorded_mergeinfo, entry,
&inherited, FALSE,
- inherit, ra_session,
+ inherit, NULL,
target_wcpath,
adm_access, ctx, pool));
if (indirect)
@@ -2838,11 +2948,11 @@ get_full_mergeinfo(svn_mergeinfo_t *reco
return SVN_NO_ERROR;
}
-/* Helper for filter_merged_revisions().
+/* Helper for ensure_implicit_mergeinfo().
PARENT, CHILD, REVISION1, REVISION2, RA_SESSION, ADM_ACCESS, and CTX
are all cascaded from the arguments of the same names in
- calculate_remaining_ranges(). PARENT and CHILD must both exist, i.e.
+ ensure_implicit_mergeinfo(). PARENT and CHILD must both exist, i.e.
this function should never be called where CHILD is the merge target.
If PARENT->IMPLICIT_MERGEINFO is NULL, obtain it from the server.
@@ -2861,7 +2971,7 @@ inherit_implicit_mergeinfo_from_parent(s
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
- const char *path_diff;
+ const char *path_diff, *common_ancestor;
/* This only works on subtrees! */
SVN_ERR_ASSERT(parent);
@@ -2879,7 +2989,21 @@ inherit_implicit_mergeinfo_from_parent(s
/* Let CHILD inherit PARENT's implicit mergeinfo. */
child->implicit_mergeinfo = apr_hash_make(pool);
- path_diff = svn_path_basename(child->path, pool);
+
+ /* Find the longest common ancestor path*/
+ common_ancestor = svn_dirent_get_longest_ancestor(child->path,
+ parent->path, pool);
+
+ /* PARENT->PATH better be an ancestor of CHILD->PATH! */
+ SVN_ERR_ASSERT(common_ancestor);
+
+ /* Calculate the pathwise difference between the longest common ancestor
+ and CHILD->PATH. */
+ path_diff = apr_pstrdup(pool, (child->path + strlen(common_ancestor)));
+
+ if (path_diff[0] == '/') /* Remove any leading '/'. */
+ path_diff++;
+
SVN_ERR(svn_client__adjust_mergeinfo_source_paths(
child->implicit_mergeinfo, path_diff,
parent->implicit_mergeinfo, pool));
@@ -2889,8 +3013,10 @@ inherit_implicit_mergeinfo_from_parent(s
/* Helper of filter_merged_revisions().
If we have deferred obtaining CHILD->IMPLICIT_MERGEINFO, then get
- it now, allocating it in RESULT_POOL. Use SCRATCH_POOL for all
- temporary allocations.
+ it now, allocating it in RESULT_POOL. If CHILD_INHERITS_PARENT is true
+ then set CHILD->IMPLICIT_MERGEINFO to the mergeinfo inherited from
+ PARNET->IMPLICIT_MERGEINFO, otherwise contact the repository. Use
+ SCRATCH_POOL for all temporary allocations.
PARENT, CHILD, ENTRY, REVISION1, REVISION2, RA_SESSION, ADM_ACCESS, and
CTX are all cascased from the arguments of the same name in
@@ -2899,6 +3025,7 @@ inherit_implicit_mergeinfo_from_parent(s
static svn_error_t *
ensure_implicit_mergeinfo(svn_client__merge_path_t *parent,
svn_client__merge_path_t *child,
+ svn_boolean_t child_inherits_parent,
const svn_wc_entry_t *entry,
svn_revnum_t revision1,
svn_revnum_t revision2,
@@ -2914,15 +3041,7 @@ ensure_implicit_mergeinfo(svn_client__me
if (child->implicit_mergeinfo)
return SVN_NO_ERROR;
-
- /* If CHILD has explicit mergeinfo only because its parent has
- non-inheritable mergeinfo (see criteria 3 in
- get_mergeinfo_paths() then CHILD can inherit PARENT's
- implicit mergeinfo and we can avoid contacting the server.
-
- If child->child_of_noninheritable is true, it implies that
- PARENT must exist per the rules of get_mergeinfo_paths(). */
- if (child->child_of_noninheritable)
+ if (child_inherits_parent)
SVN_ERR(inherit_implicit_mergeinfo_from_parent(parent,
child,
revision1,
@@ -2956,9 +3075,14 @@ ensure_implicit_mergeinfo(svn_client__me
CHILD->REMAINING_RANGES that have not alreay been merged to CHILD->PATH.
CHILD represents a working copy path which is the merge target or one of
- target's subtrees, if not NULL, PARENT is CHILD's nearest path-wise
+ the target's subtrees. If not NULL, PARENT is CHILD's nearest path-wise
ancestor - see 'THE CHILDREN_WITH_MERGEINFO ARRAY'.
+ If the function needs to consider CHILD->IMPLICIT_MERGEINFO and
+ CHILD_INHERITS_IMPLICIT is true, then set CHILD->IMPLICIT_MERGEINFO to the
+ mergeinfo inherited from PARENT->IMPLICIT_MERGEINFO. Otherwise contact
+ the repository for CHILD->IMPLICIT_MERGEINFO.
+
NOTE: If PARENT is present then this function must have previously been
called for PARENT, i.e. if populate_remaining_ranges() is calling this
function for a set of svn_client__merge_path_t* the calls must be made
@@ -2987,6 +3111,7 @@ filter_merged_revisions(svn_client__merg
svn_mergeinfo_t target_mergeinfo,
svn_revnum_t revision1,
svn_revnum_t revision2,
+ svn_boolean_t child_inherits_implicit,
svn_ra_session_t *ra_session,
svn_wc_adm_access_t *adm_access,
svn_client_ctx_t *ctx,
@@ -3075,6 +3200,7 @@ filter_merged_revisions(svn_client__merg
SVN_ERR(ensure_implicit_mergeinfo(parent,
child,
+ child_inherits_implicit,
entry,
revision1,
revision2,
@@ -3161,9 +3287,10 @@ filter_merged_revisions(svn_client__merg
{
/* Based on CHILD's TARGET_MERGEINFO there are ranges to merge.
Check CHILD's implicit mergeinfo to see if these remaining
- ranges are represented there. */
+ ranges are represented there. */
SVN_ERR(ensure_implicit_mergeinfo(parent,
child,
+ child_inherits_implicit,
entry,
revision1,
revision2,
@@ -3216,6 +3343,11 @@ filter_merged_revisions(svn_client__merg
normalization conditions do not necessarily hold. IS_SUBTREE should
always be FALSE when calling from do_file_merge().
+ If the function needs to consider CHILD->IMPLICIT_MERGEINFO and
+ CHILD_INHERITS_IMPLICIT is true, then set CHILD->IMPLICIT_MERGEINFO to the
+ mergeinfo inherited from PARENT->IMPLICIT_MERGEINFO. Otherwise contact
+ the repository for CHILD->IMPLICIT_MERGEINFO.
+
If IS_SUBTREE is FALSE then PARENT is ignored, otherwise PARENT must
represent the nearest working copy ancestor of CHILD.
@@ -3245,6 +3377,7 @@ calculate_remaining_ranges(svn_client__m
svn_mergeinfo_t target_mergeinfo,
apr_array_header_t *implicit_src_gap,
svn_boolean_t is_subtree,
+ svn_boolean_t child_inherits_implicit,
svn_ra_session_t *ra_session,
const svn_wc_entry_t *entry,
svn_wc_adm_access_t *adm_access,
@@ -3293,17 +3426,33 @@ calculate_remaining_ranges(svn_client__m
SVN_ERR(filter_merged_revisions(parent, child, entry, mergeinfo_path,
adjusted_target_mergeinfo,
revision1, revision2,
+ child_inherits_implicit,
ra_session, adm_access, ctx, pool));
if (is_subtree)
{
apr_array_header_t *deleted_rangelist, *added_rangelist;
+ svn_boolean_t is_rollback = revision2 < revision1;
+
+ /* If this is a reverse merge reorder CHILD->REMAINING_RANGES
+ so it will work with the svn_rangelist_diff API. */
+ if (is_rollback)
+ {
+ SVN_ERR(svn_rangelist_reverse(child->remaining_ranges, pool));
+ SVN_ERR(svn_rangelist_reverse(parent->remaining_ranges, pool));
+ }
SVN_ERR(svn_rangelist_diff(&deleted_rangelist, &added_rangelist,
child->remaining_ranges,
parent->remaining_ranges,
TRUE, pool));
+ if (is_rollback)
+ {
+ SVN_ERR(svn_rangelist_reverse(child->remaining_ranges, pool));
+ SVN_ERR(svn_rangelist_reverse(parent->remaining_ranges, pool));
+ }
+
/* If CHILD is the merge target we then know that primary_url,
REVISION1, and REVISION2 are provided by normalize_merge_sources()
-- see 'MERGEINFO MERGE SOURCE NORMALIZATION'. Due to this
@@ -3630,6 +3779,7 @@ populate_remaining_ranges(apr_array_head
svn_client__merge_path_t *child =
APR_ARRAY_IDX(children_with_mergeinfo, i, svn_client__merge_path_t *);
svn_client__merge_path_t *parent = NULL;
+ svn_boolean_t child_inherits_implicit;
/* If the path is absent don't do subtree merge either. */
SVN_ERR_ASSERT(child);
@@ -3680,6 +3830,13 @@ populate_remaining_ranges(apr_array_head
SVN_ERR_ASSERT(parent);
}
+ /* Issue #3443 - Can CHILD inherit PARENT's implicit mergeinfo, saving
+ us from having to ask the repos? The only time we can't do this is if
+ CHILD is the merge target and so there is no PARENT to inherit from
+ or if CHILD is the root of a switched subtree, in which case PARENT
+ exists but is not CHILD's repository parent. */
+ child_inherits_implicit = (parent && !child->switched);
+
SVN_ERR(calculate_remaining_ranges(parent, child,
source_root_url,
child_url1, revision1,
@@ -3687,6 +3844,7 @@ populate_remaining_ranges(apr_array_head
child->pre_merge_mergeinfo,
merge_b->implicit_src_gap,
i > 0, /* is subtree */
+ child_inherits_implicit,
ra_session, child_entry,
adm_access, merge_b->ctx,
pool));
@@ -5309,7 +5467,6 @@ get_mergeinfo_paths(apr_array_header_t *
child_of_noninheritable =
apr_pcalloc(pool,
sizeof(*child_of_noninheritable));
- child_of_noninheritable->child_of_noninheritable = TRUE;
child_of_noninheritable->path =
apr_pstrdup(pool,
child_path);
@@ -6018,7 +6175,7 @@ do_file_merge(const char *url1,
url1, revision1, url2, revision2,
target_mergeinfo,
merge_b->implicit_src_gap, FALSE,
- merge_b->ra_session1,
+ FALSE, merge_b->ra_session1,
entry, adm_access, ctx, pool));
remaining_ranges = merge_target->remaining_ranges;
}
@@ -7851,6 +8008,9 @@ ensure_all_missing_ranges_are_phantoms(s
path@TARGET_REV. Effectively this is the mergeinfo catalog on the
reintegrate target.
+ YC_ANCESTOR_REV is the revision of the youngest common ancestor of the
+ reintegrate source and the reintegrate target.
+
SOURCE_REPOS_REL_PATH is the path of the reintegrate source relative to
the root of the repository. TARGET_REPOS_REL_PATH is the path of the
reintegrate target relative to the root of the repository.
@@ -7884,6 +8044,7 @@ static svn_error_t *
find_unmerged_mergeinfo(svn_mergeinfo_catalog_t *unmerged_to_source_catalog,
svn_boolean_t *never_synched,
svn_revnum_t *youngest_merged_rev,
+ svn_revnum_t yc_ancestor_rev,
svn_mergeinfo_catalog_t source_catalog,
apr_hash_t *target_segments_hash,
const char *source_repos_rel_path,
@@ -7933,6 +8094,16 @@ find_unmerged_mergeinfo(svn_mergeinfo_ca
segments,
iterpool));
+ /* Remove any target history that is also part of the source's history,
+ i.e. their common ancestry. By definition this has already been
+ "merged" from the target to the source. If the source has explict
+ self referential mergeinfo it would intersect with the target's
+ history below, making it appear that some merges had been done from
+ the target to the source, when this might not actually be the case. */
+ SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(
+ &target_history_as_mergeinfo, target_history_as_mergeinfo,
+ source_rev, yc_ancestor_rev, iterpool));
+
/* Look for any explicit mergeinfo on the source path corresponding to
the target path. If we find any remove that from SOURCE_CATALOG.
When this iteration over TARGET_SEGMENTS_HASH is complete all that
@@ -8222,6 +8393,9 @@ calculate_left_hand_side(const char **ur
apr_hash_t *segments_hash = apr_hash_make(pool);
svn_boolean_t never_synced;
svn_revnum_t youngest_merged_rev;
+ const char *yc_ancestor_path;
+ const char *source_url;
+ const char *target_url;
/* Get the history (segments) for the target and any of its subtrees
with explicit mergeinfo. */
@@ -8246,6 +8420,26 @@ calculate_left_hand_side(const char **ur
APR_HASH_KEY_STRING, segments);
}
+ /* Check that SOURCE_URL@SOURCE_REV and TARGET_URL@TARGET_REV are
+ actually related, we can't reintegrate if they are not. Also
+ get an initial value for *REV_LEFT. */
+ source_url = svn_path_url_add_component2(source_repos_root,
+ source_repos_rel_path,
+ subpool),
+ target_url = svn_path_url_add_component2(source_repos_root,
+ target_repos_rel_path,
+ subpool);
+ SVN_ERR(svn_client__get_youngest_common_ancestor(&yc_ancestor_path,
+ rev_left,
+ source_url, source_rev,
+ target_url, target_rev,
+ ctx, subpool));
+ if (!(yc_ancestor_path && SVN_IS_VALID_REVNUM(*rev_left)))
+ return svn_error_createf(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
+ _("'%s@%ld' must be ancestrally related to "
+ "'%s@%ld'"), source_url, source_rev,
+ target_url, target_rev);
+
/* Get the mergeinfo from the source, including its descendants
with differing explicit mergeinfo. */
APR_ARRAY_PUSH(source_repos_rel_path_as_array, const char *)
@@ -8263,6 +8457,7 @@ calculate_left_hand_side(const char **ur
SVN_ERR(find_unmerged_mergeinfo(&unmerged_catalog,
&never_synced,
&youngest_merged_rev,
+ *rev_left,
mergeinfo_catalog,
segments_hash,
source_repos_rel_path,
@@ -8282,24 +8477,6 @@ calculate_left_hand_side(const char **ur
if (never_synced)
{
/* We never merged to the source. Just return the branch point. */
- const char *yc_ancestor_path,
- *source_url = svn_path_url_add_component2(source_repos_root,
- source_repos_rel_path,
- subpool),
- *target_url = svn_path_url_add_component2(source_repos_root,
- target_repos_rel_path,
- subpool);
-
- SVN_ERR(svn_client__get_youngest_common_ancestor(&yc_ancestor_path,
- rev_left,
- source_url, source_rev,
- target_url, target_rev,
- ctx, subpool));
- if (!(yc_ancestor_path && SVN_IS_VALID_REVNUM(*rev_left)))
- return svn_error_createf(SVN_ERR_CLIENT_NOT_READY_TO_MERGE, NULL,
- _("'%s@%ld' must be ancestrally related to "
- "'%s@%ld'"), source_url, source_rev,
- target_url, target_rev);
*url_left = svn_path_url_add_component2(source_repos_root,
yc_ancestor_path, pool);
}
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_client/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_client/mergeinfo.c?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_client/mergeinfo.c (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_client/mergeinfo.c Tue Mar 16 18:03:37 2010
@@ -304,15 +304,10 @@ svn_client__get_repos_mergeinfo(svn_ra_s
{
svn_error_t *err;
svn_mergeinfo_t repos_mergeinfo;
- const char *old_session_url;
apr_array_header_t *rel_paths = apr_array_make(pool, 1, sizeof(rel_path));
APR_ARRAY_PUSH(rel_paths, const char *) = rel_path;
- /* Temporarily point the session at the root of the repository. */
- SVN_ERR(svn_client__ensure_ra_session_url(&old_session_url, ra_session,
- NULL, pool));
-
/* Fetch the mergeinfo. */
err = svn_ra_get_mergeinfo(ra_session, &repos_mergeinfo, rel_paths, rev,
inherit, FALSE, pool);
@@ -327,10 +322,6 @@ svn_client__get_repos_mergeinfo(svn_ra_s
return err;
}
- /* If we reparented the session, put it back where our caller had it. */
- if (old_session_url)
- SVN_ERR(svn_ra_reparent(ra_session, old_session_url, pool));
-
/* Grab only the mergeinfo provided for REL_PATH. */
if (repos_mergeinfo)
*target_mergeinfo = apr_hash_get(repos_mergeinfo, rel_path,
@@ -392,21 +383,28 @@ svn_client__get_wc_or_repos_mergeinfo(sv
NULL, ctx, pool));
if (apr_hash_get(props, target_wcpath, APR_HASH_KEY_STRING) == NULL)
{
- const char *repos_rel_path;
+ const char *session_url = NULL;
+ apr_pool_t *sesspool = NULL;
- if (ra_session == NULL)
- SVN_ERR(svn_client__open_ra_session_internal(&ra_session, url,
- NULL, NULL, NULL,
- FALSE, TRUE, ctx,
- pool));
-
- SVN_ERR(svn_client__path_relative_to_root(&repos_rel_path, url,
- entry->repos, FALSE,
- ra_session, NULL,
- pool));
+ if (ra_session)
+ {
+ SVN_ERR(svn_client__ensure_ra_session_url(&session_url,
+ ra_session,
+ url, pool));
+ }
+ else
+ {
+ sesspool = svn_pool_create(pool);
+ SVN_ERR(svn_client__open_ra_session_internal(&ra_session, url,
+ NULL, NULL, NULL,
+ FALSE, TRUE,
+ ctx,
+ sesspool));
+ }
+
SVN_ERR(svn_client__get_repos_mergeinfo(ra_session,
&repos_mergeinfo,
- repos_rel_path,
+ "",
target_rev,
inherit,
TRUE,
@@ -416,6 +414,18 @@ svn_client__get_wc_or_repos_mergeinfo(sv
*target_mergeinfo = repos_mergeinfo;
*indirect = TRUE;
}
+
+ /* If we created an RA_SESSION above, destroy it.
+ Otherwise, if reparented an existing session, point
+ it back where it was when we were called. */
+ if (sesspool)
+ {
+ svn_pool_destroy(sesspool);
+ }
+ else if (session_url)
+ {
+ SVN_ERR(svn_ra_reparent(ra_session, session_url, pool));
+ }
}
}
}
Modified: subversion/branches/1.6.x-issue3432/subversion/libsvn_client/mergeinfo.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x-issue3432/subversion/libsvn_client/mergeinfo.h?rev=923910&r1=923909&r2=923910&view=diff
==============================================================================
--- subversion/branches/1.6.x-issue3432/subversion/libsvn_client/mergeinfo.h (original)
+++ subversion/branches/1.6.x-issue3432/subversion/libsvn_client/mergeinfo.h Tue Mar 16 18:03:37 2010
@@ -45,11 +45,6 @@ typedef struct svn_client__merge_path_t
svn_boolean_t absent; /* PATH is absent from the WC, probably
due to authz restrictions. */
- svn_boolean_t child_of_noninheritable; /* PATH has no explict mergeinfo
- itself but is the child of a
- path with noniheritable
- mergeinfo. */
-
/* The remaining ranges to be merged to PATH. When describing a forward
merge this rangelist adheres to the rules for rangelists described in
svn_mergeinfo.h. However, when describing reverse merges this
@@ -108,11 +103,9 @@ svn_client__get_wc_mergeinfo(svn_mergein
svn_client_ctx_t *ctx,
apr_pool_t *pool);
-/* Obtain any mergeinfo for the root-relative repository filesystem path
- REL_PATH from the repository, and set it in *TARGET_MERGEINFO.
- RA_SESSION should be an open RA session pointing at the URL that REL_PATH
- is relative to, or NULL, in which case this function will open its own
- temporary session.
+/* Obtain any mergeinfo for repository filesystem path REL_PATH
+ (relative to RA_SESSION's session URL) from the repository, and set
+ it in *TARGET_MERGEINFO.
INHERIT indicates whether explicit, explicit or inherited, or only
inherited mergeinfo for REL_PATH is obtained.
@@ -138,18 +131,18 @@ svn_client__get_repos_mergeinfo(svn_ra_s
target has no info of its own.
If no mergeinfo can be obtained from the WC or REPOS_ONLY is TRUE,
- get it from the repository. RA_SESSION should be an open RA session
- pointing at ENTRY->URL, or NULL, in which case this function will open
- its own temporary session.
+ get it from the repository. RA_SESSION should be an open RA
+ session pointing at ENTRY->URL, or NULL, in which case this
+ function will open its own temporary session.
(opening a new RA session if RA_SESSION
is NULL). Store any mergeinfo obtained for TARGET_WCPATH -- which
is reflected by ENTRY -- in *TARGET_MERGEINFO, if no mergeinfo is
found *TARGET_MERGEINFO is NULL.
- Like svn_client__get_wc_mergeinfo, this function considers no inherited
- mergeinfo to be found in the WC when trying to crawl into a parent path
- with a different working revision.
+ Like svn_client__get_wc_mergeinfo(), this function considers no
+ inherited mergeinfo to be found in the WC when trying to crawl into
+ a parent path with a different working revision.
INHERIT indicates whether explicit, explicit or inherited, or only
inherited mergeinfo for TARGET_WCPATH is retrieved.