3230 if self._format_version == REVLOGV0: |
3231 if self._format_version == REVLOGV0: |
3231 raise error.RevlogError( |
3232 raise error.RevlogError( |
3232 _(b'cannot censor with version %d revlogs') |
3233 _(b'cannot censor with version %d revlogs') |
3233 % self._format_version |
3234 % self._format_version |
3234 ) |
3235 ) |
3235 |
3236 elif self._format_version == REVLOGV1: |
3236 censorrev = self.rev(censornode) |
3237 censor.v1_censor(self, tr, censornode, tombstone) |
3237 tombstone = storageutil.packmeta({b'censored': tombstone}, b'') |
3238 else: |
3238 |
3239 # revlog v2 |
3239 if len(tombstone) > self.rawsize(censorrev): |
3240 raise error.RevlogError( |
3240 raise error.Abort( |
3241 _(b'cannot censor with version %d revlogs') |
3241 _(b'censor tombstone must be no longer than censored data') |
3242 % self._format_version |
3242 ) |
3243 ) |
3243 |
|
3244 # Rewriting the revlog in place is hard. Our strategy for censoring is |
|
3245 # to create a new revlog, copy all revisions to it, then replace the |
|
3246 # revlogs on transaction close. |
|
3247 # |
|
3248 # This is a bit dangerous. We could easily have a mismatch of state. |
|
3249 newrl = revlog( |
|
3250 self.opener, |
|
3251 target=self.target, |
|
3252 radix=self.radix, |
|
3253 postfix=b'tmpcensored', |
|
3254 censorable=True, |
|
3255 ) |
|
3256 newrl._format_version = self._format_version |
|
3257 newrl._format_flags = self._format_flags |
|
3258 newrl._generaldelta = self._generaldelta |
|
3259 newrl._parse_index = self._parse_index |
|
3260 |
|
3261 for rev in self.revs(): |
|
3262 node = self.node(rev) |
|
3263 p1, p2 = self.parents(node) |
|
3264 |
|
3265 if rev == censorrev: |
|
3266 newrl.addrawrevision( |
|
3267 tombstone, |
|
3268 tr, |
|
3269 self.linkrev(censorrev), |
|
3270 p1, |
|
3271 p2, |
|
3272 censornode, |
|
3273 REVIDX_ISCENSORED, |
|
3274 ) |
|
3275 |
|
3276 if newrl.deltaparent(rev) != nullrev: |
|
3277 raise error.Abort( |
|
3278 _( |
|
3279 b'censored revision stored as delta; ' |
|
3280 b'cannot censor' |
|
3281 ), |
|
3282 hint=_( |
|
3283 b'censoring of revlogs is not ' |
|
3284 b'fully implemented; please report ' |
|
3285 b'this bug' |
|
3286 ), |
|
3287 ) |
|
3288 continue |
|
3289 |
|
3290 if self.iscensored(rev): |
|
3291 if self.deltaparent(rev) != nullrev: |
|
3292 raise error.Abort( |
|
3293 _( |
|
3294 b'cannot censor due to censored ' |
|
3295 b'revision having delta stored' |
|
3296 ) |
|
3297 ) |
|
3298 rawtext = self._chunk(rev) |
|
3299 else: |
|
3300 rawtext = self.rawdata(rev) |
|
3301 |
|
3302 newrl.addrawrevision( |
|
3303 rawtext, tr, self.linkrev(rev), p1, p2, node, self.flags(rev) |
|
3304 ) |
|
3305 |
|
3306 tr.addbackup(self._indexfile, location=b'store') |
|
3307 if not self._inline: |
|
3308 tr.addbackup(self._datafile, location=b'store') |
|
3309 |
|
3310 self.opener.rename(newrl._indexfile, self._indexfile) |
|
3311 if not self._inline: |
|
3312 self.opener.rename(newrl._datafile, self._datafile) |
|
3313 |
|
3314 self.clearcaches() |
|
3315 self._loadindex() |
|
3316 |
3244 |
3317 def verifyintegrity(self, state): |
3245 def verifyintegrity(self, state): |
3318 """Verifies the integrity of the revlog. |
3246 """Verifies the integrity of the revlog. |
3319 |
3247 |
3320 Yields ``revlogproblem`` instances describing problems that are |
3248 Yields ``revlogproblem`` instances describing problems that are |