Bug 4547 - Mercirual crashes on repo update with largefiles extension
Summary: Mercirual crashes on repo update with largefiles extension
Status: VERIFIED FIXED
Alias: None
Product: Mercurial
Classification: Unclassified
Component: largefiles (show other bugs)
Version: 3.3
Hardware: PC Windows
: urgent bug
Assignee: Bugzilla
URL:
Keywords: regression
Depends on:
Blocks:
 
Reported: 2015-02-20 08:58 UTC by Artur Matuszewski
Modified: 2015-03-18 05:35 UTC (History)
6 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 Artur Matuszewski 2015-02-20 08:58 UTC
Hi, after installing Mercurial 3.3 one of our repositories using largefiles extension started crashing trying to update to different revisions.


Trace from using TortoiseHG Workbench:
% hg update --rev default --clean
** unknown exception encountered, please report by visiting
** http://mercurial.selenic.com/wiki/BugTracker
** Python 2.7.6 (default, Nov 10 2013, 19:24:24) [MSC v.1500 64 bit (AMD64)]
** Mercurial Distributed SCM (version 3.3)
** Extensions loaded: largefiles, tortoisehg.util.hgcommands, tortoisehg.util.partialcommit, tortoisehg.util.pipeui, tortoisehg.util.win32ill, tortoisehg.util.hgdispatch
Traceback (most recent call last):
  File "hg", line 42, in <module>
  File "mercurial\dispatch.pyo", line 28, in run
  File "mercurial\dispatch.pyo", line 71, in dispatch
  File "mercurial\dispatch.pyo", line 140, in _runcatch
  File "mercurial\dispatch.pyo", line 860, in _dispatch
  File "mercurial\dispatch.pyo", line 621, in runcommand
  File "mercurial\dispatch.pyo", line 951, in _runcommand
  File "mercurial\dispatch.pyo", line 922, in checkargs
  File "mercurial\dispatch.pyo", line 857, in <lambda>
  File "mercurial\util.pyo", line 711, in check
  File "mercurial\commands.pyo", line 5538, in serve
  File "mercurial\cmdutil.pyo", line 592, in service
  File "mercurial\commandserver.pyo", line 289, in run
  File "mercurial\commandserver.pyo", line 242, in serve
  File "mercurial\commandserver.pyo", line 220, in serveone
  File "mercurial\commandserver.pyo", line 203, in runcommand
  File "mercurial\dispatch.pyo", line 71, in dispatch
  File "mercurial\dispatch.pyo", line 140, in _runcatch
  File "mercurial\extensions.pyo", line 194, in wrap
  File "tortoisehg\util\hgdispatch.pyo", line 23, in _dispatch
  File "mercurial\dispatch.pyo", line 860, in _dispatch
  File "mercurial\dispatch.pyo", line 621, in runcommand
  File "mercurial\dispatch.pyo", line 951, in _runcommand
  File "mercurial\dispatch.pyo", line 922, in checkargs
  File "mercurial\dispatch.pyo", line 857, in <lambda>
  File "mercurial\util.pyo", line 711, in check
  File "mercurial\extensions.pyo", line 149, in wrap
  File "mercurial\util.pyo", line 711, in check
  File "hgext\largefiles\overrides.pyo", line 408, in overrideupdate
  File "mercurial\util.pyo", line 711, in check
  File "mercurial\commands.pyo", line 6262, in update
  File "mercurial\hg.pyo", line 521, in clean
  File "mercurial\hg.pyo", line 506, in updaterepo
  File "mercurial\extensions.pyo", line 194, in wrap
  File "hgext\largefiles\overrides.pyo", line 1324, in mergeupdate
  File "mercurial\merge.pyo", line 1142, in update
  File "mercurial\merge.pyo", line 772, in applyupdates
  File "mercurial\subrepo.pyo", line 186, in submerge
  File "mercurial\subrepo.pyo", line 46, in decoratedmethod
  File "mercurial\subrepo.pyo", line 768, in get
  File "mercurial\hg.pyo", line 506, in updaterepo
  File "mercurial\extensions.pyo", line 194, in wrap
  File "hgext\largefiles\overrides.pyo", line 1324, in mergeupdate
  File "mercurial\merge.pyo", line 1142, in update
  File "mercurial\merge.pyo", line 772, in applyupdates
  File "mercurial\subrepo.pyo", line 186, in submerge
  File "mercurial\subrepo.pyo", line 46, in decoratedmethod
  File "mercurial\subrepo.pyo", line 768, in get
  File "mercurial\hg.pyo", line 506, in updaterepo
  File "mercurial\extensions.pyo", line 194, in wrap
  File "hgext\largefiles\overrides.pyo", line 1324, in mergeupdate
  File "mercurial\merge.pyo", line 1142, in update
  File "mercurial\merge.pyo", line 753, in applyupdates
  File "mercurial\subrepo.pyo", line 222, in submerge
  File "mercurial\subrepo.pyo", line 46, in decoratedmethod
  File "mercurial\subrepo.pyo", line 724, in remove
  File "mercurial\hg.pyo", line 521, in clean
  File "mercurial\hg.pyo", line 506, in updaterepo
  File "mercurial\extensions.pyo", line 194, in wrap
  File "hgext\largefiles\overrides.pyo", line 1332, in mergeupdate
  File "hgext\largefiles\lfcommands.pyo", line 446, in updatelfiles
  File "hgext\largefiles\lfutil.pyo", line 581, in getstatuswriter
  File "mercurial\repoview.pyo", line 310, in __getattr__
