You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by vm...@apache.org on 2012/12/24 23:47:16 UTC
svn commit: r1425690 [1/6] - in /subversion/branches/javahl-ra: ./
contrib/server-side/fsfsfixer/ notes/ subversion/include/
subversion/include/private/ subversion/libsvn_client/
subversion/libsvn_delta/ subversion/libsvn_fs_fs/ subversion/libsvn_ra/ s...
Author: vmpn
Date: Mon Dec 24 22:47:14 2012
New Revision: 1425690
URL: http://svn.apache.org/viewvc?rev=1425690&view=rev
Log:
On the javahl-ra branch:
Bring up-to-date with trunk@1405516
Added:
subversion/branches/javahl-ra/subversion/libsvn_ra/deprecated.h
- copied unchanged from r1405516, subversion/trunk/subversion/libsvn_ra/deprecated.h
subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_update_move.c
- copied unchanged from r1405516, subversion/trunk/subversion/libsvn_wc/wc_db_update_move.c
subversion/branches/javahl-ra/subversion/tests/cmdline/import_tests_data/ (props changed)
- copied from r1405516, subversion/trunk/subversion/tests/cmdline/import_tests_data/
subversion/branches/javahl-ra/subversion/tests/cmdline/merge_automatic_tests.py
- copied unchanged from r1405516, subversion/trunk/subversion/tests/cmdline/merge_automatic_tests.py
subversion/branches/javahl-ra/tools/dev/benchmarks/suite1/generate_charts
- copied unchanged from r1405516, subversion/trunk/tools/dev/benchmarks/suite1/generate_charts
Removed:
subversion/branches/javahl-ra/subversion/tests/cmdline/merge_symmetric_tests.py
Modified:
subversion/branches/javahl-ra/ (props changed)
subversion/branches/javahl-ra/COMMITTERS
subversion/branches/javahl-ra/configure.ac
subversion/branches/javahl-ra/contrib/server-side/fsfsfixer/fix-repo
subversion/branches/javahl-ra/notes/fsfs
subversion/branches/javahl-ra/subversion/include/private/svn_client_private.h
subversion/branches/javahl-ra/subversion/include/private/svn_named_atomic.h
subversion/branches/javahl-ra/subversion/include/private/svn_ra_private.h
subversion/branches/javahl-ra/subversion/include/svn_client.h
subversion/branches/javahl-ra/subversion/include/svn_dav.h
subversion/branches/javahl-ra/subversion/include/svn_delta.h
subversion/branches/javahl-ra/subversion/include/svn_error_codes.h
subversion/branches/javahl-ra/subversion/include/svn_props.h
subversion/branches/javahl-ra/subversion/include/svn_ra_svn.h
subversion/branches/javahl-ra/subversion/libsvn_client/add.c
subversion/branches/javahl-ra/subversion/libsvn_client/client.h
subversion/branches/javahl-ra/subversion/libsvn_client/commit.c
subversion/branches/javahl-ra/subversion/libsvn_client/commit_util.c
subversion/branches/javahl-ra/subversion/libsvn_client/copy.c
subversion/branches/javahl-ra/subversion/libsvn_client/delete.c
subversion/branches/javahl-ra/subversion/libsvn_client/merge.c
subversion/branches/javahl-ra/subversion/libsvn_client/prop_commands.c
subversion/branches/javahl-ra/subversion/libsvn_delta/compat.c
subversion/branches/javahl-ra/subversion/libsvn_delta/deprecated.c
subversion/branches/javahl-ra/subversion/libsvn_delta/path_driver.c
subversion/branches/javahl-ra/subversion/libsvn_fs_fs/fs.h
subversion/branches/javahl-ra/subversion/libsvn_fs_fs/fs_fs.c
subversion/branches/javahl-ra/subversion/libsvn_fs_fs/structure
subversion/branches/javahl-ra/subversion/libsvn_ra/compat.c
subversion/branches/javahl-ra/subversion/libsvn_ra/deprecated.c
subversion/branches/javahl-ra/subversion/libsvn_ra/editor.c
subversion/branches/javahl-ra/subversion/libsvn_ra/ra_loader.c
subversion/branches/javahl-ra/subversion/libsvn_ra/ra_loader.h
subversion/branches/javahl-ra/subversion/libsvn_ra_serf/commit.c
subversion/branches/javahl-ra/subversion/libsvn_ra_serf/options.c
subversion/branches/javahl-ra/subversion/libsvn_ra_serf/property.c
subversion/branches/javahl-ra/subversion/libsvn_ra_serf/ra_serf.h
subversion/branches/javahl-ra/subversion/libsvn_ra_serf/serf.c
subversion/branches/javahl-ra/subversion/libsvn_ra_serf/util.c
subversion/branches/javahl-ra/subversion/libsvn_ra_serf/util_error.c
subversion/branches/javahl-ra/subversion/libsvn_ra_svn/client.c
subversion/branches/javahl-ra/subversion/libsvn_ra_svn/cyrus_auth.c
subversion/branches/javahl-ra/subversion/libsvn_ra_svn/marshal.c
subversion/branches/javahl-ra/subversion/libsvn_repos/fs-wrap.c
subversion/branches/javahl-ra/subversion/libsvn_repos/replay.c
subversion/branches/javahl-ra/subversion/libsvn_subr/cache-membuffer.c
subversion/branches/javahl-ra/subversion/libsvn_subr/io.c
subversion/branches/javahl-ra/subversion/libsvn_subr/named_atomic.c
subversion/branches/javahl-ra/subversion/libsvn_subr/path.c
subversion/branches/javahl-ra/subversion/libsvn_subr/sqlite.c
subversion/branches/javahl-ra/subversion/libsvn_subr/subst.c
subversion/branches/javahl-ra/subversion/libsvn_subr/temp_serializer.c
subversion/branches/javahl-ra/subversion/libsvn_subr/utf.c
subversion/branches/javahl-ra/subversion/libsvn_wc/adm_files.c
subversion/branches/javahl-ra/subversion/libsvn_wc/adm_ops.c
subversion/branches/javahl-ra/subversion/libsvn_wc/cleanup.c
subversion/branches/javahl-ra/subversion/libsvn_wc/conflicts.c
subversion/branches/javahl-ra/subversion/libsvn_wc/conflicts.h
subversion/branches/javahl-ra/subversion/libsvn_wc/context.c
subversion/branches/javahl-ra/subversion/libsvn_wc/entries.c
subversion/branches/javahl-ra/subversion/libsvn_wc/entries.h
subversion/branches/javahl-ra/subversion/libsvn_wc/lock.c
subversion/branches/javahl-ra/subversion/libsvn_wc/lock.h
subversion/branches/javahl-ra/subversion/libsvn_wc/node.c
subversion/branches/javahl-ra/subversion/libsvn_wc/old-and-busted.c
subversion/branches/javahl-ra/subversion/libsvn_wc/props.c
subversion/branches/javahl-ra/subversion/libsvn_wc/status.c
subversion/branches/javahl-ra/subversion/libsvn_wc/tree_conflicts.c
subversion/branches/javahl-ra/subversion/libsvn_wc/update_editor.c
subversion/branches/javahl-ra/subversion/libsvn_wc/upgrade.c
subversion/branches/javahl-ra/subversion/libsvn_wc/util.c
subversion/branches/javahl-ra/subversion/libsvn_wc/wc.h
subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db.c
subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db.h
subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_private.h
subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_util.c
subversion/branches/javahl-ra/subversion/libsvn_wc/wc_db_wcroot.c
subversion/branches/javahl-ra/subversion/mod_dav_svn/dav_svn.h
subversion/branches/javahl-ra/subversion/mod_dav_svn/deadprops.c
subversion/branches/javahl-ra/subversion/mod_dav_svn/liveprops.c
subversion/branches/javahl-ra/subversion/mod_dav_svn/mod_dav_svn.c
subversion/branches/javahl-ra/subversion/mod_dav_svn/reports/file-revs.c
subversion/branches/javahl-ra/subversion/mod_dav_svn/reports/replay.c
subversion/branches/javahl-ra/subversion/mod_dav_svn/reports/update.c
subversion/branches/javahl-ra/subversion/mod_dav_svn/repos.c
subversion/branches/javahl-ra/subversion/mod_dav_svn/util.c
subversion/branches/javahl-ra/subversion/mod_dav_svn/version.c
subversion/branches/javahl-ra/subversion/po/es.po
subversion/branches/javahl-ra/subversion/po/pl.po
subversion/branches/javahl-ra/subversion/po/pt_BR.po
subversion/branches/javahl-ra/subversion/po/zh_TW.po
subversion/branches/javahl-ra/subversion/svn/conflict-callbacks.c
subversion/branches/javahl-ra/subversion/svn/merge-cmd.c
subversion/branches/javahl-ra/subversion/svn/mergeinfo-cmd.c
subversion/branches/javahl-ra/subversion/svnadmin/main.c
subversion/branches/javahl-ra/subversion/svnrdump/svnrdump.c
subversion/branches/javahl-ra/subversion/svnserve/cyrus_auth.c
subversion/branches/javahl-ra/subversion/svnserve/main.c
subversion/branches/javahl-ra/subversion/svnserve/serve.c
subversion/branches/javahl-ra/subversion/svnserve/server.h
subversion/branches/javahl-ra/subversion/tests/cmdline/autoprop_tests.py
subversion/branches/javahl-ra/subversion/tests/cmdline/export_tests.py
subversion/branches/javahl-ra/subversion/tests/cmdline/externals_tests.py
subversion/branches/javahl-ra/subversion/tests/cmdline/import_tests.py
subversion/branches/javahl-ra/subversion/tests/cmdline/import_tests_data/import_tree/ (props changed)
subversion/branches/javahl-ra/subversion/tests/cmdline/import_tests_data/import_tree/DIR1.noo/ (props changed)
subversion/branches/javahl-ra/subversion/tests/cmdline/import_tests_data/import_tree/DIR2.doo/ (props changed)
subversion/branches/javahl-ra/subversion/tests/cmdline/import_tests_data/import_tree/DIR3.foo/ (props changed)
subversion/branches/javahl-ra/subversion/tests/cmdline/import_tests_data/import_tree/DIR4.goo/ (props changed)
subversion/branches/javahl-ra/subversion/tests/cmdline/import_tests_data/import_tree/DIR5.moo/ (props changed)
subversion/branches/javahl-ra/subversion/tests/cmdline/import_tests_data/import_tree/DIR6/ (props changed)
subversion/branches/javahl-ra/subversion/tests/cmdline/import_tests_data/import_tree/DIR6/DIR7/ (props changed)
subversion/branches/javahl-ra/subversion/tests/cmdline/import_tests_data/import_tree/DIR6/DIR7/DIR8.noo/ (props changed)
subversion/branches/javahl-ra/subversion/tests/cmdline/merge_tests.py
subversion/branches/javahl-ra/subversion/tests/cmdline/prop_tests.py
subversion/branches/javahl-ra/subversion/tests/cmdline/svnadmin_tests.py
subversion/branches/javahl-ra/subversion/tests/cmdline/svntest/main.py
subversion/branches/javahl-ra/subversion/tests/cmdline/update_tests.py
subversion/branches/javahl-ra/subversion/tests/cmdline/upgrade_tests.py
subversion/branches/javahl-ra/subversion/tests/libsvn_subr/named_atomic-test.c
subversion/branches/javahl-ra/subversion/tests/libsvn_wc/conflict-data-test.c
subversion/branches/javahl-ra/subversion/tests/libsvn_wc/db-test.c
subversion/branches/javahl-ra/subversion/tests/libsvn_wc/entries-compat.c
subversion/branches/javahl-ra/subversion/tests/libsvn_wc/op-depth-test.c
subversion/branches/javahl-ra/subversion/tests/libsvn_wc/utils.c
subversion/branches/javahl-ra/tools/client-side/svn-bench/main.c
subversion/branches/javahl-ra/tools/client-side/svn-bench/null-log-cmd.c
subversion/branches/javahl-ra/tools/dev/benchmarks/suite1/benchmark.py
subversion/branches/javahl-ra/tools/dev/benchmarks/suite1/cronjob
subversion/branches/javahl-ra/tools/dev/benchmarks/suite1/run
subversion/branches/javahl-ra/tools/dev/svnraisetreeconflict/main.c
subversion/branches/javahl-ra/tools/dist/make-deps-tarball.sh (props changed)
subversion/branches/javahl-ra/tools/hook-scripts/persist-ephemeral-txnprops.py
subversion/branches/javahl-ra/tools/server-side/svnpubsub/svnwcsub.py
Propchange: subversion/branches/javahl-ra/
------------------------------------------------------------------------------
Reverse-merged /subversion/branches/http-dynamic-prop-namespaces:r1396196-1398972
Merged /subversion/branches/auto-props-sdc:r1384106-1401643
Merged /subversion/trunk:r1399495-1405516
Modified: subversion/branches/javahl-ra/COMMITTERS
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/COMMITTERS?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/COMMITTERS [UTF-8] (original)
+++ subversion/branches/javahl-ra/COMMITTERS [UTF-8] Mon Dec 24 22:47:14 2012
@@ -41,7 +41,7 @@ Blanket commit access:
lgo Lieven Govaerts <lg...@mobsol.be>
hwright Hyrum Wright <hy...@hyrumwright.org>
vgeorgescu Vlad Georgescu <vg...@gmail.com>
- kameshj Kamesh Jayachandran <ka...@collab.net>
+ kameshj Kamesh Jayachandran <ka...@gmail.com>
markphip Mark Phippard <mp...@collab.net>
arfrever Arfrever Frehtes Taifersar Arahesis <ar...@gmail.com>
stsp Stefan Sperling <st...@elego.de>
Modified: subversion/branches/javahl-ra/configure.ac
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/configure.ac?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/configure.ac (original)
+++ subversion/branches/javahl-ra/configure.ac Mon Dec 24 22:47:14 2012
@@ -1017,6 +1017,11 @@ AS_HELP_STRING([--enable-maintainer-mode
CFLAGS="-Wno-system-headers $CFLAGS_KEEP"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[]])], [CFLAGS_KEEP="$CFLAGS"])
+ dnl Put this flag behind -Wall:
+
+ CFLAGS="$CFLAGS_KEEP -Wno-format-nonliteral"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[]])], [CFLAGS_KEEP="$CFLAGS"])
+
AC_LANG_POP([C])
CFLAGS="$CFLAGS_KEEP"
fi
Modified: subversion/branches/javahl-ra/contrib/server-side/fsfsfixer/fix-repo
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/contrib/server-side/fsfsfixer/fix-repo?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/contrib/server-side/fsfsfixer/fix-repo (original)
+++ subversion/branches/javahl-ra/contrib/server-side/fsfsfixer/fix-repo Mon Dec 24 22:47:14 2012
@@ -5,6 +5,7 @@ Usage: $0 REPO-DIR START-REV
Backup your repository before running these scripts."
+THIS_DIR=`dirname "$0"`
REPO_DIR="$1"
START_REV="$2"
@@ -13,7 +14,7 @@ if [ ! -d "$REPO_DIR" ] || [ "$START_REV
exit 1
fi
-YOUNGEST="$(svnlook youngest "$REPO_DIR")"
+YOUNGEST=`svnlook youngest "$REPO_DIR"`
if [ "$YOUNGEST" = "" ]; then
echo "$0: error running 'svnlook youngest $REPO_DIR'"
@@ -25,6 +26,6 @@ echo "Verifying revisions $START_REV thr
REV=$START_REV
while [ $REV -le $YOUNGEST ]; do
echo "=== r$REV"
- ./fixer/fix-rev.py "$REPO_DIR" "$REV"
+ "$THIS_DIR"/fixer/fix-rev.py "$REPO_DIR" "$REV"
REV=`expr $REV + 1`
done
Modified: subversion/branches/javahl-ra/notes/fsfs
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/notes/fsfs?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/notes/fsfs (original)
+++ subversion/branches/javahl-ra/notes/fsfs Mon Dec 24 22:47:14 2012
@@ -234,6 +234,16 @@ repository. The backed-up "current" fil
new revision which wasn't copied, or which was only partially
populated when it was copied.
+[ Update: as of 1.6, FSFS uses an optional SQLite DB, rep-cache.db, when
+rep-sharing is enabled. SQLite provides no guarantee that copying live
+databases will result in copies that are uncorrupt, or that are corrupt but
+will raise an error when accessed. 'svnadmin hotcopy' avoids the problem by
+establishing an appropriate SQLite lock (see svn_sqlite__hotcopy()). User
+code should either use an atomic filesystem snapshot (as with zfs/LVM),
+refrain from copying rep-cache.db, or stop all access to that file before
+copying it (for example, by disabling commits, by establishing a lock a la
+svn_sqlite__hotcopy(), or by using 'svnadmin freeze'). ]
+
The "svnadmin hotcopy" command avoids this problem by copying the
"current" file before copying the revision files. But a backup using
the hotcopy command isn't as efficient as a straight incremental
Modified: subversion/branches/javahl-ra/subversion/include/private/svn_client_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/include/private/svn_client_private.h?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/include/private/svn_client_private.h (original)
+++ subversion/branches/javahl-ra/subversion/include/private/svn_client_private.h Mon Dec 24 22:47:14 2012
@@ -233,12 +233,12 @@ svn_client__wc_node_get_origin(svn_clien
* Any of the output pointers may be NULL if not wanted.
*/
svn_error_t *
-svn_client__symmetric_merge_get_locations(
+svn_client__automatic_merge_get_locations(
svn_client__pathrev_t **yca,
svn_client__pathrev_t **base,
svn_client__pathrev_t **right,
svn_client__pathrev_t **target,
- const svn_client_symmetric_merge_t *merge,
+ const svn_client_automatic_merge_t *merge,
apr_pool_t *result_pool);
Modified: subversion/branches/javahl-ra/subversion/include/private/svn_named_atomic.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/include/private/svn_named_atomic.h?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/include/private/svn_named_atomic.h (original)
+++ subversion/branches/javahl-ra/subversion/include/private/svn_named_atomic.h Mon Dec 24 22:47:14 2012
@@ -83,6 +83,17 @@ svn_atomic_namespace__create(svn_atomic_
const char *name,
apr_pool_t *result_pool);
+/** Removes persistent data structures (files in particular) that got
+ * created for the namespace given by @a name. Use @a pool for temporary
+ * allocations.
+ *
+ * @note You must not call this while the respective namespace is still
+ * in use. Calling this multiple times for the same namespace is safe.
+ */
+svn_error_t *
+svn_atomic_namespace__cleanup(const char *name,
+ apr_pool_t *pool);
+
/** Find the atomic with the specified @a name in namespace @a ns and
* return it in @a *atomic. If no object with that name can be found, the
* behavior depends on @a auto_create. If it is @c FALSE, @a *atomic will
Modified: subversion/branches/javahl-ra/subversion/include/private/svn_ra_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/include/private/svn_ra_private.h?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/include/private/svn_ra_private.h (original)
+++ subversion/branches/javahl-ra/subversion/include/private/svn_ra_private.h Mon Dec 24 22:47:14 2012
@@ -208,8 +208,8 @@ typedef svn_error_t *(*svn_ra__get_copys
CB_BATON is the baton used/shared by the above three callbacks.
- CANCEL_FUNC/BATON is a standard cancellation function, and is used for
- the returned Ev2 editor, and possibly other RA-specific operations.
+ Cancellation is handled through the callbacks provided when SESSION
+ is initially opened.
*EDITOR will be allocated in RESULT_POOL, and all temporary allocations
will be performed in SCRATCH_POOL.
@@ -226,8 +226,6 @@ svn_ra__get_commit_ev2(svn_editor_t **ed
svn_ra__provide_props_cb_t provide_props_cb,
svn_ra__get_copysrc_kind_cb_t get_copysrc_kind_cb,
void *cb_baton,
- svn_cancel_func_t cancel_func,
- void *cancel_baton,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
@@ -259,6 +257,10 @@ svn_ra__replay_range_ev2(svn_ra_session_
svn_ra__replay_revstart_ev2_callback_t revstart_func,
svn_ra__replay_revfinish_ev2_callback_t revfinish_func,
void *replay_baton,
+ svn_ra__provide_base_cb_t provide_base_cb,
+ svn_ra__provide_props_cb_t provide_props_cb,
+ svn_ra__get_copysrc_kind_cb_t get_copysrc_kind_cb,
+ void *cb_baton,
apr_pool_t *scratch_pool);
/* Similar to svn_ra_replay(), but with an Ev2 editor. */
Modified: subversion/branches/javahl-ra/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/include/svn_client.h?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/include/svn_client.h (original)
+++ subversion/branches/javahl-ra/subversion/include/svn_client.h Mon Dec 24 22:47:14 2012
@@ -3376,8 +3376,8 @@ svn_client_diff_summarize_peg(const char
* @{
*/
-/* Details of a symmetric merge. */
-typedef struct svn_client_symmetric_merge_t svn_client_symmetric_merge_t;
+/* Details of an automatic merge. */
+typedef struct svn_client_automatic_merge_t svn_client_automatic_merge_t;
/* Find the information needed to merge all unmerged changes from a source
* branch into a target branch. The information is the locations of the
@@ -3388,7 +3388,7 @@ typedef struct svn_client_symmetric_merg
* SOURCE_REVISION into the target WC at TARGET_WCPATH.
*/
svn_error_t *
-svn_client_find_symmetric_merge(svn_client_symmetric_merge_t **merge,
+svn_client_find_automatic_merge(svn_client_automatic_merge_t **merge,
const char *source_path_or_url,
const svn_opt_revision_t *source_revision,
const char *target_wcpath,
@@ -3399,22 +3399,22 @@ svn_client_find_symmetric_merge(svn_clie
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-/* Find out what kind of symmetric merge would be needed, when the target
+/* Find out what kind of automatic merge would be needed, when the target
* is only known as a repository location rather than a WC.
*
- * Like svn_client_find_symmetric_merge() except that SOURCE_PATH_OR_URL @
+ * Like svn_client_find_automatic_merge() except that SOURCE_PATH_OR_URL @
* SOURCE_REVISION should refer to a repository location and not a WC.
*
* ### The result, *MERGE_P, may not be suitable for passing to
- * svn_client_do_symmetric_merge(). The target WC state would not be
+ * svn_client_do_automatic_merge(). The target WC state would not be
* checked (as in the ALLOW_* flags). We should resolve this problem:
* perhaps add the allow_* params here, or provide another way of setting
* them; and perhaps ensure __do_...() will accept the result iff given a
* WC that matches the stored target location.
*/
svn_error_t *
-svn_client_find_symmetric_merge_no_wc(
- svn_client_symmetric_merge_t **merge_p,
+svn_client_find_automatic_merge_no_wc(
+ svn_client_automatic_merge_t **merge_p,
const char *source_path_or_url,
const svn_opt_revision_t *source_revision,
const char *target_path_or_url,
@@ -3423,22 +3423,22 @@ svn_client_find_symmetric_merge_no_wc(
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
-/* Perform a symmetric merge.
+/* Perform an automatic merge.
*
* Merge according to MERGE into the WC at TARGET_WCPATH.
*
* The other parameters are as in svn_client_merge4().
*
* ### TODO: There's little point in this function being the only way the
- * caller can use the result of svn_client_find_symmetric_merge(). The
+ * caller can use the result of svn_client_find_automatic_merge(). The
* contents of MERGE should be more public, or there should be other ways
* the caller can use it, or these two functions should be combined into
* one. I want to make it more public, and also possibly have more ways
- * to use it in future (for example, do_symmetric_merge_with_step_by_-
+ * to use it in future (for example, do_automatic_merge_with_step_by_-
* step_confirmation).
*/
svn_error_t *
-svn_client_do_symmetric_merge(const svn_client_symmetric_merge_t *merge,
+svn_client_do_automatic_merge(const svn_client_automatic_merge_t *merge,
const char *target_wcpath,
svn_depth_t depth,
svn_boolean_t force,
@@ -3448,16 +3448,16 @@ svn_client_do_symmetric_merge(const svn_
svn_client_ctx_t *ctx,
apr_pool_t *scratch_pool);
-/* Return TRUE iff the symmetric merge represented by MERGE is going to be
+/* Return TRUE iff the automatic merge represented by MERGE is going to be
* a reintegrate-like merge: that is, merging in the opposite direction
* from the last full merge.
*
- * This function exists because the merge is NOT really symmetric and the
+ * This function exists because the merge is NOT really automatic and the
* client can be more friendly if it knows something about the differences.
*/
svn_boolean_t
-svn_client_symmetric_merge_is_reintegrate_like(
- const svn_client_symmetric_merge_t *merge);
+svn_client_automatic_merge_is_reintegrate_like(
+ const svn_client_automatic_merge_t *merge);
/** Merge changes from @a source1/@a revision1 to @a source2/@a revision2 into
Modified: subversion/branches/javahl-ra/subversion/include/svn_dav.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/include/svn_dav.h?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/include/svn_dav.h (original)
+++ subversion/branches/javahl-ra/subversion/include/svn_dav.h Mon Dec 24 22:47:14 2012
@@ -260,11 +260,6 @@ extern "C" {
*/
#define SVN_DAV_PROP_NS_DAV "http://subversion.tigris.org/xmlns/dav/"
-/** An extensible base URI from which other custom namespace URIs
- * extend on an as-needed basis.
- */
-#define SVN_DAV_PROP_NS_EXTENSIBLE "http://subversion.apache.org/xmlns/ext/"
-
/**
* @name Custom (extension) values for the DAV header.
@@ -317,14 +312,6 @@ extern "C" {
#define SVN_DAV_NS_DAV_SVN_EPHEMERAL_TXNPROPS\
SVN_DAV_PROP_NS_DAV "svn/ephemeral-txnprops"
-/** Presence of this in a DAV header in an OPTIONS request/response
- * indicates that the transmitter knows how to properly handle
- * Subversion properties delivered via WebDAV's PROPFIND and PROPPATCH
- * mechanisms using Subversion's extensible property namespace
- * SVN_DAV_PROP_NS_EXTENSIBLE. */
-#define SVN_DAV_NS_DAV_SVN_PROP_EXT_NS\
- SVN_DAV_PROP_NS_DAV "svn/prop-ext-ns"
-
/** @} */
/** @} */
Modified: subversion/branches/javahl-ra/subversion/include/svn_delta.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/include/svn_delta.h?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/include/svn_delta.h (original)
+++ subversion/branches/javahl-ra/subversion/include/svn_delta.h Mon Dec 24 22:47:14 2012
@@ -1324,8 +1324,9 @@ typedef svn_error_t *(*svn_delta_path_dr
* Each path in @a paths is a const char *. The editor drive will be
* performed in the same order as @a paths. The paths should be sorted
* using something like svn_sort_compare_paths to ensure that a depth-first
- * pattern is observed for directory/file baton creation. Some callers may
- * need further customization of the order (ie. libsvn_delta/compat.c).
+ * pattern is observed for directory/file baton creation. If @a sort_paths
+ * is set, the function will sort the paths for you. Some callers may need
+ * further customization of the order (ie. libsvn_delta/compat.c).
*
* Use @a scratch_pool for all necessary allocations.
*
@@ -1335,6 +1336,7 @@ svn_error_t *
svn_delta_path_driver2(const svn_delta_editor_t *editor,
void *edit_baton,
const apr_array_header_t *paths,
+ svn_boolean_t sort_paths,
svn_delta_path_driver_cb_func_t callback_func,
void *callback_baton,
apr_pool_t *scratch_pool);
Modified: subversion/branches/javahl-ra/subversion/include/svn_error_codes.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/include/svn_error_codes.h?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/include/svn_error_codes.h (original)
+++ subversion/branches/javahl-ra/subversion/include/svn_error_codes.h Mon Dec 24 22:47:14 2012
@@ -782,6 +782,11 @@ SVN_ERROR_START
SVN_ERR_FS_CATEGORY_START + 51,
"A packed revprop could not be read")
+ /** @since New in 1.8. */
+ SVN_ERRDEF(SVN_ERR_FS_REPPROP_CACHE_INIT_FAILURE,
+ SVN_ERR_FS_CATEGORY_START + 52,
+ "Could not initialize the revprop caching infrastructure.")
+
/* repos errors */
SVN_ERRDEF(SVN_ERR_REPOS_LOCKED,
Modified: subversion/branches/javahl-ra/subversion/include/svn_props.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/include/svn_props.h?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/include/svn_props.h (original)
+++ subversion/branches/javahl-ra/subversion/include/svn_props.h Mon Dec 24 22:47:14 2012
@@ -384,6 +384,14 @@ svn_prop_name_is_valid(const char *prop_
*/
#define SVN_PROP_MERGEINFO SVN_PROP_PREFIX "mergeinfo"
+/** Prefix for all Subersion inhertiable properties. */
+#define SVN_PROP_INHERITABLE_PREFIX SVN_PROP_PREFIX "inheritable-"
+
+/** Property used to record inheritable configuration auto-props. */
+#define SVN_PROP_INHERITABLE_AUTO_PROPS SVN_PROP_INHERITABLE_PREFIX "auto-props"
+
+/** Property used to record inheritable configuration ignores. */
+#define SVN_PROP_INHERITABLE_IGNORES SVN_PROP_INHERITABLE_PREFIX "ignores"
/** Meta-data properties.
*
@@ -582,6 +590,17 @@ svn_prop_name_is_valid(const char *prop_
#define SVN_PROP_TXN_USER_AGENT \
SVN_PROP_TXN_PREFIX "user-agent"
+/** The prefix reserved for copies of (ephemeral) transaction
+ * properties designed to outlive the transaction. Administrators may
+ * choose to, in their pre-commit hook scripts, copy the values of one
+ * or more properties named @c SVN_PROP_TXN_PREFIX + "something"
+ * to new properties named @c SVN_PROP_REVISION_PREFIX + "something",
+ * allowing that information to survive the commit-time removal of
+ * ephemeral transaction properties.
+ */
+#define SVN_PROP_REVISION_PREFIX SVN_PROP_PREFIX "revision-"
+
+
/** @} */
/** @} */
Modified: subversion/branches/javahl-ra/subversion/include/svn_ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/include/svn_ra_svn.h?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/include/svn_ra_svn.h (original)
+++ subversion/branches/javahl-ra/subversion/include/svn_ra_svn.h Mon Dec 24 22:47:14 2012
@@ -215,6 +215,8 @@ typedef enum svn_ra_svn_cmd_t
svn_ra_svn_cmd_replay,
svn_ra_svn_cmd_replay_range,
svn_ra_svn_cmd_get_deleted_rev,
+ svn_ra_svn_cmd_get_iprops,
+ svn_ra_svn_cmd_finish_replay,
svn_ra_svn_cmd__last
} svn_ra_svn_cmd_t;
Modified: subversion/branches/javahl-ra/subversion/libsvn_client/add.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/add.c?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/add.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/add.c Mon Dec 24 22:47:14 2012
@@ -56,27 +56,6 @@
/*** Code. ***/
-/* This structure is used as baton for enumerating the config entries
- in the auto-props section.
-*/
-typedef struct auto_props_baton_t
-{
- /* the file name for which properties are searched */
- const char *filename;
-
- /* when this flag is set the hash contains svn:executable */
- svn_boolean_t have_executable;
-
- /* when mimetype is not NULL is set the hash contains svn:mime-type */
- const char *mimetype;
-
- /* the hash table for storing the property name/value pairs */
- apr_hash_t *properties;
-
- /* a pool used for allocating memory */
- apr_pool_t *pool;
-} auto_props_baton_t;
-
/* Remove leading and trailing white space from a C string, in place. */
static void
trim_string(char **pstr)
@@ -155,114 +134,96 @@ split_props(apr_array_header_t **props,
*props = temp_props;
}
-/* For one auto-props config entry (NAME, VALUE), if the filename pattern
- NAME matches BATON->filename case insensitively then add the properties
- listed in VALUE into BATON->properties.
- BATON must point to an auto_props_baton_t.
+/* PROPVALS is a hash mapping char * property names to const char * property
+ values. PROPERTIES can be empty but not NULL.
+
+ If FILENAME doesn't match the filename pattern PATTERN case insensitively,
+ the do nothing. Otherwise for each 'name':'value' pair in PROPVALS, add
+ a new entry mappying 'name' to a svn_string_t * wrapping the 'value' in
+ PROPERTIES. The svn_string_t is allocated in the pool used to allocate
+ PROPERTIES, but the char *'s from PROPVALS are re-used in PROPERTIES.
+ If PROPVALS contains a 'svn:mime-type' mapping, then set *MIMETYPE to
+ the mapped value. Likewise if PROPVALS contains a mapping for
+ svn:executable, then set *HAVE_EXECUTABLE to TRUE.
+
+ Use SCRATCH_POOL for temporary allocations.
*/
-static svn_boolean_t
-auto_props_enumerator(const char *name,
- const char *value,
- void *baton,
- apr_pool_t *pool)
+static void
+get_auto_props_for_pattern(apr_hash_t *properties,
+ const char **mimetype,
+ svn_boolean_t *have_executable,
+ const char *filename,
+ const char *pattern,
+ apr_hash_t *propvals,
+ apr_pool_t *scratch_pool)
{
- int i;
- auto_props_baton_t *autoprops = baton;
- apr_array_header_t *props;
-
- /* nothing to do here without a value */
- if (*value == 0)
- return TRUE;
+ apr_hash_index_t *hi;
/* check if filename matches and return if it doesn't */
- if (apr_fnmatch(name, autoprops->filename, APR_FNM_CASE_BLIND) == APR_FNM_NOMATCH)
- return TRUE;
-
- split_props(&props, value, autoprops->pool);
-
- for (i = 0; i < props->nelts; i++)
- {
- size_t len;
- const char *this_value;
- char *property = APR_ARRAY_IDX(props, i, char *);
- char *equal_sign = strchr(property, '=');
-
- if (equal_sign)
- {
- *equal_sign = '\0';
- equal_sign++;
- trim_string(&equal_sign);
- unquote_string(&equal_sign);
- this_value = equal_sign;
- }
- else
- {
- this_value = "";
- }
- trim_string(&property);
- len = strlen(property);
-
- if (len > 0)
- {
- svn_string_t *propval = apr_palloc(autoprops->pool,
- sizeof(*propval));
- propval->data = this_value;
- propval->len = strlen(this_value);
-
- apr_hash_set(autoprops->properties, property, len, propval);
- if (strcmp(property, SVN_PROP_MIME_TYPE) == 0)
- autoprops->mimetype = this_value;
- else if (strcmp(property, SVN_PROP_EXECUTABLE) == 0)
- autoprops->have_executable = TRUE;
- }
+ if (apr_fnmatch(pattern, filename,
+ APR_FNM_CASE_BLIND) == APR_FNM_NOMATCH)
+ return;
+
+ for (hi = apr_hash_first(scratch_pool, propvals);
+ hi != NULL;
+ hi = apr_hash_next(hi))
+ {
+ const char *propname = svn__apr_hash_index_key(hi);
+ const char *propval = svn__apr_hash_index_val(hi);
+ svn_string_t *propval_str =
+ svn_string_create_empty(apr_hash_pool_get(properties));
+
+ propval_str->data = propval;
+ propval_str->len = strlen(propval);
+
+ apr_hash_set(properties, propname, APR_HASH_KEY_STRING,
+ propval_str);
+ if (strcmp(propname, SVN_PROP_MIME_TYPE) == 0)
+ *mimetype = propval;
+ else if (strcmp(propname, SVN_PROP_EXECUTABLE) == 0)
+ *have_executable = TRUE;
}
- return TRUE;
}
svn_error_t *
-svn_client__get_auto_props(apr_hash_t **properties,
- const char **mimetype,
- const char *path,
- svn_magic__cookie_t *magic_cookie,
- svn_client_ctx_t *ctx,
- apr_pool_t *pool)
+svn_client__get_paths_auto_props(apr_hash_t **properties,
+ const char **mimetype,
+ const char *path,
+ svn_magic__cookie_t *magic_cookie,
+ apr_hash_t *autoprops,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
- svn_config_t *cfg;
- svn_boolean_t use_autoprops;
- auto_props_baton_t autoprops;
-
- /* initialisation */
- autoprops.properties = apr_hash_make(pool);
- autoprops.filename = svn_dirent_basename(path, pool);
- autoprops.pool = pool;
- autoprops.mimetype = NULL;
- autoprops.have_executable = FALSE;
- *properties = autoprops.properties;
+ apr_hash_index_t *hi;
+ svn_boolean_t have_executable = FALSE;
- cfg = ctx->config ? apr_hash_get(ctx->config, SVN_CONFIG_CATEGORY_CONFIG,
- APR_HASH_KEY_STRING) : NULL;
+ *properties = apr_hash_make(result_pool);
+ *mimetype = NULL;
- /* check that auto props is enabled */
- SVN_ERR(svn_config_get_bool(cfg, &use_autoprops,
- SVN_CONFIG_SECTION_MISCELLANY,
- SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS, FALSE));
+ for (hi = apr_hash_first(scratch_pool, autoprops);
+ hi != NULL;
+ hi = apr_hash_next(hi))
+ {
+ const char *pattern = svn__apr_hash_index_key(hi);
+ apr_hash_t *propvals = svn__apr_hash_index_val(hi);
- /* search for auto props */
- if (use_autoprops)
- svn_config_enumerate2(cfg, SVN_CONFIG_SECTION_AUTO_PROPS,
- auto_props_enumerator, &autoprops, pool);
+ get_auto_props_for_pattern(*properties, mimetype, &have_executable,
+ svn_dirent_basename(path, scratch_pool),
+ pattern, propvals, scratch_pool);
+ }
/* if mimetype has not been set check the file */
- if (! autoprops.mimetype)
+ if (! *mimetype)
{
- SVN_ERR(svn_io_detect_mimetype2(&autoprops.mimetype, path,
- ctx->mimetypes_map, pool));
+ SVN_ERR(svn_io_detect_mimetype2(mimetype, path, ctx->mimetypes_map,
+ result_pool));
/* If we got no mime-type, or if it is "application/octet-stream",
* try to get the mime-type from libmagic. */
if (magic_cookie &&
- (!autoprops.mimetype ||
- strcmp(autoprops.mimetype, "application/octet-stream") == 0))
+ (!*mimetype ||
+ strcmp(*mimetype, "application/octet-stream") == 0))
{
const char *magic_mimetype;
@@ -275,29 +236,29 @@ svn_client__get_auto_props(apr_hash_t **
* returns "text/plain" for them. */
SVN_ERR(svn_magic__detect_binary_mimetype(&magic_mimetype,
path, magic_cookie,
- pool, pool));
+ result_pool,
+ scratch_pool));
if (magic_mimetype)
- autoprops.mimetype = magic_mimetype;
+ *mimetype = magic_mimetype;
}
- if (autoprops.mimetype)
- apr_hash_set(autoprops.properties, SVN_PROP_MIME_TYPE,
+ if (*mimetype)
+ apr_hash_set(*properties, SVN_PROP_MIME_TYPE,
strlen(SVN_PROP_MIME_TYPE),
- svn_string_create(autoprops.mimetype, pool));
+ svn_string_create(*mimetype, result_pool));
}
/* if executable has not been set check the file */
- if (! autoprops.have_executable)
+ if (! have_executable)
{
svn_boolean_t executable = FALSE;
- SVN_ERR(svn_io_is_file_executable(&executable, path, pool));
+ SVN_ERR(svn_io_is_file_executable(&executable, path, scratch_pool));
if (executable)
- apr_hash_set(autoprops.properties, SVN_PROP_EXECUTABLE,
+ apr_hash_set(*properties, SVN_PROP_EXECUTABLE,
strlen(SVN_PROP_EXECUTABLE),
- svn_string_create_empty(pool));
+ svn_string_create_empty(result_pool));
}
- *mimetype = autoprops.mimetype;
return SVN_NO_ERROR;
}
@@ -305,6 +266,7 @@ svn_client__get_auto_props(apr_hash_t **
static svn_error_t *
add_file(const char *local_abspath,
svn_magic__cookie_t *magic_cookie,
+ apr_hash_t *autoprops,
svn_client_ctx_t *ctx,
apr_pool_t *pool)
{
@@ -317,21 +279,39 @@ add_file(const char *local_abspath,
/* Check to see if this is a special file. */
SVN_ERR(svn_io_check_special_path(local_abspath, &kind, &is_special, pool));
- if (is_special)
- mimetype = NULL;
- else
- /* Get automatic properties */
- /* This may fail on write-only files:
- we open them to estimate file type.
- That's why we postpone the add until after this step. */
- SVN_ERR(svn_client__get_auto_props(&properties, &mimetype, local_abspath,
- magic_cookie, ctx, pool));
-
/* Add the file */
SVN_ERR(svn_wc_add_from_disk(ctx->wc_ctx, local_abspath,
NULL, NULL, pool));
if (is_special)
+ {
+ mimetype = NULL;
+ }
+ else
+ {
+ apr_hash_t *file_autoprops;
+
+ /* Get automatic properties */
+ /* Grab the inherited svn:inheritable-auto-props and config file
+ auto-props for this file if we haven't already got them
+ when iterating over the file's unversioned parents. */
+ if (autoprops == NULL)
+ SVN_ERR(svn_client__get_all_auto_props(
+ &file_autoprops, svn_dirent_dirname(local_abspath,pool),
+ ctx, pool, pool));
+ else
+ file_autoprops = autoprops;
+
+ /* This may fail on write-only files:
+ we open them to estimate file type.
+ That's why we postpone the add until after this step. */
+ SVN_ERR(svn_client__get_paths_auto_props(&properties, &mimetype,
+ local_abspath, magic_cookie,
+ file_autoprops, ctx, pool,
+ pool));
+ }
+
+ if (is_special)
/* This must be a special file. */
SVN_ERR(svn_wc_prop_set4(ctx->wc_ctx, local_abspath, SVN_PROP_SPECIAL,
svn_string_create(SVN_PROP_BOOLEAN_TRUE, pool),
@@ -387,8 +367,8 @@ add_file(const char *local_abspath,
}
/* Schedule directory DIR_ABSPATH, and some of the tree under it, for
- * addition. DEPTH is the depth at this
- * point in the descent (it may be changed for recursive calls).
+ * addition. DEPTH is the depth at this point in the descent (it may
+ * be changed for recursive calls).
*
* If DIR_ABSPATH (or any item below DIR_ABSPATH) is already scheduled for
* addition, add will fail and return an error unless FORCE is TRUE.
@@ -399,8 +379,27 @@ add_file(const char *local_abspath,
* Use MAGIC_COOKIE (which may be NULL) to detect the mime-type of files
* if necessary.
*
+ * If not NULL, *CONFIG_AUTOPROPS is a hash representing the config file and
+ * svn:inheritable-auto-props autoprops which apply to DIR_ABSPATH. It maps
+ * const char * file patterns to another hash which maps const char *
+ * property names to const char *property values. If *CONFIG_AUTOPROPS is
+ * NULL and DIR_ABSPATH is unversioned, then this function will populate
+ * *CONFIG_AUTOPROPS (allocated in RESULT_POOL) using DIR_ABSPATH's nearest
+ * versioned parent to determine the svn:inheritable-auto-props which DIR_ABSPATH
+ * will inherit once added.
+ *
+ * If IGNORES is not NULL, then it is an array of const char * ignore patterns
+ * that apply to any children of DIR_ABSPATH. If REFRESH_IGNORES is TRUE, then
+ * the passed in value of IGNORES (if any) is itself ignored and this function
+ * will gather all ignore patterns applicable to DIR_ABSPATH itself. Any
+ * recursive calls to this function get the refreshed ignore patterns. If
+ * IGNORES is NULL and REFRESH_IGNORES is FALSE, then all children of DIR_ABSPATH
+ * are unconditionally added.
+ *
* If CTX->CANCEL_FUNC is non-null, call it with CTX->CANCEL_BATON to allow
- * the user to cancel the operation
+ * the user to cancel the operation.
+ *
+ * Use SCRATCH_POOL for temporary allocations.
*/
static svn_error_t *
add_dir_recursive(const char *dir_abspath,
@@ -408,14 +407,19 @@ add_dir_recursive(const char *dir_abspat
svn_boolean_t force,
svn_boolean_t no_ignore,
svn_magic__cookie_t *magic_cookie,
+ apr_hash_t **config_autoprops,
+ svn_boolean_t refresh_ignores,
+ apr_array_header_t *ignores,
svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
svn_error_t *err;
apr_pool_t *iterpool;
- apr_array_header_t *ignores;
apr_hash_t *dirents;
apr_hash_index_t *hi;
+ svn_boolean_t entry_exists = FALSE;
+ svn_boolean_t found_unversioned_root = FALSE;
/* Check cancellation; note that this catches recursive calls too. */
if (ctx->cancel_func)
@@ -423,19 +427,42 @@ add_dir_recursive(const char *dir_abspat
iterpool = svn_pool_create(scratch_pool);
+ if (refresh_ignores)
+ SVN_ERR(svn_client__get_all_ignores(&ignores, dir_abspath,
+ no_ignore, ctx, scratch_pool,
+ scratch_pool));
+
/* Add this directory to revision control. */
err = svn_wc_add_from_disk(ctx->wc_ctx, dir_abspath,
ctx->notify_func2, ctx->notify_baton2,
iterpool);
- if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
- svn_error_clear(err);
- else if (err)
- return svn_error_trace(err);
+ if (err)
+ {
+ if (err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
+ {
+ svn_error_clear(err);
+ entry_exists = TRUE;
+ }
+ else if (err)
+ {
+ return svn_error_trace(err);
+ }
+ }
- if (!no_ignore)
+ /* For the root of any unversioned subtree, get some or all of the
+ following:
+
+ 1) Explicit and inherited svn:inheritable-auto-props properties on
+ DIR_ABSPATH
+ 2) Explicit and inherited svn:inheritabled-ignores properties on
+ DIR_ABSPATH
+ 3) auto-props from the CTX->CONFIG hash */
+ if (!entry_exists && *config_autoprops == NULL)
{
- SVN_ERR(svn_wc_get_ignores2(&ignores, ctx->wc_ctx, dir_abspath,
- ctx->config, scratch_pool, iterpool));
+ SVN_ERR(svn_client__get_all_auto_props(config_autoprops, dir_abspath,
+ ctx, result_pool,
+ scratch_pool));
+ found_unversioned_root = TRUE;
}
SVN_ERR(svn_io_get_dirents3(&dirents, dir_abspath, TRUE, scratch_pool,
@@ -460,7 +487,8 @@ add_dir_recursive(const char *dir_abspat
if (svn_wc_is_adm_dir(name, iterpool))
continue;
- if ((!no_ignore) && svn_wc_match_ignore_list(name, ignores, iterpool))
+ if (ignores
+ && svn_wc_match_ignore_list(name, ignores, iterpool))
continue;
/* Construct the full path of the entry. */
@@ -473,14 +501,23 @@ add_dir_recursive(const char *dir_abspat
if (depth == svn_depth_immediates)
depth_below_here = svn_depth_empty;
+ /* When DIR_ABSPATH is the root of an unversioned subtree then
+ it and all of its children have the same set of ignores. So
+ save any recursive calls the extra work of finding the same
+ set of ignores. */
+ if (refresh_ignores && !entry_exists)
+ refresh_ignores = FALSE;
+
SVN_ERR(add_dir_recursive(abspath, depth_below_here,
force, no_ignore, magic_cookie,
- ctx, iterpool));
+ config_autoprops, refresh_ignores,
+ ignores, ctx, iterpool, iterpool));
}
else if ((dirent->kind == svn_node_file || dirent->special)
&& depth >= svn_depth_files)
{
- err = add_file(abspath, magic_cookie, ctx, iterpool);
+ err = add_file(abspath, magic_cookie, *config_autoprops, ctx,
+ iterpool);
if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
svn_error_clear(err);
else
@@ -491,9 +528,440 @@ add_dir_recursive(const char *dir_abspat
/* Destroy the per-iteration pool. */
svn_pool_destroy(iterpool);
+ /* Reset CONFIG_AUTOPROPS if we just finished processing the root
+ of an unversioned subtree. */
+ if (found_unversioned_root)
+ *config_autoprops = NULL;
+
return SVN_NO_ERROR;
}
+/* This structure is used as baton for collecting the config entries
+ in the auto-props section and any inherited svn:inheritable-auto-props
+ properties.
+*/
+typedef struct collect_auto_props_baton_t
+{
+ /* the hash table for storing the property name/value pairs */
+ apr_hash_t *autoprops;
+
+ /* a pool used for allocating memory */
+ apr_pool_t *result_pool;
+} collect_auto_props_baton_t;
+
+/* Implements svn_config_enumerator2_t callback.
+
+ For one auto-props config entry (NAME, VALUE), stash a copy of
+ NAME and VALUE, allocated in BATON->POOL, in BATON->AUTOPROP.
+ BATON must point to an collect_auto_props_baton_t.
+*/
+static svn_boolean_t
+all_auto_props_collector(const char *name,
+ const char *value,
+ void *baton,
+ apr_pool_t *pool)
+{
+ collect_auto_props_baton_t *autoprops_baton = baton;
+ apr_array_header_t *autoprops;
+ int i;
+
+ /* nothing to do here without a value */
+ if (*value == 0)
+ return TRUE;
+
+ split_props(&autoprops, value, pool);
+
+ for (i = 0; i < autoprops->nelts; i ++)
+ {
+ size_t len;
+ const char *this_value;
+ char *property = APR_ARRAY_IDX(autoprops, i, char *);
+ char *equal_sign = strchr(property, '=');
+
+ if (equal_sign)
+ {
+ *equal_sign = '\0';
+ equal_sign++;
+ trim_string(&equal_sign);
+ unquote_string(&equal_sign);
+ this_value = equal_sign;
+ }
+ else
+ {
+ this_value = "";
+ }
+ trim_string(&property);
+ len = strlen(property);
+
+ if (len > 0)
+ {
+ apr_hash_t *pattern_hash = apr_hash_get(autoprops_baton->autoprops,
+ name, APR_HASH_KEY_STRING);
+ svn_string_t *propval;
+
+ /* Force reserved boolean property values to '*'. */
+ if (svn_prop_is_boolean(property))
+ {
+ /* SVN_PROP_EXECUTABLE, SVN_PROP_NEEDS_LOCK, SVN_PROP_SPECIAL */
+ propval = svn_string_create("*", autoprops_baton->result_pool);
+ }
+ else
+ {
+ propval = svn_string_create(this_value,
+ autoprops_baton->result_pool);
+ }
+
+ if (!pattern_hash)
+ {
+ pattern_hash = apr_hash_make(autoprops_baton->result_pool);
+ apr_hash_set(autoprops_baton->autoprops,
+ apr_pstrdup(autoprops_baton->result_pool, name),
+ APR_HASH_KEY_STRING, pattern_hash);
+ }
+ apr_hash_set(pattern_hash,
+ apr_pstrdup(autoprops_baton->result_pool, property),
+ APR_HASH_KEY_STRING, propval->data);
+ }
+ }
+ return TRUE;
+}
+
+/* Go up the directory tree from LOCAL_ABSPATH, looking for a versioned
+ * directory. If found, return its path in *EXISTING_PARENT_ABSPATH.
+ * Otherwise, return SVN_ERR_CLIENT_NO_VERSIONED_PARENT. */
+static svn_error_t *
+find_existing_parent(const char **existing_parent_abspath,
+ svn_client_ctx_t *ctx,
+ const char *local_abspath,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_node_kind_t kind;
+ const char *parent_abspath;
+ svn_wc_context_t *wc_ctx = ctx->wc_ctx;
+
+ SVN_ERR(svn_wc_read_kind(&kind, wc_ctx, local_abspath, FALSE, scratch_pool));
+
+ if (kind == svn_node_dir)
+ {
+ svn_boolean_t is_deleted;
+
+ SVN_ERR(svn_wc__node_is_status_deleted(&is_deleted,
+ wc_ctx, local_abspath,
+ scratch_pool));
+ if (!is_deleted)
+ {
+ *existing_parent_abspath = apr_pstrdup(result_pool, local_abspath);
+ return SVN_NO_ERROR;
+ }
+ }
+
+ if (svn_dirent_is_root(local_abspath, strlen(local_abspath)))
+ return svn_error_create(SVN_ERR_CLIENT_NO_VERSIONED_PARENT, NULL, NULL);
+
+ if (svn_wc_is_adm_dir(svn_dirent_basename(local_abspath, scratch_pool),
+ scratch_pool))
+ return svn_error_createf(SVN_ERR_RESERVED_FILENAME_SPECIFIED, NULL,
+ _("'%s' ends in a reserved name"),
+ svn_dirent_local_style(local_abspath,
+ scratch_pool));
+
+ parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
+
+ if (ctx->cancel_func)
+ SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
+
+ SVN_ERR(find_existing_parent(existing_parent_abspath, ctx, parent_abspath,
+ result_pool, scratch_pool));
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_client__get_all_auto_props(apr_hash_t **autoprops,
+ const char *path_or_url,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ int i;
+ apr_array_header_t *inherited_config_auto_props;
+ apr_hash_t *props;
+ svn_opt_revision_t rev;
+ svn_string_t *config_auto_prop;
+ svn_boolean_t use_autoprops;
+ collect_auto_props_baton_t autoprops_baton;
+ svn_error_t *err = NULL;
+ svn_boolean_t target_is_url = svn_path_is_url(path_or_url);
+ svn_config_t *cfg = ctx->config ? apr_hash_get(ctx->config,
+ SVN_CONFIG_CATEGORY_CONFIG,
+ APR_HASH_KEY_STRING) : NULL;
+ *autoprops = apr_hash_make(result_pool);
+ autoprops_baton.result_pool = result_pool;
+ autoprops_baton.autoprops = *autoprops;
+
+ /* Are "traditional" auto-props enabled? If so grab them from the
+ config. This is our starting set auto-props, which may be overriden
+ by svn:inheritable-auto-props. */
+ SVN_ERR(svn_config_get_bool(cfg, &use_autoprops,
+ SVN_CONFIG_SECTION_MISCELLANY,
+ SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS, FALSE));
+ if (use_autoprops)
+ svn_config_enumerate2(cfg, SVN_CONFIG_SECTION_AUTO_PROPS,
+ all_auto_props_collector, &autoprops_baton,
+ scratch_pool);
+
+ /* Convert the config file setting (if any) into a hash mapping file
+ patterns to as hash of prop-->val mappings. */
+ if (svn_path_is_url(path_or_url))
+ rev.kind = svn_opt_revision_head;
+ else
+ rev.kind = svn_opt_revision_working;
+
+ /* If PATH_OR_URL is a WC path, then it might be unversioned, in which case
+ we find it's nearest versioned parent. */
+ while (err == NULL)
+ {
+ err = svn_client_propget5(&props, &inherited_config_auto_props,
+ SVN_PROP_INHERITABLE_AUTO_PROPS, path_or_url,
+ &rev, &rev, NULL, svn_depth_empty, NULL, ctx,
+ scratch_pool, scratch_pool);
+ if (err)
+ {
+ if (target_is_url || err->apr_err != SVN_ERR_UNVERSIONED_RESOURCE)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+ err = NULL;
+ SVN_ERR(find_existing_parent(&path_or_url, ctx, path_or_url,
+ scratch_pool, scratch_pool));
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* Stash any explicit PROPS for PARENT_PATH into the inherited props array,
+ since these are actually inherited props for LOCAL_ABSPATH. */
+ config_auto_prop = apr_hash_get(props, path_or_url, APR_HASH_KEY_STRING);
+
+ if (config_auto_prop)
+ {
+ svn_prop_inherited_item_t *new_iprop =
+ apr_palloc(scratch_pool, sizeof(*new_iprop));
+ new_iprop->path_or_url = path_or_url;
+ new_iprop->prop_hash = apr_hash_make(scratch_pool);
+ apr_hash_set(new_iprop->prop_hash,
+ SVN_PROP_INHERITABLE_AUTO_PROPS,
+ APR_HASH_KEY_STRING,
+ config_auto_prop);
+ APR_ARRAY_PUSH(inherited_config_auto_props,
+ svn_prop_inherited_item_t *) = new_iprop;
+ }
+
+ for (i = 0; i < inherited_config_auto_props->nelts; i++)
+ {
+ apr_hash_index_t *hi;
+ svn_prop_inherited_item_t *elt = APR_ARRAY_IDX(
+ inherited_config_auto_props, i, svn_prop_inherited_item_t *);
+ apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+ for (hi = apr_hash_first(scratch_pool, elt->prop_hash);
+ hi;
+ hi = apr_hash_next(hi))
+ {
+ const svn_string_t *propval = svn__apr_hash_index_val(hi);
+ const char *ch = propval->data;
+ svn_stringbuf_t *config_auto_prop_pattern;
+ svn_stringbuf_t *config_auto_prop_val;
+
+ svn_pool_clear(iterpool);
+
+ config_auto_prop_pattern = svn_stringbuf_create_empty(iterpool);
+ config_auto_prop_val = svn_stringbuf_create_empty(iterpool);
+
+ /* Parse svn:inheritable-auto-props value. */
+ while (*ch != '\0')
+ {
+ svn_stringbuf_setempty(config_auto_prop_pattern);
+ svn_stringbuf_setempty(config_auto_prop_val);
+
+ /* Parse the file pattern. */
+ while (*ch != '\0' && *ch != '=' && *ch != '\n')
+ {
+ svn_stringbuf_appendbyte(config_auto_prop_pattern, *ch);
+ ch++;
+ }
+
+ svn_stringbuf_strip_whitespace(config_auto_prop_pattern);
+
+ /* Parse the auto-prop group. */
+ while (*ch != '\0' && *ch != '\n')
+ {
+ svn_stringbuf_appendbyte(config_auto_prop_val, *ch);
+ ch++;
+ }
+
+ /* Strip leading '=' and whitespace from auto-prop group. */
+ if (config_auto_prop_val->data[0] == '=')
+ svn_stringbuf_remove(config_auto_prop_val, 0, 1);
+ svn_stringbuf_strip_whitespace(config_auto_prop_val);
+
+ all_auto_props_collector(config_auto_prop_pattern->data,
+ config_auto_prop_val->data,
+ &autoprops_baton,
+ scratch_pool);
+
+ /* Skip to next line if any. */
+ while (*ch != '\0' && *ch != '\n')
+ ch++;
+ if (*ch == '\n')
+ ch++;
+ }
+ svn_pool_destroy(iterpool);
+ }
+ }
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *svn_client__get_inherited_ignores(apr_array_header_t **ignores,
+ const char *path_or_url,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ svn_opt_revision_t rev;
+ apr_hash_t *explicit_ignores;
+ apr_array_header_t *inherited_ignores;
+ svn_boolean_t target_is_url = svn_path_is_url(path_or_url);
+ svn_string_t *explicit_prop;
+ int i;
+
+ if (target_is_url)
+ rev.kind = svn_opt_revision_head;
+ else
+ rev.kind = svn_opt_revision_working;
+
+ SVN_ERR(svn_client_propget5(&explicit_ignores, &inherited_ignores,
+ SVN_PROP_INHERITABLE_IGNORES, path_or_url,
+ &rev, &rev, NULL, svn_depth_empty, NULL, ctx,
+ scratch_pool, scratch_pool));
+
+ explicit_prop = apr_hash_get(explicit_ignores, path_or_url,
+ APR_HASH_KEY_STRING);
+
+ if (explicit_prop)
+ {
+ svn_prop_inherited_item_t *new_iprop =
+ apr_palloc(scratch_pool, sizeof(*new_iprop));
+ new_iprop->path_or_url = path_or_url;
+ new_iprop->prop_hash = apr_hash_make(scratch_pool);
+ apr_hash_set(new_iprop->prop_hash,
+ SVN_PROP_INHERITABLE_IGNORES,
+ APR_HASH_KEY_STRING,
+ explicit_prop);
+ APR_ARRAY_PUSH(inherited_ignores,
+ svn_prop_inherited_item_t *) = new_iprop;
+ }
+
+ *ignores = apr_array_make(result_pool, 16, sizeof(const char *));
+
+ for (i = 0; i < inherited_ignores->nelts; i++)
+ {
+ svn_prop_inherited_item_t *elt = APR_ARRAY_IDX(
+ inherited_ignores, i, svn_prop_inherited_item_t *);
+ svn_string_t *ignore_val = apr_hash_get(elt->prop_hash,
+ SVN_PROP_INHERITABLE_IGNORES,
+ APR_HASH_KEY_STRING);
+ if (ignore_val)
+ svn_cstring_split_append(*ignores, ignore_val->data, "\n\r\t\v ",
+ FALSE, result_pool);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *svn_client__get_all_ignores(apr_array_header_t **ignores,
+ const char *local_abspath,
+ svn_boolean_t no_ignore,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ apr_hash_t *explicit_ignores;
+ apr_array_header_t *inherited_ignores;
+ svn_error_t *err = NULL;
+ svn_string_t *explicit_prop;
+ int i;
+ svn_opt_revision_t rev;
+
+ rev.kind = svn_opt_revision_working;
+
+ /* LOCAL_ABSPATH might be unversioned, in which case we find its
+ nearest versioned parent. */
+ while (err == NULL)
+ {
+ err = svn_client_propget5(&explicit_ignores, &inherited_ignores,
+ SVN_PROP_INHERITABLE_IGNORES, local_abspath,
+ &rev, &rev, NULL, svn_depth_empty, NULL, ctx,
+ scratch_pool, scratch_pool);
+ if (err)
+ {
+ if (err->apr_err != SVN_ERR_UNVERSIONED_RESOURCE)
+ return svn_error_trace(err);
+
+ svn_error_clear(err);
+ err = NULL;
+ SVN_ERR(find_existing_parent(&local_abspath, ctx, local_abspath,
+ scratch_pool, scratch_pool));
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ explicit_prop = apr_hash_get(explicit_ignores, local_abspath,
+ APR_HASH_KEY_STRING);
+
+ if (explicit_prop)
+ {
+ svn_prop_inherited_item_t *new_iprop =
+ apr_palloc(scratch_pool, sizeof(*new_iprop));
+ new_iprop->path_or_url = local_abspath;
+ new_iprop->prop_hash = apr_hash_make(scratch_pool);
+ apr_hash_set(new_iprop->prop_hash,
+ SVN_PROP_INHERITABLE_IGNORES,
+ APR_HASH_KEY_STRING,
+ explicit_prop);
+ APR_ARRAY_PUSH(inherited_ignores,
+ svn_prop_inherited_item_t *) = new_iprop;
+ }
+
+ /* Now that we are sure we have an existing parent, get the config ignore
+ and the local ignore patterns... */
+ if (!no_ignore)
+ SVN_ERR(svn_wc_get_ignores2(ignores, ctx->wc_ctx, local_abspath,
+ ctx->config, result_pool, scratch_pool));
+ else
+ *ignores = apr_array_make(result_pool, 16, sizeof(const char *));
+
+ /* ...and add the inherited ignores to it. */
+ for (i = 0; i < inherited_ignores->nelts; i++)
+ {
+ svn_prop_inherited_item_t *elt = APR_ARRAY_IDX(
+ inherited_ignores, i, svn_prop_inherited_item_t *);
+ svn_string_t *ignore_val = apr_hash_get(elt->prop_hash,
+ SVN_PROP_INHERITABLE_IGNORES,
+ APR_HASH_KEY_STRING);
+ if (ignore_val)
+ svn_cstring_split_append(*ignores, ignore_val->data, "\n\r\t\v ",
+ FALSE, result_pool);
+ }
+
+ return SVN_NO_ERROR;
+}
/* The main logic of the public svn_client_add4.
*
@@ -512,6 +980,8 @@ add(const char *local_abspath,
svn_node_kind_t kind;
svn_error_t *err;
svn_magic__cookie_t *magic_cookie;
+ apr_hash_t *config_autoprops = NULL;
+ apr_array_header_t *ignores = NULL;
svn_magic__init(&magic_cookie, scratch_pool);
@@ -562,10 +1032,12 @@ add(const char *local_abspath,
and pass depth along no matter what it is, so that the
target's depth will be set correctly. */
err = add_dir_recursive(local_abspath, depth, force, no_ignore,
- magic_cookie, ctx, scratch_pool);
+ magic_cookie, &config_autoprops, TRUE, ignores,
+ ctx, scratch_pool, scratch_pool);
}
else if (kind == svn_node_file)
- err = add_file(local_abspath, magic_cookie, ctx, scratch_pool);
+ err = add_file(local_abspath, magic_cookie, config_autoprops, ctx,
+ scratch_pool);
else if (kind == svn_node_none)
{
svn_boolean_t tree_conflicted;
@@ -606,58 +1078,6 @@ add(const char *local_abspath,
}
-/* Go up the directory tree from LOCAL_ABSPATH, looking for a versioned
- * directory. If found, return its path in *EXISTING_PARENT_ABSPATH.
- * Otherwise, return SVN_ERR_CLIENT_NO_VERSIONED_PARENT. */
-static svn_error_t *
-find_existing_parent(const char **existing_parent_abspath,
- svn_client_ctx_t *ctx,
- const char *local_abspath,
- apr_pool_t *result_pool,
- apr_pool_t *scratch_pool)
-{
- svn_node_kind_t kind;
- const char *parent_abspath;
- svn_wc_context_t *wc_ctx = ctx->wc_ctx;
-
- SVN_ERR(svn_wc_read_kind(&kind, wc_ctx, local_abspath, FALSE, scratch_pool));
-
- if (kind == svn_node_dir)
- {
- svn_boolean_t is_deleted;
-
- SVN_ERR(svn_wc__node_is_status_deleted(&is_deleted,
- wc_ctx, local_abspath,
- scratch_pool));
- if (!is_deleted)
- {
- *existing_parent_abspath = apr_pstrdup(result_pool, local_abspath);
- return SVN_NO_ERROR;
- }
- }
-
- if (svn_dirent_is_root(local_abspath, strlen(local_abspath)))
- return svn_error_create(SVN_ERR_CLIENT_NO_VERSIONED_PARENT, NULL, NULL);
-
- if (svn_wc_is_adm_dir(svn_dirent_basename(local_abspath, scratch_pool),
- scratch_pool))
- return svn_error_createf(SVN_ERR_RESERVED_FILENAME_SPECIFIED, NULL,
- _("'%s' ends in a reserved name"),
- svn_dirent_local_style(local_abspath,
- scratch_pool));
-
- parent_abspath = svn_dirent_dirname(local_abspath, scratch_pool);
-
- if (ctx->cancel_func)
- SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
-
- SVN_ERR(find_existing_parent(existing_parent_abspath, ctx, parent_abspath,
- result_pool, scratch_pool));
-
- return SVN_NO_ERROR;
-}
-
-
svn_error_t *
svn_client_add4(const char *path,
@@ -945,9 +1365,8 @@ mkdir_urls(const apr_array_header_t *url
pool));
/* Call the path-based editor driver. */
- err = svn_delta_path_driver(editor, edit_baton, SVN_INVALID_REVNUM,
- targets, path_driver_cb_func,
- (void *)editor, pool);
+ err = svn_delta_path_driver2(editor, edit_baton, targets, TRUE,
+ path_driver_cb_func, (void *)editor, pool);
if (err)
{
/* At least try to abort the edit (and fs txn) before throwing err. */
Modified: subversion/branches/javahl-ra/subversion/libsvn_client/client.h
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/client.h?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/client.h (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/client.h Mon Dec 24 22:47:14 2012
@@ -326,21 +326,88 @@ svn_client__ra_make_cb_baton(svn_wc_cont
/*** Add/delete ***/
-/* Read automatic properties matching PATH from CTX->config.
+/* Read automatic properties matching PATH from AUTOPROPS. AUTOPROPS
+ is is a hash as per svn_client__get_all_auto_props.
+
Set *PROPERTIES to a hash containing propname/value pairs
- (const char * keys mapping to svn_string_t * values), or if
- auto-props are disabled, set *PROPERTIES to NULL.
+ (const char * keys mapping to svn_string_t * values). *PROPERTIES
+ may be an empty hash, but will not be NULL.
+
Set *MIMETYPE to the mimetype, if any, or to NULL.
+
If MAGIC_COOKIE is not NULL and no mime-type can be determined
via CTX->config try to detect the mime-type with libmagic.
- Allocate the hash table, keys, values, and mimetype in POOL. */
-svn_error_t *svn_client__get_auto_props(apr_hash_t **properties,
- const char **mimetype,
- const char *path,
- svn_magic__cookie_t *magic_cookie,
- svn_client_ctx_t *ctx,
- apr_pool_t *pool);
+ Allocate the *PROPERTIES and its contents as well as *MIMETYPE, in
+ RESULT_POOL. Use SCRATCH_POOL for temporary allocations. */
+svn_error_t *svn_client__get_paths_auto_props(
+ apr_hash_t **properties,
+ const char **mimetype,
+ const char *path,
+ svn_magic__cookie_t *magic_cookie,
+ apr_hash_t *autoprops,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Gather all auto-props from CTX->config (or none if auto-props are
+ disabled) and all svn:inheritable-auto-props explicitly set on or inherited
+ by PATH_OR_URL.
+
+ If PATH_OR_URL is an unversioned WC path then gather the
+ svn:inheritable-auto-props inherited by PATH_OR_URL's nearest versioned
+ parent.
+
+ If PATH_OR_URL is a URL ask for the properties @HEAD, if it is a WC
+ path as sfor the working properties.
+
+ Store both types of auto-props in *AUTOPROPS, a hash mapping const
+ char * file patterns to another hash which maps const char * property
+ names to const char *property values.
+
+ If a given property name exists for the same pattern in both the config
+ file and in an a svn:inheritable-auto-props property, the latter overrides the
+ former. If a given property name exists for the same pattern in two
+ different inherited svn:inheritable-auto-props, then the closer path-wise
+ property overrides the more distant. svn:inheritable-auto-props explicitly set
+ on PATH_OR_URL have the highest precedence and override inherited props
+ and config file settings.
+
+ Allocate *AUTOPROPS in RESULT_POOL. Use SCRATCH_POOL for temporary
+ allocations. */
+svn_error_t *svn_client__get_all_auto_props(apr_hash_t **autoprops,
+ const char *path_or_url,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Get a combined list of ignore patterns from CTX->CONFIG, local ignore
+ patterns on LOCAL_ABSPATH (per the svn:ignore property), and from any
+ svn:inheritable-ignores properties set on, or inherited by, LOCAL_ABSPATH.
+ If LOCAL_ABSPATH is unversioned but is located within a valid working copy,
+ then find its nearest versioned parent path, if any, and return the ignore
+ patterns for that parent. Return an SVN_ERR_WC_NOT_WORKING_COPY error if
+ LOCAL_ABSPATH is neither a versioned working copy path nor an unversioned
+ path within a working copy. Store the collected patterns as const char *
+ elements in the array *IGNORES. Allocate *IGNORES and its contents in
+ RESULT_POOL. Use SCRATCH_POOL for temporary allocations. */
+svn_error_t *svn_client__get_all_ignores(apr_array_header_t **ignores,
+ const char *local_abspath,
+ svn_boolean_t no_ignore,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Get a list of ignore patterns defined by the svn:inheritable-ignores
+ properties set on, or inherited by, PATH_OR_URL. Store the collected
+ patterns as const char * elements in the array *IGNORES. Allocate
+ *IGNORES and its contents in RESULT_POOL. Use SCRATCH_POOL for
+ temporary allocations. */
+svn_error_t *svn_client__get_inherited_ignores(apr_array_header_t **ignores,
+ const char *path_or_url,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
/* The main logic for client deletion from a working copy. Deletes PATH
from CTX->WC_CTX. If PATH (or any item below a directory PATH) is
Modified: subversion/branches/javahl-ra/subversion/libsvn_client/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/javahl-ra/subversion/libsvn_client/commit.c?rev=1425690&r1=1425689&r2=1425690&view=diff
==============================================================================
--- subversion/branches/javahl-ra/subversion/libsvn_client/commit.c (original)
+++ subversion/branches/javahl-ra/subversion/libsvn_client/commit.c Mon Dec 24 22:47:14 2012
@@ -75,6 +75,13 @@ typedef struct import_ctx_t
/* A magic cookie for mime-type detection. */
svn_magic__cookie_t *magic_cookie;
+
+ /* Collection of all possible configuration file dictated auto-props and
+ svn:inheritable-auto-props. A hash mapping const char * file patterns to a
+ second hash which maps const char * property names to const char *
+ property values. Properties which don't have a value, e.g. svn:executable,
+ simply map the property name to an empty string. */
+ apr_hash_t *autoprops;
} import_ctx_t;
@@ -219,9 +226,11 @@ import_file(const svn_delta_editor_t *ed
if (! dirent->special)
{
/* add automatic properties */
- SVN_ERR(svn_client__get_auto_props(&properties, &mimetype, local_abspath,
- import_ctx->magic_cookie,
- ctx, pool));
+ SVN_ERR(svn_client__get_paths_auto_props(&properties, &mimetype,
+ local_abspath,
+ import_ctx->magic_cookie,
+ import_ctx->autoprops,
+ ctx, pool, pool));
}
else
properties = apr_hash_make(pool);
@@ -278,7 +287,8 @@ import_file(const svn_delta_editor_t *ed
/* Return in CHILDREN a mapping of basenames to dirents for the importable
* children of DIR_ABSPATH. EXCLUDES is a hash of absolute paths to filter
- * out. IGNORES, if non-NULL, is a list of basenames to filter out.
+ * out. IGNORES and MANDATORY_IGNORES, if non-NULL, are lists of basename
+ * patterns to filter out.
* FILTER_CALLBACK and FILTER_BATON will be called for each absolute path,
* allowing users to further filter the list of returned entries.
*
@@ -288,6 +298,7 @@ get_filtered_children(apr_hash_t **child
const char *dir_abspath,
apr_hash_t *excludes,
apr_array_header_t *ignores,
+ apr_array_header_t *mandatory_ignores,
svn_client_import_filter_func_t filter_callback,
void *filter_baton,
svn_client_ctx_t *ctx,
@@ -348,6 +359,12 @@ get_filtered_children(apr_hash_t **child
continue;
}
+ if (svn_wc_match_ignore_list(base_name, mandatory_ignores, iterpool))
+ {
+ apr_hash_set(dirents, base_name, APR_HASH_KEY_STRING, NULL);
+ continue;
+ }
+
if (filter_callback)
{
svn_boolean_t filter = FALSE;
@@ -375,6 +392,7 @@ import_dir(const svn_delta_editor_t *edi
const char *edit_path,
svn_depth_t depth,
apr_hash_t *excludes,
+ apr_array_header_t *mandatory_ignores,
svn_boolean_t no_ignore,
svn_boolean_t ignore_unknown_node_types,
svn_client_import_filter_func_t filter_callback,
@@ -394,6 +412,7 @@ import_children(const char *dir_abspath,
void *dir_baton,
svn_depth_t depth,
apr_hash_t *excludes,
+ apr_array_header_t *mandatory_ignores,
svn_boolean_t no_ignore,
svn_boolean_t ignore_unknown_node_types,
svn_client_import_filter_func_t filter_callback,
@@ -436,10 +455,9 @@ import_children(const char *dir_abspath,
SVN_ERR(import_dir(editor, dir_baton, this_abspath,
this_edit_path, depth_below_here, excludes,
- no_ignore, ignore_unknown_node_types,
- filter_callback, filter_baton,
- import_ctx, ctx,
- iterpool));
+ mandatory_ignores, no_ignore,
+ ignore_unknown_node_types, filter_callback,
+ filter_baton, import_ctx, ctx, iterpool));
}
else if (dirent->kind == svn_node_file && depth >= svn_depth_files)
{
@@ -490,6 +508,9 @@ import_children(const char *dir_abspath,
* EXCLUDES is a hash whose keys are absolute paths to exclude from
* the import (values are unused).
*
+ * MANDATORY_IGNORES is an array of const char * ignore patterns. Any child
+ * of LOCAL_ABSPATH which matches one or more of the patterns is not imported.
+ *
* If NO_IGNORE is FALSE, don't import files or directories that match
* ignore patterns.
*
@@ -507,6 +528,7 @@ import_dir(const svn_delta_editor_t *edi
const char *edit_path,
svn_depth_t depth,
apr_hash_t *excludes,
+ apr_array_header_t *mandatory_ignores,
svn_boolean_t no_ignore,
svn_boolean_t ignore_unknown_node_types,
svn_client_import_filter_func_t filter_callback,
@@ -525,8 +547,8 @@ import_dir(const svn_delta_editor_t *edi
SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, pool));
SVN_ERR(get_filtered_children(&dirents, local_abspath, excludes, ignores,
- filter_callback, filter_baton, ctx,
- pool, pool));
+ mandatory_ignores, filter_callback,
+ filter_baton, ctx, pool, pool));
/* Import this directory, but not yet its children. */
{
@@ -556,8 +578,8 @@ import_dir(const svn_delta_editor_t *edi
/* Now import the children recursively. */
SVN_ERR(import_children(local_abspath, edit_path, dirents, editor,
- this_dir_baton, depth, excludes, no_ignore,
- ignore_unknown_node_types,
+ this_dir_baton, depth, excludes, mandatory_ignores,
+ no_ignore, ignore_unknown_node_types,
filter_callback, filter_baton,
import_ctx, ctx, pool));
@@ -590,6 +612,19 @@ import_dir(const svn_delta_editor_t *edi
* EXCLUDES is a hash whose keys are absolute paths to exclude from
* the import (values are unused).
*
+ * AUTOPROPS is hash of all config file autoprops and
+ * svn:inheritable-auto-props inherited by the import target, see the
+ * IMPORT_CTX member of the same name.
+ *
+ * LOCAL_IGNORES is an array of const char * ignore patterns which
+ * correspond to the svn:ignore property (if any) set on the root of the
+ * repository target and thus dictates which immediate children of that
+ * target should be ignored and not imported.
+ *
+ * MANDATORY_IGNORES is an array of const char * ignore patterns which
+ * correspond to the svn:inheritable-ignores properties (if any) set on
+ * the root of the repository target or inherited by it.
+ *
* If NO_IGNORE is FALSE, don't import files or directories that match
* ignore patterns.
*
@@ -610,6 +645,9 @@ import(const char *local_abspath,
void *edit_baton,
svn_depth_t depth,
apr_hash_t *excludes,
+ apr_hash_t *autoprops,
+ apr_array_header_t *local_ignores,
+ apr_array_header_t *mandatory_ignores,
svn_boolean_t no_ignore,
svn_boolean_t ignore_unknown_node_types,
svn_client_import_filter_func_t filter_callback,
@@ -624,6 +662,7 @@ import(const char *local_abspath,
import_ctx_t *import_ctx = apr_pcalloc(pool, sizeof(*import_ctx));
const svn_io_dirent2_t *dirent;
+ import_ctx->autoprops = autoprops;
svn_magic__init(&import_ctx->magic_cookie, pool);
/* Get a root dir baton. We pass an invalid revnum to open_root
@@ -687,8 +726,9 @@ import(const char *local_abspath,
if (!no_ignore)
{
SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, pool));
- ignores_match = svn_wc_match_ignore_list(local_abspath,
- ignores, pool);
+ ignores_match =
+ (svn_wc_match_ignore_list(local_abspath, ignores, pool)
+ || svn_wc_match_ignore_list(local_abspath, local_ignores, pool));
}
if (!ignores_match)
SVN_ERR(import_file(editor, root_baton, local_abspath, edit_path,
@@ -699,15 +739,35 @@ import(const char *local_abspath,
apr_hash_t *dirents;
if (!no_ignore)
- SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, pool));
+ {
+ int i;
+
+ SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, pool));
- SVN_ERR(get_filtered_children(&dirents, local_abspath, excludes, ignores,
+ /* If we are not creating new repository paths, then we are creating
+ importing new paths to an existing directory. If that directory
+ has the svn:ignore property set on it, then we want to ignore
+ immediate children that match the pattern(s) defined by that
+ property. */
+ if (!new_entries->nelts)
+ {
+ for (i = 0; i < local_ignores->nelts; i++)
+ {
+ const char *ignore = APR_ARRAY_IDX(local_ignores, i,
+ const char *);
+ APR_ARRAY_PUSH(ignores, const char *) = ignore;
+ }
+ }
+ }
+
+ SVN_ERR(get_filtered_children(&dirents, local_abspath, excludes,
+ ignores, mandatory_ignores,
filter_callback, filter_baton, ctx,
pool, pool));
SVN_ERR(import_children(local_abspath, edit_path, dirents, editor,
- root_baton, depth, excludes, no_ignore,
- ignore_unknown_node_types,
+ root_baton, depth, excludes, mandatory_ignores,
+ no_ignore, ignore_unknown_node_types,
filter_callback, filter_baton,
import_ctx, ctx, pool));
@@ -853,6 +913,11 @@ svn_client_import5(const char *path,
const char *dir;
apr_hash_t *commit_revprops;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ apr_hash_t *autoprops;
+ apr_array_header_t *mandatory_ignores;
+ svn_opt_revision_t rev;
+ apr_hash_t *local_ignores_hash;
+ apr_array_header_t *local_ignores_arr;
if (svn_path_is_url(path))
return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
@@ -964,13 +1029,35 @@ svn_client_import5(const char *path,
commit_baton, NULL, TRUE,
scratch_pool));
+ /* Get inherited svn:inheritable-auto-props, svn:inheritable-ignores, and
+ svn:ignores for the location we are importing to. */
+ SVN_ERR(svn_client__get_all_auto_props(&autoprops, url, ctx,
+ scratch_pool, iterpool));
+ SVN_ERR(svn_client__get_inherited_ignores(&mandatory_ignores, url,
+ ctx, scratch_pool, iterpool));
+ rev.kind = svn_opt_revision_head;
+ SVN_ERR(svn_client_propget5(&local_ignores_hash, NULL, SVN_PROP_IGNORE, url,
+ &rev, &rev, NULL, svn_depth_empty, NULL, ctx,
+ scratch_pool, scratch_pool));
+ local_ignores_arr = apr_array_make(scratch_pool, 1, sizeof(const char *));
+
+ if (apr_hash_count(local_ignores_hash))
+ {
+ svn_string_t *propval = apr_hash_get(local_ignores_hash, url,
+ APR_HASH_KEY_STRING);
+ if (propval)
+ {
+ svn_cstring_split_append(local_ignores_arr, propval->data,
+ "\n\r\t\v ", FALSE, scratch_pool);
+ }
+ }
+
/* If an error occurred during the commit, abort the edit and return
the error. We don't even care if the abort itself fails. */
if ((err = import(local_abspath, new_entries, editor, edit_baton,
- depth, excludes, no_ignore,
- ignore_unknown_node_types,
- filter_callback, filter_baton,
- ctx, iterpool)))
+ depth, excludes, autoprops, local_ignores_arr,
+ mandatory_ignores, no_ignore, ignore_unknown_node_types,
+ filter_callback, filter_baton, ctx, iterpool)))
{
svn_error_clear(editor->abort_edit(edit_baton, iterpool));
return svn_error_trace(err);
@@ -1341,14 +1428,14 @@ append_externals_as_explicit_targets(apr
/* Easy part of applying DEPTH to externals. */
if (depth == svn_depth_empty)
- {
- /* Don't recurse. */
- return SVN_NO_ERROR;
- }
- else if (depth != svn_depth_infinity)
- {
- include_dir_externals = FALSE;
- /* We slip in dir externals as explicit targets. When we do that,
+ {
+ /* Don't recurse. */
+ return SVN_NO_ERROR;
+ }
+ else if (depth != svn_depth_infinity)
+ {
+ include_dir_externals = FALSE;
+ /* We slip in dir externals as explicit targets. When we do that,
* depth_immediates should become depth_empty for dir externals targets.
* But adding the dir external to the list of targets makes it get
* handled with depth_immediates itself, and thus will also include the
@@ -1363,7 +1450,7 @@ append_externals_as_explicit_targets(apr
* ### --depth=immediates --include-externals', commit dir externals
* ### (only immediate children of a target) with depth_empty instead of
* ### not at all. No other effect. So not doing that for now. */
- }
+ }
/* Iterate *and* grow REL_TARGETS at the same time. */
rel_targets_nelts_fixed = rel_targets->nelts;