~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Martin Packman
  • Date: 2012-02-01 13:24:42 UTC
  • mto: (6437.23.4 2.5)
  • mto: This revision was merged to the branch mainline in revision 6462.
  • Revision ID: martin.packman@canonical.com-20120201132442-ela7jc4mxv4b058o
Treat path for .bzr.log as unicode

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2012 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
39
39
    repository,
40
40
    revision as _mod_revision,
41
41
    rio,
42
 
    shelf,
43
42
    tag as _mod_tag,
44
43
    transport,
45
44
    ui,
252
251
        """
253
252
        raise NotImplementedError(self._get_config)
254
253
 
255
 
    def store_uncommitted(self, creator):
256
 
        """Store uncommitted changes from a ShelfCreator.
257
 
 
258
 
        :param creator: The ShelfCreator containing uncommitted changes, or
259
 
            None to delete any stored changes.
260
 
        :raises: ChangesAlreadyStored if the branch already has changes.
261
 
        """
262
 
        raise NotImplementedError(self.store_uncommitted)
263
 
 
264
 
    def get_unshelver(self, tree):
265
 
        """Return a shelf.Unshelver for this branch and tree.
266
 
 
267
 
        :param tree: The tree to use to construct the Unshelver.
268
 
        :return: an Unshelver or None if no changes are stored.
269
 
        """
270
 
        raise NotImplementedError(self.get_unshelver)
271
 
 
272
254
    def _get_fallback_repository(self, url, possible_transports):
273
255
        """Get the repository we fallback to at url."""
274
256
        url = urlutils.join(self.base, url)
784
766
        """Print `file` to stdout."""
785
767
        raise NotImplementedError(self.print_file)
786
768
 
 
769
    @deprecated_method(deprecated_in((2, 4, 0)))
 
770
    def set_revision_history(self, rev_history):
 
771
        """See Branch.set_revision_history."""
 
772
        self._set_revision_history(rev_history)
 
773
 
 
774
    @needs_write_lock
 
775
    def _set_revision_history(self, rev_history):
 
776
        if len(rev_history) == 0:
 
777
            revid = _mod_revision.NULL_REVISION
 
778
        else:
 
779
            revid = rev_history[-1]
 
780
        if rev_history != self._lefthand_history(revid):
 
781
            raise errors.NotLefthandHistory(rev_history)
 
782
        self.set_last_revision_info(len(rev_history), revid)
 
783
        self._cache_revision_history(rev_history)
 
784
        for hook in Branch.hooks['set_rh']:
 
785
            hook(self, rev_history)
 
786
 
787
787
    @needs_write_lock
788
788
    def set_last_revision_info(self, revno, revision_id):
789
789
        """Set the last revision of this branch.
986
986
        This means the next call to revision_history will need to call
987
987
        _gen_revision_history.
988
988
 
989
 
        This API is semi-public; it is only for use by subclasses, all other
990
 
        code should consider it to be private.
 
989
        This API is semi-public; it only for use by subclasses, all other code
 
990
        should consider it to be private.
991
991
        """
992
992
        self._revision_history_cache = None
993
993
        self._revision_id_to_revno_cache = None
1013
1013
        """
1014
1014
        raise NotImplementedError(self._gen_revision_history)
1015
1015
 
 
1016
    @deprecated_method(deprecated_in((2, 5, 0)))
 
1017
    @needs_read_lock
 
1018
    def revision_history(self):
 
1019
        """Return sequence of revision ids on this branch.
 
1020
 
 
1021
        This method will cache the revision history for as long as it is safe to
 
1022
        do so.
 
1023
        """
 
1024
        return self._revision_history()
 
1025
 
1016
1026
    def _revision_history(self):
1017
1027
        if 'evil' in debug.debug_flags:
1018
1028
            mutter_callsite(3, "revision_history scales with history.")
1052
1062
    def _read_last_revision_info(self):
1053
1063
        raise NotImplementedError(self._read_last_revision_info)
1054
1064
 
 
1065
    @deprecated_method(deprecated_in((2, 4, 0)))
 
1066
    def import_last_revision_info(self, source_repo, revno, revid):
 
1067
        """Set the last revision info, importing from another repo if necessary.
 
1068
 
 
1069
        :param source_repo: Source repository to optionally fetch from
 
1070
        :param revno: Revision number of the new tip
 
1071
        :param revid: Revision id of the new tip
 
1072
        """
 
1073
        if not self.repository.has_same_location(source_repo):
 
