13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
"""Reconcilers are able to fix some potential data errors in a branch."""
63
63
def reconcile(self):
64
64
"""Perform reconciliation.
66
66
After reconciliation the following attributes document found issues:
67
67
inconsistent_parents: The number of revisions in the repository whose
68
68
ancestry was being reported incorrectly.
137
137
def _reconcile_revision_history(self):
138
138
repo = self.branch.repository
139
139
last_revno, last_revision_id = self.branch.last_revision_info()
142
for revid in repo.iter_reverse_revision_history(
144
real_history.append(revid)
145
except errors.RevisionNotPresent:
146
pass # Hit a ghost left hand parent
140
real_history = list(repo.iter_reverse_revision_history(
147
142
real_history.reverse()
148
143
if last_revno != len(real_history):
149
144
self.fixed_history = True
164
159
"""Reconciler that reconciles a repository.
166
161
The goal of repository reconciliation is to make any derived data
167
consistent with the core data committed by a user. This can involve
162
consistent with the core data committed by a user. This can involve
168
163
reindexing, or removing unreferenced data if that can interfere with
169
164
queries in a given repository.
187
182
def reconcile(self):
188
183
"""Perform reconciliation.
190
185
After reconciliation the following attributes document found issues:
191
186
inconsistent_parents: The number of revisions in the repository whose
192
187
ancestry was being reported incorrectly.
210
205
def _reweave_inventory(self):
211
206
"""Regenerate the inventory weave for the repository from scratch.
213
This is a smart function: it will only do the reweave if doing it
208
This is a smart function: it will only do the reweave if doing it
214
209
will correct data issues. The self.thorough flag controls whether
215
210
only data-loss causing issues (!self.thorough) or all issues
216
211
(self.thorough) are treated as requiring the reweave.
218
213
# local because needing to know about WeaveFile is a wart we want to hide
219
214
from bzrlib.weave import WeaveFile, Weave
220
215
transaction = self.repo.get_transaction()
221
self.pb.update('Reading inventory data')
216
self.pb.update('Reading inventory data.')
222
217
self.inventory = self.repo.inventories
223
218
self.revisions = self.repo.revisions
224
219
# the total set of revisions to process
234
229
# put a revision into the graph.
235
230
self._graph_revision(rev_id)
236
231
self._check_garbage_inventories()
237
# if there are no inconsistent_parents and
232
# if there are no inconsistent_parents and
238
233
# (no garbage inventories or we are not doing a thorough check)
239
if (not self.inconsistent_parents and
234
if (not self.inconsistent_parents and
240
235
(not self.garbage_inventories or not self.thorough)):
241
236
self.pb.note('Inventory ok.')
243
self.pb.update('Backing up inventory', 0, 0)
238
self.pb.update('Backing up inventory...', 0, 0)
244
239
self.repo._backup_inventory()
245
self.pb.note('Backup inventory created.')
240
self.pb.note('Backup Inventory created.')
246
241
new_inventories = self.repo._temp_inventories()
248
243
# we have topological order of revisions and non ghost parents ready.
356
351
def _load_indexes(self):
357
352
"""Load indexes for the reconciliation."""
358
353
self.transaction = self.repo.get_transaction()
359
self.pb.update('Reading indexes', 0, 2)
354
self.pb.update('Reading indexes.', 0, 2)
360
355
self.inventory = self.repo.inventories
361
self.pb.update('Reading indexes', 1, 2)
356
self.pb.update('Reading indexes.', 1, 2)
362
357
self.repo._check_for_inconsistent_revision_parents()
363
358
self.revisions = self.repo.revisions
364
self.pb.update('Reading indexes', 2, 2)
359
self.pb.update('Reading indexes.', 2, 2)
366
361
def _gc_inventory(self):
367
362
"""Remove inventories that are not referenced from the revision store."""
368
self.pb.update('Checking unused inventories', 0, 1)
363
self.pb.update('Checking unused inventories.', 0, 1)
369
364
self._check_garbage_inventories()
370
self.pb.update('Checking unused inventories', 1, 3)
365
self.pb.update('Checking unused inventories.', 1, 3)
371
366
if not self.garbage_inventories:
372
367
self.pb.note('Inventory ok.')
374
self.pb.update('Backing up inventory', 0, 0)
369
self.pb.update('Backing up inventory...', 0, 0)
375
370
self.repo._backup_inventory()
376
self.pb.note('Backup Inventory created')
371
self.pb.note('Backup Inventory created.')
377
372
# asking for '' should never return a non-empty weave
378
373
new_inventories = self.repo._temp_inventories()
379
374
# we have topological order of revisions and non ghost parents ready.
510
505
total_inventories = len(list(
511
506
collection.inventory_index.combined_index.iter_all_entries()))
512
507
if len(all_revisions):
513
new_pack = self.repo._reconcile_pack(collection, packs,
514
".reconcile", all_revisions, self.pb)
508
self._packer = repofmt.pack_repo.ReconcilePacker(
509
collection, packs, ".reconcile", all_revisions)
510
new_pack = self._packer.pack(pb=self.pb)
515
511
if new_pack is not None:
516
512
self._discard_and_save(packs)