~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branchbuilder.py

  • Committer: Andrew Bennetts
  • Date: 2009-07-27 05:35:00 UTC
  • mfrom: (4570 +trunk)
  • mto: (4634.6.29 2.0)
  • mto: This revision was merged to the branch mainline in revision 4680.
  • Revision ID: andrew.bennetts@canonical.com-20090727053500-q76zsn2dx33jhmj5
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
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
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Utility for create branches with particular contents."""
18
18
 
56
56
        a series in progress, it should be None.
57
57
    """
58
58
 
59
 
    def __init__(self, transport, format=None):
 
59
    def __init__(self, transport=None, format=None, branch=None):
60
60
        """Construct a BranchBuilder on transport.
61
61
 
62
62
        :param transport: The transport the branch should be created on.
64
64
            it will be created.
65
65
        :param format: Either a BzrDirFormat, or the name of a format in the
66
66
            bzrdir format registry for the branch to be built.
 
67
        :param branch: An already constructed branch to use.  This param is
 
68
            mutually exclusive with the transport and format params.
67
69
        """
68
 
        if not transport.has('.'):
69
 
            transport.mkdir('.')
70
 
        if format is None:
71
 
            format = 'default'
72
 
        if isinstance(format, str):
73
 
            format = bzrdir.format_registry.make_bzrdir(format)
74
 
        self._branch = bzrdir.BzrDir.create_branch_convenience(transport.base,
75
 
            format=format, force_new_tree=False)
 
70
        if branch is not None:
 
71
            if format is not None:
 
72
                raise AssertionError(
 
73
                    "branch and format kwargs are mutually exclusive")
 
74
            if transport is not None:
 
75
                raise AssertionError(
 
76
                    "branch and transport kwargs are mutually exclusive")
 
77
            self._branch = branch
 
78
        else:
 
79
            if not transport.has('.'):
 
80
                transport.mkdir('.')
 
81
            if format is None:
 
82
                format = 'default'
 
83
            if isinstance(format, str):
 
84
                format = bzrdir.format_registry.make_bzrdir(format)
 
85
            self._branch = bzrdir.BzrDir.create_branch_convenience(
 
86
                transport.base, format=format, force_new_tree=False)
76
87
        self._tree = None
77
88
 
78
89
    def build_commit(self, **commit_kwargs):
100
111
            reporter=reporter,
101
112
            **kwargs)
102
113
 
103
 
    def _move_branch_pointer(self, new_revision_id):
 
114
    def _move_branch_pointer(self, new_revision_id,
 
115
        allow_leftmost_as_ghost=False):
104
116
        """Point self._branch to a different revision id."""
105
117
        self._branch.lock_write()
106
118
        try:
107
119
            # We don't seem to have a simple set_last_revision(), so we
108
120
            # implement it here.
109
121
            cur_revno, cur_revision_id = self._branch.last_revision_info()
110
 
            g = self._branch.repository.get_graph()
111
 
            new_revno = g.find_distance_to_null(new_revision_id,
112
 
                                                [(cur_revision_id, cur_revno)])
113
 
            self._branch.set_last_revision_info(new_revno, new_revision_id)
 
122
            try:
 
123
                g = self._branch.repository.get_graph()
 
124
                new_revno = g.find_distance_to_null(new_revision_id,
 
125
                    [(cur_revision_id, cur_revno)])
 
126
                self._branch.set_last_revision_info(new_revno, new_revision_id)
 
127
            except errors.GhostRevisionsHaveNoRevno:
 
128
                if not allow_leftmost_as_ghost:
 
129
                    raise
 
130
                new_revno = 1
114
131
        finally:
115
132
            self._branch.unlock()
116
133
        if self._tree is not None:
144
161
        self._tree = None
145
162
 
146
163
    def build_snapshot(self, revision_id, parent_ids, actions,
147
 
                       message=None, timestamp=None):
 
164
        message=None, timestamp=None, allow_leftmost_as_ghost=False,
 
165
        committer=None, timezone=None):
148
166
        """Build a commit, shaped in a specific way.
149
167
 
150
168
        :param revision_id: The handle for the new commit, can be None
159
177
            commit message will be written.
160
178
        :param timestamp: If non-None, set the timestamp of the commit to this
161
179
            value.
 
180
        :param timezone: An optional timezone for timestamp.
 
181
        :param committer: An optional username to use for commit
 
182
        :param allow_leftmost_as_ghost: True if the leftmost parent should be
 
183
            permitted to be a ghost.
162
184
        :return: The revision_id of the new commit
163
185
        """
164
186
        if parent_ids is not None:
165
187
            base_id = parent_ids[0]
166
188
            if base_id != self._branch.last_revision():
167
 
                self._move_branch_pointer(base_id)
 
189
                self._move_branch_pointer(base_id,
 
190
                    allow_leftmost_as_ghost=allow_leftmost_as_ghost)
168
191
 
169
192
        if self._tree is not None:
170
193
            tree = self._tree
173
196
        tree.lock_write()
174
197
        try:
175
198
            if parent_ids is not None:
176
 
                tree.set_parent_ids(parent_ids)
 
199
                tree.set_parent_ids(parent_ids,
 
200
                    allow_leftmost_as_ghost=allow_leftmost_as_ghost)
177
201
            # Unfortunately, MemoryTree.add(directory) just creates an
178
202
            # inventory entry. And the only public function to create a
179
203
            # directory is MemoryTree.mkdir() which creates the directory, but
220
244
            for file_id, content in new_contents.iteritems():
221
245
                tree.put_file_bytes_non_atomic(file_id, content)
222
246
            return self._do_commit(tree, message=message, rev_id=revision_id,
223
 
                timestamp=timestamp)
 
247
                timestamp=timestamp, timezone=timezone, committer=committer)
224
248
        finally:
225
249
            tree.unlock()
226
250