AttributeError: 'localrepository' object has no attribute '_lfstatuswriters'
** unknown exception encountered, please report by visiting
** http://mercurial.selenic.com/wiki/BugTracker
** Python 2.7.6 (default, Nov 10 2013, 19:24:24) [MSC v.1500 64 bit (AMD64)]
** Mercurial Distributed SCM (version 3.3)
** Extensions loaded: largefiles, tortoisehg.util.hgcommands, tortoisehg.util.partialcommit, tortoisehg.util.pipeui, tortoisehg.util.win32ill, tortoisehg.util.hgdispatch
cmdserver: process exited unexpectedly with code 255


The same happens when not using TortoiseHG Workbench:
hg update --rev default --clean
** unknown exception encountered, please report by visiting
** http://mercurial.selenic.com/wiki/BugTracker
** Python 2.7.6 (default, Nov 10 2013, 19:24:24) [MSC v.1500 64 bit (AMD64)]
** Mercurial Distributed SCM (version 3.3)
** Extensions loaded: largefiles
Traceback (most recent call last):
  File "hg", line 42, in <module>
  File "mercurial\dispatch.pyo", line 28, in run
  File "mercurial\dispatch.pyo", line 71, in dispatch
  File "mercurial\dispatch.pyo", line 140, in _runcatch
  File "mercurial\dispatch.pyo", line 860, in _dispatch
  File "mercurial\dispatch.pyo", line 621, in runcommand
  File "mercurial\dispatch.pyo", line 951, in _runcommand
  File "mercurial\dispatch.pyo", line 922, in checkargs
  File "mercurial\dispatch.pyo", line 857, in <lambda>
  File "mercurial\util.pyo", line 711, in check
  File "mercurial\extensions.pyo", line 149, in wrap
  File "mercurial\util.pyo", line 711, in check
  File "hgext\largefiles\overrides.pyo", line 408, in overrideupdate
  File "mercurial\util.pyo", line 711, in check
  File "mercurial\commands.pyo", line 6262, in update
  File "mercurial\hg.pyo", line 521, in clean
  File "mercurial\hg.pyo", line 506, in updaterepo
  File "mercurial\extensions.pyo", line 194, in wrap
  File "hgext\largefiles\overrides.pyo", line 1324, in mergeupdate
  File "mercurial\merge.pyo", line 1142, in update
  File "mercurial\merge.pyo", line 772, in applyupdates
  File "mercurial\subrepo.pyo", line 186, in submerge
  File "mercurial\subrepo.pyo", line 46, in decoratedmethod
  File "mercurial\subrepo.pyo", line 768, in get
  File "mercurial\hg.pyo", line 506, in updaterepo
  File "mercurial\extensions.pyo", line 194, in wrap
  File "hgext\largefiles\overrides.pyo", line 1324, in mergeupdate
  File "mercurial\merge.pyo", line 1142, in update
  File "mercurial\merge.pyo", line 772, in applyupdates
  File "mercurial\subrepo.pyo", line 186, in submerge
  File "mercurial\subrepo.pyo", line 46, in decoratedmethod
  File "mercurial\subrepo.pyo", line 768, in get
  File "mercurial\hg.pyo", line 506, in updaterepo
  File "mercurial\extensions.pyo", line 194, in wrap
  File "hgext\largefiles\overrides.pyo", line 1324, in mergeupdate
  File "mercurial\merge.pyo", line 1142, in update
  File "mercurial\merge.pyo", line 753, in applyupdates
  File "mercurial\subrepo.pyo", line 222, in submerge
  File "mercurial\subrepo.pyo", line 46, in decoratedmethod
  File "mercurial\subrepo.pyo", line 724, in remove
  File "mercurial\hg.pyo", line 521, in clean
  File "mercurial\hg.pyo", line 506, in updaterepo
  File "mercurial\extensions.pyo", line 194, in wrap
  File "hgext\largefiles\overrides.pyo", line 1332, in mergeupdate
  File "hgext\largefiles\lfcommands.pyo", line 446, in updatelfiles
  File "hgext\largefiles\lfutil.pyo", line 581, in getstatuswriter
  File "mercurial\repoview.pyo", line 310, in __getattr__
AttributeError: 'localrepository' object has no attribute '_lfstatuswriters'