1074
            self.repository.fetch(source_repo, revision_id=revid)
 
1075
        self.set_last_revision_info(revno, revid)
 
1076
 
1055
1077
    def import_last_revision_info_and_tags(self, source, revno, revid,
1056
1078
                                           lossy=False):
1057
1079
        """Set the last revision info, importing from another repo if necessary.
1595
1617
    def __ne__(self, other):
1596
1618
        return not (self == other)
1597
1619
 
 
1620
    @classmethod
 
1621
    @deprecated_method(deprecated_in((2, 4, 0)))
 
1622
    def get_default_format(klass):
 
1623
        """Return the current default format."""
 
1624
        return format_registry.get_default()
 
1625
 
 
1626
    @classmethod
 
1627
    @deprecated_method(deprecated_in((2, 4, 0)))
 
1628
    def get_formats(klass):
 
1629
        """Get all the known formats.
 
1630
 
 
1631
        Warning: This triggers a load of all lazy registered formats: do not
 
1632
        use except when that is desireed.
 
1633
        """
 
1634
        return format_registry._get_all()
 
1635
 
1598
1636
    def get_reference(self, controldir, name=None):
1599
1637
        """Get the target reference of the branch in controldir.
1600
1638
 
1688
1726
        """
1689
1727
        raise NotImplementedError(self.open)
1690
1728
 
 
1729
    @classmethod
 
1730
    @deprecated_method(deprecated_in((2, 4, 0)))
 
1731
    def register_format(klass, format):
 
1732
        """Register a metadir format.
 
1733
 
 
1734
        See MetaDirBranchFormatFactory for the ability to register a format
 
1735
        without loading the code the format needs until it is actually used.
 
1736
        """
 
1737
        format_registry.register(format)
 
1738
 
 
1739
    @classmethod
 
1740
    @deprecated_method(deprecated_in((2, 4, 0)))
 
1741
    def set_default_format(klass, format):
 
1742
        format_registry.set_default(format)
 
1743
 
1691
1744
    def supports_set_append_revisions_only(self):
1692
1745
        """True if this format supports set_append_revisions_only."""
1693
1746
        return False
1700
1753
        """True if this format supports leaving locks in place."""
1701
1754
        return False # by default
1702
1755
 
 
1756
    @classmethod
 
1757
    @deprecated_method(deprecated_in((2, 4, 0)))
 
1758
    def unregister_format(klass, format):
 
1759
        format_registry.remove(format)
 
1760
 
1703
1761
    def __str__(self):
1704
1762
        return self.get_format_description().rstrip()
1705
1763
 
1747
1805
class BranchHooks(Hooks):
1748
1806
    """A dictionary mapping hook name to a list of callables for branch hooks.
1749
1807
 
1750
 
    e.g. ['post_push'] Is the list of items to be called when the
1751
 
    push function is invoked.
 
1808
    e.g. ['set_rh'] Is the list of items to be called when the
 
1809
    set_revision_history function is invoked.
1752
1810
    """
1753
1811
 
1754
1812
    def __init__(self):
1758
1816
        notified.
1759
1817
        """
1760
1818
        Hooks.__init__(self, "bzrlib.branch", "Branch.hooks")
 
1819
        self.add_hook('set_rh',
 
1820
            "Invoked whenever the revision history has been set via "
 
1821
            "set_revision_history. The api signature is (branch, "
 
1822
            "revision_history), and the branch will be write-locked. "
 
1823
            "The set_rh hook can be expensive for bzr to trigger, a better "
 
1824
            "hook to use is Branch.post_change_branch_tip.", (0, 15))
1761
1825
        self.add_hook('open',
1762
1826
            "Called with the Branch object that has been opened after a "
1763
1827
            "branch is opened.", (1, 8))
1981
2045
 
1982
2046
    def _initialize_helper(self, a_bzrdir, utf8_files, name=None,
1983
2047
                           repository=None):
1984
 
        """Initialize a branch in a control dir, with specified files
 
2048
        """Initialize a branch in a bzrdir, with specified files
1985
2049
 
1986
2050
        :param a_bzrdir: The bzrdir to initialize the branch in
1987
2051
        :param utf8_files: The files to create as a list of
2057
2121
            recommend_upgrade=recommend_upgrade, basedir=basedir)
2058
2122
 
2059
2123
 
 
2124
class BzrBranchFormat5(BranchFormatMetadir):
 
