comparison mercurial/transaction.py @ 23249:84720eab4fbd

transaction: mark backup-related attributes private As the transaction is gaining more functions and attributes, it is important to clarify what is part of the public API.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Wed, 05 Nov 2014 09:31:57 +0000
parents e754b62373ad
children 8919dc7f2dbb
comparison
equal deleted inserted replaced
23248:e754b62373ad 23249:84720eab4fbd
81 self.opener = opener 81 self.opener = opener
82 self.after = after 82 self.after = after
83 self.onclose = onclose 83 self.onclose = onclose
84 self.onabort = onabort 84 self.onabort = onabort
85 self.entries = [] 85 self.entries = []
86 self.map = {}
86 # a list of ('path', 'backuppath') entries. 87 # a list of ('path', 'backuppath') entries.
87 self.backupentries = [] 88 self._backupentries = []
88 self.map = {} 89 self._backupmap = {}
89 self.backupmap = {}
90 self.journal = journal 90 self.journal = journal
91 self._queue = [] 91 self._queue = []
92 # a dict of arguments to be passed to hooks 92 # a dict of arguments to be passed to hooks
93 self.hookargs = {} 93 self.hookargs = {}
94 94
95 self.backupjournal = "%s.backupfiles" % journal 95 self._backupjournal = "%s.backupfiles" % journal
96 self.file = opener.open(self.journal, "w") 96 self.file = opener.open(self.journal, "w")
97 self.backupsfile = opener.open(self.backupjournal, 'w') 97 self._backupsfile = opener.open(self._backupjournal, 'w')
98 self.backupsfile.write('%d\n' % version) 98 self._backupsfile.write('%d\n' % version)
99 if createmode is not None: 99 if createmode is not None:
100 opener.chmod(self.journal, createmode & 0666) 100 opener.chmod(self.journal, createmode & 0666)
101 opener.chmod(self.backupjournal, createmode & 0666) 101 opener.chmod(self._backupjournal, createmode & 0666)
102 102
103 # hold file generations to be performed on commit 103 # hold file generations to be performed on commit
104 self._filegenerators = {} 104 self._filegenerators = {}
105 # hold callbalk to write pending data for hooks 105 # hold callbalk to write pending data for hooks
106 self._pendingcallback = {} 106 self._pendingcallback = {}
121 121
122 @active 122 @active
123 def endgroup(self): 123 def endgroup(self):
124 q = self._queue.pop() 124 q = self._queue.pop()
125 self.entries.extend(q[0]) 125 self.entries.extend(q[0])
126 self.backupentries.extend(q[1]) 126 self._backupentries.extend(q[1])
127 127
128 offsets = [] 128 offsets = []
129 backups = [] 129 backups = []
130 for f, o, _data in q[0]: 130 for f, o, _data in q[0]:
131 offsets.append((f, o)) 131 offsets.append((f, o))
136 d = ''.join(['%s\0%d\n' % (f, o) for f, o in offsets]) 136 d = ''.join(['%s\0%d\n' % (f, o) for f, o in offsets])
137 self.file.write(d) 137 self.file.write(d)
138 self.file.flush() 138 self.file.flush()
139 139
140 d = ''.join(['%s\0%s\n' % (f, b) for f, b in backups]) 140 d = ''.join(['%s\0%s\n' % (f, b) for f, b in backups])
141 self.backupsfile.write(d) 141 self._backupsfile.write(d)
142 self.backupsfile.flush() 142 self._backupsfile.flush()
143 143
144 @active 144 @active
145 def add(self, file, offset, data=None): 145 def add(self, file, offset, data=None):
146 if file in self.map or file in self.backupmap: 146 if file in self.map or file in self._backupmap:
147 return 147 return
148 if self._queue: 148 if self._queue:
149 self._queue[-1][0].append((file, offset, data)) 149 self._queue[-1][0].append((file, offset, data))
150 return 150 return
151 151
165 165
166 * `file`: the file path, relative to .hg/store 166 * `file`: the file path, relative to .hg/store
167 * `hardlink`: use a hardlink to quickly create the backup 167 * `hardlink`: use a hardlink to quickly create the backup
168 """ 168 """
169 169
170 if file in self.map or file in self.backupmap: 170 if file in self.map or file in self._backupmap:
171 return 171 return
172 backupfile = "%s.backup.%s" % (self.journal, file) 172 backupfile = "%s.backup.%s" % (self.journal, file)
173 if vfs is None: 173 if vfs is None:
174 vfs = self.opener 174 vfs = self.opener
175 if vfs.exists(file): 175 if vfs.exists(file):
182 182
183 if self._queue: 183 if self._queue:
184 self._queue[-1][1].append((file, backupfile)) 184 self._queue[-1][1].append((file, backupfile))
185 return 185 return
186 186
187 self.backupentries.append((file, backupfile)) 187 self._backupentries.append((file, backupfile))
188 self.backupmap[file] = len(self.backupentries) - 1 188 self._backupmap[file] = len(self._backupentries) - 1
189 self.backupsfile.write("%s\0%s\n" % (file, backupfile)) 189 self._backupsfile.write("%s\0%s\n" % (file, backupfile))
190 self.backupsfile.flush() 190 self._backupsfile.flush()
191 191
192 @active 192 @active
193 def addfilegenerator(self, genid, filenames, genfunc, order=0, vfs=None): 193 def addfilegenerator(self, genid, filenames, genfunc, order=0, vfs=None):
194 """add a function to generates some files at transaction commit 194 """add a function to generates some files at transaction commit
195 195
236 236
237 @active 237 @active
238 def find(self, file): 238 def find(self, file):
239 if file in self.map: 239 if file in self.map:
240 return self.entries[self.map[file]] 240 return self.entries[self.map[file]]
241 if file in self.backupmap: 241 if file in self._backupmap:
242 return self.backupentries[self.backupmap[file]] 242 return self._backupentries[self._backupmap[file]]
243 return None 243 return None
244 244
245 @active 245 @active
246 def replace(self, file, offset, data=None): 246 def replace(self, file, offset, data=None):
247 ''' 247 '''
322 322
323 self.count -= 1 323 self.count -= 1
324 if self.count != 0: 324 if self.count != 0:
325 return 325 return
326 self.file.close() 326 self.file.close()
327 self.backupsfile.close() 327 self._backupsfile.close()
328 self.entries = [] 328 self.entries = []
329 if self.after: 329 if self.after:
330 self.after() 330 self.after()
331 if self.opener.isfile(self.journal): 331 if self.opener.isfile(self.journal):
332 self.opener.unlink(self.journal) 332 self.opener.unlink(self.journal)
333 if self.opener.isfile(self.backupjournal): 333 if self.opener.isfile(self._backupjournal):
334 self.opener.unlink(self.backupjournal) 334 self.opener.unlink(self._backupjournal)
335 for _f, b in self.backupentries: 335 for _f, b in self._backupentries:
336 self.opener.unlink(b) 336 self.opener.unlink(b)
337 self.backupentries = [] 337 self._backupentries = []
338 self.journal = None 338 self.journal = None
339 # run post close action 339 # run post close action
340 categories = sorted(self._postclosecallback) 340 categories = sorted(self._postclosecallback)
341 for cat in categories: 341 for cat in categories:
342 self._postclosecallback[cat]() 342 self._postclosecallback[cat]()
350 350
351 def _abort(self): 351 def _abort(self):
352 self.count = 0 352 self.count = 0
353 self.usages = 0 353 self.usages = 0
354 self.file.close() 354 self.file.close()
355 self.backupsfile.close() 355 self._backupsfile.close()
356 356
357 if self.onabort is not None: 357 if self.onabort is not None:
358 self.onabort() 358 self.onabort()
359 359
360 try: 360 try:
361 if not self.entries and not self.backupentries: 361 if not self.entries and not self._backupentries:
362 if self.journal: 362 if self.journal:
363 self.opener.unlink(self.journal) 363 self.opener.unlink(self.journal)
364 if self.backupjournal: 364 if self._backupjournal:
365 self.opener.unlink(self.backupjournal) 365 self.opener.unlink(self._backupjournal)
366 return 366 return
367 367
368 self.report(_("transaction abort!\n")) 368 self.report(_("transaction abort!\n"))
369 369
370 try: 370 try:
371 _playback(self.journal, self.report, self.opener, 371 _playback(self.journal, self.report, self.opener,
372 self.entries, self.backupentries, False) 372 self.entries, self._backupentries, False)
373 self.report(_("rollback completed\n")) 373 self.report(_("rollback completed\n"))
374 except Exception: 374 except Exception:
375 self.report(_("rollback failed - please run hg recover\n")) 375 self.report(_("rollback failed - please run hg recover\n"))
376 finally: 376 finally:
377 self.journal = None 377 self.journal = None