Show More
@@ -3259,3 +3259,59 b' def clearunfinished(repo):' | |||
|
3259 | 3259 | for f, clearable, allowcommit, msg, hint in unfinishedstates: |
|
3260 | 3260 | if clearable and repo.vfs.exists(f): |
|
3261 | 3261 | util.unlink(repo.join(f)) |
|
3262 | ||
|
3263 | class dirstateguard(object): | |
|
3264 | '''Restore dirstate at unexpected failure. | |
|
3265 | ||
|
3266 | At the construction, this class does: | |
|
3267 | ||
|
3268 | - write current ``repo.dirstate`` out, and | |
|
3269 | - save ``.hg/dirstate`` into the backup file | |
|
3270 | ||
|
3271 | This restores ``.hg/dirstate`` from backup file, if ``release()`` | |
|
3272 | is invoked before ``close()``. | |
|
3273 | ||
|
3274 | This just removes the backup file at ``close()`` before ``release()``. | |
|
3275 | ''' | |
|
3276 | ||
|
3277 | def __init__(self, repo, name): | |
|
3278 | repo.dirstate.write() | |
|
3279 | self._repo = repo | |
|
3280 | self._filename = 'dirstate.backup.%s.%d' % (name, id(self)) | |
|
3281 | repo.vfs.write(self._filename, repo.vfs.tryread('dirstate')) | |
|
3282 | self._active = True | |
|
3283 | self._closed = False | |
|
3284 | ||
|
3285 | def __del__(self): | |
|
3286 | if self._active: # still active | |
|
3287 | # this may occur, even if this class is used correctly: | |
|
3288 | # for example, releasing other resources like transaction | |
|
3289 | # may raise exception before ``dirstateguard.release`` in | |
|
3290 | # ``release(tr, ....)``. | |
|
3291 | self._abort() | |
|
3292 | ||
|
3293 | def close(self): | |
|
3294 | if not self._active: # already inactivated | |
|
3295 | msg = (_("can't close already inactivated backup: %s") | |
|
3296 | % self._filename) | |
|
3297 | raise util.Abort(msg) | |
|
3298 | ||
|
3299 | self._repo.vfs.unlink(self._filename) | |
|
3300 | self._active = False | |
|
3301 | self._closed = True | |
|
3302 | ||
|
3303 | def _abort(self): | |
|
3304 | # this "invalidate()" prevents "wlock.release()" from writing | |
|
3305 | # changes of dirstate out after restoring to original status | |
|
3306 | self._repo.dirstate.invalidate() | |
|
3307 | ||
|
3308 | self._repo.vfs.rename(self._filename, 'dirstate') | |
|
3309 | self._active = False | |
|
3310 | ||
|
3311 | def release(self): | |
|
3312 | if not self._closed: | |
|
3313 | if not self._active: # already inactivated | |
|
3314 | msg = (_("can't release already inactivated backup: %s") | |
|
3315 | % self._filename) | |
|
3316 | raise util.Abort(msg) | |
|
3317 | self._abort() |
General Comments 0
You need to be logged in to leave comments.
Login now