~abentley/bzrtools/bzrtools.dev

360.1.2 by Aaron Bentley
Tweak switch command
1
# Copyright (C) 2006 Canonical Limited.
2
# Authors: David Allouche <david@allouche.net>
3
#          Aaron Bentley <aaron.bentley@utoronto.ca>
4
#
5
#    This program is free software; you can redistribute it and/or modify
6
#    it under the terms of the GNU General Public License as published by
7
#    the Free Software Foundation; either version 2 of the License, or
8
#    (at your option) any later version.
9
#
10
#    This program is distributed in the hope that it will be useful,
11
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
#    GNU General Public License for more details.
14
#
15
#    You should have received a copy of the GNU General Public License
16
#    along with this program; if not, write to the Free Software
17
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
360.1.1 by Aaron Bentley
Add switch command
18
from bzrlib.errors import BzrCommandError
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
19
from bzrlib.commands import register_command
360.1.1 by Aaron Bentley
Add switch command
20
from bzrlib.branch import Branch, BranchFormat
21
from bzrlib.bzrdir import BzrDir, BzrDirFormat
22
from bzrlib.transport import get_transport
409 by Aaron Bentley
Update colordiff to use wrapped versions of diff
23
from bzrlib.builtins import cmd_update
360.1.1 by Aaron Bentley
Add switch command
24
from bzrlib.trace import note
360.1.2 by Aaron Bentley
Tweak switch command
25
from bzrlib.workingtree import WorkingTree
360.1.1 by Aaron Bentley
Add switch command
26
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
27
from command import BzrToolsCommand
28
29
class cmd_switch(BzrToolsCommand):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
30
    """Set the branch of a lightweight checkout and update."""
360.1.1 by Aaron Bentley
Add switch command
31
32
    takes_args = ['to_location']
33
34
    def run(self, to_location):
35
        to_branch = Branch.open(to_location)
365 by Aaron Bentley
Switch fix from ddaa
36
        tree_location = '.'
37
        self._switch(tree_location, to_branch)
38
        # need to re-open tree to get the new branch
39
        tree = WorkingTree.open_containing(tree_location)[0]
40
        self._update(tree)
41
42
    def _switch(self, tree_location, to_branch):
43
        tree = WorkingTree.open_containing(tree_location)[0]
44
        tree.lock_write()
360.1.1 by Aaron Bentley
Add switch command
45
        try:
365 by Aaron Bentley
Switch fix from ddaa
46
            self._check_switch_branch_format(tree_location)
47
            self.set_branch_location(tree.bzrdir, to_branch.base)
360.1.2 by Aaron Bentley
Tweak switch command
48
            note('Switched to branch: %s' % (to_branch.base,))
365 by Aaron Bentley
Switch fix from ddaa
49
        finally:
50
            tree.unlock()
51
52
    def _update(self, tree):
53
        tree.lock_write()
54
        try:
55
            if tree.last_revision() == tree.branch.last_revision():
56
                assert tree.branch.get_master_branch() is None, (
57
                    "switch tried to update a fat checkout")
58
                note("Tree is up to date.")
59
                return
60
            tree.update()
360.1.2 by Aaron Bentley
Tweak switch command
61
            note('Updated to revision %d' %
365 by Aaron Bentley
Switch fix from ddaa
62
                 (tree.branch.revision_id_to_revno(tree.last_revision()),))
360.1.1 by Aaron Bentley
Add switch command
63
        finally:
365 by Aaron Bentley
Switch fix from ddaa
64
            tree.unlock()
360.1.1 by Aaron Bentley
Add switch command
65
66
    def _check_switch_branch_format(self, url):
67
        transport = get_transport(url)
68
        format = BzrDirFormat.find_format(transport)
69
        format_string = format.get_format_string()
70
        if not format_string.startswith("Bazaar-NG meta directory, "):
71
            raise BzrCommandError(
72
                'The switch command can only be used on a light checkout.\n'
73
                'Expected metadir, found %s at %s' % (
74
                format_string.strip(), transport.base))
75
        control = BzrDir.open_containing_from_transport(transport)[0]
76
        branch_format = BranchFormat.find_format(control)
77
        format_string = branch_format.get_format_string()
78
        if not format_string.startswith("Bazaar-NG Branch Reference Format "):
79
            raise BzrCommandError(
80
                'The switch command can only be used on a light checkout.\n'
81
                'Expected branch reference, found %s at %s' % (
82
                format_string.strip(), transport.base))
83
        if not format_string == "Bazaar-NG Branch Reference Format 1\n":
84
            raise BzrCommandError(
85
                'Unsupported: %r' % (format_string.strip(),))        
86
87
    def set_branch_location(self, control, location):
88
        """Set location value of a branch reference.
89
90
        The branch living in the control (BzrDir) object must be locked for
91
        writing.
92
93
        :param control: BzrDir containing the branch reference
94
        :param location: value to write to the branch reference location.
95
        """
96
        branch_format = BranchFormat.find_format(control)
97
        transport = control.get_branch_transport(None)
98
        branch = branch_format.open(control)
464 by Aaron Bentley
Update switch API use
99
        location = transport.put_bytes('location', location)