Argh!!!

Phillip Neiswanger sigsegv at prodigy.net
Wed Mar 14 17:13:21 CDT 2007


On Wed, 14 Mar 2007 15:22:29 -0600, Matt Mackall <mpm at selenic.com> wrote:

> On Wed, Mar 14, 2007 at 03:18:49PM -0600, Phillip Neiswanger wrote:
>> All commands that try to make use of the repository no longer work, ie
>
>> prompt> hg verify
> ...
>>     self.manifest = manifest.manifest(self.sopener, v)
> ...
>>     e = struct.unpack(self.indexformat, cur)
>
> Somehow you've corrupted your manifest index. Not sure how you managed
> that precisely, running commands as root shouldn't cause that.
>
> But because Mercurial is append-only, the corruption is very likely at
> the very end of the index. To fix it, all you need to do is truncate
> it back to a working revision.
>
> So start with:
>
> $ ls -l .hg/store/
> total 2280
> -rw-r--r-- 1 username username  779981 Mar 14 15:48 00changelog.d
> -rw-r--r-- 1 username username  254976 Mar 14 15:48 00changelog.i
> -rw-r--r-- 1 username username 1012185 Mar 14 15:48 00manifest.d
> -rw-r--r-- 1 username username  254976 Mar 14 15:48 00manifest.i
> drwxr-xr-x 8 username username    4096 Feb  6 16:09 data/
>
> The size of each index entry is 64 bytes:
>
> $ python
> Python 2.4.4 (#2, Jan 13 2007, 17:50:26)
> [GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>>>> 254976/64.0
> 3984.0
>
> To truncate it back to manifest revision 3980, do something like:
>>>> 3980 * 64
> 254720
>
> $ cp manifest.i manifest.i.orig
> $ dd if=manifest.i.orig of=manifest.i bs=1 count=254720
>
> Then it should be readable.
>
> If you've got changelog entries that point to truncated manifest
> entries, you'll obviously have trouble pulling or checking out those
> versions, but you should be able to clone -r <last full version>.

So here's what I've tried.

prompt> cd project/.hg/store
prompt> ls -l
total 80
-rw-r--r--   1 pgn  user  31773 Mar 13 21:33 00changelog.i
-rw-r--r--   1 pgn  user  44799 Mar 13 21:33 00manifest.i
drwxr-xr-x  10 pgn  user    512 Feb 23 00:56 data
-rw-r--r--   1 pgn  user     80 Mar 13 21:33 undo

prompt> python
Python 2.4.3 (#2, Nov  8 2006, 23:56:15)
[GCC 3.4.6 [FreeBSD] 20060305] on freebsd6
Type "help", "copyright", "credits" or "license" for more information.
>>> 44799/64.0
699.984375
>>> 699*64.0
44736.0

prompt> cp 00manifest.i 00manifest.i.orig
prompt> dd if=00manifest.i.orig of=00manifest.i bs=1 count=44736
44736+0 records in
44736+0 records out
44736 bytes transferred in 0.396996 secs (112686 bytes/sec)

In another terminal:
prompt> cd project
prompt> hg status
** unknown exception encountered, details follow
** report bug details to http://www.selenic.com/mercurial/bts
** or mercurial at selenic.com
** Mercurial Distributed SCM (version 0.9.3)
Traceback (most recent call last):
   File "/usr/local/bin/hg", line 12, in ?
     commands.run()
   File "/usr/local/lib/python2.4/site-packages/mercurial/commands.py",  
line 3000, in run
     sys.exit(dispatch(sys.argv[1:]))
   File "/usr/local/lib/python2.4/site-packages/mercurial/commands.py",  
line 3172, in dispatch
     repo = hg.repository(u, path=path)
   File "/usr/local/lib/python2.4/site-packages/mercurial/hg.py", line 56,  
in repository
     repo = _lookup(path).instance(ui, path, create)
   File "/usr/local/lib/python2.4/site-packages/mercurial/localrepo.py",  
line 1968, in instance
     return localrepository(ui, util.drop_scheme('file', path), create)
   File "/usr/local/lib/python2.4/site-packages/mercurial/localrepo.py",  
line 103, in __init__
     self.manifest = manifest.manifest(self.sopener, v)
   File "/usr/local/lib/python2.4/site-packages/mercurial/manifest.py",  
line 44, in __init__
     defversion)
   File "/usr/local/lib/python2.4/site-packages/mercurial/revlog.py", line  
327, in __init__
     self.load()
   File "/usr/local/lib/python2.4/site-packages/mercurial/revlog.py", line  
383, in load
     self.parseindex(f, st)
   File "/usr/local/lib/python2.4/site-packages/mercurial/revlog.py", line  
423, in parseindex
     e = struct.unpack(self.indexformat, cur)
struct.error: unpack str size does not match format

I then realize I've only commited around 120 times.  I can't remember  
exactly how many at this point.  120*64 = 8000 so...

Terminal #1
prompt> dd if=00manifest.i.orig of=00manifest.i bs=1 count=8000
8000+0 records in
8000+0 records out
8000 bytes transferred in 0.066301 secs (120662 bytes/sec)

Terminal #2
prompt> hg status
prompt> hg log
abort: 00manifest.i: no node a7471e18e63f915c4ff4b1931778e945d9b5a6cd!



Definitely have had 100 commits so...

Terminal #1
prompt> dd if=00manifest.i.orig of=00manifest.i bs=1 count=6400
8000+0 records in
8000+0 records out
8000 bytes transferred in 0.066301 secs (120662 bytes/sec)

Terminal #2
prompt> hg status
prompt> hg log
abort: 00manifest.i: no node a7471e18e63f915c4ff4b1931778e945d9b5a6cd!

A hex dump of the 00manifest.i.orig file reveals mostly random data with  
the occational file name in it.
--
phil



More information about the Mercurial mailing list