I have created and used the local clone of the repository before, with an earlier version of Mercurial.


The repository has the following structure (sizes include working directories):
Repo Root (total 15GB)
+- Subrepo1 (2GB)
+---Sub-subrepo1 (1.4 GB)
+----Sub-sub-subrepo1 (24 MB)
+---Sub-subrepo2 (720 MB)
+- Subrepo2 (13 GB) (This Subrepo has .hglf)
+- Subrepo3 (1 MB)
+- Subrepo4 (9 MB)
+- Subrepo5 (22 MB)

The extension is enabled on the Repo Root repository. That is the only extension used.
I have a fresh Windows 7 SP1 install and a fresh Mercurial 3.3 install.
Comment 1 Artur Matuszewski 2015-02-20 09:01 UTC
It's known to work on Mercurial 3.1. I'll try to check against 3.2.
Comment 2 Artur Matuszewski 2015-02-20 09:30 UTC
The same local clone of the repository works fine with Mercurial 3.2. So it's a regression in 3.3.
Comment 3 kiilerix 2015-02-20 10:29 UTC
The problem is that reposetup not is called correctly. Can you reproduce with a pure command line hg call?

We had the same symptom in Kallithea where I am sure it is our own fault. We worked around it with https://kallithea-scm.org/repos/kallithea/changeset/4aa02271dc1349d54bdc908f46d89fc9db179116
Comment 4 Artur Matuszewski 2015-02-20 10:49 UTC
What do you mean pure command line hg call?
I have the same problem both running under TortoiseHG Workbench and under Windows command line (pasted both logs in the original message).

We tried a fresh clone too, which worked. So if you clone a fresh clone of the repository using Mercurial 3.3 from remote, it will work. But if you created the repository with an earlier version of Mercurial, and then upgrade and try to work with it under Mercurial 3.3, it will not. Which is still a problem, arguably a smaller one.

As far as I can tell my local clone of the repository is not corrupted (works fine with Mercurial 3.2).
Comment 5 FUJIWARA Katsunori 2015-02-20 11:02 UTC
I think that not-enabling largefiles in one of subrepositories
causes this problem. Probably, I overlooked this case at working
for 94ac64bcf6fe :-<

I'll examine more deeply, soon.
Comment 6 Danylo Hlynskyi 2015-02-21 06:16 UTC
One may be interested to this comment http://bz.selenic.com/show_bug.cgi?id=4548#c2
There is same crash with `hg clone`
Comment 7 HG Bot 2015-03-02 02:00 UTC
Fixed by http://selenic.com/repo/hg/rev/d414c28db84d
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
largefiles: access to specific fields only if largefiles enabled (issue4547)

Even if largefiles extension is enabled in a repository, "repo"
object, which isn't "largefiles.reposetup()"-ed, is passed to
overridden functions in the cases below unexpectedly, because
extensions are enabled for each repositories strictly.

  (1) clone without -U:
  (2) pull with -U:
  (3) pull with --rebase:

    combination of "enabled@src", "disabled@dst" and
    "not-required@src" cause this situation.

       largefiles     requirement
    @src     @dst     @src            result
    -------- -------- --------------- --------------------
    enabled  disabled not-required    aborted unexpectedly
                      required        requirement error (intentional)
    -------- -------- --------------- --------------------
    enabled  enabled  *               success
    -------- -------- --------------- --------------------
    disabled enabled  *               success (only for "pull")
    -------- -------- --------------- --------------------
    disabled disabled not-required    success
                      required        requirement error (intentional)
    -------- -------- --------------- --------------------

  (4) update/revert with a subrepo disabling largefiles

In these cases, overridden functions cause accessing to largefiles
specific fields of not "largefiles.reposetup()"-ed "repo" object, and
execution is aborted.

  - (1), (2), (4) cause accessing to "_lfstatuswriters" in
    "getstatuswriter()" invoked via "updatelfiles()"

  - (3) causes accessing to "_lfcommithooks" in "overriderebase()"

For safe accessing to these fields, this patch examines whether passed
"repo" object is "largefiles.reposetup()"-ed or not before accessing
to them.

This patch chooses examining existence of newly introduced
"_largefilesenabled" instead of "_lfcommithooks" and
"_lfstatuswriters" directly, because the former is better name for the
generic "largefiles is enabled in this repo" mark than the latter.

In the future, all other overridden functions should avoid largefiles
specific processing for efficiency, and "_largefilesenabled" is better
also for such purpose.

BTW, "lfstatus" can't be used for such purpose, because some code
paths set it forcibly regardless of existence of it in specified
"repo" object.

(please test the fix)
Comment 8 Bugzilla 2015-03-10 01:00 UTC
Bug was set to TESTING for 7 days, resolving
Comment 9 Artur Matuszewski 2015-03-18 05:35 UTC
As far as I can tell it has fixed the issues I was seeing.
Thanks a lot for the fix!