subversion-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jens Christian Restemeier" <j...@playtonicgames.com>
Subject RE: "Unable to parse reversed revision range" when merging from trunk to branch
Date Mon, 03 Jul 2017 14:31:00 GMT
I narrowed it down to the code in subversion/libsvn_subr/mergeinfo.c line 892-898 in adjust_remaining_ranges.
At that point next_range actually starts before modified_range, so my guess is svn_sort__array_insert
has some unexpected behaviour.

   x892                   svn_merge_range_t *new_modified_range =                        
                                                                                         
                        x
   x893                     apr_palloc(result_pool, sizeof(*new_modified_range));        
                                                                                         
                        x
   x894                   new_modified_range->start = next_range->end;             
                                                                                         
                              x
   x895                   new_modified_range->end = modified_range->end;           
                                                                                         
                              x
   x896                   new_modified_range->inheritable = FALSE;                    
                                                                                         
                           x
   x897                   modified_range->end = next_range->start;                 
                                                                                         
                              x
   x898                   (*range_index)+=2;                                             
                                                                                         
                        x
  >x899                   svn_sort__array_insert(rangelist, &new_modified_range,  
                                                                                         
                               x
                                          *range_index);                                 
                                                                                         
                 x
   x901                   /* Recurse with the new range. */                              
                                                                                         
                        x
   x902                   adjust_remaining_ranges(rangelist, range_index, result_pool);  
                                                                                         
                        x
   
Intuitively it seems to be awfully complicated to expand a range to the end of a change, and
then cut it down recursively with adjust_remaining_ranges. My first thought would be to step
through "rangelist" and "changes" side by side in svn_rangelist_merge2, and to modify, insert
or skip a range in either list until you're at the end. Though obviously I have no idea about
all the edge cases the current code most likely fixes...

So how should I proceed from here? Should I open a bug with my findings and the test case?

-----Original Message-----
From: Jens Restemeier [mailto:jens@playtonicgames.com] 
Sent: 02 July 2017 23:44
To: Johan Corveleyn <jcorvel@gmail.com>
Cc: Stefan Sperling <stsp@elego.de>; users@subversion.apache.org
Subject: Re: "Unable to parse reversed revision range" when merging from trunk to branch

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 <jcorvel@gmail.com>:
> 
> On Fri, Jun 30, 2017 at 6:10 PM, Jens Christian Restemeier 
> <jens@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



Mime
View raw message