9
def _install_info(branch, cset_info, cset_tree, cset_inv):
10
"""Make sure that there is a text entry for each
11
file in the changeset.
13
from bzrlib.xml import pack_xml
14
from cStringIO import StringIO
16
# First, install all required texts
17
for file_id, text_id in cset_info.text_ids.iteritems():
18
if text_id not in branch.text_store:
19
branch.text_store.add(cset_tree.get_file(file_id), text_id)
21
# Now install the final inventory
22
if cset_info.target not in branch.inventory_store:
23
# bzrlib.commit uses a temporary file, but store.add
24
# reads in the entire file anyway
26
pack_xml(cset_inv, sio)
27
branch.inventory_store.add(sio.getvalue(), cset_info.target)
30
# Now that we have installed the inventory and texts
31
# install the revision entries.
32
for rev in cset_info.real_revisions:
33
if rev.revision_id not in branch.revision_store:
36
branch.inventory_store.add(sio.getvalue(), rev.revision_id)
39
def get_tree(treespec, temp_root, label):
40
location, revno = treespec
41
branch = find_branch(location)
43
base_tree = branch.working_tree()
45
base_tree = branch.basis_tree()
47
base_tree = branch.revision_tree(branch.lookup_revision(revno))
48
temp_path = os.path.join(temp_root, label)
50
return branch, MergeTree(base_tree, temp_path)
52
def merge_revs(branch, rev_base, rev_other,
53
ignore_zero=False, check_clean=True):
54
"""This will merge the tree of rev_other into
55
the working tree of branch using the base given by rev_base.
56
All the revision XML should be inside branch.
58
import tempfile, shutil
59
from bzrlib.merge import merge_inner, MergeTree
60
from bzrlib.errors import BzrCommandError
62
tempdir = tempfile.mkdtemp(prefix='bzr-')
65
from bzrlib.diff import compare_trees
66
changes = compare_trees(branch.working_tree(),
67
branch.basis_tree(), False)
69
if changes.has_changed():
70
raise BzrCommandError("Working tree has uncommitted changes.")
72
other_dir = os.path.join(tempdir, 'other')
73
other_tree = MergeTree(branch.revision_tree(rev_other), other_dir)
75
base_dir = os.path.join(tempdir, 'base')
76
base_tree = MergeTree(branch.revision_tree(rev_base), base_dir)
78
merge_inner(branch, other_tree, base_tree, tempdir,
79
ignore_zero=ignore_zero)
81
shutil.rmtree(tempdir)
8
84
def apply_changeset(branch, from_file, auto_commit=False):
9
from bzrlib.merge import merge_inner
10
85
import sys, read_changeset
13
cset_info, cset_tree, cset_inv = read_changeset.read_changeset(from_file)
87
cset_info, cset_tree, cset_inv = \
88
read_changeset.read_changeset(from_file)
90
_install_info(branch, cset_info, cset_tree, cset_inv)
92
# We could technically optimize more, by using the ChangesetTree
93
# we already have in memory, but after installing revisions
94
# this code can work the way merge should work in the
98
# This shouldn't use the base of the changeset as the base
99
# for the merge, the merge code should pick the best merge
100
# based on the ancestry of both trees.
102
merge_revs(branch, cset_info.base, cset_info.target)
16
105
from bzrlib.commit import commit
17
if branch.last_patch() == cset_info.precursor:
18
# This patch can be applied directly
19
commit(branch, message = cset_info.message,
20
timestamp=float(cset_info.timestamp),
21
timezone=float(cset_info.timezone),
22
committer=cset_info.committer,
23
rev_id=cset_info.revision)
107
# When merging, if the revision to be merged has a parent
108
# of the current revision, then it can be installed
112
# There is actually a slightly stronger statement
113
# whereby if the current revision is in the ancestry
114
# of the merged revisions, it doesn't need to be the
115
# immediate ancestry, but that requires searching
116
# a potentially branching history.
118
target_has_parent = False
119
target_rev = branch.get_revision(cset_info.target)
120
lastrev_id = branch.last_patch()
121
for parent in target_rev.parents:
122
if parent.revision_id == lastrev_id:
123
target_has_parent = True
125
if target_has_parent:
126
branch.append_revision(target_rev.revision_id)
128
print '** Could not auto-commit.'