[PATCH 2 of 7 main-line-of-work] transaction: handle missing file in backupentries (instead of using entries)
Pierre-Yves David
pierre-yves.david at ens-lyon.org
Tue Nov 11 11:35:09 CST 2014
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1415151528 0
# Wed Nov 05 01:38:48 2014 +0000
# Node ID 10b65c6db73ef5a94fc4933981a0403d38cb18a0
# Parent 24a121a4798948ed7eaa1bd3a730ad5c165ec4f0
transaction: handle missing file in backupentries (instead of using entries)
The case were a backup of a missing file was requested was previously handled by
the `entries` list. As the `backupentries` is about to gain ability to backup
files outside of `.hg/store`, we want it to be able to handle the missing file
too.
reminder: using `addbackup` on a missing file means that such file needs to be
deleted if we rollback the transaction.
diff --git a/mercurial/transaction.py b/mercurial/transaction.py
--- a/mercurial/transaction.py
+++ b/mercurial/transaction.py
@@ -42,18 +42,25 @@ def _playback(journal, report, opener, e
if inst.errno != errno.ENOENT:
raise
backupfiles = []
for f, b in backupentries:
- filepath = opener.join(f)
- backuppath = opener.join(b)
- try:
- util.copyfile(backuppath, filepath)
- backupfiles.append(b)
- except IOError:
- report(_("failed to recover %s\n") % f)
- raise
+ if b:
+ filepath = opener.join(f)
+ backuppath = opener.join(b)
+ try:
+ util.copyfile(backuppath, filepath)
+ backupfiles.append(b)
+ except IOError:
+ report(_("failed to recover %s\n") % f)
+ raise
+ else:
+ try:
+ opener.unlink(f)
+ except (IOError, OSError), inst:
+ if inst.errno != errno.ENOENT:
+ raise
opener.unlink(journal)
backuppath = "%s.backupfiles" % journal
if opener.exists(backuppath):
opener.unlink(backuppath)
@@ -83,10 +90,11 @@ class transaction(object):
self.onclose = onclose
self.onabort = onabort
self.entries = []
self.map = {}
# a list of ('path', 'backuppath') entries.
+ # if 'backuppath' is empty, no file existed at backup time
self._backupentries = []
self._backupmap = {}
self.journal = journal
self._queue = []
# a dict of arguments to be passed to hooks
@@ -177,12 +185,11 @@ class transaction(object):
if vfs.exists(file):
filepath = vfs.join(file)
backuppath = self.opener.join(backupfile)
util.copyfiles(filepath, backuppath, hardlink=hardlink)
else:
- self.add(file, 0)
- return
+ backupfile = ''
self._backupentries.append((file, backupfile))
self._backupmap[file] = len(self._backupentries) - 1
self._backupsfile.write("%s\0%s\n" % (file, backupfile))
self._backupsfile.flush()
@@ -329,11 +336,12 @@ class transaction(object):
if self.opener.isfile(self.journal):
self.opener.unlink(self.journal)
if self.opener.isfile(self._backupjournal):
self.opener.unlink(self._backupjournal)
for _f, b in self._backupentries:
- self.opener.unlink(b)
+ if b:
+ self.opener.unlink(b)
self._backupentries = []
self.journal = None
# run post close action
categories = sorted(self._postclosecallback)
for cat in categories:
More information about the Mercurial-devel
mailing list