Bug 3855 - KeyError: '.hgsubstate' with hg merge
Summary: KeyError: '.hgsubstate' with hg merge
Status: RESOLVED FIXED
Alias: None
Product: Mercurial
Classification: Unclassified
Component: Mercurial (show other bugs)
Version: unspecified
Hardware: PC Windows
: critical bug
Assignee: Bugzilla
URL:
Keywords:
: 3823 3862 (view as bug list)
Depends on:
Blocks:
 
Reported: 2013-03-13 09:37 UTC by Angel Ezquerra
Modified: 2014-11-04 14:53 UTC (History)
11 users (show)

See Also:
Python Version: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Angel Ezquerra 2013-03-13 09:37 UTC
I have a repository on drive E:. The repository has some subrepos. I have two heads on default which I want to merge. The repository has several subrepositories, and each of the anonymous branches leading to each of the two heads modifies different repositories.

When I tried to merge both heads using TortoiseHg it failed right after displaying .hgsubstate. Running hg merge from the command line (after going into the repository root) worked. Since TortoiseHg is installed in C:\ Steve Borho suggested trying to run the merge from outside the repository and using --cwd or --repository (as TortoiseHg does internally). This works if I run it from the same drive were the repository is found (i.e. from somewhere on the E: drive). But if I try to run it from the C:\ drive it fails as follows:

C:\Program Files\TortoiseHg>hg --repository E:\SPB_SRC merge
** unknown exception encountered, please report by visiting
** http://mercurial.selenic.com/wiki/BugTracker
** Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)]
** Mercurial Distributed SCM (version 2.5.2+12-fabbaa250977)
** Extensions loaded:
Traceback (most recent call last):
  File "hg", line 42, in <module>
  File "mercurial\dispatch.pyo", line 28, in run
  File "mercurial\dispatch.pyo", line 65, in dispatch
  File "mercurial\dispatch.pyo", line 88, in _runcatch
  File "mercurial\dispatch.pyo", line 746, in _dispatch
  File "mercurial\dispatch.pyo", line 515, in runcommand
  File "mercurial\dispatch.pyo", line 841, in _runcommand
  File "mercurial\dispatch.pyo", line 812, in checkargs
  File "mercurial\dispatch.pyo", line 741, in <lambda>
  File "mercurial\util.pyo", line 500, in check
  File "mercurial\commands.pyo", line 4116, in merge
  File "mercurial\hg.pyo", line 481, in merge
  File "mercurial\merge.pyo", line 704, in update
  File "mercurial\merge.pyo", line 474, in applyupdates
  File "mercurial\merge.pyo", line 67, in resolve
  File "mercurial\merge.pyo", line 57, in __getitem__
KeyError: '.hgsubstate'

Note that hg is run from the C: drive but the repository is on the E:\ drive.

I tried to come up with a small test case for this but I could not make it fail. It seems to happen on this particular repository.
Comment 1 Alexander 2013-03-14 01:02 UTC
Repository has two heads. Each has two subrepo. Tried to merge:

