I think/hope I found the problem (well certainly *a* problem):
Allocating mergeinfo in a short-lived iterpool, see
http://svn.apache.org/viewvc?view=revision&revision=1080034
/me watches the buildbots expectantly...
On Wed, Mar 9, 2011 at 5:00 PM, Paul Burba <ptburba_at_gmail.com> wrote:
> The test I tried to fix in this commit,
>
> log_tests.py 31: log -g differentiates forward and reverse merges,
>
> is failing on the buildbots :
>
> With bdb x ra_neon the server has problems:
> http://ci.apache.org/builders/svn-x64-centos%20gcc/builds/2442/steps/Test%20bdb%2Bra_neon/logs/faillog
> [[[
> CMD: svn log -g -r8 svn-test-work/working_copies/log_tests-31/A_COPY/D
> --config-dir /home/bt/slaves/x64-centos/build/subversion/tests/cmdline/svn-test-work/local_tmp/config
> --password rayjandom --no-auth-cache --username jrandom
> CMD: /home/bt/slaves/x64-centos/build/subversion/svn/svn log -g -r8
> svn-test-work/working_copies/log_tests-31/A_COPY/D --config-dir
> /home/bt/slaves/x64-centos/build/subversion/tests/cmdline/svn-test-work/local_tmp/config
> --password rayjandom --no-auth-cache --username jrandom exited with 1
> <TIME = 0.069142>
> subversion/svn/log-cmd.c:746: (apr_err=175002)
> subversion/libsvn_client/log.c:617: (apr_err=175002)
> subversion/libsvn_ra_neon/util.c:1322: (apr_err=175002)
> subversion/libsvn_ra_neon/util.c:659: (apr_err=175002)
> svn: E175002: REPORT of
> '/svn-test-work/repositories/log_tests-31/!svn/bc/8/A_COPY/D': Could
> not read status line: connection was closed by server.
> (http://localhost:19930)
> ]]]
>
> With fsfs x ra_svn the log command works, but an expected revision is missing:
> http://ci.apache.org/builders/svn-debian-x86_64-32%20shared%20gcc/builds/2964/steps/Test%20fsfs%2Bra_svn/logs/faillog
> [[[
> CMD: svn log -g -r8 svn-test-work/working_copies/log_tests-31/A_COPY/D
> --config-dir /home/svnbuilder/slave/eh-debsarge1/build/subversion/tests/cmdline/svn-test-work/local_tmp/config
> --password rayjandom --no-auth-cache --username jrandom
> <TIME = 0.037864>
> ------------------------------------------------------------------------
> r8 | jrandom | 2011-03-09 20:49:28 +0000 (Wed, 09 Mar 2011) | 1 line
>
> Merge -c-3,-5,4,6 from A to A_COPY
> ------------------------------------------------------------------------
> r6 | jrandom | 2011-03-09 20:49:27 +0000 (Wed, 09 Mar 2011) | 1 line
> Merged via: r8
>
> log msg
> ------------------------------------------------------------------------
> r4 | jrandom | 2011-03-09 20:49:27 +0000 (Wed, 09 Mar 2011) | 1 line
> Merged via: r8
>
> log msg
> ------------------------------------------------------------------------
> CWD: /home/svnbuilder/slave/eh-debsarge1/build/subversion/tests/cmdline
> EXCEPTION: SVNUnexpectedLogs: Reverse merged revision '3' missing:
> Actual revision list was [8, 6, 4]
> Traceback (most recent call last):
> Â File "/home/svnbuilder/slave/eh-debsarge1/build/subversion/tests/cmdline/svntest/main.py",
> line 1263, in run
> Â Â rc = self.pred.run(sandbox)
> Â File "/home/svnbuilder/slave/eh-debsarge1/build/subversion/tests/cmdline/svntest/testcase.py",
> line 254, in run
> Â Â return self._delegate.run(sandbox)
> Â File "/home/svnbuilder/slave/eh-debsarge1/build/subversion/tests/cmdline/svntest/testcase.py",
> line 176, in run
> Â Â return self.func(sandbox)
> Â File "/home/svnbuilder/slave/eh-debsarge1/build/subversion/tests/cmdline/log_tests.py",
> line 1870, in merge_sensitive_log_reverse_merges
> Â Â check_merge_results(log_chain, expected_merges, expected_reverse_merges)
> Â File "/home/svnbuilder/slave/eh-debsarge1/build/subversion/tests/cmdline/log_tests.py",
> line 1193, in check_merge_results
> Â Â log_chain)
> SVNUnexpectedLogs: Reverse merged revision '3' missing: Actual
> revision list was [8, 6, 4]
> FAIL: Â log_tests.py 31: log -g differentiates forward and reverse merges
> ]]]
>
> Unfortunately I can't replicate these failures on my local machine (in
> either debug or release builds). Â Is anyone seeing these locally?
>
> Paul
>
> On Wed, Mar 9, 2011 at 3:37 PM, Â <pburba_at_apache.org> wrote:
>> Author: pburba
>> Date: Wed Mar  9 20:37:55 2011
>> New Revision: 1079983
>>
>> URL: http://svn.apache.org/viewvc?rev=1079983&view=rev
>> Log:
>> Fix issue #3176 'log -g output for merge reversal is bit confusing'.
>>
>> The output of 'svn log -g' now differentiates between merged revisions that
>> resulting from forward merges and those resulting from reverse merges. Â In a
>> nutshell: svn_log_entry_t has a new member 'subtractive_merge' that
>> identifies merged revisions that result from reverse merges.
>>
>> * subversion/include/svn_types.h
>>
>> Â (svn_log_entry_t): Add a new member to flag log entries resulting from
>> Â reverse merges. Â Note: No need to update svn_log_entry_dup() since the
>> Â new member is a boolean.
>>
>> * subversion/libsvn_ra_neon/log.c
>>
>> Â (reset_log_item): Reset new svn_log_entry_t member.
>>
>> Â (log_start_element): Parse "subtractive-merge" element.
>>
>> * subversion/libsvn_ra_neon/ra_neon.h
>>
>> Â (global): Add 'ELEM_subtractive_merge' to the Neon element enums.
>>
>> * subversion/libsvn_ra_serf/log.c
>>
>> Â (log_state_e): Add 'SUBTRACTIVE_MERGE' enum.
>>
>> Â (start_log): Parse "subtractive-merge" element.
>>
>> Â (end_log): Set new svn_log_entry_t member.
>>
>> * subversion/libsvn_ra_svn/client.c
>>
>> Â (ra_svn_log): Parse "subtractive-merge" element.
>>
>> * subversion/libsvn_ra_svn/protocol:
>>
>> Â Note changes to 'log-entry' protocol.
>>
>> * subversion/libsvn_repos/log.c
>>
>> Â (get_combined_mergeinfo_changes): Return added and deleted mergeinfo
>> Â separately, rather than as a single mergeinfo.
>>
>> Â (send_log): Add an argument to identify logs which are the result of a
>> Â reverse merged revision, use this to populate the new svn_log_entry_t
>> Â member.
>>
>> Â (path_list_range): Add new member to identify revisions resulting from a
>> Â reverse merge.
>>
>> Â (combine_mergeinfo_path_lists): Add new member to identify mergeinfo
>> Â resulting from a reverse merge.
>>
>> Â (compare_path_list_range): New sort helper for handle_merged_revisions().
>>
>> Â (handle_merged_revisions): Split MERGEINFO argument into two,
>> Â differentiating between added and deleted mergeinfo. Â Update call to
>> Â do_logs().
>>
>> Â (added_deleted_mergeinfo): New struct.
>>
>> Â (do_logs): Add an argument to identify logs which are the result of a
>> Â reverse merge. Â Track mergeinfo changes from forward and reverse merges
>> Â separately and pass this along to send_log and when we recurse.
>>
>> Â (svn_repos_get_logs4): Update calls to send_log() and do_logs().
>>
>> * subversion/mod_dav_svn/reports/log.c
>>
>> Â (log_receiver): Send the new 'subtractive-merge' element.
>>
>> * subversion/svn/log-cmd.c
>>
>> Â (log_entry_receiver): Print new 'Reverse merged via' message for merged
>> Â revisions resulting from a reverse merge.
>>
>> * subversion/svnserve/serve.c
>>
>> Â (log_receiver): Send the new 'subtractive-merge' element
>>
>> * subversion/tests/cmdline/log_tests.py
>>
>> Â (merge_sensitive_log_added_mergeinfo_replaces_inherited): Tweak test
>> Â expecatations to account for new reverse merge log text.
>>
>> Â (merge_sensitive_log_reverse_merges): Remove XFail decorator and comments
>> Â regarding failure status.
>>
>> Modified:
>> Â Â subversion/trunk/subversion/include/svn_types.h
>> Â Â subversion/trunk/subversion/libsvn_ra_neon/log.c
>> Â Â subversion/trunk/subversion/libsvn_ra_neon/ra_neon.h
>> Â Â subversion/trunk/subversion/libsvn_ra_serf/log.c
>> Â Â subversion/trunk/subversion/libsvn_ra_svn/client.c
>> Â Â subversion/trunk/subversion/libsvn_ra_svn/protocol
>> Â Â subversion/trunk/subversion/libsvn_repos/log.c
>> Â Â subversion/trunk/subversion/mod_dav_svn/reports/log.c
>> Â Â subversion/trunk/subversion/svn/log-cmd.c
>> Â Â subversion/trunk/subversion/svnserve/serve.c
>> Â Â subversion/trunk/subversion/tests/cmdline/log_tests.py
>>
>> Modified: subversion/trunk/subversion/include/svn_types.h
>> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_types.h?rev=1079983&r1=1079982&r2=1079983&view=diff
>> ==============================================================================
>> --- subversion/trunk/subversion/include/svn_types.h (original)
>> +++ subversion/trunk/subversion/include/svn_types.h Wed Mar  9 20:37:55 2011
>> @@ -854,6 +854,13 @@ typedef struct svn_log_entry_t
>> Â Â */
>> Â svn_boolean_t non_inheritable;
>>
>> + Â /**
>> + Â * Whether @a revision is a merged revision resulting from a reverse merge.
>> + Â *
>> + Â * @since New in 1.7.
>> + Â */
>> + Â svn_boolean_t subtractive_merge;
>> +
>> Â /* NOTE: Add new fields at the end to preserve binary compatibility.
>> Â Â Â Also, if you add fields here, you have to update
>> Â Â Â svn_log_entry_dup(). */
>>
>> Modified: subversion/trunk/subversion/libsvn_ra_neon/log.c
>> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_neon/log.c?rev=1079983&r1=1079982&r2=1079983&view=diff
>> ==============================================================================
>> --- subversion/trunk/subversion/libsvn_ra_neon/log.c (original)
>> +++ subversion/trunk/subversion/libsvn_ra_neon/log.c Wed Mar  9 20:37:55 2011
>> @@ -101,6 +101,7 @@ reset_log_item(struct log_baton *lb)
>>  lb->log_entry->changed_paths  = NULL;
>>  lb->log_entry->has_children  = FALSE;
>> Â lb->log_entry->changed_paths2 = NULL;
>> + Â lb->log_entry->subtractive_merge = FALSE;
>>
>> Â svn_pool_clear(lb->subpool);
>> Â }
>> @@ -137,6 +138,8 @@ log_start_element(int *elem, void *baton
>> Â Â Â { "DAV:", "comment", ELEM_comment, SVN_RA_NEON__XML_CDATA },
>> Â Â Â { SVN_XML_NAMESPACE, "has-children", ELEM_has_children,
>> Â Â Â Â SVN_RA_NEON__XML_CDATA },
>> + Â Â Â { SVN_XML_NAMESPACE, "subtractive-merge", ELEM_subtractive_merge,
>> + Â Â Â Â SVN_RA_NEON__XML_CDATA },
>> Â Â Â { NULL }
>> Â Â };
>> Â const svn_ra_neon__xml_elm_t *elm
>> @@ -172,6 +175,9 @@ log_start_element(int *elem, void *baton
>> Â Â case ELEM_has_children:
>> Â Â Â lb->log_entry->has_children = TRUE;
>> Â Â Â break;
>> + Â Â case ELEM_subtractive_merge:
>> + Â Â Â lb->log_entry->subtractive_merge = TRUE;
>> + Â Â Â break;
>>
>> Â Â default:
>> Â Â Â lb->want_cdata = NULL;
>>
>> Modified: subversion/trunk/subversion/libsvn_ra_neon/ra_neon.h
>> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_neon/ra_neon.h?rev=1079983&r1=1079982&r2=1079983&view=diff
>> ==============================================================================
>> --- subversion/trunk/subversion/libsvn_ra_neon/ra_neon.h (original)
>> +++ subversion/trunk/subversion/libsvn_ra_neon/ra_neon.h Wed Mar  9 20:37:55 2011
>> @@ -862,7 +862,8 @@ enum {
>> Â ELEM_has_children,
>> Â ELEM_merged_revision,
>> Â ELEM_deleted_rev_report,
>> - Â ELEM_validate_inherited_mergeinfo
>> + Â ELEM_validate_inherited_mergeinfo,
>> + Â ELEM_subtractive_merge,
>> Â };
>>
>> Â /* ### docco */
>>
>> Modified: subversion/trunk/subversion/libsvn_ra_serf/log.c
>> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/log.c?rev=1079983&r1=1079982&r2=1079983&view=diff
>> ==============================================================================
>> --- subversion/trunk/subversion/libsvn_ra_serf/log.c (original)
>> +++ subversion/trunk/subversion/libsvn_ra_serf/log.c Wed Mar  9 20:37:55 2011
>> @@ -63,6 +63,7 @@ typedef enum log_state_e {
>> Â REPLACED_PATH,
>> Â DELETED_PATH,
>> Â MODIFIED_PATH,
>> + Â SUBTRACTIVE_MERGE,
>> Â } log_state_e;
>>
>> Â typedef struct log_info_t {
>> @@ -231,6 +232,10 @@ start_log(svn_ra_serf__xml_parser_t *par
>> Â Â Â Â {
>> Â Â Â Â Â push_state(parser, log_ctx, HAS_CHILDREN);
>> Â Â Â Â }
>> + Â Â Â else if (strcmp(name.name, "subtractive-merge") == 0)
>> + Â Â Â Â {
>> + Â Â Â Â Â push_state(parser, log_ctx, SUBTRACTIVE_MERGE);
>> + Â Â Â Â }
>> Â Â Â else if (strcmp(name.name, "added-path") == 0)
>> Â Â Â Â {
>> Â Â Â Â Â const char *copy_path, *copy_rev_str;
>> @@ -401,6 +406,12 @@ end_log(svn_ra_serf__xml_parser_t *parse
>> Â Â Â info->log_entry->has_children = TRUE;
>> Â Â Â svn_ra_serf__xml_pop_state(parser);
>> Â Â }
>> + Â else if (state == SUBTRACTIVE_MERGE &&
>> + Â Â Â Â Â strcmp(name.name, "subtractive-merge") == 0)
>> + Â Â {
>> + Â Â Â info->log_entry->subtractive_merge = TRUE;
>> + Â Â Â svn_ra_serf__xml_pop_state(parser);
>> + Â Â }
>> Â else if ((state == ADDED_PATH &&
>> Â Â Â Â Â Â strcmp(name.name, "added-path") == 0) ||
>> Â Â Â Â Â Â (state == DELETED_PATH &&
>>
>> Modified: subversion/trunk/subversion/libsvn_ra_svn/client.c
>> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_svn/client.c?rev=1079983&r1=1079982&r2=1079983&view=diff
>> ==============================================================================
>> --- subversion/trunk/subversion/libsvn_ra_svn/client.c (original)
>> +++ subversion/trunk/subversion/libsvn_ra_svn/client.c Wed Mar  9 20:37:55 2011
>> @@ -1405,10 +1405,12 @@ static svn_error_t *ra_svn_log(svn_ra_se
>> Â while (1)
>> Â Â {
>> Â Â Â apr_uint64_t has_children_param, invalid_revnum_param;
>> + Â Â Â apr_uint64_t has_subtractive_merge_param;
>> Â Â Â svn_string_t *author, *date, *message;
>> Â Â Â apr_array_header_t *cplist, *rplist;
>> Â Â Â svn_log_entry_t *log_entry;
>> Â Â Â svn_boolean_t has_children;
>> + Â Â Â svn_boolean_t subtractive_merge = FALSE;
>> Â Â Â apr_uint64_t revprop_count;
>> Â Â Â svn_ra_svn_item_t *item;
>> Â Â Â apr_hash_t *cphash;
>> @@ -1423,11 +1425,12 @@ static svn_error_t *ra_svn_log(svn_ra_se
>> Â Â Â Â return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â _("Log entry not a list"));
>> Â Â Â SVN_ERR(svn_ra_svn_parse_tuple(item->u.list, iterpool,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "lr(?s)(?s)(?s)?BBnl",
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "lr(?s)(?s)(?s)?BBnl?B",
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â &cplist, &rev, &author, &date,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â &message, &has_children_param,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â &invalid_revnum_param,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â &revprop_count, &rplist));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â &revprop_count, &rplist,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â &has_subtractive_merge_param));
>> Â Â Â if (want_custom_revprops && rplist == NULL)
>> Â Â Â Â {
>> Â Â Â Â Â /* Caller asked for custom revprops, but server is too old. */
>> @@ -1441,6 +1444,11 @@ static svn_error_t *ra_svn_log(svn_ra_se
>> Â Â Â else
>> Â Â Â Â has_children = (svn_boolean_t) has_children_param;
>>
>> + Â Â Â if (has_subtractive_merge_param == SVN_RA_SVN_UNSPECIFIED_NUMBER)
>> + Â Â Â Â subtractive_merge = FALSE;
>> + Â Â Â else
>> + Â Â Â Â subtractive_merge = (svn_boolean_t) has_subtractive_merge_param;
>> +
>> Â Â Â /* Because the svn protocol won't let us send an invalid revnum, we have
>> Â Â Â Â Â to recover that fact using the extra parameter. */
>> Â Â Â if (invalid_revnum_param != SVN_RA_SVN_UNSPECIFIED_NUMBER
>> @@ -1493,6 +1501,7 @@ static svn_error_t *ra_svn_log(svn_ra_se
>> Â Â Â Â Â log_entry->changed_paths2 = cphash;
>> Â Â Â Â Â log_entry->revision = rev;
>> Â Â Â Â Â log_entry->has_children = has_children;
>> + Â Â Â Â Â log_entry->subtractive_merge = subtractive_merge;
>> Â Â Â Â Â if (rplist)
>> Â Â Â Â Â Â SVN_ERR(svn_ra_svn_parse_proplist(rplist, pool,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â &log_entry->revprops));
>>
>> Modified: subversion/trunk/subversion/libsvn_ra_svn/protocol
>> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_svn/protocol?rev=1079983&r1=1079982&r2=1079983&view=diff
>> ==============================================================================
>> --- subversion/trunk/subversion/libsvn_ra_svn/protocol (original)
>> +++ subversion/trunk/subversion/libsvn_ra_svn/protocol Wed Mar  9 20:37:55 2011
>> @@ -378,7 +378,8 @@ second place for auth-request point as n
>> Â Â log-entry: ( ( change:changed-path-entry ... ) rev:number
>> Â Â Â Â Â Â Â Â Â [ author:string ] [ date:string ] [ message:string ]
>> Â Â Â Â Â Â Â Â Â ? has-children:bool invalid-revnum:bool
>> - Â Â Â Â Â Â Â Â revprop-count:number rev-props:proplist )
>> + Â Â Â Â Â Â Â Â revprop-count:number rev-props:proplist
>> + Â Â Â Â Â Â Â Â ? subtractive-merge:bool )
>> Â Â Â Â Â Â Â | done
>> Â Â changed-path-entry: ( path:string A|D|R|M
>> Â Â Â Â Â Â Â Â Â Â Â Â Â ? ( ? copy-path:string copy-rev:number )
>>
>> Modified: subversion/trunk/subversion/libsvn_repos/log.c
>> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/log.c?rev=1079983&r1=1079982&r2=1079983&view=diff
>> ==============================================================================
>> --- subversion/trunk/subversion/libsvn_repos/log.c (original)
>> +++ subversion/trunk/subversion/libsvn_repos/log.c Wed Mar  9 20:37:55 2011
>> @@ -731,10 +731,12 @@ fs_mergeinfo_changed(svn_mergeinfo_catal
>>
>>
>> Â /* Determine what (if any) mergeinfo for PATHS was modified in
>> - Â revision REV, returning the diffs as a single combined rangelist in
>> - Â *COMBINED_MERGEINFO. Â Use POOL for all allocations. */
>> + Â revision REV, returning the differences for added mergeinfo in
>> + Â *ADDED_MERGEINFO and deleted mergeinfo in *DELETED_MERGEINFO.
>> + Â Use POOL for all allocations. */
>> Â static svn_error_t *
>> -get_combined_mergeinfo_changes(svn_mergeinfo_t *combined_mergeinfo,
>> +get_combined_mergeinfo_changes(svn_mergeinfo_t *added_mergeinfo,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_mergeinfo_t *deleted_mergeinfo,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_fs_t *fs,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â const apr_array_header_t *paths,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_revnum_t rev,
>> @@ -747,7 +749,8 @@ get_combined_mergeinfo_changes(svn_merge
>> Â int i;
>>
>> Â /* Initialize return value. */
>> - Â *combined_mergeinfo = apr_hash_make(pool);
>> + Â *added_mergeinfo = apr_hash_make(pool);
>> + Â *deleted_mergeinfo = apr_hash_make(pool);
>>
>> Â /* If we're asking about revision 0, there's no mergeinfo to be found. */
>> Â if (rev == 0)
>> @@ -839,12 +842,9 @@ get_combined_mergeinfo_changes(svn_merge
>> Â Â Â /* Compare, constrast, and combine the results. */
>> Â Â Â SVN_ERR(svn_mergeinfo_diff(&deleted, &added, prev_mergeinfo,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â mergeinfo, FALSE, iterpool));
>> - Â Â Â mergeinfo = deleted;
>> - Â Â Â SVN_ERR(svn_mergeinfo_merge(mergeinfo, added, iterpool));
>> - Â Â Â SVN_ERR(svn_mergeinfo_merge(*combined_mergeinfo,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_mergeinfo_dup(mergeinfo, pool),
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â pool));
>> - Â Â }
>> + Â Â Â SVN_ERR(svn_mergeinfo_merge(*deleted_mergeinfo, deleted, pool));
>> + Â Â Â SVN_ERR(svn_mergeinfo_merge(*added_mergeinfo, added, pool));
>> + Â Â }
>> Â svn_pool_destroy(iterpool);
>>
>> Â /* Merge all the mergeinfos which are, or are children of, one of
>> @@ -856,28 +856,22 @@ get_combined_mergeinfo_changes(svn_merge
>> Â Â Â apr_ssize_t klen;
>> Â Â Â void *val;
>> Â Â Â const char *changed_path;
>> - Â Â Â svn_mergeinfo_t added_mergeinfo, deleted_mergeinfo;
>> + Â Â Â svn_mergeinfo_t added, deleted;
>>
>> Â Â Â /* The path is the key, the mergeinfo delta is the value. */
>> Â Â Â apr_hash_this(hi, &key, &klen, &val);
>> Â Â Â changed_path = key;
>> - Â Â Â added_mergeinfo = val;
>> + Â Â Â added = val;
>>
>> Â Â Â for (i = 0; i < paths->nelts; i++)
>> Â Â Â Â {
>> Â Â Â Â Â const char *path = APR_ARRAY_IDX(paths, i, const char *);
>> Â Â Â Â Â if (! svn_dirent_is_ancestor(path, changed_path))
>> Â Â Â Â Â Â continue;
>> - Â Â Â Â Â deleted_mergeinfo =
>> - Â Â Â Â Â Â apr_hash_get(deleted_mergeinfo_catalog, key, klen);
>> - Â Â Â Â Â SVN_ERR(svn_mergeinfo_merge(*combined_mergeinfo,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_mergeinfo_dup(deleted_mergeinfo,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â pool),
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â pool));
>> - Â Â Â Â Â SVN_ERR(svn_mergeinfo_merge(*combined_mergeinfo,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_mergeinfo_dup(added_mergeinfo,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â pool),
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â pool));
>> + Â Â Â Â Â deleted = apr_hash_get(deleted_mergeinfo_catalog, key, klen);
>> + Â Â Â Â Â SVN_ERR(svn_mergeinfo_merge(*deleted_mergeinfo, deleted, pool));
>> + Â Â Â Â Â SVN_ERR(svn_mergeinfo_merge(*added_mergeinfo, added, pool));
>> +
>> Â Â Â Â Â break;
>> Â Â Â Â }
>> Â Â }
>> @@ -1010,12 +1004,14 @@ fill_log_entry(svn_log_entry_t *log_entr
>> Â Â per the arguments of the same name to DO_LOGS. Â If
>> Â Â HANDLING_MERGED_REVISIONS is true and *all* changed paths within REV are
>> Â Â already represented in LOG_TARGET_HISTORY_AS_MERGEINFO, then don't send
>> - Â the log message for REV. */
>> + Â the log message for REV. Â If SUBTRACTIVE_MERGE is true, then REV was
>> + Â reverse merged */
>> Â static svn_error_t *
>> Â send_log(svn_revnum_t rev,
>> Â Â Â Â Â svn_fs_t *fs,
>> Â Â Â Â Â svn_mergeinfo_t log_target_history_as_mergeinfo,
>> Â Â Â Â Â svn_boolean_t discover_changed_paths,
>> + Â Â Â Â svn_boolean_t subtractive_merge,
>> Â Â Â Â Â svn_boolean_t handling_merged_revision,
>> Â Â Â Â Â const apr_array_header_t *revprops,
>> Â Â Â Â Â svn_boolean_t has_children,
>> @@ -1035,6 +1031,7 @@ send_log(svn_revnum_t rev,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â revprops, authz_read_func, authz_read_baton,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â pool));
>> Â log_entry->has_children = has_children;
>> + Â log_entry->subtractive_merge = subtractive_merge;
>>
>> Â /* Is REV a merged revision that is already part of
>> Â Â Â LOG_TARGET_HISTORY_AS_MERGEINFO? Â If so then there is no
>> @@ -1247,6 +1244,9 @@ struct path_list_range
>> Â {
>> Â apr_array_header_t *paths;
>> Â svn_merge_range_t range;
>> +
>> + Â /* Is RANGE the result of a reverse merge? */
>> + Â svn_boolean_t reverse_merge;
>> Â };
>>
>> Â /* A struct which represents "inverse mergeinfo", that is, instead of having
>> @@ -1292,10 +1292,13 @@ compare_rangelist_paths(const void *a, c
>>
>> Â /* From MERGEINFO, return in *COMBINED_LIST, allocated in POOL, a list of
>> Â Â 'struct path_list_range's. Â This list represents the rangelists in
>> - Â MERGEINFO and each path which has mergeinfo in that range. Â */
>> + Â MERGEINFO and each path which has mergeinfo in that range.
>> + Â If REVERSE_MERGE is true, then MERGEINFO represents mergeinfo removed
>> + Â as the result of a reverse merge. */
>> Â static svn_error_t *
>> Â combine_mergeinfo_path_lists(apr_array_header_t **combined_list,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_mergeinfo_t mergeinfo,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_boolean_t reverse_merge,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â apr_pool_t *pool)
>> Â {
>> Â apr_hash_index_t *hi;
>> @@ -1326,7 +1329,9 @@ combine_mergeinfo_path_lists(apr_array_h
>> Â /* Loop over the (revision range, path) tuples, chopping them into
>> Â Â Â (revision range, paths) tuples, and appending those to the output
>> Â Â Â list. */
>> - Â *combined_list = apr_array_make(pool, 0, sizeof(struct path_list_range *));
>> + Â if (! *combined_list)
>> + Â Â *combined_list = apr_array_make(pool, 0, sizeof(struct path_list_range *));
>> +
>> Â while (rangelist_paths->nelts > 1)
>> Â Â {
>> Â Â Â svn_revnum_t youngest, next_youngest, tail, youngest_end;
>> @@ -1375,6 +1380,7 @@ combine_mergeinfo_path_lists(apr_array_h
>> Â Â Â /* Insert the (earliest, tail) tuple into the output list, along with
>> Â Â Â Â Â a list of paths which match it. */
>> Â Â Â plr = apr_palloc(pool, sizeof(*plr));
>> + Â Â Â plr->reverse_merge = reverse_merge;
>> Â Â Â plr->range.start = youngest;
>> Â Â Â plr->range.end = tail;
>> Â Â Â plr->paths = apr_array_make(pool, num_revs, sizeof(const char *));
>> @@ -1426,6 +1432,7 @@ combine_mergeinfo_path_lists(apr_array_h
>> Â Â Â Â {
>> Â Â Â Â Â struct path_list_range *plr = apr_palloc(pool, sizeof(*plr));
>>
>> + Â Â Â Â Â plr->reverse_merge = reverse_merge;
>> Â Â Â Â Â plr->paths = apr_array_make(pool, 1, sizeof(const char *));
>> Â Â Â Â Â APR_ARRAY_PUSH(plr->paths, const char *) = first_rp->path;
>> Â Â Â Â Â plr->range = *APR_ARRAY_IDX(first_rp->rangelist, 0,
>> @@ -1453,6 +1460,7 @@ do_logs(svn_fs_t *fs,
>> Â Â Â Â svn_boolean_t strict_node_history,
>> Â Â Â Â svn_boolean_t include_merged_revisions,
>> Â Â Â Â svn_boolean_t handling_merged_revisions,
>> + Â Â Â Â svn_boolean_t subtractive_merge,
>> Â Â Â Â svn_boolean_t ignore_missing_locations,
>> Â Â Â Â const apr_array_header_t *revprops,
>> Â Â Â Â svn_boolean_t descending_order,
>> @@ -1462,14 +1470,34 @@ do_logs(svn_fs_t *fs,
>> Â Â Â Â void *authz_read_baton,
>> Â Â Â Â apr_pool_t *pool);
>>
>> +/* Comparator function for handle_merged_revisions(). Â Sorts path_list_range
>> + Â structs in increasing order based on the struct's RANGE.START revision,
>> + Â then RANGE.END revision. */
>> +static int
>> +compare_path_list_range(const void *a, const void *b)
>> +{
>> + Â struct path_list_range *plr_a = *((struct path_list_range *const *) a);
>> + Â struct path_list_range *plr_b = *((struct path_list_range *const *) b);
>> +
>> + Â if (plr_a->range.start < plr_b->range.start)
>> + Â Â return -1;
>> + Â if (plr_a->range.start > plr_b->range.start)
>> + Â Â return 1;
>> + Â if (plr_a->range.end < plr_b->range.end)
>> + Â Â return -1;
>> + Â if (plr_a->range.end > plr_b->range.end)
>> + Â Â return 1;
>> +
>> + Â return 0;
>> +}
>>
>> -/* Examine the combined mergeinfo for revision REV in FS (as collected
>> - Â by examining paths of interest to a log operation), and determine
>> - Â which revisions to report as having been merged via the commit
>> - Â resulting in REV.
>> +/* Examine the ADDED_MERGEINFO and DELETED_MERGEINFO for revision REV in FS
>> + Â (as collected by examining paths of interest to a log operation), and
>> + Â determine which revisions to report as having been merged or reverse-merged
>> + Â via the commit resulting in REV.
>>
>> Â Â Silently ignore some failures to find the revisions mentioned in the
>> - Â mergeinfo, as might happen if there is invalid mergeinfo.
>> + Â added/deleted mergeinfos, as might happen if there is invalid mergeinfo.
>>
>> Â Â Other parameters are as described by do_logs(), around which this
>> Â Â is a recursion wrapper. */
>> @@ -1477,7 +1505,8 @@ static svn_error_t *
>> Â handle_merged_revisions(svn_revnum_t rev,
>> Â Â Â Â Â Â Â Â Â Â Â Â svn_fs_t *fs,
>> Â Â Â Â Â Â Â Â Â Â Â Â svn_mergeinfo_t log_target_history_as_mergeinfo,
>> - Â Â Â Â Â Â Â Â Â Â Â Â svn_mergeinfo_t mergeinfo,
>> + Â Â Â Â Â Â Â Â Â Â Â Â svn_mergeinfo_t added_mergeinfo,
>> + Â Â Â Â Â Â Â Â Â Â Â Â svn_mergeinfo_t deleted_mergeinfo,
>> Â Â Â Â Â Â Â Â Â Â Â Â svn_boolean_t discover_changed_paths,
>> Â Â Â Â Â Â Â Â Â Â Â Â svn_boolean_t strict_node_history,
>> Â Â Â Â Â Â Â Â Â Â Â Â const apr_array_header_t *revprops,
>> @@ -1487,15 +1516,25 @@ handle_merged_revisions(svn_revnum_t rev
>> Â Â Â Â Â Â Â Â Â Â Â Â void *authz_read_baton,
>> Â Â Â Â Â Â Â Â Â Â Â Â apr_pool_t *pool)
>> Â {
>> - Â apr_array_header_t *combined_list;
>> + Â apr_array_header_t *combined_list = NULL;
>> Â svn_log_entry_t *empty_log_entry;
>> Â apr_pool_t *iterpool;
>> Â int i;
>>
>> - Â if (apr_hash_count(mergeinfo) == 0)
>> + Â if (apr_hash_count(added_mergeinfo) == 0
>> + Â Â Â && apr_hash_count(deleted_mergeinfo) == 0)
>> Â Â return SVN_NO_ERROR;
>>
>> - Â SVN_ERR(combine_mergeinfo_path_lists(&combined_list, mergeinfo, pool));
>> + Â if (apr_hash_count(added_mergeinfo))
>> + Â Â SVN_ERR(combine_mergeinfo_path_lists(&combined_list, added_mergeinfo,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â FALSE, pool));
>> +
>> + Â if (apr_hash_count(deleted_mergeinfo))
>> + Â Â SVN_ERR(combine_mergeinfo_path_lists(&combined_list, deleted_mergeinfo,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â TRUE, pool));
>> +
>> + Â qsort(combined_list->elts, combined_list->nelts,
>> + Â Â Â Â combined_list->elt_size, compare_path_list_range);
>>
>> Â /* Because the combined_lists are ordered youngest to oldest,
>> Â Â Â iterate over them in reverse. */
>> @@ -1509,9 +1548,9 @@ handle_merged_revisions(svn_revnum_t rev
>> Â Â Â SVN_ERR(do_logs(fs, pl_range->paths, log_target_history_as_mergeinfo,
>> Â Â Â Â Â Â Â Â Â Â Â pl_range->range.start, pl_range->range.end, 0,
>> Â Â Â Â Â Â Â Â Â Â Â discover_changed_paths, strict_node_history,
>> - Â Â Â Â Â Â Â Â Â Â Â TRUE, TRUE, TRUE, revprops, TRUE,
>> - Â Â Â Â Â Â Â Â Â Â Â receiver, receiver_baton, authz_read_func,
>> - Â Â Â Â Â Â Â Â Â Â Â authz_read_baton, iterpool));
>> + Â Â Â Â Â Â Â Â Â Â Â TRUE, pl_range->reverse_merge, TRUE, TRUE,
>> + Â Â Â Â Â Â Â Â Â Â Â revprops, TRUE, receiver, receiver_baton,
>> + Â Â Â Â Â Â Â Â Â Â Â authz_read_func, authz_read_baton, iterpool));
>> Â Â }
>> Â svn_pool_destroy(iterpool);
>>
>> @@ -1521,6 +1560,14 @@ handle_merged_revisions(svn_revnum_t rev
>> Â return (*receiver)(receiver_baton, empty_log_entry, pool);
>> Â }
>>
>> +/* This is used by do_logs to differentiate between forward and
>> + Â reverse merges. */
>> +struct added_deleted_mergeinfo
>> +{
>> + Â svn_mergeinfo_t added_mergeinfo;
>> + Â svn_mergeinfo_t deleted_mergeinfo;
>> +};
>> +
>> Â /* Find logs for PATHS from HIST_START to HIST_END in FS, and invoke
>> Â Â RECEIVER with RECEIVER_BATON on them. Â If DESCENDING_ORDER is TRUE, send
>> Â Â the logs back as we find them, else buffer the logs and send them back
>> @@ -1534,7 +1581,8 @@ handle_merged_revisions(svn_revnum_t rev
>>
>> Â Â If HANDLING_MERGED_REVISIONS is TRUE then this is a recursive call for
>> Â Â merged revisions, see INCLUDE_MERGED_REVISIONS argument to
>> - Â svn_repos_get_logs4().
>> + Â svn_repos_get_logs4(). Â If SUBTRACTIVE_MERGE is true, then this is a
>> + Â recursive call for reverse merged revisions.
>>
>> Â Â Other parameters are the same as svn_repos_get_logs4().
>> Â */
>> @@ -1548,6 +1596,7 @@ do_logs(svn_fs_t *fs,
>> Â Â Â Â svn_boolean_t discover_changed_paths,
>> Â Â Â Â svn_boolean_t strict_node_history,
>> Â Â Â Â svn_boolean_t include_merged_revisions,
>> + Â Â Â Â svn_boolean_t subtractive_merge,
>> Â Â Â Â svn_boolean_t handling_merged_revisions,
>> Â Â Â Â svn_boolean_t ignore_missing_locations,
>> Â Â Â Â const apr_array_header_t *revprops,
>> @@ -1603,7 +1652,8 @@ do_logs(svn_fs_t *fs,
>> Â Â Â /* If any of the paths changed in this rev then add or send it. */
>> Â Â Â if (changed)
>> Â Â Â Â {
>> - Â Â Â Â Â svn_mergeinfo_t mergeinfo = NULL;
>> + Â Â Â Â Â svn_mergeinfo_t added_mergeinfo = NULL;
>> + Â Â Â Â Â svn_mergeinfo_t deleted_mergeinfo = NULL;
>> Â Â Â Â Â svn_boolean_t has_children = FALSE;
>>
>> Â Â Â Â Â /* If we're including merged revisions, we need to calculate
>> @@ -1623,9 +1673,12 @@ do_logs(svn_fs_t *fs,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â struct path_info *);
>> Â Â Â Â Â Â Â Â Â APR_ARRAY_PUSH(cur_paths, const char *) = info->path->data;
>> Â Â Â Â Â Â Â Â }
>> - Â Â Â Â Â Â Â SVN_ERR(get_combined_mergeinfo_changes(&mergeinfo, fs, cur_paths,
>> + Â Â Â Â Â Â Â SVN_ERR(get_combined_mergeinfo_changes(&added_mergeinfo,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â &deleted_mergeinfo,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â fs, cur_paths,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â current, iterpool));
>> - Â Â Â Â Â Â Â has_children = (apr_hash_count(mergeinfo) > 0);
>> + Â Â Â Â Â Â Â has_children = (apr_hash_count(added_mergeinfo) > 0
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â || apr_hash_count(deleted_mergeinfo) > 0);
>> Â Â Â Â Â Â }
>>
>> Â Â Â Â Â /* If our caller wants logs in descending order, we can send
>> @@ -1636,15 +1689,16 @@ do_logs(svn_fs_t *fs,
>> Â Â Â Â Â Â Â SVN_ERR(send_log(current, fs,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â log_target_history_as_mergeinfo,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â discover_changed_paths,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â handling_merged_revisions, revprops,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â has_children, receiver, receiver_baton,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â subtractive_merge, handling_merged_revisions,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â revprops, has_children,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â receiver, receiver_baton,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â authz_read_func, authz_read_baton, iterpool));
>> Â Â Â Â Â Â Â if (has_children)
>> Â Â Â Â Â Â Â Â {
>> Â Â Â Â Â Â Â Â Â SVN_ERR(handle_merged_revisions(
>> Â Â Â Â Â Â Â Â Â Â current, fs,
>> Â Â Â Â Â Â Â Â Â Â log_target_history_as_mergeinfo,
>> - Â Â Â Â Â Â Â Â Â Â mergeinfo,
>> + Â Â Â Â Â Â Â Â Â Â added_mergeinfo, deleted_mergeinfo,
>> Â Â Â Â Â Â Â Â Â Â discover_changed_paths,
>> Â Â Â Â Â Â Â Â Â Â strict_node_history,
>> Â Â Â Â Â Â Â Â Â Â revprops,
>> @@ -1666,14 +1720,25 @@ do_logs(svn_fs_t *fs,
>> Â Â Â Â Â Â Â Â revs = apr_array_make(pool, 64, sizeof(svn_revnum_t));
>> Â Â Â Â Â Â Â APR_ARRAY_PUSH(revs, svn_revnum_t) = current;
>>
>> - Â Â Â Â Â Â Â if (mergeinfo)
>> + Â Â Â Â Â Â Â if (added_mergeinfo || deleted_mergeinfo)
>> Â Â Â Â Â Â Â Â {
>> - Â Â Â Â Â Â Â Â Â svn_revnum_t *cur_rev = apr_palloc(pool, sizeof(*cur_rev));
>> + Â Â Â Â Â Â Â Â Â svn_revnum_t *cur_rev = apr_pcalloc(pool, sizeof(*cur_rev));
>> + Â Â Â Â Â Â Â Â Â struct added_deleted_mergeinfo *add_and_del_mergeinfo =
>> + Â Â Â Â Â Â Â Â Â Â apr_palloc(pool, sizeof(*add_and_del_mergeinfo));
>> +
>> + Â Â Â Â Â Â Â Â Â if (added_mergeinfo)
>> + Â Â Â Â Â Â Â Â Â Â add_and_del_mergeinfo->added_mergeinfo =
>> + Â Â Â Â Â Â Â Â Â Â Â svn_mergeinfo_dup(added_mergeinfo, pool);
>> +
>> + Â Â Â Â Â Â Â Â Â if (deleted_mergeinfo)
>> + Â Â Â Â Â Â Â Â Â Â add_and_del_mergeinfo->deleted_mergeinfo =
>> + Â Â Â Â Â Â Â Â Â Â Â svn_mergeinfo_dup(deleted_mergeinfo, pool);
>> +
>> Â Â Â Â Â Â Â Â Â *cur_rev = current;
>> Â Â Â Â Â Â Â Â Â if (! rev_mergeinfo)
>> Â Â Â Â Â Â Â Â Â Â rev_mergeinfo = apr_hash_make(pool);
>> Â Â Â Â Â Â Â Â Â apr_hash_set(rev_mergeinfo, cur_rev, sizeof(*cur_rev),
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_mergeinfo_dup(mergeinfo, pool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â add_and_del_mergeinfo);
>> Â Â Â Â Â Â Â Â }
>> Â Â Â Â Â Â }
>> Â Â Â Â }
>> @@ -1687,7 +1752,8 @@ do_logs(svn_fs_t *fs,
>> Â Â Â iterpool = svn_pool_create(pool);
>> Â Â Â for (i = 0; i < revs->nelts; ++i)
>> Â Â Â Â {
>> - Â Â Â Â Â svn_mergeinfo_t mergeinfo;
>> + Â Â Â Â Â svn_mergeinfo_t added_mergeinfo;
>> + Â Â Â Â Â svn_mergeinfo_t deleted_mergeinfo;
>> Â Â Â Â Â svn_boolean_t has_children = FALSE;
>>
>> Â Â Â Â Â svn_pool_clear(iterpool);
>> @@ -1699,21 +1765,25 @@ do_logs(svn_fs_t *fs,
>> Â Â Â Â Â Â Â revisions we need to handle recursively. */
>> Â Â Â Â Â if (rev_mergeinfo)
>> Â Â Â Â Â Â {
>> - Â Â Â Â Â Â Â mergeinfo = apr_hash_get(rev_mergeinfo, ¤t,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â sizeof(svn_revnum_t));
>> - Â Â Â Â Â Â Â has_children = (apr_hash_count(mergeinfo) > 0);
>> + Â Â Â Â Â Â Â struct added_deleted_mergeinfo *add_and_del_mergeinfo =
>> + Â Â Â Â Â Â Â Â apr_hash_get(rev_mergeinfo, ¤t, sizeof(svn_revnum_t));
>> + Â Â Â Â Â Â Â added_mergeinfo = add_and_del_mergeinfo->added_mergeinfo;
>> + Â Â Â Â Â Â Â deleted_mergeinfo = add_and_del_mergeinfo->deleted_mergeinfo;
>> + Â Â Â Â Â Â Â has_children = (apr_hash_count(added_mergeinfo) > 0
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â || apr_hash_count(deleted_mergeinfo) > 0);
>> Â Â Â Â Â Â }
>>
>> Â Â Â Â Â SVN_ERR(send_log(current, fs, log_target_history_as_mergeinfo,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â discover_changed_paths, handling_merged_revisions,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â revprops, has_children,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â discover_changed_paths, subtractive_merge,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â handling_merged_revisions, revprops, has_children,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â receiver, receiver_baton, authz_read_func,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â authz_read_baton, iterpool));
>> Â Â Â Â Â if (has_children)
>> Â Â Â Â Â Â {
>> Â Â Â Â Â Â Â SVN_ERR(handle_merged_revisions(current, fs,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â log_target_history_as_mergeinfo,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â mergeinfo,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â added_mergeinfo,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â deleted_mergeinfo,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â discover_changed_paths,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â strict_node_history, revprops,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â receiver, receiver_baton,
>> @@ -1896,8 +1966,8 @@ svn_repos_get_logs4(svn_repos_t *repos,
>> Â Â Â Â Â if (descending_order)
>> Â Â Â Â Â Â rev = end - i;
>> Â Â Â Â Â SVN_ERR(send_log(rev, fs, NULL, discover_changed_paths, FALSE,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â revprops, FALSE,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â receiver, receiver_baton, authz_read_func,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â FALSE, revprops, FALSE, receiver,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â receiver_baton, authz_read_func,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â authz_read_baton, iterpool));
>> Â Â Â Â }
>> Â Â Â svn_pool_destroy(iterpool);
>> @@ -1924,7 +1994,7 @@ svn_repos_get_logs4(svn_repos_t *repos,
>>
>> Â return do_logs(repos->fs, paths, paths_history_mergeinfo, start, end,
>> Â Â Â Â Â Â Â Â Â limit, discover_changed_paths, strict_node_history,
>> - Â Â Â Â Â Â Â Â include_merged_revisions, FALSE, FALSE, revprops,
>> + Â Â Â Â Â Â Â Â include_merged_revisions, FALSE, FALSE, FALSE, revprops,
>> Â Â Â Â Â Â Â Â Â descending_order, receiver, receiver_baton,
>> Â Â Â Â Â Â Â Â Â authz_read_func, authz_read_baton, pool);
>> Â }
>>
>> Modified: subversion/trunk/subversion/mod_dav_svn/reports/log.c
>> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/reports/log.c?rev=1079983&r1=1079982&r2=1079983&view=diff
>> ==============================================================================
>> --- subversion/trunk/subversion/mod_dav_svn/reports/log.c (original)
>> +++ subversion/trunk/subversion/mod_dav_svn/reports/log.c Wed Mar  9 20:37:55 2011
>> @@ -158,6 +158,10 @@ log_receiver(void *baton,
>> Â Â Â lrb->stack_depth++;
>> Â Â }
>>
>> + Â if (log_entry->subtractive_merge)
>> + Â Â SVN_ERR(dav_svn__brigade_puts(lrb->bb, lrb->output,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â "<S:subtractive-merge/>"));
>> +
>> Â if (log_entry->changed_paths2)
>> Â Â {
>> Â Â Â apr_hash_index_t *hi;
>>
>> Modified: subversion/trunk/subversion/svn/log-cmd.c
>> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/log-cmd.c?rev=1079983&r1=1079982&r2=1079983&view=diff
>> ==============================================================================
>> --- subversion/trunk/subversion/svn/log-cmd.c (original)
>> +++ subversion/trunk/subversion/svn/log-cmd.c Wed Mar  9 20:37:55 2011
>> @@ -248,7 +248,10 @@ log_entry_receiver(void *baton,
>> Â Â Â int i;
>>
>> Â Â Â /* Print the result of merge line */
>> - Â Â Â SVN_ERR(svn_cmdline_printf(pool, _("Merged via:")));
>> + Â Â Â if (log_entry->subtractive_merge)
>> + Â Â Â Â SVN_ERR(svn_cmdline_printf(pool, _("Reverse merged via:")));
>> + Â Â Â else
>> + Â Â Â Â SVN_ERR(svn_cmdline_printf(pool, _("Merged via:")));
>> Â Â Â for (i = 0; i < lb->merge_stack->nelts; i++)
>> Â Â Â Â {
>> Â Â Â Â Â svn_revnum_t rev = APR_ARRAY_IDX(lb->merge_stack, i, svn_revnum_t);
>>
>> Modified: subversion/trunk/subversion/svnserve/serve.c
>> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnserve/serve.c?rev=1079983&r1=1079982&r2=1079983&view=diff
>> ==============================================================================
>> --- subversion/trunk/subversion/svnserve/serve.c (original)
>> +++ subversion/trunk/subversion/svnserve/serve.c Wed Mar  9 20:37:55 2011
>> @@ -1970,7 +1970,8 @@ static svn_error_t *log_receiver(void *b
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â log_entry->has_children,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â invalid_revnum, revprop_count));
>> Â SVN_ERR(svn_ra_svn_write_proplist(conn, pool, log_entry->revprops));
>> - Â SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!)"));
>> + Â SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "!)b",
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â log_entry->subtractive_merge));
>>
>> Â if (log_entry->has_children)
>> Â Â b->stack_depth++;
>>
>> Modified: subversion/trunk/subversion/tests/cmdline/log_tests.py
>> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/log_tests.py?rev=1079983&r1=1079982&r2=1079983&view=diff
>> ==============================================================================
>> --- subversion/trunk/subversion/tests/cmdline/log_tests.py (original)
>> +++ subversion/trunk/subversion/tests/cmdline/log_tests.py Wed Mar  9 20:37:55 2011
>> @@ -1686,7 +1686,8 @@ def merge_sensitive_log_added_mergeinfo_
>>
>> Â def run_log_g_r8(log_target):
>> Â Â expected_merges = {
>> - Â Â Â 8 : [],
>> + Â Â Â 8 : []}
>> + Â Â expected_reverse_merges = {
>> Â Â Â 3 : [8]}
>> Â Â exit_code, output, err = svntest.actions.run_and_verify_svn(None, None,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â [],
>> @@ -1694,7 +1695,7 @@ def merge_sensitive_log_added_mergeinfo_
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â '-r8',
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â log_target)
>> Â Â log_chain = parse_log_output(output)
>> - Â Â check_merge_results(log_chain, expected_merges)
>> + Â Â check_merge_results(log_chain, expected_merges, expected_reverse_merges)
>>
>> Â run_log_g_r8(wc_dir)
>> Â run_log_g_r8(os.path.join(wc_dir, "A_COPY"))
>> @@ -1814,7 +1815,6 @@ def log_of_local_copy(sbox):
>>
>> Â @SkipUnless(server_has_mergeinfo)
>> Â @Issue(3176)
>> -_at_XFail()
>> Â def merge_sensitive_log_reverse_merges(sbox):
>> Â "log -g differentiates forward and reverse merges"
>>
>> @@ -1845,8 +1845,6 @@ def merge_sensitive_log_reverse_merges(s
>> Â exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [],
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â 'log', '-g', '-r8',
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â A_COPY_path)
>> - Â # This test currently fails because reverse merges are not differentiated
>> - Â # from forward merges.
>> Â log_chain = parse_log_output(out)
>> Â expected_merges = {
>> Â Â 8 : [],
>>
>>
>>
>
Received on 2011-03-09 23:20:32 CET