/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.26 by Aaron Bentley
Use correct base for shelving
20
from bzrlib import errors, 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())
0.12.26 by Aaron Bentley
Use correct base for shelving
126
            shelf_file.write(serializer.bytes_record(
127
                self.target_tree.get_revision_id(), (('revision-id',),)))
0.12.19 by Aaron Bentley
Add support for writing shelves
128
            for bytes in serialize_transform.serialize(
129
                self.shelf_transform, serializer):
130
                shelf_file.write(bytes)
131
            shelf_file.write(serializer.end())
132
        finally:
133
            shelf_file.close()
134
        return filename
0.12.21 by Aaron Bentley
Add failing test of unshelver
135
136
137
class Unshelver(object):
138
139
    def __init__(self, tree, base_tree, transform):
140
        self.tree = tree
0.12.24 by Aaron Bentley
Get unshelve using merge codepath, not applying transform directly
141
        self.base_tree = base_tree
0.12.21 by Aaron Bentley
Add failing test of unshelver
142
        self.transform = transform
143
144
    @classmethod
145
    def from_tree_and_shelf(klass, tree, shelf_filename):
146
        parser = pack.ContainerPushParser()
147
        shelf_file = open(shelf_filename, 'rb')
148
        try:
149
            parser.accept_bytes(shelf_file.read())
150
        finally:
151
            shelf_file.close()
0.12.24 by Aaron Bentley
Get unshelve using merge codepath, not applying transform directly
152
        tt = transform.TransformPreview(tree)
0.12.21 by Aaron Bentley
Add failing test of unshelver
153
        records = iter(parser.read_pending_records())
0.12.26 by Aaron Bentley
Use correct base for shelving
154
        names, base_revision_id = records.next()
0.12.21 by Aaron Bentley
Add failing test of unshelver
155
        serialize_transform.deserialize(tt, records)
0.12.26 by Aaron Bentley
Use correct base for shelving
156
        try:
157
            base_tree = tree.revision_tree(base_revision_id)
158
        except errors.NoSuchRevisionInTree:
159
            base_tree = tree.branch.repository.revision_tree(base_revision_id)
160
        return klass(tree, base_tree, tt)
0.12.21 by Aaron Bentley
Add failing test of unshelver
161
162
    def unshelve(self):
0.12.25 by Aaron Bentley
Update to use new from_uncommitted API
163
        pb = ui.ui_factory.nested_progress_bar()
164
        try:
165
            target_tree = self.transform.get_preview_tree()
166
            merger = merge.Merger.from_uncommitted(self.tree, target_tree, pb,
167
                                                   self.base_tree)
168
            merger.merge_type = merge.Merge3Merger
169
            merger.do_merge()
170
        finally:
171
            pb.finished()
172
173
    def finalize(self):
174
        self.transform.finalize()