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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
from bzrlib.lazy_import import lazy_import
22
lazy_import(globals(), """
21
23
from bzrlib import (
31
from bzrlib.util import bencode
34
34
class ShelfCreator(object):
37
37
def __init__(self, work_tree, target_tree, file_list=None):
40
:param work_tree: The working tree to apply changes to
40
:param work_tree: The working tree to apply changes to. This is not
41
required to be locked - a tree_write lock will be taken out.
41
42
:param target_tree: The tree to make the working tree more similar to.
43
This is not required to be locked - a read_lock will be taken out.
42
44
:param file_list: The files to make more similar to the target.
44
46
self.work_tree = work_tree
45
47
self.work_transform = transform.TreeTransform(work_tree)
46
self.target_tree = target_tree
47
self.shelf_transform = transform.TransformPreview(self.target_tree)
51
self.iter_changes = work_tree.iter_changes(self.target_tree,
52
specific_files=file_list)
49
self.target_tree = target_tree
50
self.shelf_transform = transform.TransformPreview(self.target_tree)
55
self.iter_changes = work_tree.iter_changes(
56
self.target_tree, specific_files=file_list)
58
self.shelf_transform.finalize()
61
self.work_transform.finalize()
54
64
def iter_shelvable(self):
55
65
"""Iterable of tuples describing shelvable changes.
57
67
As well as generating the tuples, this updates several members.
59
70
('add file', file_id, work_kind, work_path)
60
71
('delete file', file_id, target_kind, target_path)
61
72
('rename', file_id, target_path, work_path)
62
73
('change kind', file_id, target_kind, work_kind, target_path)
63
74
('modify text', file_id)
75
('modify target', file_id, target_target, work_target)
65
77
for (file_id, paths, changed, versioned, parents, names, kind,
66
78
executable) in self.iter_changes:
79
# don't shelve add of tree root. Working tree should never
80
# lack roots, and bzr misbehaves when they do.
81
# FIXME ADHB (2009-08-09): should still shelve adds of tree roots
82
# when a tree root was deleted / renamed.
83
if kind[0] is None and names[1] == '':
85
# Also don't shelve deletion of tree root.
86
if kind[1] is None and names[0] == '':
67
88
if kind[0] is None or versioned[0] == False:
68
89
self.creation[file_id] = (kind[1], names[1], parents[1],
80
101
if kind[0] != kind [1]:
81
102
yield ('change kind', file_id, kind[0], kind[1], paths[0])
103
elif kind[0] == 'symlink':
104
t_target = self.target_tree.get_symlink_target(file_id)
105
w_target = self.work_tree.get_symlink_target(file_id)
106
yield ('modify target', file_id, paths[0], t_target,
83
109
yield ('modify text', file_id)
111
def shelve_change(self, change):
112
"""Shelve a change in the iter_shelvable format."""
113
if change[0] == 'rename':
114
self.shelve_rename(change[1])
115
elif change[0] == 'delete file':
116
self.shelve_deletion(change[1])
117
elif change[0] == 'add file':
118
self.shelve_creation(change[1])
119
elif change[0] in ('change kind', 'modify text'):
120
self.shelve_content_change(change[1])
121
elif change[0] == 'modify target':
122
self.shelve_modify_target(change[1])
124
raise ValueError('Unknown change kind: "%s"' % change[0])
126
def shelve_all(self):
127
"""Shelve all changes."""
128
for change in self.iter_shelvable():
129
self.shelve_change(change)
85
131
def shelve_rename(self, file_id):
86
132
"""Shelve a file rename.
96
142
shelf_parent = self.shelf_transform.trans_id_file_id(parents[1])
97
143
self.shelf_transform.adjust_path(names[1], shelf_parent, s_trans_id)
145
def shelve_modify_target(self, file_id):
146
"""Shelve a change of symlink target.
148
:param file_id: The file id of the symlink which changed target.
149
:param new_target: The target that the symlink should have due
152
new_target = self.target_tree.get_symlink_target(file_id)
153
w_trans_id = self.work_transform.trans_id_file_id(file_id)
154
self.work_transform.delete_contents(w_trans_id)
155
self.work_transform.create_symlink(new_target, w_trans_id)
157
old_target = self.work_tree.get_symlink_target(file_id)
158
s_trans_id = self.shelf_transform.trans_id_file_id(file_id)
159
self.shelf_transform.delete_contents(s_trans_id)
160
self.shelf_transform.create_symlink(old_target, s_trans_id)
99
162
def shelve_lines(self, file_id, new_lines):
100
163
"""Shelve text changes to a file, using provided lines.
264
327
tt.deserialize(records)
265
328
return klass(tree, base_tree, tt, metadata.get('message'))
267
def make_merger(self):
330
def make_merger(self, task=None):
268
331
"""Return a merger that can unshelve the changes."""
269
pb = ui.ui_factory.nested_progress_bar()
271
target_tree = self.transform.get_preview_tree()
272
merger = merge.Merger.from_uncommitted(self.tree, target_tree, pb,
274
merger.merge_type = merge.Merge3Merger
332
target_tree = self.transform.get_preview_tree()
333
merger = merge.Merger.from_uncommitted(self.tree, target_tree,
334
task, self.base_tree)
335
merger.merge_type = merge.Merge3Merger
279
338
def finalize(self):
280
339
"""Release all resources held by this Unshelver."""