1393.1.5
by Martin Pool
- move copy_branch into bzrlib.clone |
1 |
# Copyright (C) 2004, 2005 by Canonical Ltd
|
2 |
||
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.
|
|
7 |
||
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.
|
|
12 |
||
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
|
|
16 |
||
1393.1.20
by Martin Pool
- faster branch command that just copies whole weaves without unpacking them |
17 |
"""Make a copy of an entire branch and all its history.
|
18 |
||
19 |
This is the underlying function for the branch/get/clone commands."""
|
|
20 |
||
1393.1.5
by Martin Pool
- move copy_branch into bzrlib.clone |
21 |
# TODO: This could be done *much* more efficiently by just copying
|
22 |
# all the whole weaves and revisions, rather than getting one
|
|
23 |
# revision at a time.
|
|
24 |
||
1393.1.20
by Martin Pool
- faster branch command that just copies whole weaves without unpacking them |
25 |
# TODO: Optionally, after copying, discard any irrelevant information from
|
26 |
# the destination, such as revisions committed after the last one we're interested
|
|
27 |
# in. This needs to apply a weave prune operation (not written yet) to each
|
|
28 |
# weave one by one.
|
|
29 |
||
30 |
# Copying must be done in a way that supports http transports, where we
|
|
31 |
# can't list a directory, and therefore have to rely on information
|
|
32 |
# retrieved from top-level objects whose names we do know.
|
|
33 |
#
|
|
34 |
# In practice this means we first fetch the revision history and ancestry.
|
|
35 |
# These give us a list of all the revisions that need to be fetched. We
|
|
36 |
# also get the inventory weave. We then just need to get a list of all
|
|
37 |
# file-ids ever referenced by this tree. (It might be nice to keep a list
|
|
38 |
# of them directly.) This is done by walking over the inventories of all
|
|
39 |
# copied revisions and accumulating a list of file ids.
|
|
40 |
#
|
|
41 |
# For local branches it is possible to optimize this considerably in two
|
|
42 |
# ways. One is to hardlink the files (if possible and requested), rather
|
|
43 |
# than copying them. Another is to simply list the directory rather than
|
|
44 |
# walking through the inventories to find out what files are present -- but
|
|
45 |
# there it may be better to just be consistent with remote branches.
|
|
46 |
||
1393.1.11
by Martin Pool
- copy_branch creates destination if it doesn't exist |
47 |
import os |
1393.1.5
by Martin Pool
- move copy_branch into bzrlib.clone |
48 |
import sys |
49 |
||
1092.2.24
by Robert Collins
merge from martins newformat branch - brings in transport abstraction |
50 |
import bzrlib |
1393.1.10
by Martin Pool
- factor out stereotyped use of merge to build working dir |
51 |
from bzrlib.merge import build_working_dir |
1393.1.5
by Martin Pool
- move copy_branch into bzrlib.clone |
52 |
from bzrlib.branch import Branch |
1393.1.20
by Martin Pool
- faster branch command that just copies whole weaves without unpacking them |
53 |
from bzrlib.trace import mutter, note |
54 |
from bzrlib.store import copy_all |
|
1185.21.7
by Jelmer Vernooij
Properly import exception. |
55 |
from bzrlib.errors import InvalidRevisionId |
1393.1.5
by Martin Pool
- move copy_branch into bzrlib.clone |
56 |
|
57 |
def copy_branch(branch_from, to_location, revision=None, basis_branch=None): |
|
58 |
"""Copy branch_from into the existing directory to_location.
|
|
59 |
||
1393.1.20
by Martin Pool
- faster branch command that just copies whole weaves without unpacking them |
60 |
Returns the newly created branch object.
|
61 |
||
62 |
revision
|
|
63 |
If not None, only revisions up to this point will be copied.
|
|
64 |
The head of the new branch will be that revision. Must be a
|
|
65 |
revid or None.
|
|
66 |
||
67 |
to_location -- The destination directory; must either exist and be
|
|
68 |
empty, or not exist, in which case it is created.
|
|
69 |
||
70 |
basis_branch
|
|
71 |
A local branch to copy revisions from, related to branch_from.
|
|
72 |
This is used when branching from a remote (slow) branch, and we have
|
|
73 |
a local branch that might contain some relevant revisions.
|
|
74 |
"""
|
|
75 |
assert isinstance(branch_from, Branch) |
|
76 |
assert isinstance(to_location, basestring) |
|
77 |
if basis_branch is not None: |
|
78 |
note("basis_branch is not supported for fast weave copy yet.") |
|
1185.15.5
by Martin Pool
- clone should be done with the source branch read-locked |
79 |
branch_from.lock_read() |
80 |
try: |
|
81 |
if not (branch_from.weave_store.listable() |
|
82 |
and branch_from.revision_store.listable()): |
|
83 |
return copy_branch_slower(branch_from, to_location, revision, |
|
84 |
basis_branch) |
|
85 |
history = _get_truncated_history(branch_from, revision) |
|
86 |
if not bzrlib.osutils.lexists(to_location): |
|
87 |
os.mkdir(to_location) |
|
88 |
branch_to = Branch.initialize(to_location) |
|
89 |
mutter("copy branch from %s to %s", branch_from, branch_to) |
|
1457.1.10
by Robert Collins
Move set_root_id to WorkingTree. |
90 |
branch_to.working_tree().set_root_id(branch_from.get_root_id()) |
1185.15.5
by Martin Pool
- clone should be done with the source branch read-locked |
91 |
_copy_control_weaves(branch_from, branch_to) |
92 |
_copy_text_weaves(branch_from, branch_to) |
|
93 |
_copy_revision_store(branch_from, branch_to) |
|
1185.33.59
by Martin Pool
[patch] keep a cached basis inventory (Johan Rydberg) |
94 |
branch_to.set_parent(branch_from.base) |
95 |
# must be done *after* history is copied across
|
|
96 |
branch_to.append_revision(*history) |
|
1185.15.5
by Martin Pool
- clone should be done with the source branch read-locked |
97 |
build_working_dir(to_location) |
98 |
mutter("copied") |
|
99 |
return branch_to |
|
100 |
finally: |
|
101 |
branch_from.unlock() |
|
1393.1.20
by Martin Pool
- faster branch command that just copies whole weaves without unpacking them |
102 |
|
103 |
||
1185.31.1
by John Arbash Meinel
Made InvalidRevisionId take the revision_id as a parameter, fixed up locations where it was called. |
104 |
def _get_truncated_history(branch_from, revision_id): |
1393.1.23
by Martin Pool
- fix cloning of part of a branch |
105 |
history = branch_from.revision_history() |
1185.31.1
by John Arbash Meinel
Made InvalidRevisionId take the revision_id as a parameter, fixed up locations where it was called. |
106 |
if revision_id is None: |
1393.1.23
by Martin Pool
- fix cloning of part of a branch |
107 |
return history |
108 |
try: |
|
1185.31.1
by John Arbash Meinel
Made InvalidRevisionId take the revision_id as a parameter, fixed up locations where it was called. |
109 |
idx = history.index(revision_id) |
1393.1.23
by Martin Pool
- fix cloning of part of a branch |
110 |
except ValueError: |
1185.16.103
by mbp at sourcefrog
Fix up all calls to InvalidRevisionId() to specify parameters. |
111 |
raise InvalidRevisionId(revision_id=revision, branch=branch_from) |
1393.1.23
by Martin Pool
- fix cloning of part of a branch |
112 |
return history[:idx+1] |
113 |
||
1393.1.20
by Martin Pool
- faster branch command that just copies whole weaves without unpacking them |
114 |
def _copy_text_weaves(branch_from, branch_to): |
115 |
copy_all(branch_from.weave_store, branch_to.weave_store) |
|
116 |
||
117 |
||
118 |
def _copy_revision_store(branch_from, branch_to): |
|
119 |
copy_all(branch_from.revision_store, branch_to.revision_store) |
|
120 |
||
121 |
||
122 |
def _copy_control_weaves(branch_from, branch_to): |
|
123 |
to_control = branch_to.control_weaves |
|
124 |
from_control = branch_from.control_weaves |
|
1415
by Robert Collins
remove the ancestry weave file |
125 |
to_control.copy_multi(from_control, ['inventory']) |
1393.1.20
by Martin Pool
- faster branch command that just copies whole weaves without unpacking them |
126 |
|
127 |
||
128 |
def copy_branch_slower(branch_from, to_location, revision=None, basis_branch=None): |
|
129 |
"""Copy branch_from into the existing directory to_location.
|
|
130 |
||
1393.1.5
by Martin Pool
- move copy_branch into bzrlib.clone |
131 |
revision
|
132 |
If not None, only revisions up to this point will be copied.
|
|
133 |
The head of the new branch will be that revision. Must be a
|
|
134 |
revid or None.
|
|
135 |
||
1393.1.11
by Martin Pool
- copy_branch creates destination if it doesn't exist |
136 |
to_location -- The destination directory; must either exist and be
|
137 |
empty, or not exist, in which case it is created.
|
|
1393.1.5
by Martin Pool
- move copy_branch into bzrlib.clone |
138 |
|
139 |
revno
|
|
140 |
The revision to copy up to
|
|
141 |
||
142 |
basis_branch
|
|
1393.1.12
by Martin Pool
- merge Transport from John into newformat |
143 |
A local branch to copy revisions from, related to branch_from.
|
144 |
This is used when branching from a remote (slow) branch, and we have
|
|
145 |
a local branch that might contain some relevant revisions.
|
|
1393.1.5
by Martin Pool
- move copy_branch into bzrlib.clone |
146 |
"""
|
147 |
assert isinstance(branch_from, Branch) |
|
148 |
assert isinstance(to_location, basestring) |
|
1092.2.24
by Robert Collins
merge from martins newformat branch - brings in transport abstraction |
149 |
if not bzrlib.osutils.lexists(to_location): |
1393.1.11
by Martin Pool
- copy_branch creates destination if it doesn't exist |
150 |
os.mkdir(to_location) |
1393.1.5
by Martin Pool
- move copy_branch into bzrlib.clone |
151 |
br_to = Branch.initialize(to_location) |
152 |
mutter("copy branch from %s to %s", branch_from, br_to) |
|
153 |
if basis_branch is not None: |
|
154 |
basis_branch.push_stores(br_to) |
|
1457.1.10
by Robert Collins
Move set_root_id to WorkingTree. |
155 |
br_to.working_tree().set_root_id(branch_from.get_root_id()) |
1393.1.5
by Martin Pool
- move copy_branch into bzrlib.clone |
156 |
if revision is None: |
157 |
revision = branch_from.last_revision() |
|
158 |
br_to.update_revisions(branch_from, stop_revision=revision) |
|
1393.1.10
by Martin Pool
- factor out stereotyped use of merge to build working dir |
159 |
build_working_dir(to_location) |
1393.1.5
by Martin Pool
- move copy_branch into bzrlib.clone |
160 |
br_to.set_parent(branch_from.base) |
161 |
mutter("copied") |
|
162 |
return br_to |