2125
    """Bzr branch format 5.
 
2126
 
 
2127
    This format has:
 
2128
     - a revision-history file.
 
2129
     - a format string
 
2130
     - a lock dir guarding the branch itself
 
2131
     - all of this stored in a branch/ subdirectory
 
2132
     - works with shared repositories.
 
2133
 
 
2134
    This format is new in bzr 0.8.
 
2135
    """
 
2136
 
 
2137
    def _branch_class(self):
 
2138
        return BzrBranch5
 
2139
 
 
2140
    @classmethod
 
2141
    def get_format_string(cls):
 
2142
        """See BranchFormat.get_format_string()."""
 
2143
        return "Bazaar-NG branch format 5\n"
 
2144
 
 
2145
    def get_format_description(self):
 
2146
        """See BranchFormat.get_format_description()."""
 
2147
        return "Branch format 5"
 
2148
 
 
2149
    def initialize(self, a_bzrdir, name=None, repository=None,
 
2150
                   append_revisions_only=None):
 
2151
        """Create a branch of this format in a_bzrdir."""
 
2152
        if append_revisions_only:
 
2153
            raise errors.UpgradeRequired(a_bzrdir.user_url)
 
2154
        utf8_files = [('revision-history', ''),
 
2155
                      ('branch-name', ''),
 
2156
                      ]
 
2157
        return self._initialize_helper(a_bzrdir, utf8_files, name, repository)
 
2158
 
 
2159
    def supports_tags(self):
 
2160
        return False
 
2161
 
 
2162
 
2060
2163
class BzrBranchFormat6(BranchFormatMetadir):
2061
2164
    """Branch format with last-revision and tags.
2062
2165
 
2311
2414
 
2312
2415
# formats which have no format string are not discoverable
2313
2416
# and not independently creatable, so are not registered.
 
2417
__format5 = BzrBranchFormat5()
2314
2418
__format6 = BzrBranchFormat6()
2315
2419
__format7 = BzrBranchFormat7()
2316
2420
__format8 = BzrBranchFormat8()
2317
 
format_registry.register_lazy(
2318
 
    "Bazaar-NG branch format 5\n", "bzrlib.branchfmt.fullhistory", "BzrBranchFormat5")
 
2421
format_registry.register(__format5)
2319
2422
format_registry.register(BranchReferenceFormat())
2320
2423
format_registry.register(__format6)
2321
2424
format_registry.register(__format7)
2378
2481
        self.control_files = _control_files
2379
2482
        self._transport = _control_files._transport
2380
2483
        self.repository = _repository
2381
 
        self.conf_store = None
2382
2484
        Branch.__init__(self, possible_transports)
2383
2485
 
2384
2486
    def __str__(self):
2400
2502
        return _mod_config.TransportConfig(self._transport, 'branch.conf')
2401
2503
 
2402
2504
    def _get_config_store(self):
2403
 
        if self.conf_store is None:
2404
 
            self.conf_store =  _mod_config.BranchStore(self)
2405
 
        return self.conf_store
2406
 
 
2407
 
    def _uncommitted_branch(self):
2408
 
        """Return the branch that may contain uncommitted changes."""
2409
 
        master = self.get_master_branch()
2410
 
        if master is not None:
2411
 
            return master
2412
 
        else:
2413
 
            return self
2414
 
 
2415
 
    def store_uncommitted(self, creator):
2416
 
        """Store uncommitted changes from a ShelfCreator.
2417
 
 
2418
 
        :param creator: The ShelfCreator containing uncommitted changes, or
2419
 
            None to delete any stored changes.
2420
 
        :raises: ChangesAlreadyStored if the branch already has changes.
2421
 
        """
2422
 
        branch = self._uncommitted_branch()
2423
 
        if creator is None:
2424
 
            branch._transport.delete('stored-transform')
2425
 
            return
2426
 
        if branch._transport.has('stored-transform'):
2427
 
            raise errors.ChangesAlreadyStored
2428
 
        transform = StringIO()
2429
 
        creator.write_shelf(transform)
2430
 
        transform.seek(0)
2431
 
        branch._transport.put_file('stored-transform', transform)
2432
 
 
2433
 
    def get_unshelver(self, tree):
2434
 
        """Return a shelf.Unshelver for this branch and tree.
2435
 
 
2436
 
        :param tree: The tree to use to construct the Unshelver.
2437
 
        :return: an Unshelver or None if no changes are stored.
