~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/weave.py

  • Committer: Jelmer Vernooij
  • Date: 2009-06-09 00:59:51 UTC
  • mto: (4443.1.1 bzr.dev)
  • mto: This revision was merged to the branch mainline in revision 4444.
  • Revision ID: jelmer@samba.org-20090609005951-apv900cdk35o2ygh
Move squashing of XML-invalid characters to XMLSerializer.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2009 Canonical Ltd
 
1
#! /usr/bin/python
 
2
 
 
3
# Copyright (C) 2005 Canonical Ltd
2
4
#
3
5
# This program is free software; you can redistribute it and/or modify
4
6
# it under the terms of the GNU General Public License as published by
69
71
from copy import copy
70
72
from cStringIO import StringIO
71
73
import os
 
74
import time
 
75
import warnings
72
76
 
73
77
from bzrlib.lazy_import import lazy_import
74
78
lazy_import(globals(), """
77
81
from bzrlib import (
78
82
    errors,
79
83
    osutils,
 
84
    progress,
80
85
    )
81
86
from bzrlib.errors import (WeaveError, WeaveFormatError, WeaveParentMismatch,
82
87
        RevisionAlreadyPresent,
83
88
        RevisionNotPresent,
84
89
        UnavailableRepresentation,
 
90
        WeaveRevisionAlreadyPresent,
 
91
        WeaveRevisionNotPresent,
85
92
        )
86
93
from bzrlib.osutils import dirname, sha, sha_strings, split_lines
87
94
import bzrlib.patiencediff
1018
1025
        wr._add(name, lines, [wr._lookup(i) for i in combined_parents[name]])
1019
1026
    return wr
1020
1027
 
1021
 
 
1022
1028
def _reweave_parent_graphs(wa, wb):
1023
1029
    """Return combined parent ancestry for two weaves.
1024
1030
 
1029
1035
            p = combined.setdefault(name, set())
1030
1036
            p.update(map(weave._idx_to_name, weave._parents[idx]))
1031
1037
    return combined
 
1038
 
 
1039
 
 
1040
def weave_toc(w):
 
1041
    """Show the weave's table-of-contents"""
 
1042
    print '%6s %50s %10s %10s' % ('ver', 'name', 'sha1', 'parents')
 
1043
    for i in (6, 50, 10, 10):
 
1044
        print '-' * i,
 
1045
    print
 
1046
    for i in range(w.num_versions()):
 
1047
        sha1 = w._sha1s[i]
 
1048
        name = w._names[i]
 
1049
        parent_str = ' '.join(map(str, w._parents[i]))
 
1050
        print '%6d %-50.50s %10.10s %s' % (i, name, sha1, parent_str)
 
1051
 
 
1052
 
 
1053
 
 
1054
def weave_stats(weave_file, pb):
 
1055
    from bzrlib.weavefile import read_weave
 
1056
 
 
1057
    wf = file(weave_file, 'rb')
 
1058
    w = read_weave(wf)
 
1059
    # FIXME: doesn't work on pipes
 
1060
    weave_size = wf.tell()
 
1061
 
 
1062
    total = 0
 
1063
    vers = len(w)
 
1064
    for i in range(vers):
 
1065
        pb.update('checking sizes', i, vers)
 
1066
        for origin, lineno, line in w._extract([i]):
 
1067
            total += len(line)
 
1068
 
 
1069
    pb.clear()
 
1070
 
 
1071
    print 'versions          %9d' % vers
 
1072
    print 'weave file        %9d bytes' % weave_size
 
1073
    print 'total contents    %9d bytes' % total
 
1074
    print 'compression ratio %9.2fx' % (float(total) / float(weave_size))
 
1075
    if vers:
 
1076
        avg = total/vers
 
1077
        print 'average size      %9d bytes' % avg
 
1078
        print 'relative size     %9.2fx' % (float(weave_size) / float(avg))
 
1079
 
 
1080
 
 
1081
def usage():
 
1082
    print """bzr weave tool
 
1083
 
 
1084
Experimental tool for weave algorithm.
 
1085
 
 
1086
usage:
 
1087
    weave init WEAVEFILE
 
1088
        Create an empty weave file
 
1089
    weave get WEAVEFILE VERSION
 
1090
        Write out specified version.
 
1091
    weave check WEAVEFILE
 
1092
        Check consistency of all versions.
 
1093
    weave toc WEAVEFILE
 
1094
        Display table of contents.
 
1095
    weave add WEAVEFILE NAME [BASE...] < NEWTEXT
 
1096
        Add NEWTEXT, with specified parent versions.
 
1097
    weave annotate WEAVEFILE VERSION
 
1098
        Display origin of each line.
 
1099
    weave merge WEAVEFILE VERSION1 VERSION2 > OUT
 
1100
        Auto-merge two versions and display conflicts.
 
1101
    weave diff WEAVEFILE VERSION1 VERSION2
 
1102
        Show differences between two versions.
 
1103
 
 
1104
example:
 
1105
 
 
1106
    % weave init foo.weave
 
1107
    % vi foo.txt
 
1108
    % weave add foo.weave ver0 < foo.txt
 
1109
    added version 0
 
1110
 
 
1111
    (create updated version)
 
1112
    % vi foo.txt
 
1113
    % weave get foo.weave 0 | diff -u - foo.txt
 
1114
    % weave add foo.weave ver1 0 < foo.txt
 
1115
    added version 1
 
1116
 
 
1117
    % weave get foo.weave 0 > foo.txt       (create forked version)
 
1118
    % vi foo.txt
 
1119
    % weave add foo.weave ver2 0 < foo.txt
 
1120
    added version 2
 
1121
 
 
1122
    % weave merge foo.weave 1 2 > foo.txt   (merge them)
 
1123
    % vi foo.txt                            (resolve conflicts)
 
1124
    % weave add foo.weave merged 1 2 < foo.txt     (commit merged version)
 
1125
 
 
1126
"""
 
1127
 
 
1128
 
 
1129
 
 
1130
def main(argv):
 
1131
    import sys
 
1132
    import os
 
1133
    try:
 
1134
        import bzrlib
 
1135
    except ImportError:
 
1136
        # in case we're run directly from the subdirectory
 
1137
        sys.path.append('..')
 
1138
        import bzrlib
 
1139
    from bzrlib.weavefile import write_weave, read_weave
 
1140
    from bzrlib.progress import ProgressBar
 
1141
 
 
1142
    try:
 
1143
        import psyco
 
1144
        psyco.full()
 
1145
    except ImportError:
 
1146
        pass
 
1147
 
 
1148
    if len(argv) < 2:
 
1149
        usage()
 
1150
        return 0
 
1151
 
 
1152
    cmd = argv[1]
 
1153
 
 
1154
    def readit():
 
1155
        return read_weave(file(argv[2], 'rb'))
 
1156
 
 
1157
    if cmd == 'help':
 
1158
        usage()
 
1159
    elif cmd == 'add':
 
1160
        w = readit()
 
1161
        # at the moment, based on everything in the file
 
1162
        name = argv[3]
 
1163
        parents = map(int, argv[4:])
 
1164
        lines = sys.stdin.readlines()
 
1165
        ver = w.add(name, parents, lines)
 
1166
        write_weave(w, file(argv[2], 'wb'))
 
1167
        print 'added version %r %d' % (name, ver)
 
1168
    elif cmd == 'init':
 
1169
        fn = argv[2]
 
1170
        if os.path.exists(fn):
 
1171
            raise IOError("file exists")
 
1172
        w = Weave()
 
1173
        write_weave(w, file(fn, 'wb'))
 
1174
    elif cmd == 'get': # get one version
 
1175
        w = readit()
 
1176
        sys.stdout.writelines(w.get_iter(int(argv[3])))
 
1177
 
 
1178
    elif cmd == 'diff':
 
1179
        w = readit()
 
1180
        fn = argv[2]
 
1181
        v1, v2 = map(int, argv[3:5])
 
1182
        lines1 = w.get(v1)
 
1183
        lines2 = w.get(v2)
 
1184
        diff_gen = bzrlib.patiencediff.unified_diff(lines1, lines2,
 
1185
                                '%s version %d' % (fn, v1),
 
1186
                                '%s version %d' % (fn, v2))
 
1187
        sys.stdout.writelines(diff_gen)
 
1188
 
 
1189
    elif cmd == 'annotate':
 
1190
        w = readit()
 
1191
        # newline is added to all lines regardless; too hard to get
 
1192
        # reasonable formatting otherwise
 
1193
        lasto = None
 
1194
        for origin, text in w.annotate(int(argv[3])):
 
1195
            text = text.rstrip('\r\n')
 
1196
            if origin == lasto:
 
1197
                print '      | %s' % (text)
 
1198
            else:
 
1199
                print '%5d | %s' % (origin, text)
 
1200
                lasto = origin
 
1201
 
 
1202
    elif cmd == 'toc':
 
1203
        weave_toc(readit())
 
1204
 
 
1205
    elif cmd == 'stats':
 
1206
        weave_stats(argv[2], ProgressBar())
 
1207
 
 
1208
    elif cmd == 'check':
 
1209
        w = readit()
 
1210
        pb = ProgressBar()
 
1211
        w.check(pb)
 
1212
        pb.clear()
 
1213
        print '%d versions ok' % w.num_versions()
 
1214
 
 
1215
    elif cmd == 'inclusions':
 
1216
        w = readit()
 
1217
        print ' '.join(map(str, w.inclusions([int(argv[3])])))
 
1218
 
 
1219
    elif cmd == 'parents':
 
1220
        w = readit()
 
1221
        print ' '.join(map(str, w._parents[int(argv[3])]))
 
1222
 
 
1223
    elif cmd == 'plan-merge':
 
1224
        # replaced by 'bzr weave-plan-merge'
 
1225
        w = readit()
 
1226
        for state, line in w.plan_merge(int(argv[3]), int(argv[4])):
 
1227
            if line:
 
1228
                print '%14s | %s' % (state, line),
 
1229
    elif cmd == 'merge':
 
1230
        # replaced by 'bzr weave-merge-text'
 
1231
        w = readit()
 
1232
        p = w.plan_merge(int(argv[3]), int(argv[4]))
 
1233
        sys.stdout.writelines(w.weave_merge(p))
 
1234
    else:
 
1235
        raise ValueError('unknown command %r' % cmd)
 
1236
 
 
1237
 
 
1238
if __name__ == '__main__':
 
1239
    import sys
 
1240
    sys.exit(main(sys.argv))