/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.12.12 by Aaron Bentley
Implement shelf creator
1
# Copyright (C) 2008 Aaron Bentley <aaron@aaronbentley.com>
2
#
3
#    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 by
5
#    the Free Software Foundation; either version 2 of the License, or
6
#    (at your option) any later version.
7
#
8
#    This program is distributed in the hope that it will be useful,
9
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
10
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
#    GNU General Public License for more details.
12
#
13
#    You should have received a copy of the GNU General Public License
14
#    along with this program; if not, write to the Free Software
15
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
0.12.13 by Aaron Bentley
Implement shelving content
18
from cStringIO import StringIO
19
0.12.25 by Aaron Bentley
Update to use new from_uncommitted API
20
from bzrlib import merge, merge3, pack, transform, ui
0.12.19 by Aaron Bentley
Add support for writing shelves
21
22
from bzrlib.plugins.shelf2 import serialize_transform
0.12.12 by Aaron Bentley
Implement shelf creator
23
24
25
class ShelfCreator(object):
26
0.14.1 by Aaron Bentley
Use explicit target in ShelfCreator
27
    def __init__(self, work_tree, target_tree):
0.12.12 by Aaron Bentley
Implement shelf creator
28
        self.work_tree = work_tree
29
        self.work_transform = transform.TreeTransform(work_tree)
0.14.1 by Aaron Bentley
Use explicit target in ShelfCreator
30
        self.target_tree = target_tree
31
        self.shelf_transform = transform.TransformPreview(self.target_tree)
0.12.12 by Aaron Bentley
Implement shelf creator
32
        self.renames = {}
0.14.2 by Aaron Bentley
Somewhat clean up shelving
33
        self.creation = {}
0.14.1 by Aaron Bentley
Use explicit target in ShelfCreator
34
        self.iter_changes = work_tree.iter_changes(self.target_tree)
0.12.12 by Aaron Bentley
Implement shelf creator
35
36
    def __iter__(self):
37
        for (file_id, paths, changed, versioned, parents, names, kind,
38
             executable) in self.iter_changes:
0.12.14 by Aaron Bentley
Add shelving of created files
39
            if kind[0] is None or versioned[0] == False:
0.14.2 by Aaron Bentley
Somewhat clean up shelving
40
                self.creation[file_id] = (kind[1], names[1], parents[1])
0.12.14 by Aaron Bentley
Add shelving of created files
41
                yield ('add file', file_id, kind[1])
42
            else:
43
                if names[0] != names[1] or parents[0] != parents[1]:
44
                    self.renames[file_id] = (names, parents)
45
                    yield ('rename', file_id) + paths
46
                if changed:
47
                    yield ('modify text', file_id)
0.12.12 by Aaron Bentley
Implement shelf creator
48
49
    def shelve_rename(self, file_id):
50
        names, parents = self.renames[file_id]
51
        w_trans_id = self.work_transform.trans_id_file_id(file_id)
52
        work_parent = self.work_transform.trans_id_file_id(parents[0])
53
        self.work_transform.adjust_path(names[0], work_parent, w_trans_id)
54
55
        s_trans_id = self.shelf_transform.trans_id_file_id(file_id)
56
        shelf_parent = self.shelf_transform.trans_id_file_id(parents[1])
57
        self.shelf_transform.adjust_path(names[1], shelf_parent, s_trans_id)
58
0.12.13 by Aaron Bentley
Implement shelving content
59
    def shelve_text(self, file_id, new_text):
60
        s = StringIO()
61
        s.writelines(new_text)
62
        s.seek(0)
63
        new_lines = s.readlines()
64
        w_trans_id = self.work_transform.trans_id_file_id(file_id)
65
        self.work_transform.delete_contents(w_trans_id)
66
        self.work_transform.create_file(new_lines, w_trans_id)
67
68
        s_trans_id = self.shelf_transform.trans_id_file_id(file_id)
69
        self.shelf_transform.delete_contents(s_trans_id)
70
        inverse_lines = self._inverse_lines(new_lines, file_id)
71
        self.shelf_transform.create_file(inverse_lines, s_trans_id)
72
0.14.2 by Aaron Bentley
Somewhat clean up shelving
73
    def shelve_creation(self, file_id):
74
        kind, name, parent = self.creation[file_id]
0.12.14 by Aaron Bentley
Add shelving of created files
75
        w_trans_id = self.work_transform.trans_id_file_id(file_id)
0.14.2 by Aaron Bentley
Somewhat clean up shelving
76
        if parent is not None:
77
            self.work_transform.delete_contents(w_trans_id)
0.12.15 by Aaron Bentley
Handle file-id when shelving creation
78
        self.work_transform.unversion_file(w_trans_id)
0.12.14 by Aaron Bentley
Add shelving of created files
79
80
        s_trans_id = self.shelf_transform.trans_id_file_id(file_id)