2438
 
        """
2439
 
        branch = self._uncommitted_branch()
2440
 
        try:
2441
 
            transform = branch._transport.get('stored-transform')
2442
 
        except errors.NoSuchFile:
2443
 
            return None
2444
 
        return shelf.Unshelver.from_tree_and_shelf(tree, transform)
 
2505
        return _mod_config.BranchStore(self)
2445
2506
 
2446
2507
    def is_locked(self):
2447
2508
        return self.control_files.is_locked()
2455
2516
        """
2456
2517
        if not self.is_locked():
2457
2518
            self._note_lock('w')
 
2519
        # All-in-one needs to always unlock/lock.
 
2520
        repo_control = getattr(self.repository, 'control_files', None)
 
2521
        if self.control_files == repo_control or not self.is_locked():
2458
2522
            self.repository._warn_if_deprecated(self)
2459
2523
            self.repository.lock_write()
2460
2524
            took_lock = True
2475
2539
        """
2476
2540
        if not self.is_locked():
2477
2541
            self._note_lock('r')
 
2542
        # All-in-one needs to always unlock/lock.
 
2543
        repo_control = getattr(self.repository, 'control_files', None)
 
2544
        if self.control_files == repo_control or not self.is_locked():
2478
2545
            self.repository._warn_if_deprecated(self)
2479
2546
            self.repository.lock_read()
2480
2547
            took_lock = True
2490
2557
 
2491
2558
    @only_raises(errors.LockNotHeld, errors.LockBroken)
2492
2559
    def unlock(self):
2493
 
        if self.control_files._lock_count == 1 and self.conf_store is not None:
2494
 
            self.conf_store.save_changes()
2495
2560
        try:
2496
2561
            self.control_files.unlock()
2497
2562
        finally:
 
2563
            # All-in-one needs to always unlock/lock.
 
2564
            repo_control = getattr(self.repository, 'control_files', None)
 
2565
            if (self.control_files == repo_control or
 
2566
                not self.control_files.is_locked()):
 
2567
                self.repository.unlock()
2498
2568
            if not self.control_files.is_locked():
2499
 
                self.repository.unlock()
2500
2569
                # we just released the lock
2501
2570
                self._clear_cached_state()
2502
2571
 
2680
2749
        self.control_transport.put_bytes('format', self._format.as_string())
2681
2750
 
2682
2751
 
 
2752
class FullHistoryBzrBranch(BzrBranch):
 
2753
    """Bzr branch which contains the full revision history."""
 
2754
 
 
2755
    @needs_write_lock
 
2756
    def set_last_revision_info(self, revno, revision_id):
 
2757
        if not revision_id or not isinstance(revision_id, basestring):
 
2758
            raise errors.InvalidRevisionId(revision_id=revision_id, branch=self)
 
2759
        revision_id = _mod_revision.ensure_null(revision_id)
 
2760
        # this old format stores the full history, but this api doesn't
 
2761
        # provide it, so we must generate, and might as well check it's
 
2762
        # correct
 
2763
        history = self._lefthand_history(revision_id)
 
2764
        if len(history) != revno:
 
2765
            raise AssertionError('%d != %d' % (len(history), revno))
 
2766
        self._set_revision_history(history)
 
2767
 
 
2768
    def _read_last_revision_info(self):
 
2769
        rh = self._revision_history()
 
2770
        revno = len(rh)
 
2771
        if revno:
 
2772
            return (revno, rh[-1])
 
2773
        else:
 
2774
            return (0, _mod_revision.NULL_REVISION)
 
2775
 
 
2776
    @deprecated_method(deprecated_in((2, 4, 0)))
 
2777
    @needs_write_lock
 
2778
    def set_revision_history(self, rev_history):
 
2779
        """See Branch.set_revision_history."""
 
2780
        self._set_revision_history(rev_history)
 
2781
 
 
2782
    def _set_revision_history(self, rev_history):
 
2783
        if 'evil' in debug.debug_flags:
 
2784
            mutter_callsite(3, "set_revision_history scales with history.")
 
2785
        check_not_reserved_id = _mod_revision.check_not_reserved_id
 
2786
        for rev_id in rev_history:
 
2787
            check_not_reserved_id(rev_id)
 
2788
        if Branch.hooks['post_change_branch_tip']:
 
2789
            # Don't calculate the last_revision_info() if there are no hooks
 
2790
            # that will use it.
 
2791
            old_revno, old_revid = self.last_revision_info()
 
2792
        if len(rev_history) == 0:
 
2793
            revid = _mod_revision.NULL_REVISION
 
2794
        else:
 
2795
            revid = rev_history[-1]
 
2796
        self._run_pre_change_branch_tip_hooks(len(rev_history), revid)
 
2797
        self._write_revision_history(rev_history)
 
2798
        self._clear_cached_state()
 
2799
        self._cache_revision_history(rev_history)
 
2800
        for hook in Branch.hooks['set_rh']:
 
2801
            hook(self, rev_history)
 
2802
        if Branch.hooks['post_change_branch_tip']:
 
2803
            self._run_post_change_branch_tip_hooks(old_revno, old_revid)
 
2804
 
 
2805
    def _write_revision_history(self, history):
 
2806
        """Factored out of set_revision_history.
 
