Argh!!!
Phillip Neiswanger
sigsegv at prodigy.net
Wed Mar 14 22:13:21 UTC 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