1
# Copyright (C) 2005 by Canonical Ltd
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.
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.
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
21
from bzrlib.trace import mutter, note
22
from bzrlib.branch import Branch
23
from bzrlib.progress import ProgressBar
26
def greedy_fetch(to_branch, from_branch, revision, pb):
27
f = Fetcher(to_branch, from_branch, revision, pb)
28
return f.count_copied, f.failed_revisions
31
class Fetcher(object):
32
"""Pull history from one branch to another."""
33
def __init__(self, to_branch, from_branch, revision_limit=None, pb=None):
34
self.to_branch = to_branch
35
self.from_branch = from_branch
36
self.revision_limit = revision_limit
38
self.pb = bzrlib.ui.ui_factory.progress_bar()
41
self._scan_histories()
42
self.failed_revisions = []
47
def _scan_histories(self):
48
self.from_history = from_branch.revision_history()
49
self.required_revisions = set(from_history)
50
self.to_history = to_branch.revision_history()
51
if self.revision_limit:
52
raise NotImplementedError('sorry, revision_limit not handled yet')
53
self.need_revisions = []
54
for rev_id in self.from_history:
55
if not has_revision(self.to_branch):
56
self.need_revisions.append(rev_id)
57
mutter('need to get revision {%s}', rev_id)
61
while self.need_revisions:
62
rev_id = self.need_revisions.pop()
63
mutter('try to get revision {%s}', rev_id)
69
def has_revision(branch, revision_id):
71
branch.get_revision_xml(revision_id)
73
except bzrlib.errors.NoSuchRevision:
77
def old_greedy_fetch(to_branch, from_branch, revision=None, pb=None):
78
"""Copy all history from one branch to another.
81
If set, copy only up to this point in the source branch.
83
@returns: number copied, missing ids
85
from_history = from_branch.revision_history()
86
required_revisions = set(from_history)
88
if revision is not None:
89
required_revisions.add(revision)
91
rev_index = from_history.index(revision)
94
if rev_index is not None:
95
from_history = from_history[:rev_index + 1]
97
from_history = [revision]
98
to_history = to_branch.revision_history()
100
for rev_id in from_history:
101
if not has_revision(to_branch, rev_id):
102
missing.append(rev_id)
104
# recurse down through the revision graph, looking for things that
107
while len(missing) > 0:
108
installed, failed = to_branch.install_revisions(from_branch,
109
revision_ids=missing,
112
required_failed = failed.intersection(required_revisions)
113
if len(required_failed) > 0:
114
raise bzrlib.errors.InstallFailed(required_failed)
115
for rev_id in failed:
116
note("Failed to install %s" % rev_id)
117
all_failed.update(failed)
119
for rev_id in missing:
121
revision = from_branch.get_revision(rev_id)
122
except bzrlib.errors.NoSuchRevision:
123
if revision in from_history:
127
for parent in [p.revision_id for p in revision.parents]:
128
if not has_revision(to_branch, parent):
129
new_missing.add(parent)
130
missing = new_missing
131
return count, all_failed
134
def old_install_revisions(branch, other, revision_ids, pb):
135
"""Copy revisions from other branch into branch.
137
This is a lower-level function used by a pull or a merge. It
138
incorporates some history from one branch into another, but
139
does not update the revision history or operate on the working
143
Sequence of revisions to copy.
146
Progress bar for copying.
149
if hasattr(other.revision_store, "prefetch"):
150
other.revision_store.prefetch(revision_ids)
151
if hasattr(other.inventory_store, "prefetch"):
152
other.inventory_store.prefetch(revision_ids)
155
pb = bzrlib.ui.ui_factory.progress_bar()
162
for i, rev_id in enumerate(revision_ids):
163
pb.update('fetching revision', i+1, len(revision_ids))
165
rev = other.get_revision(rev_id)
166
except bzrlib.errors.NoSuchRevision:
170
revisions.append(rev)
171
inv = other.get_inventory(rev_id)
172
for key, entry in inv.iter_entries():
173
if entry.text_id is None:
175
if entry.text_id not in branch.text_store:
176
needed_texts.add(entry.text_id)
180
count, cp_fail = branch.text_store.copy_multi(other.text_store,
182
count, cp_fail = branch.inventory_store.copy_multi(other.inventory_store,
184
count, cp_fail = branch.revision_store.copy_multi(other.revision_store,
187
assert len(cp_fail) == 0
188
return count, failures