2807
 
 
2808
        This performs the actual writing to disk.
 
2809
        It is intended to be called by set_revision_history."""
 
2810
        self._transport.put_bytes(
 
2811
            'revision-history', '\n'.join(history),
 
2812
            mode=self.bzrdir._get_file_mode())
 
2813
 
 
2814
    def _gen_revision_history(self):
 
2815
        history = self._transport.get_bytes('revision-history').split('\n')
 
2816
        if history[-1:] == ['']:
 
2817
            # There shouldn't be a trailing newline, but just in case.
 
2818
            history.pop()
 
2819
        return history
 
2820
 
 
2821
    def _synchronize_history(self, destination, revision_id):
 
2822
        if not isinstance(destination, FullHistoryBzrBranch):
 
2823
            super(BzrBranch, self)._synchronize_history(
 
2824
                destination, revision_id)
 
2825
            return
 
2826
        if revision_id == _mod_revision.NULL_REVISION:
 
2827
            new_history = []
 
2828
        else:
 
2829
            new_history = self._revision_history()
 
2830
        if revision_id is not None and new_history != []:
 
2831
            try:
 
2832
                new_history = new_history[:new_history.index(revision_id) + 1]
 
2833
            except ValueError:
 
2834
                rev = self.repository.get_revision(revision_id)
 
2835
                new_history = rev.get_history(self.repository)[1:]
 
2836
        destination._set_revision_history(new_history)
 
2837
 
 
2838
    @needs_write_lock
 
2839
    def generate_revision_history(self, revision_id, last_rev=None,
 
2840
        other_branch=None):
 
2841
        """Create a new revision history that will finish with revision_id.
 
2842
 
 
2843
        :param revision_id: the new tip to use.
 
2844
        :param last_rev: The previous last_revision. If not None, then this
 
2845
            must be a ancestory of revision_id, or DivergedBranches is raised.
 
2846
        :param other_branch: The other branch that DivergedBranches should
 
2847
            raise with respect to.
 
2848
        """
 
2849
        self._set_revision_history(self._lefthand_history(revision_id,
 
2850
            last_rev, other_branch))
 
2851
 
 
2852
 
 
2853
class BzrBranch5(FullHistoryBzrBranch):
 
2854
    """A format 5 branch. This supports new features over plain branches.
 
2855
 
 
2856
    It has support for a master_branch which is the data for bound branches.
 
2857
    """
 
2858
 
 
2859
 
2683
2860
class BzrBranch8(BzrBranch):
2684
2861
    """A branch that stores tree-reference locations."""
2685
2862
 
2965
3142
    :ivar tag_updates: A dict with new tags, see BasicTags.merge_to
2966
3143
    """
2967
3144
 
 
3145
    @deprecated_method(deprecated_in((2, 3, 0)))
 
3146
    def __int__(self):
 
3147
        """Return the relative change in revno.
 
3148
 
 
3149
        :deprecated: Use `new_revno` and `old_revno` instead.
 
3150
        """
 
3151
        return self.new_revno - self.old_revno
 
3152
 
2968
3153
    def report(self, to_file):
2969
3154
        tag_conflicts = getattr(self, "tag_conflicts", None)
2970
3155
        tag_updates = getattr(self, "tag_updates", None)
3000
3185
        target, otherwise it will be None.
3001
3186
    """
3002
3187
 
 
3188
    @deprecated_method(deprecated_in((2, 3, 0)))
 
3189
    def __int__(self):
 
3190
        """Return the relative change in revno.
 
3191
 
 
3192
        :deprecated: Use `new_revno` and `old_revno` instead.
 
