This file is indexed.

/usr/share/pyshared/Codeville/upgrade.py is in codeville 0.8.0-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
import binascii
from Codeville.bencode import bdecode, bencode
from Codeville.client_helpers import create_handle, gen_diff
from Codeville.DFS import DFS
from Codeville.history import sync_history, write_changeset
from Codeville.history import roothandle, rootnode
from Codeville.history import read_diff, write_diff, write_index
from Codeville.history import handle_contents_at_point
from Codeville.history import handle_name_at_point
from Codeville.history import HistoryError
from Codeville.old.history import handle_contents_at_point as old_handle_contents_at_point
from Codeville.old.history import handle_name_at_point as old_handle_name_at_point
import copy
import hashlib
from sys import stdout
import zlib

class UpgradeRepository:
    def __init__(self, old_repo, new_repo, txn):
        self.point_map       = {}
        self.handle_map      = {}
        self.all_old_handles = {}

        self.old_repo = old_repo
        self.new_repo = new_repo
        self.txn      = txn
        return

    def sort_history(self, handle_list):
        history_dfs = DFS(self._history_deps, [self.old_repo])
        for point in handle_list:
            history_dfs.search(point)
        return history_dfs.result()

    def _history_deps(node, args):
        co = args[0]

        cset = bdecode(co.lcrepo.get(node))
        cset['precursors'].reverse()

        return cset['precursors']

    _history_deps = staticmethod(_history_deps)

    def sort_names(self, handles):
        name_dfs = DFS(self._name_deps, [handles])
        for old_handle in handles.keys():
            name_dfs.search(old_handle)
        return name_dfs.result()

    def _name_deps(node, args):
        handles = args[0]

        if handles.has_key(node) and handles[node].has_key('parent'):
            parent = handles[node]['parent']
            if handles.has_key(parent) and handles[parent].has_key('name'):
                return [parent]

        return []

    _name_deps = staticmethod(_name_deps)

    def clean_merges(self, UR, dagdb, point):
        clean_merges = {}
        handles      = []
        for handle in UR.all_old_handles.keys():
            if not dagdb.has_key(handle + point):
                continue

            hinfo = bdecode(dagdb.get(handle + point))
            if hinfo.has_key('handle'):
                continue

            if len(hinfo['precursors']) <= 1:
                continue

            clean_merges[handle] = 1
            handles.append(handle)

        return clean_merges, handles


def upgrade(old_repo, new_repo, changes, txn):
    UR = UpgradeRepository(old_repo, new_repo, txn)

    for old_handle in old_repo.staticdb.keys():
        hinfo = bdecode(old_repo.staticdb.get(old_handle))
        if hinfo['type'] == 'file':
            UR.all_old_handles[old_handle] = hinfo

    # sort the history
    ordering = UR.sort_history(changes)

    # sort again for better dag construction
    ordering.reverse()
    ordering = UR.sort_history(ordering)

    assert rootnode == ordering[0]

    print "%d changesets to convert" % (len(ordering), )

    for point in ordering:
        new_point = convert_cset(UR, point)

        stdout.write('.')
        stdout.flush()

    return UR

