Issue #25 resolved

Traceback from crecord operation

Jason Harris
created an issue

Here is the traceback with --debug on:

I was doing a crecord operation and I received the following back trace. I have included the full debug output in the attached file.

Sorry I don't have a smaller example... (I can get the person who will handle this access to the repository that can reproduce this...)

{{{ [salt:/Development/MacHgDev/MacHgClone17] MacHgClone17 880(880) mq:1/17 ⌘ hg --debug crecord

.....

unknown exception encountered, please report by visiting http://mercurial.selenic.com/wiki/BugTracker Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] Mercurial Distributed SCM (version 1.9.3+20111011) Extensions loaded: extdiff, patchbomb, mq, rebase, histedit, crecord, prompt, committer, ban- changesets Traceback (most recent call last): File "/usr/local/bin/hg", line 38, in <module> mercurial.dispatch.run() File "/Library/Python/2.7/site-packages/mercurial/dispatch.py", line 27, in run sys.exit(dispatch(request(sys.argv[1:]))) File "/Library/Python/2.7/site-packages/mercurial/dispatch.py", line 64, in dispatch return _runcatch(req) File "/Library/Python/2.7/site-packages/mercurial/dispatch.py", line 87, in _runcatch return _dispatch(req) File "/Library/Python/2.7/site-packages/mercurial/dispatch.py", line 688, in _dispatch cmdpats, cmdoptions) File "/Library/Python/2.7/site-packages/mercurial/dispatch.py", line 463, in runcommand ret = _runcommand(ui, options, cmd, d) File "/Library/Python/2.7/site-packages/mercurial/dispatch.py", line 742, in _runcommand return checkargs() File "/Library/Python/2.7/site-packages/mercurial/dispatch.py", line 696, in checkargs return cmdfunc() File "/Library/Python/2.7/site-packages/mercurial/dispatch.py", line 685, in <lambda> d = lambda: util.checksignature(func)(ui, *args, cmdoptions) File "/Library/Python/2.7/site-packages/mercurial/util.py", line 389, in check return func(args, kwargs) File "/Library/Python/2.7/site-packages/mercurial/extensions.py", line 137, in wrap util.checksignature(origfn), *args, kwargs) File "/Library/Python/2.7/site-packages/mercurial/util.py", line 389, in check return func(args, kwargs) File "/Library/Python/2.7/site-packages/hgext/mq.py", line 3218, in mqcommand return orig(ui, repo, *args, kwargs) File "/Library/Python/2.7/site-packages/mercurial/util.py", line 389, in check return func(*args, kwargs) File "/Users/jason/Library/MercurialExtensions/crecord/__init__.py", line 29, in crecord dorecord(ui, repo, commands.commit, *pats, opts) File "/Users/jason/Library/MercurialExtensions/crecord/crecord_core.py", line 179, in dorecord return cmdutil.commit(ui, repo, recordfunc, pats, opts) File "/Library/Python/2.7/site-packages/mercurial/cmdutil.py", line 1189, in commit scmutil.match(repo[None], pats, opts), opts) File "/Users/jason/Library/MercurialExtensions/crecord/crecord_core.py", line 124, in recordfunc patch.internalpatch(ui, repo, fp, strip=1, eolmode=None) File "/Library/Python/2.7/site-packages/mercurial/patch.py", line 1420, in internalpatch return patchbackend(ui, backend, patchobj, strip, files, eolmode) File "/Library/Python/2.7/site-packages/mercurial/patch.py", line 1405, in patchbackend eolmode=eolmode) File "/Library/Python/2.7/site-packages/mercurial/patch.py", line 1266, in applydiff eolmode=eolmode) File "/Library/Python/2.7/site-packages/mercurial/patch.py", line 1282, in _applydiff ret = current_file.apply(values) File "/Library/Python/2.7/site-packages/mercurial/patch.py", line 759, in apply cand = self.findlines(old[0][1:], search_start) IndexError: list index out of range }}}

Comments (8)

  1. immerrr

    I encounter the same for my repository time to time and have already proceeded with debugging.

    In my case, the trouble is in the last hunk of a file, which adds 6 lines to the end of the file. So, in the traceback, old is empty (old = []) and old[0] generates IndexError.

    I'll try and fix this tomorrow, this issue really spoils crecord experience for me.

  2. immerrr
    • changed status to open

    Alright, I've somewhat traced it down. It appears that crpatch module , which scans output of 'hg di --git' and constructs a tree from it, is responsible for the error. I managed to reduce the test case to simple commands yesterday, let me reproduce them on my home computer and I'll post them here.

    crpatch basically parses output of 'hg diff --git', creating a tree node, a crecord hunk, for each span of changed lines, while git diff format allows several such spans per git hunk. So, AFAIU, the following diff

    diff --combined describe.c
    index fabadb8,cc95eb0..4866510
    --- a/describe.c
    +++ b/describe.c
    @@@ -98,20 -98,12 +98,20 @@@
            return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
      }
    
    - static void describe(char *arg)
    + static void describe(char *arg, int last_one)
      {
    +      unsigned char sha1[20];
    +      struct commit *cmit;
           struct commit_list *list;
           static int initialized = 0;
           struct commit_name *n;
    
    +      if (get_sha1(arg, sha1) < 0)
    +              usage(describe_usage);
    +      cmit = lookup_commit_reference(sha1);
    +      if (!cmit)
    +              usage(describe_usage);
    +
           if (!initialized) {
                   initialized = 1;
                   for_each_ref(get_name);
    

    would be split in three, namely

            return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1;
      }
    
    - static void describe(char *arg)
    + static void describe(char *arg, int last_one)
    
      {
    
    +      unsigned char sha1[20];
    +      struct commit *cmit;
           struct commit_list *list;
           static int initialized = 0;
           struct commit_name *n;
    
    +      if (get_sha1(arg, sha1) < 0)
    +              usage(describe_usage);
    +      cmit = lookup_commit_reference(sha1);
    +      if (!cmit)
    +              usage(describe_usage);
    +
           if (!initialized) {
                   initialized = 1;
                   for_each_ref(get_name);
    

    The bug is most probably triggered by hunk range specification arithmetics, i.e. lines like the one below that need to be calculated manually whens splitting.

    @@@ -98,20 -98,12 +98,20 @@@
    

    I think so, because I've tried doing 'hg diff -U 0' (zero context lines, thus every span of changed lines will have its own git hunk), and it appears to create somewhat different line specifications when compared to crecord tree. Re-checking the line arithmetics, though being trivial, requires extra attention and time, and I'm not sure it's worth the effort to investigate what's wrong with it. The question is, why not print diff hunks as-is, why bother splitting them manually? Is there a design constraint that requires such operation?

  3. immerrr

    Here's the reproduction sequence:

    • create repository
    mkdir testrepo && cd testrepo/ && hg init
    
    • commit a file
    cat /dev/urandom | strings | head -n10 > file && hg add file && hg ci -m 'init'
    
    • modify every third line of file so that git diff contains single hunk and add some lines to the end
    { rm file; awk '{print} (NR%3)==0{ printf "\n" } END {printf "foo\nbar\nbaz\n" }' > file; } < file 
    
    • make sure git diff contains single hunk
    hg diff --git
    
    • try committing changes with crecord
    hg crecord
    
  4. edgimar repo owner

    The changes look good to me, and I've pulled them into my repo. Thanks immerrr for looking into this. Jason, if you find that the patch solves the problem for you, can you close this bug?

  5. Log in to comment