3193
        """
 
3194
        return self.new_revno - self.old_revno
 
3195
 
3003
3196
    def report(self, to_file):
3004
3197
        # TODO: This function gets passed a to_file, but then
3005
3198
        # ignores it and calls note() instead. This is also
3052
3245
 
3053
3246
        # Copy source data into target
3054
3247
        new_branch._write_last_revision_info(*branch.last_revision_info())
3055
 
        new_branch.lock_write()
3056
 
        try:
3057
 
            new_branch.set_parent(branch.get_parent())
3058
 
            new_branch.set_bound_location(branch.get_bound_location())
3059
 
            new_branch.set_push_location(branch.get_push_location())
3060
 
        finally:
3061
 
            new_branch.unlock()
 
3248
        new_branch.set_parent(branch.get_parent())
 
3249
        new_branch.set_bound_location(branch.get_bound_location())
 
3250
        new_branch.set_push_location(branch.get_push_location())
3062
3251
 
3063
3252
        # New branch has no tags by default
3064
3253
        new_branch.tags._set_tag_dict({})
3070
3259
 
3071
3260
        # Clean up old files
3072
3261
        new_branch._transport.delete('revision-history')
3073
 
        branch.lock_write()
3074
3262
        try:
3075
 
            try:
3076
 
                branch.set_parent(None)
3077
 
            except errors.NoSuchFile:
3078
 
                pass
3079
 
            branch.set_bound_location(None)
3080
 
        finally:
3081
 
            branch.unlock()
 
3263
            branch.set_parent(None)
 
3264
        except errors.NoSuchFile:
 
3265
            pass
 
3266
        branch.set_bound_location(None)
3082
3267
 
3083
3268
 
3084
3269
class Converter6to7(object):
3161
3346
        raise NotImplementedError(self.fetch)
3162
3347
 
3163
3348
 
3164
 
def _fix_overwrite_type(overwrite):
3165
 
    if isinstance(overwrite, bool):
3166
 
        if overwrite:
3167
 
            return ["history", "tags"]
3168
 
        else:
3169
 
            return []
3170
 
    return overwrite
3171
 
 
3172
 
 
3173
3349
class GenericInterBranch(InterBranch):
3174
3350
    """InterBranch implementation that uses public Branch functions."""
3175
3351
 
3340
3516
        result.target_branch = self.target
3341
3517
        result.old_revno, result.old_revid = self.target.last_revision_info()
3342
3518
        self.source.update_references(self.target)
3343
 
        overwrite = _fix_overwrite_type(overwrite)
3344
3519
        if result.old_revid != stop_revision:
3345
3520
            # We assume that during 'push' this repository is closer than
3346
3521
            # the target.
3347
3522
            graph = self.source.repository.get_graph(self.target.repository)
3348
 
            self._update_revisions(stop_revision,
3349
 
                overwrite=("history" in overwrite),
3350
 
                graph=graph)
 
3523
            self._update_revisions(stop_revision, overwrite=overwrite,
 
3524
                    graph=graph)
3351
3525
        if self.source._push_should_merge_tags():
3352
3526
            result.tag_updates, result.tag_conflicts = (
3353
 
                self.source.tags.merge_to(
3354
 
                self.target.tags, "tags" in overwrite))
 
3527
                self.source.tags.merge_to(self.target.tags, overwrite))
3355
3528
        result.new_revno, result.new_revid = self.target.last_revision_info()
3356
3529
        return result
3357
3530
 
3435
3608
            # -- JRV20090506
3436
3609
            result.old_revno, result.old_revid = \
3437
3610
                self.target.last_revision_info()
3438
 
            overwrite = _fix_overwrite_type(overwrite)
3439
 
            self._update_revisions(stop_revision,
3440
 
                overwrite=("history" in overwrite),
 
3611
            self._update_revisions(stop_revision, overwrite=overwrite,
3441
3612
                graph=graph)
3442
3613
            # TODO: The old revid should be specified when merging tags, 
3443
3614
            # so a tags implementation that versions tags can only 
3444
3615
            # pull in the most recent changes. -- JRV20090506
3445
3616
            result.tag_updates, result.tag_conflicts = (
3446
 
                self.source.tags.merge_to(self.target.tags,
3447
 
                    "tags" in overwrite,
 
3617
                self.source.tags.merge_to(self.target.tags, overwrite,
3448
3618
                    ignore_master=not merge_tags_to_master))
3449
3619
            result.new_revno, result.new_revid = self.target.last_revision_info()
3450
3620
            if _hook_master: