~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/weave.py

  • Committer: Martin Pool
  • Date: 2005-08-18 07:11:44 UTC
  • Revision ID: mbp@sourcefrog.net-20050818071144-ac563170b231e8e1
- if weave tool is invoked with no arguments, show help

- rename weave command from 'info' to 'toc'
  (because it's kind of nerdy information)

Show diffs side-by-side

added added

removed removed

Lines of Context:
51
51
 
52
52
 
53
53
 
 
54
 
54
55
# TODO: Perhaps have copy method for Weave instances?
55
56
 
56
57
# XXX: If we do weaves this way, will a merge still behave the same
62
63
# binaries, perhaps by naively splitting on \n or perhaps using
63
64
# something like a rolling checksum.
64
65
 
 
66
# TODO: Track version names as well as indexes. 
 
67
 
65
68
# TODO: End marker for each version so we can stop reading?
66
69
 
67
70
# TODO: Check that no insertion occurs inside a deletion that was
76
79
# description of which revisions include it.  Nice for checking all
77
80
# shas in parallel.
78
81
 
79
 
# TODO: Using a single _extract routine and then processing the output
80
 
# is probably inefficient.  It's simple enough that we can afford to
81
 
# have slight specializations for different ways its used: annotate,
82
 
# basis for add, get, etc.
83
 
 
84
 
# TODO: Perhaps the API should work only in names to hide the integer
85
 
# indexes from the user?
86
 
 
87
 
 
88
 
 
89
 
import sha
90
82
 
91
83
 
92
84
 
174
166
        each version; the parent's parents are implied.
175
167
 
176
168
    _sha1s
177
 
        List of hex SHA-1 of each version.
178
 
 
179
 
    _names
180
 
        List of symbolic names for each version.  Each should be unique.
181
 
 
182
 
    _name_map
183
 
        For each name, the version number.
 
169
        List of hex SHA-1 of each version, or None if not recorded.
184
170
    """
185
171
 
186
 
    __slots__ = ['_weave', '_parents', '_sha1s', '_names', '_name_map']
 
172
    __slots__ = ['_weave', '_parents', '_sha1s']
187
173
    
188
174
    def __init__(self):
189
175
        self._weave = []
190
176
        self._parents = []
191
177
        self._sha1s = []
192
 
        self._names = []
193
 
        self._name_map = {}
194
178
 
195
179
 
196
180
    def __eq__(self, other):
197
181
        if not isinstance(other, Weave):
198
182
            return False
199
183
        return self._parents == other._parents \
200
 
               and self._weave == other._weave \
201
 
               and self._sha1s == other._sha1s 
 
184
               and self._weave == other._weave
 
185
    
202
186
 
203
 
    
204
187
    def __ne__(self, other):
205
188
        return not self.__eq__(other)
206
189
 
207
 
 
208
 
    def lookup(self, name):
209
 
        try:
210
 
            return self._name_map[name]
211
 
        except KeyError:
212
 
            raise WeaveError("name %s not present in weave" % name)
213
 
 
214
190
        
215
 
    def add(self, name, parents, text):
 
191
    def add(self, parents, text):
216
192
        """Add a single text on top of the weave.
217
193
  
218
194
        Returns the index number of the newly added version.
219
195
 
220
 
        name
221
 
            Symbolic name for this version.
222
 
            (Typically the revision-id of the revision that added it.)
223
 
 
224
196
        parents
225
197
            List or set of direct parent version numbers.
226
198
            
227
199
        text
228
200
            Sequence of lines to be added in the new version."""
229
201
 
230
 
        assert isinstance(name, basestring)
231
 
        if name in self._name_map:
232
 
            raise WeaveError("name %r already present in weave" % name)
233
 
        
234
202
        self._check_versions(parents)
235
203
        ## self._check_lines(text)
236
204
        new_version = len(self._parents)
237
205
 
 
206
        import sha
238
207
        s = sha.new()
239
208
        map(s.update, text)
240
209
        sha1 = s.hexdigest()
241
210
        del s
242
211
 
243
 
        # if we abort after here the (in-memory) weave will be corrupt because only
244
 
        # some fields are updated
245
 
        self._parents.append(parents[:])
 
212
        # if we abort after here the weave will be corrupt
 
213
        self._parents.append(frozenset(parents))
246
214
        self._sha1s.append(sha1)
247
 
        self._names.append(name)
248
 
        self._name_map[name] = new_version
249
215
 
250
216
            
251
217
        if not parents:
548
514
 
549
515
        # try extracting all versions; this is a bit slow and parallel
550
516
        # extraction could be used
 
517
        import sha
551
518
        nv = self.numversions()
552
519
        for version in range(nv):
553
520
            if progress_bar:
711
678
 
712
679
def weave_toc(w):
713
680
    """Show the weave's table-of-contents"""
714
 
    print '%6s %50s %10s %10s' % ('ver', 'name', 'sha1', 'parents')
715
 
    for i in (6, 50, 10, 10):
 
681
    print '%6s %40s %20s' % ('ver', 'sha1', 'parents')
 
682
    for i in (6, 40, 20):
716
683
        print '-' * i,
717
684
    print
718
685
    for i in range(w.numversions()):
719
686
        sha1 = w._sha1s[i]
720
 
        name = w._names[i]
721
 
        parent_str = ' '.join(map(str, w._parents[i]))
722
 
        print '%6d %-50.50s %10.10s %s' % (i, name, sha1, parent_str)
 
687
        print '%6d %40s %s' % (i, sha1, ' '.join(map(str, w._parents[i])))
723
688
 
724
689
 
725
690
 
767
732
        Check consistency of all versions.
768
733
    weave toc WEAVEFILE
769
734
        Display table of contents.
770
 
    weave add WEAVEFILE NAME [BASE...] < NEWTEXT
 
735
    weave add WEAVEFILE [BASE...] < NEWTEXT
771
736
        Add NEWTEXT, with specified parent versions.
772
737
    weave annotate WEAVEFILE VERSION
773
738
        Display origin of each line.
780
745
 
781
746
    % weave init foo.weave
782
747
    % vi foo.txt
783
 
    % weave add foo.weave ver0 < foo.txt
 
748
    % weave add foo.weave < foo.txt
784
749
    added version 0
785
750
 
786
751
    (create updated version)
787
752
    % vi foo.txt
788
753
    % weave get foo.weave 0 | diff -u - foo.txt
789
 
    % weave add foo.weave ver1 0 < foo.txt
 
754
    % weave add foo.weave 0 < foo.txt
790
755
    added version 1
791
756
 
792
757
    % weave get foo.weave 0 > foo.txt       (create forked version)
793
758
    % vi foo.txt
794
 
    % weave add foo.weave ver2 0 < foo.txt
 
759
    % weave add foo.weave 0 < foo.txt
795
760
    added version 2
796
761
 
797
762
    % weave merge foo.weave 1 2 > foo.txt   (merge them)
798
763
    % vi foo.txt                            (resolve conflicts)
799
 
    % weave add foo.weave merged 1 2 < foo.txt     (commit merged version)     
 
764
    % weave add foo.weave 1 2 < foo.txt     (commit merged version)     
800
765
    
801
766
"""
802
767
    
828
793
    elif cmd == 'add':
829
794
        w = readit()
830
795
        # at the moment, based on everything in the file
831
 
        name = argv[3]
832
 
        parents = map(int, argv[4:])
 
796
        parents = map(int, argv[3:])
833
797
        lines = sys.stdin.readlines()
834
 
        ver = w.add(name, parents, lines)
 
798
        ver = w.add(parents, lines)
835
799
        write_weave(w, file(argv[2], 'wb'))
836
 
        print 'added version %r %d' % (name, ver)
 
800
        print 'added version %d' % ver
837
801
    elif cmd == 'init':
838
802
        fn = argv[2]
839
803
        if os.path.exists(fn):