The problem seems to come from svn_rangelist_merge2. This test program recreates the problem.
#include <svn_pools.h> #include <svn_mergeinfo.h> int main(int argc, char * argv[]) { apr_pool_t *pool; int exit_code = EXIT_SUCCESS; svn_error_t *err; if (svn_cmdline_init("svn", stderr) != EXIT_SUCCESS) return EXIT_FAILURE; pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE)); // 15014-19472,19473-19612*,19613-19614,19615-19630*,19631-19634,19635-20055* svn_rangelist_t * rangelist = apr_array_make(pool, 1, sizeof(svn_merge_range_t *)); svn_merge_range_t *mrange = apr_pcalloc(pool, sizeof(*mrange)); mrange->start = 15013; mrange->end = 19472; mrange->inheritable = TRUE; APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = mrange; mrange = apr_pcalloc(pool, sizeof(*mrange)); mrange->start = 19472; mrange->end = 19612; mrange->inheritable = FALSE; APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = mrange; mrange = apr_pcalloc(pool, sizeof(*mrange)); mrange->start = 19612; mrange->end = 19614; mrange->inheritable = TRUE; APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = mrange; mrange = apr_pcalloc(pool, sizeof(*mrange)); mrange->start = 19614; mrange->end = 19630; mrange->inheritable = FALSE; APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = mrange; mrange = apr_pcalloc(pool, sizeof(*mrange)); mrange->start = 19630; mrange->end = 19634; mrange->inheritable = TRUE; APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = mrange; mrange = apr_pcalloc(pool, sizeof(*mrange)); mrange->start = 19634; mrange->end = 20055; mrange->inheritable = FALSE; APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = mrange; // 15014-20515* svn_rangelist_t * changes = apr_array_make(pool, 1, sizeof(svn_merge_range_t *)); mrange = apr_pcalloc(pool, sizeof(*mrange)); mrange->start = 15013; mrange->end = 20515; mrange->inheritable = FALSE; APR_ARRAY_PUSH(changes, svn_merge_range_t *) = mrange; { svn_string_t * tmpString; svn_rangelist_to_string(&tmpString, rangelist, pool); printf("rangelist %s\n", tmpString->data); } { svn_string_t * tmpString; svn_rangelist_to_string(&tmpString, changes, pool); printf("changes %s\n", tmpString->data); } svn_rangelist_merge2(rangelist, changes, pool, pool); { svn_string_t * tmpString; svn_rangelist_to_string(&tmpString, rangelist, pool); printf("result %s\n", tmpString->data); } // wrong result // result 15014-19472,19473-19612*,19613-19614,19615-19630*,19634-19631*,19631-19634,19635-20515* svn_pool_destroy(pool); return exit_code; } So while this correctly expands the last range from 20055 to 20515 it inserts a wrong inverse range. It’s a bit late, I’ll have a look tomorrow unless someone beats me to it. ;) > Am 30.06.2017 um 20:50 schrieb Johan Corveleyn <jcor...@gmail.com>: > > On Fri, Jun 30, 2017 at 6:10 PM, Jens Christian Restemeier > <j...@playtonicgames.com> wrote: >> I narrowed it down to somewhere in update_wc_mergeinfo. At the start of the >> function where it gets the mergeinfo for the root directory it is: >> /trunk:15014-19472,19473-19612*,19613-19614,19615-19630*,19631-19634,19635-2 >> 0055* >> >> A bit later where this gets parsed again from svn_wc_canonicalize_svn_prop >> it is: >> /trunk:15014-19472,19473-19612*,19613-19614,19615-19630*,19634-19631*,19631- >> 19634,19635-20511* >> >> So somewhere in the mergeinfo update this gets added. >> >> Debugging this in gdb is not fun, though... > > Maybe it comes from a parent or child of your root directory (either > in the working copy, or even part of the repository but outside of the > scope of your working copy). Mergeinfo has some inheritance semantics, > so it doesn't have to be directly defined on your root directory to be > applicable. > > -- > Johan