term@fort ~/Projects/arm/workspace/pdh_p_5 $ LANG=C hg merge new_system
** unknown exception encountered, please report by visiting
** http://mercurial.selenic.com/wiki/BugTracker
** Python 2.7.3 (default, Dec 17 2012, 08:19:36) [GCC 4.6.3]
** Mercurial Distributed SCM (version 2.5.2)
** Extensions loaded: extdiff
Traceback (most recent call last):
  File "/usr/bin/hg-python2.7", line 38, in <module>
    mercurial.dispatch.run()
  File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line 28, in run
    sys.exit((dispatch(request(sys.argv[1:])) or 0) & 255)
  File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line 65, in dispatch
    return _runcatch(req)
  File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line 88, in _runcatch
    return _dispatch(req)
  File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line 743, in _dispatch
    cmdpats, cmdoptions)
  File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line 514, in runcommand
    ret = _runcommand(ui, options, cmd, d)
  File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line 833, in _runcommand
    return checkargs()
  File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line 804, in checkargs
    return cmdfunc()
  File "/usr/lib64/python2.7/site-packages/mercurial/dispatch.py", line 740, in <lambda>
    d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
  File "/usr/lib64/python2.7/site-packages/mercurial/util.py", line 475, in check
    return func(*args, **kwargs)
  File "/usr/lib64/python2.7/site-packages/mercurial/commands.py", line 4440, in merge
    return hg.merge(repo, node, force=opts.get('force'))
  File "/usr/lib64/python2.7/site-packages/mercurial/hg.py", line 481, in merge
    stats = mergemod.update(repo, node, True, force, False)
  File "/usr/lib64/python2.7/site-packages/mercurial/merge.py", line 630, in update
    stats = applyupdates(repo, actions, wc, p2, pa, overwrite)
  File "/usr/lib64/python2.7/site-packages/mercurial/merge.py", line 391, in applyupdates
    r = ms.resolve(fd, wctx, mctx)
  File "/usr/lib64/python2.7/site-packages/mercurial/merge.py", line 67, in resolve
    if self[dfile] == 'r':
  File "/usr/lib64/python2.7/site-packages/mercurial/merge.py", line 57, in __getitem__
    return self._state[dfile][0]
KeyError: '.hgsubstate'
Comment 2 Matt Mackall 2013-03-18 16:55 UTC
Alexander, your report seems unrelated to Angel's which depends on using the --repository switch. Please file a new bug.
Comment 3 Matt Mackall 2013-03-18 17:13 UTC
http://www.selenic.com/hg/file/a07be8953733/mercurial/merge.py#l467

467 if m == "m": # merge
468     if fd == '.hgsubstate': # subrepo states need updating
469         subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx),
470                          overwrite)
471         continue
472     f2, fd, move = args
473     audit(fd)
474     r = ms.resolve(fd, wctx, mctx) 

We seem to get to line 474 with fd == '.hgsubstate'.. which shouldn't be possible due to the 'if' at 468.

But you'll notice we overwrite fd at line 472.. so where is fd set? Answer: in the previous loop iteration.

Oops:

http://www.selenic.com/hg/diff/6ba58ab719e5/mercurial/merge.py

Regression, raising to urgent.
Comment 4 Matt Mackall 2013-03-18 17:32 UTC
*** Bug 3823 has been marked as a duplicate of this bug. ***
Comment 5 Kevin Bullock 2013-03-20 11:17 UTC
Fix is in crew: http://hg.intevation.org/mercurial/crew/rev/0705ad73e878
Comment 6 Kevin Bullock 2013-03-20 11:17 UTC
*** Bug 3862 has been marked as a duplicate of this bug. ***
Comment 7 Dmitry Zanozin 2013-04-04 06:06 UTC
Why did you fix this bug in default branch instead of stable?
Do we need to wait for this simple and obvious fix another couple of months?
Comment 8 Kevin Bullock 2013-04-04 11:00 UTC
Sorry, I accidentally queued the patch on the wrong branch. It should've gone into 2.5.3.

I could backport it to stable, but at this point our next major release is less than a month away[1], which means default will be merged to stable -- and a release candidate cut -- in less than two weeks. Unless Matt wants to do an out-of-band bugfix release.

[1]: http://mercurial.selenic.com/wiki/TimeBasedReleasePlan
Comment 9 Matt Mackall 2013-04-04 16:47 UTC
Sigh.

The fact that we've gotten almost all the way through the 2.5 cycle with a bug that makes subrepos unusable is paper-bag-on-head-level embarrassing.

Yes, this is probably the sort of bug fix we don't want to wait a month to get fixed.
Comment 10 HG Bot 2013-04-04 17:30 UTC
Fixed by http://selenic.com/repo/hg/rev/8a7bd2dccd44
Kevin Bullock <kbullock@ringworld.org>
applyupdates: assign variable before we try to use it (issue3855)

The variable 'fd' was getting used with a value left over from a prior
iteration, causing a KeyError: '.hgsubstate'.

(please test the fix)
Comment 11 Siddharth Agarwal 2013-04-19 22:31 UTC
*** Bug 3897 has been marked as a duplicate of this bug. ***