~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/weave.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-04-26 05:42:38 UTC
  • mfrom: (2432.2.9 hpss-protocol2)
  • Revision ID: pqm@pqm.ubuntu.com-20070426054238-v6k5ge3z766vaafk
(Andrew Bennetts, Robert Collins) Smart server protocol versioning.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#! /usr/bin/python
2
2
 
3
3
# Copyright (C) 2005 Canonical Ltd
4
 
 
 
4
#
5
5
# This program is free software; you can redistribute it and/or modify
6
6
# it under the terms of the GNU General Public License as published by
7
7
# the Free Software Foundation; either version 2 of the License, or
8
8
# (at your option) any later version.
9
 
 
 
9
#
10
10
# This program is distributed in the hope that it will be useful,
11
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
13
# GNU General Public License for more details.
14
 
 
 
14
#
15
15
# You should have received a copy of the GNU General Public License
16
16
# along with this program; if not, write to the Free Software
17
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
27
# property.
28
28
 
29
29
# TODO: Nothing here so far assumes the lines are really \n newlines,
30
 
# rather than being split up in some other way.  We could accomodate
 
30
# rather than being split up in some other way.  We could accommodate
31
31
# binaries, perhaps by naively splitting on \n or perhaps using
32
32
# something like a rolling checksum.
33
33
 
70
70
 
71
71
from copy import copy
72
72
from cStringIO import StringIO
73
 
from difflib import SequenceMatcher
74
73
import os
75
74
import sha
76
75
import time
 
76
import warnings
77
77
 
 
78
from bzrlib import (
 
79
    progress,
 
80
    )
78
81
from bzrlib.trace import mutter
79
82
from bzrlib.errors import (WeaveError, WeaveFormatError, WeaveParentMismatch,
80
83
        RevisionAlreadyPresent,
84
87
        )
85
88
import bzrlib.errors as errors
86
89
from bzrlib.osutils import sha_strings
87
 
from bzrlib.symbol_versioning import *
 
90
import bzrlib.patiencediff
 
91
from bzrlib.symbol_versioning import (deprecated_method,
 
92
        deprecated_function,
 
93
        zero_eight,
 
94
        )
88
95
from bzrlib.tsort import topo_sort
89
96
from bzrlib.versionedfile import VersionedFile, InterVersionedFile
90
97
from bzrlib.weavefile import _read_weave_v5, write_weave_v5
180
187
    """
181
188
 
182
189
    __slots__ = ['_weave', '_parents', '_sha1s', '_names', '_name_map',
183
 
                 '_weave_name']
 
190
                 '_weave_name', '_matcher']
184
191
    
185
 
    def __init__(self, weave_name=None, access_mode='w'):
 
192
    def __init__(self, weave_name=None, access_mode='w', matcher=None):
186
193
        super(Weave, self).__init__(access_mode)
187
194
        self._weave = []
188
195
        self._parents = []
190
197
        self._names = []
191
198
        self._name_map = {}
192
199
        self._weave_name = weave_name
 
200
        if matcher is None:
 
201
            self._matcher = bzrlib.patiencediff.PatienceSequenceMatcher
 
202
        else:
 
203
            self._matcher = matcher
193
204
 
194
205
    def __repr__(self):
195
206
        return "Weave(%r)" % self._weave_name
227
238
 
228
239
    @deprecated_method(zero_eight)
229
240
    def lookup(self, name):
230
 
        """Backwards compatability thunk:
 
241
        """Backwards compatibility thunk:
231
242
 
232
243
        Return name, as name is valid in the api now, and spew deprecation
233
244
        warnings everywhere.
236
247
 
237
248
    def _lookup(self, name):
238
249
        """Convert symbolic version name to index."""
 
250
        self.check_not_reserved_id(name)
239
251
        try:
240
252
            return self._name_map[name]
241
253
        except KeyError:
257
269
 
258
270
    def has_version(self, version_id):
259
271
        """See VersionedFile.has_version."""
260
 
        return self._name_map.has_key(version_id)
 
272
        return (version_id in self._name_map)
261
273
 
262
274
    __contains__ = has_version
263
275
 
518
530
        if lines == basis_lines:
519
531
            return new_version            
520
532
 
521
 
        # add a sentinal, because we can also match against the final line
 
533
        # add a sentinel, because we can also match against the final line
522
534
        basis_lineno.append(len(self._weave))
523
535
 
524
536
        # XXX: which line of the weave should we really consider
528
540
        #print 'basis_lines:', basis_lines
529
541
        #print 'new_lines:  ', lines
530
542
 
531
 
        s = SequenceMatcher(None, basis_lines, lines)
 
543
        s = self._matcher(None, basis_lines, lines)
532
544
 
533
545
        # offset gives the number of lines that have been inserted
534
546
        # into the weave up to the current point; if the original edit instruction
629
641
        """
630
642
        return len(other_parents.difference(my_parents)) == 0
631
643
 
632
 
    def annotate(self, version_id):
633
 
        if isinstance(version_id, int):
634
 
            warn('Weave.annotate(int) is deprecated. Please use version names'
635
 
                 ' in all circumstances as of 0.8',
636
 
                 DeprecationWarning,
637
 
                 stacklevel=2
638
 
                 )
639
 
            result = []
640
 
            for origin, lineno, text in self._extract([version_id]):
641
 
                result.append((origin, text))
642
 
            return result
643
 
        else:
644
 
            return super(Weave, self).annotate(version_id)
645
 
    
646
644
    def annotate_iter(self, version_id):
