##// END OF EJS Templates
strip: make repair.strip transactional to avoid repository corruption...
Henrik Stuart -
r8073:e8a28556 default
parent child Browse files
Show More
@@ -0,0 +1,36 b''
1 #!/bin/sh
2
3 echo "[extensions]" >> $HGRCPATH
4 echo "mq=">> $HGRCPATH
5
6 teststrip() {
7 hg -q up -C $1
8 echo % before update $1, strip $2
9 hg parents
10 chmod -$3 $4
11 hg strip $2 2>&1 | sed 's/\(saving bundle to \).*/\1/' | sed 's/Permission denied.*\.hg\/store\/\(.*\)/Permission denied \.hg\/store\/\1/'
12 echo % after update $1, strip $2
13 chmod +$3 $4
14 hg verify
15 echo % journal contents
16 cat .hg/store/journal | sed 's/\.i[^\n]*/\.i/'
17 ls .hg/store/journal >/dev/null 2>&1 && hg recover
18 ls .hg/strip-backup/* >/dev/null 2>&1 && hg unbundle -q .hg/strip-backup/*
19 rm -rf .hg/strip-backup
20 }
21
22 hg init test
23 cd test
24
25 echo a > a
26 hg -q ci -m "a" -A
27
28 echo b > b
29 hg -q ci -m "b" -A
30
31 echo c > c
32 hg -q ci -m "c" -A
33
34 teststrip 0 1 w .hg/store/data/b.i
35 teststrip 0 1 r .hg/store/data/b.i
36 teststrip 0 1 w .hg/store/00changelog.i
@@ -0,0 +1,83 b''
1 % before update 0, strip 1
2 changeset: 0:cb9a9f314b8b
3 user: test
4 date: Thu Jan 01 00:00:00 1970 +0000
5 summary: a
6
7 saving bundle to
8 transaction abort!
9 failed to truncate data/b.i
10 rollback failed - please run hg recover
11 abort: Permission denied .hg/store/data/b.i
12 % after update 0, strip 1
13 checking changesets
14 checking manifests
15 crosschecking files in changesets and manifests
16 checking files
17 warning: orphan revlog 'data/b.i'
18 1 files, 1 changesets, 1 total revisions
19 1 warnings encountered!
20 % journal contents
21 00changelog.i
22 00manifest.i
23 data/b.i
24 data/c.i
25 rolling back interrupted transaction
26 checking changesets
27 checking manifests
28 crosschecking files in changesets and manifests
29 checking files
30 1 files, 1 changesets, 1 total revisions
31 % before update 0, strip 1
32 changeset: 0:cb9a9f314b8b
33 user: test
34 date: Thu Jan 01 00:00:00 1970 +0000
35 summary: a
36
37 abort: Permission denied .hg/store/data/b.i
38 % after update 0, strip 1
39 checking changesets
40 checking manifests
41 crosschecking files in changesets and manifests
42 checking files
43 3 files, 3 changesets, 3 total revisions
44 % journal contents
45 cat: .hg/store/journal: No such file or directory
46 % before update 0, strip 1
47 changeset: 0:cb9a9f314b8b
48 user: test
49 date: Thu Jan 01 00:00:00 1970 +0000
50 summary: a
51
52 saving bundle to
53 transaction abort!
54 failed to truncate 00changelog.i
55 rollback failed - please run hg recover
56 abort: Permission denied .hg/store/00changelog.i
57 % after update 0, strip 1
58 checking changesets
59 checking manifests
60 crosschecking files in changesets and manifests
61 1: changeset refers to unknown manifest a539ce0c1a22
62 2: changeset refers to unknown manifest e3738bf54399
63 b@1: in changeset but not in manifest
64 c@2: in changeset but not in manifest
65 checking files
66 data/b.i@1: missing revlog!
67 0: empty or missing b
68 data/c.i@2: missing revlog!
69 0: empty or missing c
70 3 files, 3 changesets, 1 total revisions
71 8 integrity errors encountered!
72 (first damaged changeset appears to be 0)
73 % journal contents
74 00changelog.i
75 00manifest.i
76 data/b.i
77 data/c.i
78 rolling back interrupted transaction
79 checking changesets
80 checking manifests
81 crosschecking files in changesets and manifests
82 checking files
83 1 files, 1 changesets, 1 total revisions
@@ -118,11 +118,25 b' def strip(ui, repo, node, backup="all"):'
118 chgrpfile = _bundle(repo, savebases, saveheads, node, 'temp',
118 chgrpfile = _bundle(repo, savebases, saveheads, node, 'temp',
119 extranodes)
119 extranodes)
120
120
121 cl.strip(striprev)
121 fs = [repo.file(name) for name in files]
122 repo.manifest.strip(striprev)
122 mfst = repo.manifest
123 for name in files:
123
124 f = repo.file(name)
124 tr = repo.transaction()
125 f.strip(striprev)
125 offset = len(tr.entries)
126
127 cl.strip(striprev, tr)
128 mfst.strip(striprev, tr)
129 for f in fs:
130 f.strip(striprev, tr)
131
132 try:
133 for i in xrange(offset, len(tr.entries)):
134 file, troffset, ignore = tr.entries[i]
135 repo.sopener(file, 'a').truncate(troffset)
136 tr.close()
137 except:
138 tr.abort()
139 raise
126
140
127 if saveheads or extranodes:
141 if saveheads or extranodes:
128 ui.status(_("adding branch\n"))
142 ui.status(_("adding branch\n"))
@@ -1285,7 +1285,7 b' class revlog(object):'
1285
1285
1286 return node
1286 return node
1287
1287
1288 def strip(self, minlink):
1288 def strip(self, minlink, transaction):
1289 """truncate the revlog on the first revision with a linkrev >= minlink
1289 """truncate the revlog on the first revision with a linkrev >= minlink
1290
1290
1291 This function is called when we're stripping revision minlink and
1291 This function is called when we're stripping revision minlink and
@@ -1314,14 +1314,12 b' class revlog(object):'
1314 # first truncate the files on disk
1314 # first truncate the files on disk
1315 end = self.start(rev)
1315 end = self.start(rev)
1316 if not self._inline:
1316 if not self._inline:
1317 df = self.opener(self.datafile, "a")
1317 transaction.add(self.datafile, end)
1318 df.truncate(end)
1319 end = rev * self._io.size
1318 end = rev * self._io.size
1320 else:
1319 else:
1321 end += rev * self._io.size
1320 end += rev * self._io.size
1322
1321
1323 indexf = self.opener(self.indexfile, "a")
1322 transaction.add(self.indexfile, end)
1324 indexf.truncate(end)
1325
1323
1326 # then reset internal state in memory to forget those revisions
1324 # then reset internal state in memory to forget those revisions
1327 self._cache = None
1325 self._cache = None
General Comments 0
You need to be logged in to leave comments. Login now