14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
18
"""Foreign branch utilities."""
19
from __future__ import absolute_import
22
21
from bzrlib.branch import (
25
25
from bzrlib.commands import Command, Option
26
26
from bzrlib.repository import Repository
261
261
class cmd_dpush(Command):
262
__doc__ = """Push into a different VCS without any custom bzr metadata.
262
"""Push into a different VCS without any custom bzr metadata.
264
264
This will afterwards rebase the local branch on the remote
265
265
branch unless the --no-rebase option is used, in which case
266
266
the two branches will be out of sync after the push.
268
269
takes_args = ['location?']
269
270
takes_options = [
283
284
def run(self, location=None, remember=False, directory=None,
284
285
no_rebase=False, strict=None):
285
286
from bzrlib import urlutils
286
from bzrlib.controldir import ControlDir
287
from bzrlib.bzrdir import BzrDir
287
288
from bzrlib.errors import BzrCommandError, NoWorkingTree
288
289
from bzrlib.workingtree import WorkingTree
295
296
except NoWorkingTree:
296
297
source_branch = Branch.open(directory)
298
if source_wt is not None:
299
source_wt.check_changed_or_out_of_date(
300
strict, 'dpush_strict',
301
more_error='Use --no-strict to force the push.',
302
more_warning='Uncommitted changes will not be pushed.')
300
strict = source_branch.get_config(
301
).get_user_option_as_bool('dpush_strict')
302
if strict is None: strict = True # default value
303
if strict and source_wt is not None:
304
if (source_wt.has_changes()):
305
raise errors.UncommittedChanges(
306
source_wt, more='Use --no-strict to force the push.')
307
if source_wt.last_revision() != source_wt.branch.last_revision():
308
# The tree has lost sync with its branch, there is little
309
# chance that the user is aware of it but he can still force
310
# the push with --no-strict
311
raise errors.OutOfDateTree(
312
source_wt, more='Use --no-strict to force the push.')
303
313
stored_loc = source_branch.get_push_location()
304
314
if location is None:
305
315
if stored_loc is None:
306
raise BzrCommandError(gettext("No push location known or specified."))
316
raise BzrCommandError("No push location known or specified.")
308
318
display_url = urlutils.unescape_for_display(stored_loc,
309
319
self.outf.encoding)
311
gettext("Using saved location: %s\n") % display_url)
320
self.outf.write("Using saved location: %s\n" % display_url)
312
321
location = stored_loc
314
controldir = ControlDir.open(location)
315
target_branch = controldir.open_branch()
323
bzrdir = BzrDir.open(location)
324
target_branch = bzrdir.open_branch()
316
325
target_branch.lock_write()
319
push_result = source_branch.push(target_branch, lossy=True)
328
push_result = source_branch.lossy_push(target_branch)
320
329
except errors.LossyPushToSameVCS:
321
raise BzrCommandError(gettext("{0!r} and {1!r} are in the same VCS, lossy "
322
"push not necessary. Please use regular push.").format(
323
source_branch, target_branch))
330
raise BzrCommandError("%r and %r are in the same VCS, lossy "
331
"push not necessary. Please use regular push." %
332
(source_branch, target_branch))
324
333
# We successfully created the target, remember it
325
334
if source_branch.get_push_location() is None or remember:
326
# FIXME: Should be done only if we succeed ? -- vila 2012-01-18
327
335
source_branch.set_push_location(target_branch.base)
328
336
if not no_rebase:
329
337
old_last_revid = source_branch.last_revision()
340
348
push_result.report(self.outf)
342
350
target_branch.unlock()
353
class InterToForeignBranch(InterBranch):
355
def lossy_push(self, stop_revision=None):
356
"""Push deltas into another branch.
358
:note: This does not, like push, retain the revision ids from
359
the source branch and will, rather than adding bzr-specific
360
metadata, push only those semantics of the revision that can be
361
natively represented by this branch' VCS.
363
:param target: Target branch
364
:param stop_revision: Revision to push, defaults to last revision.
365
:return: BranchPushResult with an extra member revidmap:
366
A dictionary mapping revision ids from the target branch
367
to new revision ids in the target branch, for each
368
revision that was pushed.
370
raise NotImplementedError(self.lossy_push)