647
645
        """Yield list of (version-id, line) pairs for the specified version.
648
646
 
656
654
        """_walk has become visit, a supported api."""
657
655
        return self._walk_internal()
658
656
 
659
 
    def iter_lines_added_or_present_in_versions(self, version_ids=None):
 
657
    def iter_lines_added_or_present_in_versions(self, version_ids=None,
 
658
                                                pb=None):
660
659
        """See VersionedFile.iter_lines_added_or_present_in_versions()."""
661
660
        if version_ids is None:
662
661
            version_ids = self.versions()
1065
1064
 
1066
1065
    @deprecated_method(zero_eight)
1067
1066
    def reweave(self, other, pb=None, msg=None):
1068
 
        """reweave has been superceded by plain use of join."""
 
1067
        """reweave has been superseded by plain use of join."""
1069
1068
        return self.join(other, pb, msg)
1070
1069
 
1071
1070
    def _reweave(self, other, pb, msg):
1108
1107
 
1109
1108
    def _add_lines(self, version_id, parents, lines, parent_texts):
1110
1109
        """Add a version and save the weave."""
 
1110
        self.check_not_reserved_id(version_id)
1111
1111
        result = super(WeaveFile, self)._add_lines(version_id, parents, lines,
1112
1112
                                                   parent_texts)
1113
1113
        self._save()
1124
1124
        sio = StringIO()
1125
1125
        write_weave_v5(self, sio)
1126
1126
        sio.seek(0)
1127
 
        transport.put(name + WeaveFile.WEAVE_SUFFIX, sio, self._filemode)
 
1127
        transport.put_file(name + WeaveFile.WEAVE_SUFFIX, sio, self._filemode)
1128
1128
 
1129
1129
    def create_empty(self, name, transport, filemode=None):
1130
1130
        return WeaveFile(name, transport, filemode, create=True)
1135
1135
        sio = StringIO()
1136
1136
        write_weave_v5(self, sio)
1137
1137
        sio.seek(0)
1138
 
        self._transport.put(self._weave_name + WeaveFile.WEAVE_SUFFIX,
1139
 
                            sio,
1140
 
                            self._filemode)
 
1138
        self._transport.put_file(self._weave_name + WeaveFile.WEAVE_SUFFIX,
 
1139
                                 sio,
 
1140
                                 self._filemode)
1141
1141
 
1142
1142
    @staticmethod
1143
1143
    def get_suffixes():
1235
1235
    from bzrlib.weavefile import read_weave
1236
1236
 
1237
1237
    wf = file(weave_file, 'rb')
1238
 
    w = read_weave(wf, WeaveVersionedFile)
 
1238
    w = read_weave(wf)
1239
1239
    # FIXME: doesn't work on pipes
1240
1240
    weave_size = wf.tell()
1241
1241
 
1356
1356
        sys.stdout.writelines(w.get_iter(int(argv[3])))
1357
1357
        
1358
1358
    elif cmd == 'diff':
1359
 
        from difflib import unified_diff
1360
1359
        w = readit()
1361
1360
        fn = argv[2]
1362
1361
        v1, v2 = map(int, argv[3:5])
1363
1362
        lines1 = w.get(v1)
1364
1363
        lines2 = w.get(v2)
1365
 
        diff_gen = unified_diff(lines1, lines2,
 
1364
        diff_gen = bzrlib.patiencediff.unified_diff(lines1, lines2,
1366
1365
                                '%s version %d' % (fn, v1),
1367
1366
                                '%s version %d' % (fn, v2))
1368
1367
        sys.stdout.writelines(diff_gen)
1416
1415
        raise ValueError('unknown command %r' % cmd)
1417
1416
    
1418
1417
 
1419
 
 
1420
 
def profile_main(argv):
1421
 
    import tempfile, hotshot, hotshot.stats
1422
 
 
1423
 
    prof_f = tempfile.NamedTemporaryFile()
1424
 
 
1425
 
    prof = hotshot.Profile(prof_f.name)
1426
 
 
1427
 
    ret = prof.runcall(main, argv)
1428
 
    prof.close()
1429
 
 
1430
 
    stats = hotshot.stats.load(prof_f.name)
1431
 
    #stats.strip_dirs()
1432
 
    stats.sort_stats('cumulative')
1433
 
    ## XXX: Might like to write to stderr or the trace file instead but
1434
 
    ## print_stats seems hardcoded to stdout
1435
 
    stats.print_stats(20)
1436
 
            
1437
 
    return ret
1438
 
 
1439
 
 
1440
 
def lsprofile_main(argv): 
1441
 
    from bzrlib.lsprof import profile
1442
 
    ret,stats = profile(main, argv)
1443
 
    stats.sort()
1444
 
    stats.pprint()
1445
 
    return ret
1446
 
 
1447
 
 
1448
1418
if __name__ == '__main__':
1449
1419
    import sys
1450
 
    if '--profile' in sys.argv:
1451
 
        args = sys.argv[:]
1452
 
        args.remove('--profile')
1453
 
        sys.exit(profile_main(args))
1454
 
    elif '--lsprof' in sys.argv:
1455
 
        args = sys.argv[:]
1456
 
        args.remove('--lsprof')
1457
 
        sys.exit(lsprofile_main(args))
1458
 
    else:
1459
 
        sys.exit(main(sys.argv))
 
1420
    sys.exit(main(sys.argv))
1460
1421
 
1461
1422
 
1462
1423
class InterWeave(InterVersionedFile):