78
78
def apply_changeset(branch, from_file, reverse=False, auto_commit=False):
79
79
"""Read in a changeset from the given file, and apply it to
80
80
the supplied branch.
82
:return: True if the changeset was automatically committed to the
83
ancestry, False otherwise.
82
85
import sys, read_changeset
87
90
cset = read_changeset.read_changeset(from_file, branch)
89
_apply_cset(branch, cset, reverse=reverse, auto_commit=auto_commit)
92
return _apply_cset(branch, cset, reverse=reverse, auto_commit=auto_commit)
91
94
def _apply_cset(branch, cset, reverse=False, auto_commit=False):
92
95
"""Apply an in-memory changeset to a given branch.
109
112
merge_revs(branch, cset_info.base, cset_info.target)
114
auto_committed = False
116
# There are 2 cases where I am allowing automatic committing.
117
# 1) If the final revision has a parent of the current last revision
118
# (branch.last_patch() in cset.target.parents)
119
# that means that the changeset target has already merged the current
121
# 2) A cset contains a list of revisions. If the first entry has a parent
122
# of branch.last_patch(), then we can start merging there, and add the
123
# rest of the revisions. But it gets better. Some of the entries in the
124
# list might already be in the revision list, so we keep going until
125
# we find the first revision *not* in the list. If it's parent is
126
# branch.last_patch(), then we can also append history from there.
127
# This second part is a little more controversial, because the cset
128
# probably does not include all of the inventories. So you would have
129
# entries in branch.revision_history() without an associated inventory.
130
# we could just explicitly disable this. But if we had the inventory
131
# entries available, it is what 'bzr merge' would do.
132
# If we disable this, the target will just show up as a pending_merge
112
from bzrlib.commit import commit
114
134
# When merging, if the revision to be merged has a parent
115
135
# of the current revision, then it can be installed
122
142
# immediate ancestry, but that requires searching
123
143
# a potentially branching history.
125
target_has_parent = False
126
target_rev = branch.get_revision(cset_info.target)
127
lastrev_id = branch.last_patch()
128
for parent in target_rev.parents:
129
if parent.revision_id == lastrev_id:
130
target_has_parent = True
132
if target_has_parent:
133
branch.append_revision(target_rev.revision_id)
135
print '** Could not auto-commit.'
145
rh = branch.revision_history()
148
if len(rh) == 0 and len(cset_info.real_revisions[0].parents) == 0:
150
revs_to_merge = cset_info.real_revisions
152
for rev_num, rev in enumerate(cset_info.real_revisions):
153
if rev.revision_id not in rh:
154
for parent in rev.parents:
155
if parent.revision_id == rh[-1]:
158
# All revisions up until now already
159
# existed in the target history
160
# and this last one is a child of the
161
# last entry in the history.
162
# so we can add the rest
163
revs_to_merge = cset_info.real_revisions[rev_num:]
164
# Even if we don't find anything, we need to
169
rev_ids = [r.revision_id for r in revs_to_merge]
170
branch.append_revision(*rev_ids)
171
auto_committed = True
173
# We can also merge if the *last* revision has an
174
# appropriate parent.
175
target_has_parent = False
176
target_rev = branch.get_revision(cset_info.target)
177
lastrev_id = branch.last_patch()
178
for parent in target_rev.parents:
179
if parent.revision_id == lastrev_id:
180
target_has_parent = True
182
if target_has_parent:
183
branch.append_revision(target_rev.revision_id)
185
print '** Could not auto-commit.'
187
if not auto_committed:
188
branch.add_pending_merge(cset_info.target)
190
return auto_committed