Merge lp:~vila/bzr/697815-repair-repo into lp:bzr

Proposed by Vincent Ladeuil
Status: Work in progress
Proposed branch: lp:~vila/bzr/697815-repair-repo
Merge into: lp:bzr
Diff against target: 177 lines (+101/-36)
3 files modified
bzrlib/builtins.py (+27/-2)
bzrlib/check.py (+1/-34)
tools/repair-repo.py (+73/-0)
To merge this branch: bzr merge lp:~vila/bzr/697815-repair-repo
Reviewer Review Type Date Requested Status
bzr-core Pending
Review via email: mp+45945@code.launchpad.net

Description of the change

This add a script that repair repos containing an empty pack file.

As seen in bug #697815 this repair a broken repository but is an incomplete solution as the branch is left in a broken state.

Still, I don't feel like addressing the later but having this script easily available sounds like a useful thing anyway.

I wanted to add some tests but... this script is not a command and I don't feel like starting a new test infrastructure for that...

So I thought I may ask for feedback about whether it's acceptable to land this first and what people think about:
- turning it into its own command,
- somehow make it part of check/reconcile
- something else

To post a comment you must log in.
Revision history for this message
Martin Pool (mbp) wrote :

That's useful.

I think putting it into a hidden command is better than putting into
tools/, because the latter will not be easily accessible to people
running bzr from a package or a binary installer.

Ultimately I think this should move into probably reconcile or check.
It might be enough to just give them an option to run this particular
fix, like

 check --fixer empty_packs

should run this code.

--
Martin

lp:~vila/bzr/697815-repair-repo updated
5598. By Vincent Ladeuil

Remove code deprecated in 1.6.0 and 1.16.0.

5599. By Vincent Ladeuil

Sort the lazy registered commands in ascii order.

5600. By Vincent Ladeuil

Unfinished stuff

Unmerged revisions

5600. By Vincent Ladeuil

Unfinished stuff

5599. By Vincent Ladeuil

Sort the lazy registered commands in ascii order.

5598. By Vincent Ladeuil

Remove code deprecated in 1.6.0 and 1.16.0.

5597. By Vincent Ladeuil

Give some context and mention the missing features/tests.

5596. By Vincent Ladeuil

Add the copyright notice.

5595. By Vincent Ladeuil

