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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
20
import bzrlib.errors
17
21
from bzrlib.trace import mutter, note
18
22
from bzrlib.branch import Branch
19
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)
23
69
def has_revision(branch, revision_id):
31
def greedy_fetch(to_branch, from_branch, revision=None, pb=None):
32
"""Copy a revision and all available ancestors from one branch to another
33
If no revision is specified, uses the last revision in the source branch's
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
36
85
from_history = from_branch.revision_history()
37
86
required_revisions = set(from_history)
51
100
for rev_id in from_history:
52
101
if not has_revision(to_branch, rev_id):
53
102
missing.append(rev_id)
104
# recurse down through the revision graph, looking for things that
56
107
while len(missing) > 0:
57
108
installed, failed = to_branch.install_revisions(from_branch,
76
127
for parent in [p.revision_id for p in revision.parents]:
77
128
if not has_revision(to_branch, parent):
78
new_missing.append(parent)
129
new_missing.add(parent)
79
130
missing = new_missing
80
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