Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 7BA73C47 for ; Fri, 31 Aug 2012 19:21:47 +0000 (UTC) Received: (qmail 86557 invoked by uid 500); 31 Aug 2012 19:21:47 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 86506 invoked by uid 500); 31 Aug 2012 19:21:47 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 86499 invoked by uid 99); 31 Aug 2012 19:21:47 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 31 Aug 2012 19:21:47 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 31 Aug 2012 19:21:39 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 0877B23888E3; Fri, 31 Aug 2012 19:20:54 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1379554 - in /subversion/branches/inheritable-props: ./ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/include/ subversion/include/private/ subversion/libsvn_auth_gnome_keyring/ subversion/libsvn_fs_fs/ subversion/... Date: Fri, 31 Aug 2012 19:20:52 -0000 To: commits@subversion.apache.org From: pburba@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120831192054.0877B23888E3@eris.apache.org> Author: pburba Date: Fri Aug 31 19:20:50 2012 New Revision: 1379554 URL: http://svn.apache.org/viewvc?rev=1379554&view=rev Log: On the inheritable-props branch: Sync with ^/subversion/trunk through r1379553. Added: subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnpubsub - copied unchanged from r1379553, subversion/trunk/tools/server-side/svnpubsub/rc.d/svnpubsub subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnpubsub.freebsd - copied unchanged from r1379553, subversion/trunk/tools/server-side/svnpubsub/rc.d/svnpubsub.freebsd subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnwcsub - copied unchanged from r1379553, subversion/trunk/tools/server-side/svnpubsub/rc.d/svnwcsub subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnwcsub.freebsd - copied unchanged from r1379553, subversion/trunk/tools/server-side/svnpubsub/rc.d/svnwcsub.freebsd Modified: subversion/branches/inheritable-props/ (props changed) subversion/branches/inheritable-props/build.conf subversion/branches/inheritable-props/subversion/bindings/javahl/src/org/apache/subversion/javahl/ConflictDescriptor.java subversion/branches/inheritable-props/subversion/include/private/svn_sqlite.h subversion/branches/inheritable-props/subversion/include/svn_wc.h subversion/branches/inheritable-props/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c subversion/branches/inheritable-props/subversion/libsvn_fs_fs/caching.c subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs.h subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs_fs.c subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.c subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.h subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h subversion/branches/inheritable-props/subversion/libsvn_ra_serf/replay.c subversion/branches/inheritable-props/subversion/libsvn_ra_serf/update.c subversion/branches/inheritable-props/subversion/libsvn_ra_serf/util.c subversion/branches/inheritable-props/subversion/libsvn_subr/gpg_agent.c subversion/branches/inheritable-props/subversion/libsvn_subr/opt.c subversion/branches/inheritable-props/subversion/libsvn_subr/sqlite.c subversion/branches/inheritable-props/subversion/libsvn_subr/sysinfo.c subversion/branches/inheritable-props/subversion/libsvn_subr/sysinfo.h subversion/branches/inheritable-props/subversion/libsvn_wc/conflicts.c subversion/branches/inheritable-props/subversion/libsvn_wc/tree_conflicts.c subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c subversion/branches/inheritable-props/subversion/mod_dav_svn/reports/update.c subversion/branches/inheritable-props/subversion/svn/tree-conflicts.c subversion/branches/inheritable-props/tools/server-side/svnpubsub/README.txt subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnpubsub.debian subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnwcsub.debian subversion/branches/inheritable-props/tools/server-side/svnpubsub/svnwcsub.py Propchange: subversion/branches/inheritable-props/ ------------------------------------------------------------------------------ Merged /subversion/trunk:r1377920-1379553 Modified: subversion/branches/inheritable-props/build.conf URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/build.conf?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/build.conf (original) +++ subversion/branches/inheritable-props/build.conf Fri Aug 31 19:20:50 2012 @@ -83,6 +83,27 @@ swig-checkout-files = common.swg swigrun # # BUILD TARGETS # +# Target parameters: +# description - optional build target description +# type - the target type, defines how to build it +# when - the name of an autoconf-substed variable that muset be +# defined to either "true" or "false", that determines +# whether this target should be built and installed. +# path - relative path to target sources +# sources - explicit list of target sources +# install - the installation group/type +# manpages - the man pages associated with this target +# libs - libraries that this target depends on +# nonlibs - dependencies that are not linked into the target +# lang - bindings for language $(lang) +# msvc-libs - additional libraries to link with on Windows +# msvc-export - additional list of files to expose in dsp/vc(x)proj +# msvc-static - visual studio target produces only a static lib +# add-deps - expands to additional autoconf-defined dependencies +# add-install-deps - like add-deps, but for the install step +# external-lib - expands to additional autoconf-defined libs +# external-project - visual studio project to depend on +# # The subversion command-line client [svn] Modified: subversion/branches/inheritable-props/subversion/bindings/javahl/src/org/apache/subversion/javahl/ConflictDescriptor.java URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/bindings/javahl/src/org/apache/subversion/javahl/ConflictDescriptor.java?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/bindings/javahl/src/org/apache/subversion/javahl/ConflictDescriptor.java (original) +++ subversion/branches/inheritable-props/subversion/bindings/javahl/src/org/apache/subversion/javahl/ConflictDescriptor.java Fri Aug 31 19:20:50 2012 @@ -250,7 +250,19 @@ public class ConflictDescriptor /** * Object is already replaced. */ - replaced; + replaced, + + /** + * Object is moved away. + * @since 1.8 + */ + moved_away, + + /** + * Object is moved here. + * @since 1.8 + */ + moved_here; } public enum Operation Modified: subversion/branches/inheritable-props/subversion/include/private/svn_sqlite.h URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/include/private/svn_sqlite.h?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/include/private/svn_sqlite.h (original) +++ subversion/branches/inheritable-props/subversion/include/private/svn_sqlite.h Fri Aug 31 19:20:50 2012 @@ -37,6 +37,17 @@ extern "C" { #endif /* __cplusplus */ +/* Because the SQLite code can be inlined into libsvn_subre/sqlite.c, + we define accessors to its compile-time and run-time version + numbers here. */ + +/* Return the value that SQLITE_VERSION had at compile time. */ +const char *svn_sqlite__compiled_version(void); + +/* Return the value of sqlite3_libversion() at run time. */ +const char *svn_sqlite__runtime_version(void); + + typedef struct svn_sqlite__db_t svn_sqlite__db_t; typedef struct svn_sqlite__stmt_t svn_sqlite__stmt_t; typedef struct svn_sqlite__context_t svn_sqlite__context_t; Modified: subversion/branches/inheritable-props/subversion/include/svn_wc.h URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/include/svn_wc.h?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/include/svn_wc.h (original) +++ subversion/branches/inheritable-props/subversion/include/svn_wc.h Fri Aug 31 19:20:50 2012 @@ -1593,10 +1593,6 @@ typedef enum svn_wc_conflict_reason_t svn_wc_conflict_reason_replaced, /** Object is moved away. @since New in 1.8. */ svn_wc_conflict_reason_moved_away, - /** Object is moved away and was edited post-move. @since New in 1.8. */ - /* ### Do we really need this. The edit state is on a different node, - which might just change while the tree conflict exists? */ - svn_wc_conflict_reason_moved_away_and_edited, /** Object is moved here. @since New in 1.8. */ svn_wc_conflict_reason_moved_here Modified: subversion/branches/inheritable-props/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_auth_gnome_keyring/gnome_keyring.c Fri Aug 31 19:20:50 2012 @@ -428,12 +428,14 @@ simple_gnome_keyring_save_creds(svn_bool pool); } +#if GLIB_CHECK_VERSION(2,6,0) static void log_noop(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data) { /* do nothing */ } +#endif static void init_gnome_keyring(void) @@ -449,7 +451,9 @@ init_gnome_keyring(void) suppress stderr spam for not only libgnome-keyring, but for anything else the app is linked to that uses glib logging and doesn't specify a log_domain. */ +#if GLIB_CHECK_VERSION(2,6,0) g_log_set_default_handler(log_noop, NULL); +#endif } static const svn_auth_provider_t gnome_keyring_simple_provider = { Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/caching.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/caching.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/caching.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/caching.c Fri Aug 31 19:20:50 2012 @@ -429,6 +429,19 @@ svn_fs_fs__initialize_caches(svn_fs_t *f SVN_ERR(init_callbacks(ffd->node_revision_cache, fs, no_handler, pool)); + /* initialize node change list cache, if caching has been enabled */ + SVN_ERR(create_cache(&(ffd->changes_cache), + NULL, + membuffer, + 0, 0, /* Do not use inprocess cache */ + svn_fs_fs__serialize_changes, + svn_fs_fs__deserialize_changes, + sizeof(svn_revnum_t), + apr_pstrcat(pool, prefix, "CHANGES", (char *)NULL), + fs->pool)); + + SVN_ERR(init_callbacks(ffd->changes_cache, fs, no_handler, pool)); + return SVN_NO_ERROR; } Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs.h URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs.h?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs.h (original) +++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs.h Fri Aug 31 19:20:50 2012 @@ -285,6 +285,10 @@ typedef struct fs_fs_data_t /* Cache for node_revision_t objects; the key is (revision, id offset) */ svn_cache__t *node_revision_cache; + /* Cache for change lists as APR arrays of change_t * objects; the key + is the revision */ + svn_cache__t *changes_cache; + /* If set, there are or have been more than one concurrent transaction */ svn_boolean_t concurrent_transactions; Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs_fs.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs_fs.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs_fs.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/fs_fs.c Fri Aug 31 19:20:50 2012 @@ -5748,7 +5748,7 @@ read_change(change_t **change_p, return SVN_NO_ERROR; } -/* Fetch all the changed path entries from FILE and store then in +/* Examine all the changed path entries in CHANGES and store them in *CHANGED_PATHS. Folding is done to remove redundant or unnecessary *data. Store a hash of paths to copyfrom "REV PATH" strings in COPYFROM_HASH if it is non-NULL. If PREFOLDED is true, assume that @@ -5757,22 +5757,22 @@ read_change(change_t **change_p, remove children of replaced or deleted directories. Do all allocations in POOL. */ static svn_error_t * -fetch_all_changes(apr_hash_t *changed_paths, - apr_hash_t *copyfrom_cache, - apr_file_t *file, - svn_boolean_t prefolded, - apr_pool_t *pool) +process_changes(apr_hash_t *changed_paths, + apr_hash_t *copyfrom_cache, + apr_array_header_t *changes, + svn_boolean_t prefolded, + apr_pool_t *pool) { - change_t *change; apr_pool_t *iterpool = svn_pool_create(pool); + int i; /* Read in the changes one by one, folding them into our local hash as necessary. */ - SVN_ERR(read_change(&change, file, iterpool)); - - while (change) + for (i = 0; i < changes->nelts; ++i) { + change_t *change = APR_ARRAY_IDX(changes, i, change_t *); + SVN_ERR(fold_change(changed_paths, change, copyfrom_cache)); /* Now, if our change was a deletion or replacement, we have to @@ -5826,8 +5826,6 @@ fetch_all_changes(apr_hash_t *changed_pa /* Clear the per-iteration subpool. */ svn_pool_clear(iterpool); - - SVN_ERR(read_change(&change, file, iterpool)); } /* Destroy the per-iteration subpool. */ @@ -5836,6 +5834,29 @@ fetch_all_changes(apr_hash_t *changed_pa return SVN_NO_ERROR; } +/* Fetch all the changes from FILE and store them in *CHANGES. Do all + allocations in POOL. */ +static svn_error_t * +read_all_changes(apr_array_header_t **changes, + apr_file_t *file, + apr_pool_t *pool) +{ + change_t *change; + + /* pre-allocate enough room for most change lists + (will be auto-expanded as necessary) */ + *changes = apr_array_make(pool, 30, sizeof(change_t *)); + + SVN_ERR(read_change(&change, file, pool)); + while (change) + { + APR_ARRAY_PUSH(*changes, change_t*) = change; + SVN_ERR(read_change(&change, file, pool)); + } + + return SVN_NO_ERROR; +} + svn_error_t * svn_fs_fs__txn_changes_fetch(apr_hash_t **changed_paths_p, svn_fs_t *fs, @@ -5844,11 +5865,15 @@ svn_fs_fs__txn_changes_fetch(apr_hash_t { apr_file_t *file; apr_hash_t *changed_paths = apr_hash_make(pool); + apr_array_header_t *changes; + apr_pool_t *scratch_pool = svn_pool_create(pool); SVN_ERR(svn_io_file_open(&file, path_txn_changes(fs, txn_id, pool), APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool)); - SVN_ERR(fetch_all_changes(changed_paths, NULL, file, FALSE, pool)); + SVN_ERR(read_all_changes(&changes, file, scratch_pool)); + SVN_ERR(process_changes(changed_paths, NULL, changes, FALSE, pool)); + svn_pool_destroy(scratch_pool); SVN_ERR(svn_io_file_close(file, pool)); @@ -5857,17 +5882,32 @@ svn_fs_fs__txn_changes_fetch(apr_hash_t return SVN_NO_ERROR; } -svn_error_t * -svn_fs_fs__paths_changed(apr_hash_t **changed_paths_p, - svn_fs_t *fs, - svn_revnum_t rev, - apr_hash_t *copyfrom_cache, - apr_pool_t *pool) +/* Fetch the list of change in revision REV in FS and return it in *CHANGES. + * Allocate the result in POOL. + */ +static svn_error_t * +get_changes(apr_array_header_t **changes, + svn_fs_t *fs, + svn_revnum_t rev, + apr_pool_t *pool) { apr_off_t changes_offset; - apr_hash_t *changed_paths; apr_file_t *revision_file; + svn_boolean_t found; + fs_fs_data_t *ffd = fs->fsap_data; + + /* try cache lookup first */ + + if (ffd->changes_cache) + { + SVN_ERR(svn_cache__get((void **) changes, &found, ffd->changes_cache, + &rev, pool)); + if (found) + return SVN_NO_ERROR; + } + /* read changes from revision file */ + SVN_ERR(ensure_revision_exists(fs, rev, pool)); SVN_ERR(open_pack_or_rev_file(&revision_file, fs, rev, pool)); @@ -5876,14 +5916,37 @@ svn_fs_fs__paths_changed(apr_hash_t **ch rev, pool)); SVN_ERR(svn_io_file_seek(revision_file, APR_SET, &changes_offset, pool)); + SVN_ERR(read_all_changes(changes, revision_file, pool)); + + SVN_ERR(svn_io_file_close(revision_file, pool)); - changed_paths = apr_hash_make(pool); + /* cache for future reference */ + + if (ffd->changes_cache) + SVN_ERR(svn_cache__set(ffd->changes_cache, &rev, *changes, pool)); - SVN_ERR(fetch_all_changes(changed_paths, copyfrom_cache, revision_file, - TRUE, pool)); + return SVN_NO_ERROR; +} - /* Close the revision file. */ - SVN_ERR(svn_io_file_close(revision_file, pool)); + +svn_error_t * +svn_fs_fs__paths_changed(apr_hash_t **changed_paths_p, + svn_fs_t *fs, + svn_revnum_t rev, + apr_hash_t *copyfrom_cache, + apr_pool_t *pool) +{ + apr_hash_t *changed_paths; + apr_array_header_t *changes; + apr_pool_t *scratch_pool = svn_pool_create(pool); + + SVN_ERR(get_changes(&changes, fs, rev, scratch_pool)); + + changed_paths = apr_hash_make(pool); + + SVN_ERR(process_changes(changed_paths, copyfrom_cache, changes, + TRUE, pool)); + svn_pool_destroy(scratch_pool); *changed_paths_p = changed_paths; Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.c Fri Aug 31 19:20:50 2012 @@ -1079,3 +1079,135 @@ svn_fs_fs__replace_dir_entry(void **data return SVN_NO_ERROR; } + +/* Utility function to serialize change CHANGE_P in the given serialization + * CONTEXT. + */ +static void +serialize_change(svn_temp_serializer__context_t *context, + change_t * const *change_p) +{ + const change_t * change = *change_p; + if (change == NULL) + return; + + /* serialize the change struct itself */ + svn_temp_serializer__push(context, + (const void * const *)change_p, + sizeof(*change)); + + /* serialize sub-structures */ + svn_fs_fs__id_serialize(context, &change->noderev_id); + + svn_temp_serializer__add_string(context, &change->path); + svn_temp_serializer__add_string(context, &change->copyfrom_path); + + /* return to the caller's nesting level */ + svn_temp_serializer__pop(context); +} + +/* Utility function to serialize the CHANGE_P within the given + * serialization CONTEXT. + */ +static void +deserialize_change(void *buffer, change_t **change_p) +{ + change_t * change; + + /* fix-up of the pointer to the struct in question */ + svn_temp_deserializer__resolve(buffer, (void **)change_p); + + change = *change_p; + if (change == NULL) + return; + + /* fix-up of sub-structures */ + svn_fs_fs__id_deserialize(change, (svn_fs_id_t **)&change->noderev_id); + + svn_temp_deserializer__resolve(change, (void **)&change->path); + svn_temp_deserializer__resolve(change, (void **)&change->copyfrom_path); +} + +/* Auxiliary structure representing the content of a change_t array. + This structure is much easier to (de-)serialize than an APR array. + */ +typedef struct changes_data_t +{ + /* number of entries in the array */ + int count; + + /* reference to the changes */ + change_t **changes; +} changes_data_t; + +svn_error_t * +svn_fs_fs__serialize_changes(void **data, + apr_size_t *data_len, + void *in, + apr_pool_t *pool) +{ + apr_array_header_t *array = in; + changes_data_t changes; + svn_temp_serializer__context_t *context; + svn_stringbuf_t *serialized; + int i; + + /* initialize our auxiliary data structure */ + changes.count = array->nelts; + changes.changes = apr_palloc(pool, sizeof(change_t*) * changes.count); + + /* populate it with the array elements */ + for (i = 0; i < changes.count; ++i) + changes.changes[i] = APR_ARRAY_IDX(array, i, change_t*); + + /* serialize it and all its elements */ + context = svn_temp_serializer__init(&changes, + sizeof(changes), + changes.count * 100, + pool); + + svn_temp_serializer__push(context, + (const void * const *)&changes.changes, + changes.count * sizeof(change_t*)); + + for (i = 0; i < changes.count; ++i) + serialize_change(context, &changes.changes[i]); + + svn_temp_serializer__pop(context); + + /* return the serialized result */ + serialized = svn_temp_serializer__get(context); + + *data = serialized->data; + *data_len = serialized->len; + + return SVN_NO_ERROR; +} + +svn_error_t * +svn_fs_fs__deserialize_changes(void **out, + void *data, + apr_size_t data_len, + apr_pool_t *pool) +{ + int i; + changes_data_t *changes = (changes_data_t *)data; + apr_array_header_t *array = apr_array_make(pool, changes->count, + sizeof(change_t *)); + + /* de-serialize our auxiliary data structure */ + svn_temp_deserializer__resolve(changes, (void**)&changes->changes); + + /* de-serialize each entry and add it to the array */ + for (i = 0; i < changes->count; ++i) + { + deserialize_change((void*)changes->changes, + (change_t **)&changes->changes[i]); + APR_ARRAY_PUSH(array, change_t *) = changes->changes[i]; + } + + /* done */ + *out = array; + + return SVN_NO_ERROR; +} Modified: subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.h URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.h?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.h (original) +++ subversion/branches/inheritable-props/subversion/libsvn_fs_fs/temp_serializer.h Fri Aug 31 19:20:50 2012 @@ -235,4 +235,24 @@ svn_fs_fs__replace_dir_entry(void **data void *baton, apr_pool_t *pool); +/** + * Implements #svn_cache__serialize_func_t for an #apr_array_header_t of + * #change_t *. + */ +svn_error_t * +svn_fs_fs__serialize_changes(void **data, + apr_size_t *data_len, + void *in, + apr_pool_t *pool); + +/** + * Implements #svn_cache__deserialize_func_t for an #apr_array_header_t of + * #change_t *. + */ +svn_error_t * +svn_fs_fs__deserialize_changes(void **out, + void *data, + apr_size_t data_len, + apr_pool_t *pool); + #endif Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h (original) +++ subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h Fri Aug 31 19:20:50 2012 @@ -62,6 +62,10 @@ extern "C" { APR_STRINGIFY(SERF_MINOR_VERSION) "." \ APR_STRINGIFY(SERF_PATCH_VERSION) +/** Wait duration (in microseconds) used in calls to serf_context_run() */ +#define SVN_RA_SERF__CONTEXT_RUN_DURATION 500000 + + /* Forward declarations. */ typedef struct svn_ra_serf__session_t svn_ra_serf__session_t; Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_serf/replay.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_serf/replay.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_ra_serf/replay.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_ra_serf/replay.c Fri Aug 31 19:20:50 2012 @@ -732,6 +732,7 @@ svn_ra_serf__replay_range(svn_ra_session svn_revnum_t rev = start_revision; const char *report_target; int active_reports = 0; + apr_short_interval_time_t waittime_left = session->timeout; SVN_ERR(svn_ra_serf__report_resource(&report_target, session, NULL, pool)); @@ -855,18 +856,36 @@ svn_ra_serf__replay_range(svn_ra_session ### ahead and apply it here, too, in case serf eventually uses ### that parameter. */ - status = serf_context_run(session->context, session->timeout, + status = serf_context_run(session->context, + SVN_RA_SERF__CONTEXT_RUN_DURATION, pool); err = session->pending_error; session->pending_error = NULL; + /* If the context duration timeout is up, we'll subtract that + duration from the total time alloted for such things. If + there's no time left, we fail with a message indicating that + the connection timed out. */ if (APR_STATUS_IS_TIMEUP(status)) { svn_error_clear(err); - return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT, - NULL, - _("Connection timed out")); + err = SVN_NO_ERROR; + status = 0; + + if (waittime_left > SVN_RA_SERF__CONTEXT_RUN_DURATION) + { + waittime_left -= SVN_RA_SERF__CONTEXT_RUN_DURATION; + } + else + { + return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT, NULL, + _("Connection timed out")); + } + } + else + { + waittime_left = session->timeout; } /* Substract the number of completely handled responses from our Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_serf/update.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_serf/update.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_ra_serf/update.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_ra_serf/update.c Fri Aug 31 19:20:50 2012 @@ -313,6 +313,10 @@ struct report_context_t { /* Do we want the server to send copyfrom args or not? */ svn_boolean_t send_copyfrom_args; + /* Is the server including properties inline for newly added + files/dirs? */ + svn_boolean_t add_props_included; + /* Path -> lock token mapping. */ apr_hash_t *lock_path_tokens; @@ -358,6 +362,9 @@ struct report_context_t { /* Are we done parsing the REPORT response? */ svn_boolean_t done; + /* Did we get a complete (non-truncated) report? */ + svn_boolean_t report_completed; + /* The XML parser context for the REPORT response. */ svn_ra_serf__xml_parser_t *parser_ctx; }; @@ -1216,9 +1223,9 @@ fetch_file(report_context_t *ctx, report if (!info->url) { - return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL, - _("The OPTIONS response did not include the " - "requested checked-in value")); + return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, + _("The REPORT or PROPFIND response did not " + "include the requested checked-in value")); } /* If needed, create the PROPFIND to retrieve the file's properties. */ @@ -1388,7 +1395,13 @@ start_report(svn_ra_serf__xml_parser_t * state = parser->state->current_state; - if (state == NONE && strcmp(name.name, "target-revision") == 0) + if (state == NONE && strcmp(name.name, "update-report") == 0) + { + const char *val = svn_xml_get_attr_value("inline-props", attrs); + if (val && (strcmp(val, "true") == 0)) + ctx->add_props_included = TRUE; + } + else if (state == NONE && strcmp(name.name, "target-revision") == 0) { const char *rev; @@ -1528,7 +1541,11 @@ start_report(svn_ra_serf__xml_parser_t * /* Mark that we don't have a base. */ info->base_rev = SVN_INVALID_REVNUM; dir->base_rev = info->base_rev; - dir->fetch_props = TRUE; + + /* If the server isn't included properties for added items, + we'll need to fetch them ourselves. */ + if (! ctx->add_props_included) + dir->fetch_props = TRUE; dir->repos_relpath = svn_relpath_join(dir->parent_dir->repos_relpath, dir->base_name, dir->pool); @@ -1585,9 +1602,13 @@ start_report(svn_ra_serf__xml_parser_t * info = push_state(parser, ctx, ADD_FILE); info->base_rev = SVN_INVALID_REVNUM; - info->fetch_props = TRUE; info->fetch_file = TRUE; + /* If the server isn't included properties for added items, + we'll need to fetch them ourselves. */ + if (! ctx->add_props_included) + info->fetch_props = TRUE; + info->base_name = apr_pstrdup(info->pool, file_name); info->name = NULL; @@ -1862,8 +1883,15 @@ end_report(svn_ra_serf__xml_parser_t *pa if (state == NONE) { - /* nothing to close yet. */ - return SVN_NO_ERROR; + if (strcmp(name.name, "update-report") == 0) + { + ctx->report_completed = TRUE; + } + else + { + /* nothing to close yet. */ + return SVN_NO_ERROR; + } } if (((state == OPEN_DIR && (strcmp(name.name, "open-directory") == 0)) || @@ -1886,9 +1914,9 @@ end_report(svn_ra_serf__xml_parser_t *pa if (!checked_in_url && (!SVN_IS_VALID_REVNUM(info->dir->base_rev) || info->dir->fetch_props)) { - return svn_error_create(SVN_ERR_RA_DAV_OPTIONS_REQ_FAILED, NULL, - _("The OPTIONS response did not include the " - "requested checked-in value")); + return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, + _("The REPORT or PROPFIND response did not " + "include the requested checked-in value")); } info->dir->url = checked_in_url; @@ -1896,7 +1924,7 @@ end_report(svn_ra_serf__xml_parser_t *pa /* At this point, we should have the checked-in href. * If needed, create the PROPFIND to retrieve the dir's properties. */ - if (!SVN_IS_VALID_REVNUM(info->dir->base_rev) || info->dir->fetch_props) + if (info->dir->fetch_props) { /* Unconditionally set fetch_props now. */ info->dir->fetch_props = TRUE; @@ -2353,6 +2381,7 @@ finish_report(void *report_baton, svn_stringbuf_t *buf = NULL; apr_pool_t *iterpool = svn_pool_create(pool); svn_error_t *err; + apr_short_interval_time_t waittime_left = sess->timeout; svn_xml_make_close_tag(&buf, iterpool, "S:update-report"); SVN_ERR(svn_io_file_write_full(report->body_file, buf->data, buf->len, @@ -2435,7 +2464,9 @@ finish_report(void *report_baton, and what items are allocated within. */ iterpool_inner = svn_pool_create(iterpool); - status = serf_context_run(sess->context, sess->timeout, iterpool_inner); + status = serf_context_run(sess->context, + SVN_RA_SERF__CONTEXT_RUN_DURATION, + iterpool_inner); err = sess->pending_error; sess->pending_error = SVN_NO_ERROR; @@ -2445,12 +2476,29 @@ finish_report(void *report_baton, err = handler->server_error->error; } + /* If the context duration timeout is up, we'll subtract that + duration from the total time alloted for such things. If + there's no time left, we fail with a message indicating that + the connection timed out. */ if (APR_STATUS_IS_TIMEUP(status)) { svn_error_clear(err); - return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT, - NULL, - _("Connection timed out")); + err = SVN_NO_ERROR; + status = 0; + + if (waittime_left > SVN_RA_SERF__CONTEXT_RUN_DURATION) + { + waittime_left -= SVN_RA_SERF__CONTEXT_RUN_DURATION; + } + else + { + return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT, NULL, + _("Connection timed out")); + } + } + else + { + waittime_left = sess->timeout; } SVN_ERR(err); @@ -2607,7 +2655,12 @@ finish_report(void *report_baton, SVN_ERR(close_all_dirs(report->root_dir)); } - err = report->update_editor->close_edit(report->update_baton, iterpool); + /* If we got a complete report, close the edit. Otherwise, abort it. */ + if (report->report_completed) + err = report->update_editor->close_edit(report->update_baton, iterpool); + else + err = svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL, + _("Missing update-report close tag")); svn_pool_destroy(iterpool); return svn_error_trace(err); @@ -2750,6 +2803,10 @@ make_update_reporter(svn_ra_session_t *r make_simple_xml_tag(&buf, "S:recursive", "no", scratch_pool); } + /* Subversion 1.8+ servers can be told to send properties for newly + added items inline even when doing a skelta response. */ + make_simple_xml_tag(&buf, "S:include-props", "yes", scratch_pool); + make_simple_xml_tag(&buf, "S:depth", svn_depth_to_word(depth), scratch_pool); SVN_ERR(svn_io_file_write_full(report->body_file, buf->data, buf->len, Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_serf/util.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_serf/util.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_ra_serf/util.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_ra_serf/util.c Fri Aug 31 19:20:50 2012 @@ -707,7 +707,8 @@ svn_ra_serf__context_run_wait(svn_boolea apr_pool_t *scratch_pool) { apr_pool_t *iterpool; - + apr_short_interval_time_t waittime_left = sess->timeout; + assert(sess->pending_error == SVN_NO_ERROR); iterpool = svn_pool_create(scratch_pool); @@ -722,17 +723,36 @@ svn_ra_serf__context_run_wait(svn_boolea if (sess->cancel_func) SVN_ERR((*sess->cancel_func)(sess->cancel_baton)); - status = serf_context_run(sess->context, sess->timeout, iterpool); + status = serf_context_run(sess->context, + SVN_RA_SERF__CONTEXT_RUN_DURATION, + iterpool); err = sess->pending_error; sess->pending_error = SVN_NO_ERROR; + /* If the context duration timeout is up, we'll subtract that + duration from the total time alloted for such things. If + there's no time left, we fail with a message indicating that + the connection timed out. */ if (APR_STATUS_IS_TIMEUP(status)) { svn_error_clear(err); - return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT, - NULL, - _("Connection timed out")); + err = SVN_NO_ERROR; + status = 0; + + if (waittime_left > SVN_RA_SERF__CONTEXT_RUN_DURATION) + { + waittime_left -= SVN_RA_SERF__CONTEXT_RUN_DURATION; + } + else + { + return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT, NULL, + _("Connection timed out")); + } + } + else + { + waittime_left = sess->timeout; } SVN_ERR(err); Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/gpg_agent.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/gpg_agent.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_subr/gpg_agent.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_subr/gpg_agent.c Fri Aug 31 19:20:50 2012 @@ -110,6 +110,10 @@ receive_from_gpg_agent(int sd, char *buf int recvd; char c; + /* Clear existing buffer concent before reading response. */ + if (n > 0) + *buf = '\0'; + /* Require the message to fit into the buffer and be terminated * with a newline. */ while (i < n) Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/opt.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/opt.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_subr/opt.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_subr/opt.c Fri Aug 31 19:20:50 2012 @@ -1134,6 +1134,7 @@ svn_opt__print_version_info(const char * { const char *const host = svn_sysinfo__canonical_host(pool); const char *const relname = svn_sysinfo__release_name(pool); + const char *const slibs = svn_sysinfo__linked_libs(pool); const char *const dlibs = svn_sysinfo__loaded_libs(pool); SVN_ERR(svn_cmdline_fputs(_("System information:\n\n"), stdout, pool)); @@ -1144,6 +1145,13 @@ svn_opt__print_version_info(const char * else SVN_ERR(svn_cmdline_printf(pool, _("* running on %s\n"), host)); + if (slibs) + { + SVN_ERR(svn_cmdline_fputs(_("* linked dependencies:\n"), + stdout, pool)); + SVN_ERR(svn_cmdline_fputs(slibs, stdout, pool)); + } + if (dlibs) { SVN_ERR(svn_cmdline_fputs(_("* loaded shared libraries:\n"), Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/sqlite.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/sqlite.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_subr/sqlite.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_subr/sqlite.c Fri Aug 31 19:20:50 2012 @@ -54,6 +54,20 @@ #error SQLite is too old -- version 3.7.12 is the minimum required version #endif +const char * +svn_sqlite__compiled_version(void) +{ + static const char sqlite_version[] = SQLITE_VERSION; + return sqlite_version; +} + +const char * +svn_sqlite__runtime_version(void) +{ + return sqlite3_libversion(); +} + + INTERNAL_STATEMENTS_SQL_DECLARE_STATEMENTS(internal_statements); Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/sysinfo.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/sysinfo.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_subr/sysinfo.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_subr/sysinfo.c Fri Aug 31 19:20:50 2012 @@ -37,11 +37,15 @@ #include #include #include +#include +#include #include "svn_ctype.h" #include "svn_error.h" #include "svn_utf.h" +#include "private/svn_sqlite.h" + #include "sysinfo.h" #include "svn_private_config.h" @@ -96,6 +100,28 @@ svn_sysinfo__release_name(apr_pool_t *po #endif } +const char * +svn_sysinfo__linked_libs(apr_pool_t *pool) +{ + const char *apr_ver = + apr_psprintf(pool, "APR %s (compiled with %s)", + apr_version_string(), APR_VERSION_STRING); + const char *apr_util_ver = + apr_psprintf(pool, "APR-Util %s (compiled with %s)", + apu_version_string(), APU_VERSION_STRING); + const char *sqlite_ver = +#ifdef SVN_SQLITE_INLINE + apr_psprintf(pool, "SQLite %s (amalgamated)", + svn_sqlite__runtime_version()); +#else + apr_psprintf(pool, "SQLite %s (compiled with %s)", + svn_sqlite__runtime_version(), + svn_sqlite__compiled_version()); +#endif + + return apr_psprintf(pool, " - %s\n - %s\n - %s\n", + apr_ver, apr_util_ver, sqlite_ver); +} const char * svn_sysinfo__loaded_libs(apr_pool_t *pool) Modified: subversion/branches/inheritable-props/subversion/libsvn_subr/sysinfo.h URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_subr/sysinfo.h?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_subr/sysinfo.h (original) +++ subversion/branches/inheritable-props/subversion/libsvn_subr/sysinfo.h Fri Aug 31 19:20:50 2012 @@ -44,6 +44,13 @@ const char *svn_sysinfo__canonical_host( */ const char *svn_sysinfo__release_name(apr_pool_t *pool); +/* Return a description of the link-time and run-time versions of + * dependent libraries. + * + * All allocations are done in POOL. + */ +const char *svn_sysinfo__linked_libs(apr_pool_t *pool); + /* Return a string containing a list of shared libraries loaded by the * running process, including their versions where applicable, or NULL * if the information is not available. Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/conflicts.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/conflicts.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_wc/conflicts.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_wc/conflicts.c Fri Aug 31 19:20:50 2012 @@ -511,9 +511,6 @@ static const svn_token_map_t local_chang { "replaced", svn_wc_conflict_reason_replaced }, { "moved-away", svn_wc_conflict_reason_moved_away }, { "moved-here", svn_wc_conflict_reason_moved_here }, - /* ### Do we really need this. The edit state is on a different node, - which might just change while the tree conflict exists? */ - { "moved-and-edited", svn_wc_conflict_reason_moved_away_and_edited }, { NULL } }; Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/tree_conflicts.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/tree_conflicts.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_wc/tree_conflicts.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_wc/tree_conflicts.c Fri Aug 31 19:20:50 2012 @@ -78,7 +78,6 @@ const svn_token_map_t svn_wc__conflict_r { "replaced", svn_wc_conflict_reason_replaced }, { "unversioned", svn_wc_conflict_reason_unversioned }, { "moved-away", svn_wc_conflict_reason_moved_away }, - { "moved-away-and-edited", svn_wc_conflict_reason_moved_away_and_edited }, { "moved-here", svn_wc_conflict_reason_moved_here }, { NULL } }; Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c (original) +++ subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c Fri Aug 31 19:20:50 2012 @@ -1480,7 +1480,6 @@ check_tree_conflict(svn_skel_t **pconfli if (reason == svn_wc_conflict_reason_edited || reason == svn_wc_conflict_reason_deleted || reason == svn_wc_conflict_reason_moved_away - || reason == svn_wc_conflict_reason_moved_away_and_edited || reason == svn_wc_conflict_reason_replaced) /* When the node existed before (it was locally deleted, replaced or * edited), then 'update' cannot add it "again". So it can only send @@ -1736,7 +1735,6 @@ delete_entry(const char *path, } else if (reason == svn_wc_conflict_reason_deleted || reason == svn_wc_conflict_reason_moved_away - || reason == svn_wc_conflict_reason_moved_away_and_edited || reason == svn_wc_conflict_reason_replaced) { /* The item does not exist locally because it was already shadowed. @@ -2270,7 +2268,6 @@ open_directory(const char *path, db->pool, db->pool)); SVN_ERR_ASSERT(reason == svn_wc_conflict_reason_deleted || reason == svn_wc_conflict_reason_moved_away - || reason == svn_wc_conflict_reason_moved_away_and_edited || reason == svn_wc_conflict_reason_replaced); /* Continue updating BASE */ @@ -3332,7 +3329,6 @@ open_file(const char *path, fb->pool, fb->pool)); SVN_ERR_ASSERT(reason == svn_wc_conflict_reason_deleted || reason == svn_wc_conflict_reason_moved_away - || reason == svn_wc_conflict_reason_moved_away_and_edited || reason == svn_wc_conflict_reason_replaced); /* Continue updating BASE */ Modified: subversion/branches/inheritable-props/subversion/mod_dav_svn/reports/update.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/mod_dav_svn/reports/update.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/mod_dav_svn/reports/update.c (original) +++ subversion/branches/inheritable-props/subversion/mod_dav_svn/reports/update.c Fri Aug 31 19:20:50 2012 @@ -81,6 +81,10 @@ typedef struct update_ctx_t { /* True iff client requested all data inline in the report. */ svn_boolean_t send_all; + /* True iff client requested that properties be transmitted + inline. (This is implied when "send_all" is set.) */ + svn_boolean_t include_props; + /* SVNDIFF version to send to client. */ int svndiff_version; @@ -119,6 +123,10 @@ typedef struct item_baton_t { /* File/dir copied? */ svn_boolean_t copyfrom; + /* Does the client need to fetch additional properties for this + item? */ + svn_boolean_t fetch_props; + /* Array of const char * names of removed properties. (Used only for copied files/dirs in skelta mode.) */ apr_array_header_t *removed_props; @@ -432,7 +440,7 @@ open_helper(svn_boolean_t is_dir, static svn_error_t * -close_helper(svn_boolean_t is_dir, item_baton_t *baton) +close_helper(svn_boolean_t is_dir, item_baton_t *baton, apr_pool_t *pool) { if (baton->uc->resource_walk) return SVN_NO_ERROR; @@ -446,14 +454,21 @@ close_helper(svn_boolean_t is_dir, item_ for (i = 0; i < baton->removed_props->nelts; i++) { - /* We already XML-escaped the property name in change_xxx_prop. */ qname = APR_ARRAY_IDX(baton->removed_props, i, const char *); + qname = apr_xml_quote_string(pool, qname, 1); SVN_ERR(dav_svn__brigade_printf(baton->uc->bb, baton->uc->output, "" DEBUG_CR, qname)); } } + /* If our client need to fetch properties, let it know. */ + if (baton->fetch_props) + SVN_ERR(dav_svn__brigade_printf(baton->uc->bb, baton->uc->output, + "" DEBUG_CR)); + + + /* Let's tie it off, nurse. */ if (baton->added) SVN_ERR(dav_svn__brigade_printf(baton->uc->bb, baton->uc->output, "" DEBUG_CR, @@ -473,13 +488,13 @@ maybe_start_update_report(update_ctx_t * { if ((! uc->resource_walk) && (! uc->started_update)) { - SVN_ERR(dav_svn__brigade_printf(uc->bb, uc->output, - DAV_XML_HEADER DEBUG_CR - "" DEBUG_CR, - uc->send_all ? "send-all=\"true\"" : "")); + SVN_ERR(dav_svn__brigade_printf( + uc->bb, uc->output, + DAV_XML_HEADER DEBUG_CR "" DEBUG_CR, + uc->send_all ? "send-all=\"true\"" : "", + uc->include_props ? "inline-props=\"true\"" : "")); uc->started_update = TRUE; } @@ -593,87 +608,117 @@ upd_open_directory(const char *path, static svn_error_t * +send_propchange(item_baton_t *b, + const char *name, + const svn_string_t *value, + apr_pool_t *pool) +{ + const char *qname; + + /* Ensure that the property name is XML-safe. + apr_xml_quote_string() doesn't realloc if there is nothing to + quote, so dup the name, but only if necessary. */ + qname = apr_xml_quote_string(b->pool, name, 1); + if (qname == name) + qname = apr_pstrdup(b->pool, name); + + if (value) + { + const char *qval; + + if (svn_xml_is_xml_safe(value->data, value->len)) + { + svn_stringbuf_t *tmp = NULL; + svn_xml_escape_cdata_string(&tmp, value, pool); + qval = tmp->data; + SVN_ERR(dav_svn__brigade_printf(b->uc->bb, b->uc->output, + "", + qname)); + } + else + { + qval = svn_base64_encode_string2(value, TRUE, pool)->data; + SVN_ERR(dav_svn__brigade_printf(b->uc->bb, b->uc->output, + "" DEBUG_CR, + qname)); + } + + SVN_ERR(dav_svn__brigade_puts(b->uc->bb, b->uc->output, qval)); + SVN_ERR(dav_svn__brigade_puts(b->uc->bb, b->uc->output, + "" DEBUG_CR)); + } + else /* value is null, so this is a prop removal */ + { + SVN_ERR(dav_svn__brigade_printf(b->uc->bb, b->uc->output, + "" + DEBUG_CR, + qname)); + } + + return SVN_NO_ERROR; +} + +static svn_error_t * upd_change_xxx_prop(void *baton, const char *name, const svn_string_t *value, apr_pool_t *pool) { item_baton_t *b = baton; - const char *qname; /* Resource walks say nothing about props. */ if (b->uc->resource_walk) return SVN_NO_ERROR; - /* Else this not a resource walk, so either send props or cache them - to send later, depending on whether this is a modern report - response or not. */ - - qname = apr_xml_quote_string(b->pool, name, 1); - - /* apr_xml_quote_string doesn't realloc if there is nothing to - quote, so dup the name, but only if necessary. */ - if (qname == name) - qname = apr_pstrdup(b->pool, name); + /* If we get here, this not a resource walk, so either send props or + cache them to send later, depending on whether this is a modern + report response or not. */ /* Even if we are not in send-all mode we have the prop changes already, so send them to the client now instead of telling the client to fetch them later. */ - if (b->uc->send_all || !b->added) + if (b->uc->send_all) { - if (value) + SVN_ERR(send_propchange(b, name, value, pool)); + } + else + { + if (b->added) { - const char *qval; - - if (svn_xml_is_xml_safe(value->data, value->len)) + /* This is an addition in "skelta" (that is, "not send-all") + mode so there is no strict need for an inline response. + Clients will assume that added objects need all to have + all their properties explicitly fetched from the + server. */ + + /* That said, beginning in Subversion 1.8, clients might + request even in skelta mode that we transmit properties + on newly added files explicitly. */ + if ((! b->copyfrom) && value && b->uc->include_props) { - svn_stringbuf_t *tmp = NULL; - svn_xml_escape_cdata_string(&tmp, value, pool); - qval = tmp->data; - SVN_ERR(dav_svn__brigade_printf(b->uc->bb, b->uc->output, - "", - qname)); + SVN_ERR(send_propchange(b, name, value, pool)); } - else + + /* Now, if the object is actually a copy and this is a + property removal, we'll still need to cache (and later + transmit) property removals, because fetching the + object's current property set alone isn't sufficient to + communicate the fact that additional properties were, in + fact, removed from the copied base object in order to + arrive at that set. */ + if (b->copyfrom && (! value)) { - qval = svn_base64_encode_string2(value, TRUE, pool)->data; - SVN_ERR(dav_svn__brigade_printf(b->uc->bb, b->uc->output, - "" DEBUG_CR, - qname)); + if (! b->removed_props) + b->removed_props = apr_array_make(b->pool, 1, sizeof(name)); + + APR_ARRAY_PUSH(b->removed_props, const char *) = name; } - - SVN_ERR(dav_svn__brigade_puts(b->uc->bb, b->uc->output, qval)); - SVN_ERR(dav_svn__brigade_puts(b->uc->bb, b->uc->output, - "" DEBUG_CR)); } - else /* value is null, so this is a prop removal */ - { - SVN_ERR(dav_svn__brigade_printf(b->uc->bb, b->uc->output, - "" - DEBUG_CR, - qname)); - } - } - else if (!value) - { - /* This is an addition in "skelta" (that is, "not send-all") - mode so there is no strict need for an inline response. - Clients will assume that added objects need all to have all - their properties explicitly fetched from the server. */ - - /* Now, if the object is actually a copy, we'll still need to - cache (and later transmit) property removals, because - fetching the object's current property set alone isn't - sufficient to communicate the fact that additional properties - were, in fact, removed from the copied base object in order - to arrive at that set. */ - if (b->copyfrom) + else { - if (! b->removed_props) - b->removed_props = apr_array_make(b->pool, 1, sizeof(name)); - - APR_ARRAY_PUSH(b->removed_props, const char *) = qname; + /* "skelta" mode non-addition. Just send the change. */ + SVN_ERR(send_propchange(b, name, value, pool)); } } @@ -684,7 +729,7 @@ upd_change_xxx_prop(void *baton, static svn_error_t * upd_close_directory(void *dir_baton, apr_pool_t *pool) { - return close_helper(TRUE /* is_dir */, dir_baton); + return close_helper(TRUE /* is_dir */, dir_baton, pool); } @@ -845,7 +890,7 @@ upd_close_file(void *file_baton, const c text_checksum)); } - return close_helper(FALSE /* is_dir */, file); + return close_helper(FALSE /* is_dir */, file, pool); } @@ -944,6 +989,7 @@ dav_svn__update_report(const dav_resourc && (strcmp(this_attr->value, "true") == 0)) { uc.send_all = TRUE; + uc.include_props = TRUE; break; } } @@ -1066,6 +1112,14 @@ dav_svn__update_report(const dav_resourc if (strcmp(cdata, "no") == 0) text_deltas = FALSE; } + if (child->ns == ns && strcmp(child->name, "include-props") == 0) + { + cdata = dav_xml_get_cdata(child, resource->pool, 1); + if (! *cdata) + return malformed_element_error(child->name, resource->pool); + if (strcmp(cdata, "no") != 0) + uc.include_props = TRUE; + } } if (!saw_depth && !saw_recursive && (requested_depth == svn_depth_unknown)) Modified: subversion/branches/inheritable-props/subversion/svn/tree-conflicts.c URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/svn/tree-conflicts.c?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/subversion/svn/tree-conflicts.c (original) +++ subversion/branches/inheritable-props/subversion/svn/tree-conflicts.c Fri Aug 31 19:20:50 2012 @@ -63,7 +63,6 @@ static const svn_token_map_t map_conflic { N_("replace"), svn_wc_conflict_reason_replaced }, { N_("unversioned"), svn_wc_conflict_reason_unversioned }, { N_("moved away"), svn_wc_conflict_reason_moved_away }, - { N_("moved away and edited"), svn_wc_conflict_reason_moved_away_and_edited }, { N_("moved here"), svn_wc_conflict_reason_moved_here }, { NULL, 0 } }; @@ -79,7 +78,6 @@ static const svn_token_map_t map_conflic { "replace", svn_wc_conflict_reason_replaced }, { "unversioned", svn_wc_conflict_reason_unversioned }, { "moved-away", svn_wc_conflict_reason_moved_away }, - { "moved-away-and-edited", svn_wc_conflict_reason_moved_away_and_edited }, { "moved-here", svn_wc_conflict_reason_moved_here }, { NULL, 0 } }; Modified: subversion/branches/inheritable-props/tools/server-side/svnpubsub/README.txt URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/tools/server-side/svnpubsub/README.txt?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/tools/server-side/svnpubsub/README.txt (original) +++ subversion/branches/inheritable-props/tools/server-side/svnpubsub/README.txt Fri Aug 31 19:20:50 2012 @@ -14,3 +14,36 @@ TODO: - add support for SIGHUP to reread the config and reinitialize working copies - joes will write documentation for svnpubsub as these items become fulfilled - make LOGLEVEL configurable + + +Installation instructions: + +1. Set up an svnpubsub service. + + This directory should be checked out to /usr/local/svnpubsub (or /opt/svnpubsub + on Debian). + + There are init scripts for several OSes in the rc.d/ directory; add them + to your OS boot process in the usual way for your OS. (For example, via + rc.conf(5) or update-rc.d(8).) + +2. Run "commit-hook.py $REPOS $REV" from your post-commit hook. + + (As of 1.7, these are the same ordered arguments the post-commmit hook + itself receives, so you can just symlink commit-hook.py as hooks/post-commit + hook if you don't need any other hooks to run in the server process. (This + isn't as insane as it sounds --- post-commit email hooks could also feed of + svnpubsub, and thus not be run within the committing server thread, but on + any other process or box that listens to the svnpubsub stream!)) + +3. Set up svnpubsub clients. + + (eg svnwcsub.py, svnpubsub/client.py, + 'curl -i http://${hostname}:2069/commits/json') + + +Other notes: + +- svnwcsub.py will create a file called ".revision" in the root of the working + copy it updates. That file will contain + `svn info ./ | sed -ne s/^Revision:.//p`. Modified: subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnpubsub.debian URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnpubsub.debian?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnpubsub.debian (original) +++ subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnpubsub.debian Fri Aug 31 19:20:50 2012 @@ -19,7 +19,7 @@ svnpubsub_pidfile=${svnpubsub_pidfile-"/ pidfile="${svnpubsub_pidfile}" TWSITD_CMD="/usr/bin/twistd -y /opt/svnpubsub/svnpubsub.tac \ - --logfile=/var/bwlog/svnpubsub/svnpubsub.log \ + --logfile=/var/log/svnpubsub/svnpubsub.log \ --pidfile=${pidfile} \ --uid=${svnpubsub_user} --gid=${svnpubsub_user} \ -r${svnpubsub_reactor}" Modified: subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnwcsub.debian URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnwcsub.debian?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnwcsub.debian (original) +++ subversion/branches/inheritable-props/tools/server-side/svnpubsub/rc.d/svnwcsub.debian Fri Aug 31 19:20:50 2012 @@ -16,7 +16,7 @@ svnwcsub_user=${svnwcsub_user-"svnwc"} svnwcsub_group=${svnwcsub_group-"svnwc"} svnwcsub_pidfile=${svnwcsub_pidfile-"/var/run/svnwcsub.pid"} svnwcsub_config=${svnwcsub_config-"/etc/svnwcsub.conf"} -svnwcsub_logfile=${svnwcsub_logfile-"/var/bwlog/svnwcsub/svnwcsub.log"} +svnwcsub_logfile=${svnwcsub_logfile-"/var/log/svnwcsub/svnwcsub.log"} pidfile="${svnwcsub_pidfile}" SVNWCSUB_CMD="/opt/svnpubsub/svnwcsub.py \ Modified: subversion/branches/inheritable-props/tools/server-side/svnpubsub/svnwcsub.py URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/tools/server-side/svnpubsub/svnwcsub.py?rev=1379554&r1=1379553&r2=1379554&view=diff ============================================================================== --- subversion/branches/inheritable-props/tools/server-side/svnpubsub/svnwcsub.py (original) +++ subversion/branches/inheritable-props/tools/server-side/svnpubsub/svnwcsub.py Fri Aug 31 19:20:50 2012 @@ -29,6 +29,7 @@ # See svnwcsub.conf for more information on its contents. # +import errno import subprocess import threading import sys @@ -253,6 +254,15 @@ class BackgroundWorker(threading.Thread) info = svn_info(self.svnbin, self.env, wc.path) logging.info("updated: %s now at r%s", wc.path, info['Revision']) + ### update the .revision file + dotrevision = os.path.join(wc.path, '.revision') + try: + os.unlink(dotrevision) + except IOError, e: + if e.errno != errno.ENOENT: + raise + open(dotrevision, 'w').write(info['Revision']) + def _cleanup(self, wc): "Run a cleanup on the specified working copy."