0.14.2 by Aaron Bentley
Somewhat clean up shelving
81
        if parent is not None:
82
            s_parent_id = self.shelf_transform.trans_id_file_id(parent)
83
            self.shelf_transform.adjust_path(name, s_parent_id, s_trans_id)
84
            if kind == 'file':
85
                lines = self.read_tree_lines(file_id)
86
                self.shelf_transform.create_file(lines, s_trans_id)
87
            if kind == 'directory':
88
                self.shelf_transform.create_directory(s_trans_id)
89
            if kind == 'symlink':
90
                target = self.work_tree.get_symlink_target(file_id)
91
                self.shelf_transform.create_symlink(target, s_trans_id)
0.12.15 by Aaron Bentley
Handle file-id when shelving creation
92
        self.shelf_transform.version_file(file_id, s_trans_id)
0.12.14 by Aaron Bentley
Add shelving of created files
93
94
    def read_tree_lines(self, file_id):
0.12.13 by Aaron Bentley
Implement shelving content
95
        tree_file = self.work_tree.get_file(file_id)
96
        try:
0.12.14 by Aaron Bentley
Add shelving of created files
97
            return tree_file.readlines()
0.12.13 by Aaron Bentley
Implement shelving content
98
        finally:
99
            tree_file.close()
0.12.14 by Aaron Bentley
Add shelving of created files
100
101
    def _inverse_lines(self, new_lines, file_id):
102
        """Produce a version with only those changes removed from new_lines."""
0.14.1 by Aaron Bentley
Use explicit target in ShelfCreator
103
        target_lines = self.target_tree.get_file_lines(file_id)
104
        work_lines = self.read_tree_lines(file_id)
105
        return merge3.Merge3(new_lines, target_lines, work_lines).merge_lines()
0.12.13 by Aaron Bentley
Implement shelving content
106
0.12.12 by Aaron Bentley
Implement shelf creator
107
    def finalize(self):
108
        self.work_transform.finalize()
109
        self.shelf_transform.finalize()
0.12.13 by Aaron Bentley
Implement shelving content
110
111
    def transform(self):
112
        self.work_transform.apply()
0.12.19 by Aaron Bentley
Add support for writing shelves
113
114
    def make_shelf_filename(self):
115
        transport = self.work_tree.bzrdir.root_transport.clone('.shelf2')
116
        transport.ensure_base()
117
        return transport.local_abspath('01')
118
119
    def write_shelf(self):
0.12.24 by Aaron Bentley
Get unshelve using merge codepath, not applying transform directly
120
        transform.resolve_conflicts(self.shelf_transform)
0.12.19 by Aaron Bentley
Add support for writing shelves
121
        filename = self.make_shelf_filename()
122
        shelf_file = open(filename, 'wb')
123
        try:
124
            serializer = pack.ContainerSerialiser()
125
            shelf_file.write(serializer.begin())
126
            for bytes in serialize_transform.serialize(
127
                self.shelf_transform, serializer):
128
                shelf_file.write(bytes)
129
            shelf_file.write(serializer.end())
130
        finally:
131
            shelf_file.close()
132
        return filename
0.12.21 by Aaron Bentley
Add failing test of unshelver
133
134
135
class Unshelver(object):
136
137
    def __init__(self, tree, base_tree, transform):
138
        self.tree = tree
0.12.24 by Aaron Bentley
Get unshelve using merge codepath, not applying transform directly
139
        self.base_tree = base_tree
0.12.21 by Aaron Bentley
Add failing test of unshelver
140
        self.transform = transform
141
142
    @classmethod
143
    def from_tree_and_shelf(klass, tree, shelf_filename):
144
        parser = pack.ContainerPushParser()
145
        shelf_file = open(shelf_filename, 'rb')
146
        try:
147
            parser.accept_bytes(shelf_file.read())
148
        finally:
149
            shelf_file.close()
0.12.24 by Aaron Bentley
Get unshelve using merge codepath, not applying transform directly
150
        tt = transform.TransformPreview(tree)
0.12.21 by Aaron Bentley
Add failing test of unshelver
151
        records = iter(parser.read_pending_records())
152
        serialize_transform.deserialize(tt, records)
0.12.24 by Aaron Bentley
Get unshelve using merge codepath, not applying transform directly
153
        return klass(tree, tree.basis_tree(), tt)
0.12.21 by Aaron Bentley
Add failing test of unshelver
154
155
    def unshelve(self):
0.12.25 by Aaron Bentley
Update to use new from_uncommitted API
156
        pb = ui.ui_factory.nested_progress_bar()
157
        try:
158
            target_tree = self.transform.get_preview_tree()
159
            merger = merge.Merger.from_uncommitted(self.tree, target_tree, pb,
160
                                                   self.base_tree)
161
            merger.merge_type = merge.Merge3Merger
162
            merger.do_merge()
163
        finally:
164
            pb.finished()
165
166
    def finalize(self):
167
        self.transform.finalize()