def convert_cset(UR, point):
    indices = {}

    old_cset = bdecode(UR.old_repo.lcrepo.get(point))

    new_cset = {}
    new_cset['precursors'] = [UR.point_map[pre] for pre in old_cset['precursors']]

    if old_cset.has_key('time'):
        new_cset['time'] = old_cset['time']

    if old_cset.has_key('user'):
        new_cset['user'] = old_cset['user']

    # some heuristics for comments and whether this was a server change
    clean_merge = True
    force_new_cset = False

    if old_cset.has_key('comment'):
        clean_merge = False
        new_cset['comment'] = old_cset['comment'].rstrip()
        if len(new_cset['comment']):
            new_cset['comment'] = new_cset['comment'] + '\n'

    elif point == rootnode:
        pass

    elif old_cset['handles'] != {} or len(old_cset['precursors']) != 2:
        clean_merge = False
        new_cset['comment'] = '--- comment inserted by cdvupgrade ---\n'

    # sort the handles
    handle_list = UR.sort_names(old_cset['handles'])

    # find implicit clean content merges
    clean_merges, hl = UR.clean_merges(UR, UR.old_repo.contents.dagdb, point)
    handle_list.extend(hl)

    # find implicit clean name merges
    clean_nmerges, hl = UR.clean_merges(UR, UR.old_repo.names.dagdb, point)
    handle_list.extend(hl)

    new_cset['handles'] = handles = {}
    for old_handle in handle_list:
        old_hinfo = None
        try:
            old_hinfo = old_cset['handles'][old_handle]
        except KeyError:
            old_hinfo = {}

        # not much has changed
        new_hinfo = copy.copy(old_hinfo)

        new_handle = None
        if UR.handle_map.has_key(old_handle):
            new_handle = UR.handle_map[old_handle]

        # make name changes explicit
        if clean_nmerges.has_key(old_handle):
            name = old_handle_name_at_point(UR.old_repo, old_handle, point, None)
            new_hinfo['parent'] = name['parent']
            new_hinfo['name'] = name['name']

        # fixup the parent pointers
        if old_hinfo.has_key('parent'):
            new_hinfo['parent'] = UR.handle_map[old_hinfo['parent']]

        if old_hinfo.has_key('hash') or clean_merges.has_key(old_handle):
            # figure out what the file is supposed to look like now
            lines = old_handle_contents_at_point(UR.old_repo, old_handle, point, None)['lines']

            # if the file is being added, there are no precursors
            precursors = []
            if new_handle is not None and not old_hinfo.has_key('add'):
                precursors = new_cset['precursors']

            # generate the diff against the new repo
            dinfo = gen_diff(UR.new_repo, new_handle, precursors, lines, UR.txn)
            if old_hinfo.has_key('add'):
                dinfo['add'] = 1
                assert dinfo['matches'] == []

            if dinfo is not None:
                diff = bencode(dinfo)
                new_hinfo['hash'] = hashlib.sha1(diff).digest()

                # if this used to be a clean merge, we have to replace it
                if not old_cset.has_key(old_handle) or not old_cset[old_handle].has_key('hash'):
                    force_new_cset = True

            elif new_hinfo.has_key('hash'):
                del new_hinfo['hash']

            # sanity check
            if new_handle is None:
                assert old_hinfo.has_key('add')
                assert old_hinfo['add']['type'] == 'file'

            # if the file is new, we have to create the handle before writing
            # the diff
            if old_hinfo.has_key('add'):
                nhandle = create_handle(new_cset['precursors'], new_hinfo)
                assert new_handle is None or new_handle == nhandle
                new_handle = nhandle
                UR.handle_map[old_handle] = new_handle

            # write out the new diff
            if new_hinfo.has_key('hash'):
                zdiff = zlib.compress(diff, 6)
                indices[new_handle] = write_diff(UR.new_repo, new_handle, zdiff, UR.txn)

        elif old_hinfo.has_key('add'):
            assert old_hinfo['add']['type'] == 'dir'

            nhandle = create_handle(new_cset['precursors'], new_hinfo)
            assert new_handle is None or new_handle == nhandle
            new_handle = nhandle
            UR.handle_map[old_handle] = new_handle

        if new_hinfo != {}:
            handles[new_handle] = new_hinfo

    # if it used to be a clean merge, preserve the line of clean merge heads
    index_point = None
    if clean_merge and force_new_cset:
        forced_cset = new_cset

        forced_cset['comment'] = '--- change created by cdvupgrade ---\n'

        bforced_cset = bencode(forced_cset)
        forced_point = hashlib.sha1(bforced_cset).digest()
        UR.new_repo.lcrepo.put(forced_point, bforced_cset, txn=UR.txn)

        index_point = forced_point

        new_cset = {'precursors': [forced_cset['precursors'][0], forced_point],
                    'user':       forced_cset['user'],
                    'time':       forced_cset['time'],
                    'handles':    {}}

    # calculate the new point name and write it out
    bnew_cset = bencode(new_cset)
    new_point = hashlib.sha1(bnew_cset).digest()
    UR.new_repo.lcrepo.put(new_point, bnew_cset, txn=UR.txn)

    UR.point_map[point] = new_point

    if index_point is None:
        index_point = new_point

    # now that we know the new point name, write out the indices
    for new_handle, index in indices.items():
        write_index(UR.new_repo, index_point, new_handle, index, UR.txn)

    # diff generation depends on history syncing
    named, modified = sync_history(UR.new_repo, new_point, UR.txn)

    for new_handle in modified:
        handle_contents_at_point(UR.new_repo, new_handle, new_point, UR.txn)

    return new_point