Add the working repair-repo script as-is.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bzrlib/builtins.py'
--- bzrlib/builtins.py 2011-01-21 23:21:18 +0000
+++ bzrlib/builtins.py 2011-01-25 13:41:43 +0000
@@ -1638,6 +1638,31 @@
1638 reconcile(dir, canonicalize_chks=canonicalize_chks)1638 reconcile(dir, canonicalize_chks=canonicalize_chks)
16391639
16401640
1641class cmd_repair_repo(Command):
1642 __doc__ = """Repair a repo with an empty pack file.
1643
1644 Under some (yet) unclear circumstances (but generally involving ext4),
1645 system crashes left some file systems in an inconsistent state: pack file
1646 content get lost even if later modifications are taken into account by such
1647 file systems. The most commonly observed symptom is that an empty pack file
1648 is referenced in a repository pack-names file.
1649
1650 The content of the file can't be recovered, but deleting it from the
1651 pack-names file makes the repository usable again.
1652
1653 Unless you've been instructed to use this command, please file a bug at
1654 <https://bugs.launchpad.net/bzr/+filebug> explaining as best as you can how
1655 you end up in such a situation (OS and file system used at least and
1656 whether you had a crash).
1657 """
1658
1659 takes_args = ['pack_name']
1660 hidden = True
1661
1662 def run(self, pack_name):
1663 pass
1664
1665
1641class cmd_revision_history(Command):1666class cmd_revision_history(Command):
1642 __doc__ = """Display the list of revision ids on a branch."""1667 __doc__ = """Display the list of revision ids on a branch."""
16431668
@@ -6118,11 +6143,11 @@
6118 for (name, aliases, module_name) in [6143 for (name, aliases, module_name) in [
6119 ('cmd_bundle_info', [], 'bzrlib.bundle.commands'),6144 ('cmd_bundle_info', [], 'bzrlib.bundle.commands'),
6120 ('cmd_config', [], 'bzrlib.config'),6145 ('cmd_config', [], 'bzrlib.config'),
6146 ('cmd_conflicts', [], 'bzrlib.conflicts'),
6121 ('cmd_dpush', [], 'bzrlib.foreign'),6147 ('cmd_dpush', [], 'bzrlib.foreign'),
6122 ('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6123 ('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),6148 ('cmd_resolve', ['resolved'], 'bzrlib.conflicts'),
6124 ('cmd_conflicts', [], 'bzrlib.conflicts'),
6125 ('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),6149 ('cmd_sign_my_commits', [], 'bzrlib.sign_my_commits'),
6126 ('cmd_test_script', [], 'bzrlib.cmd_test_script'),6150 ('cmd_test_script', [], 'bzrlib.cmd_test_script'),
6151 ('cmd_version_info', [], 'bzrlib.cmd_version_info'),
6127 ]:6152 ]:
6128 builtin_command_registry.register_lazy(name, aliases, module_name)6153 builtin_command_registry.register_lazy(name, aliases, module_name)
61296154
=== modified file 'bzrlib/check.py'
--- bzrlib/check.py 2011-01-13 00:14:31 +0000
+++ bzrlib/check.py 2011-01-25 13:41:43 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2005, 2006 Canonical Ltd1# Copyright (C) 2005-2011 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -330,39 +330,6 @@
330 self.text_key_references[key] = True330 self.text_key_references[key] = True
331331
332332
333@deprecated_function(deprecated_in((1,6,0)))
334def check(branch, verbose):
335 """Run consistency checks on a branch.
336
337 Results are reported through logging.
338
339 Deprecated in 1.6. Please use check_dwim instead.
340
341 :raise BzrCheckError: if there's a consistency error.
342 """
343 check_branch(branch, verbose)
344
345
346@deprecated_function(deprecated_in((1,16,0)))
347def check_branch(branch, verbose):
348 """Run consistency checks on a branch.
349
350 Results are reported through logging.
351
352 :raise BzrCheckError: if there's a consistency error.
353 """
354 branch.lock_read()
355 try:
356 needed_refs = {}
357 for ref in branch._get_check_refs():
358 needed_refs.setdefault(ref, []).append(branch)
359 result = branch.repository.check([branch.last_revision()], needed_refs)
360 branch_result = result.other_results[0]
361 finally:
362 branch.unlock()
363 branch_result.report_results(verbose)
364
365
366def scan_branch(branch, needed_refs, to_unlock):333def scan_branch(branch, needed_refs, to_unlock):
367 """Scan a branch for refs.334 """Scan a branch for refs.
368335
369336
=== added file 'tools/repair-repo.py'
--- tools/repair-repo.py 1970-01-01 00:00:00 +0000
+++ tools/repair-repo.py 2011-01-25 13:41:43 +0000
@@ -0,0 +1,73 @@
1#!/usr/bin/env python
2# Copyright (C) 2010 Canonical Ltd
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 2 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
18"""Repair a repo with an empty pack file.
19
20Under some (yet) unclear circumstances, crashes left some file systems in an
21inconsistent state: file content get lost even if later modifications are taken
22into account by such file systems. The most commonly observed symptom is that
23an empty pack file is referenced in a repository pack-names file.
24
25The content of the file can't be recovered, but deleting it from the pack-names
26file makes the repository usable again.
27
28Unless you've been instructed to use this file, please file a bug at
29<https://bugs.launchpad.net/bzr/+filebug> explaining as best as you can how you
30end up in such a situation (OS and file system used at least and whether you
31had a crash).
32
33Usage:
34
35 repair-repo.py <pack file base name>
36
37"""
38
39# FIXME: This should be turned into a proper command, possibly hidden
40
41# Missing features/tests:
42# - apply only to pack-based repositories
43# - should detect all empty pack files and report them
44# - should have a --dry-run option
45
46# - should provide help to repair the associated branch too (generally the
47# empty pack file happen for the last commit and the branch where this commit
48# occurred mentions the (now lost) revid in its last-revision file).
49
50import sys
51
52from bzrlib import branch
53
54pack_name = sys.argv[1]
55
56from bzrlib import repository, btree_index, transport
57
58location = u'.'
59b = branch.Branch.open_containing(location)[0]
60
61t = b.repository._transport
62pn_index = btree_index.BTreeGraphIndex(t, 'pack-names', None)
63nodes = pn_index.iter_all_entries()
64
65new_index = btree_index.BTreeBuilder(0, 1)
66
67for _, key, value in nodes:
68 if key == (pack_name,):
69 continue
70 new_index.add_node(key, value)
71
72new_index_content = new_index.finish()
73t.put_file('pack-names', new_index_content)