예제 #1
0
    def execute(self, inputfile, outputfile):
        """
        Fix a cvs2svn created dump file.

        @type inputfile: string
        @param inputfile: Name of the cvs2svn created dump file.
        @type outputfile: string
        @param outputfile: Name of the fixed dump file.
        """

        indump = SvnDumpFile()
        indump.open(inputfile)
        has_rev = indump.read_next_rev()
        outdump = SvnDumpFile()
        outdump.create_like(outputfile, indump)
        rc = 0
        self.__history = {}

        while has_rev and rc == 0:
            outdump.add_rev(indump.get_rev_props())
            for node in indump.get_nodes_iter():
                msglist = self.__fix_node(indump.get_rev_nr(), node)
                if msglist != None:
                    rc = 1
                    print "Error in r%d node %s:" % \
                            ( indump.get_rev_nr(), node.get_path() )
                    for msg in msglist:
                        print "  " + msg
                    break
                outdump.add_node(node)
            has_rev = indump.read_next_rev()

        indump.close()
        return rc
예제 #2
0
    def execute(self):
        """
        Executes the Edit.
        """

        # +++ catch exception and return errorcode
        srcdmp = SvnDumpFile()
        srcdmp.open(self.__in_file)

        dstdmp = None

        hasrev = srcdmp.read_next_rev()
        if hasrev:
            if not self.dry_run:
                dstdmp = SvnDumpFile()
                if srcdmp.get_rev_nr() == 0:
                    # create new dump with revision 0
                    dstdmp.create_with_rev_0(self.__out_file,
                                             srcdmp.get_uuid(),
                                             srcdmp.get_rev_date_str())
                    hasrev = srcdmp.read_next_rev()
                else:
                    # create new dump starting with the same revNr
                    # as the input dump file
                    dstdmp.create_with_rev_n(self.__out_file,
                                             srcdmp.get_uuid(),
                                             srcdmp.get_rev_nr())
            # now copy all the revisions
            while hasrev:
                self.__process_rev(srcdmp, dstdmp)
                hasrev = srcdmp.read_next_rev()
예제 #3
0
def copy_dump_file(srcfile, dstfile, transformer=None):
    """
    Copy a dump file.

    @type srcfile: string
    @param srcfile: Source filename.
    @type dstfile: string
    @param dstfile: Destination filename.
    @type transformer: class with method transform(dump)
    @param transformer: A class to perform a transformation on each revision, or None.
    """

    # SvnDumpFile classes for reading/writing dumps
    srcdmp = SvnDumpFile()
    dstdmp = SvnDumpFile()

    # open source file
    srcdmp.open(srcfile)

    hasrev = srcdmp.read_next_rev()
    if hasrev:
        # create the dump file
        dstdmp.create_like(dstfile, srcdmp)
        # now copy all the revisions
        while hasrev:
            if transformer != None:
                transformer.transform(srcdmp)
            dstdmp.add_rev_from_dump(srcdmp)
            hasrev = srcdmp.read_next_rev()
    else:
        print "no revisions in the source dump '%s' ???" % srcfile

    # cleanup
    srcdmp.close()
    dstdmp.close()
예제 #4
0
def join_dumpfiles(inputlist, outfilename):
    """
    Joins dump files.

    @type inputlist: list
    @param inputlist: A list containing the input filenames.
    @type outfilename: string
    @param outfilename: Name of the output dump file.
    @rtype: int
    @return: 0 for success.
    """

    outdump = None
    noutrev = 0
    lastrev = -1
    for filename in inputlist:
        print "reading %s ..." % filename
        ninrev = 0
        indump = SvnDumpFile()
        indump.open(filename)
        hasrev = indump.read_next_rev()
        if hasrev:
            if outdump == None:
                outdump = SvnDumpFile()
                if indump.get_rev_nr() == 0:
                    # create new dump with revision 0
                    outdump.create_with_rev_0(outfilename, indump.get_uuid(),
                                              indump.get_rev_date_str())
                    hasrev = indump.read_next_rev()
                else:
                    # create new dump starting with the
                    # same revNr as the original dump
                    outdump.create_with_rev_n(outfilename, indump.get_uuid(),
                                              indump.get_rev_nr())
            else:
                # check rev number
                if indump.get_rev_nr() == 0:
                    hasrev = indump.read_next_rev()
                if hasrev:
                    if (lastrev + 1) != indump.get_rev_nr():
                        print "renumbering of revisions not supported."
                        print "last rev was %d, next is %d." % (
                            lastrev, indump.get_rev_nr())
                        indump.close()
                        outdump.close()
                        return 1
            while hasrev:
                outdump.add_rev_from_dump(indump)
                ninrev += 1
                lastrev = indump.get_rev_nr()
                hasrev = indump.read_next_rev()
        indump.close()
        print "  copied %d revisions." % ninrev
        noutrev += ninrev
    outdump.close()
    print "wrote %d revisions, last was r%d." % (noutrev, lastrev)
예제 #5
0
def copy_dump_file(srcfile, dstfile, transformer=None):
    """
    Copy a dump file.

    @type srcfile: string
    @param srcfile: Source filename.
    @type dstfile: string
    @param dstfile: Destination filename.
    @type transformer: class with method transform(dump)
    @param transformer: A class to perform a transformation on each revision, or None.
    """

    # SvnDumpFile classes for reading/writing dumps
    srcdmp = SvnDumpFile()
    dstdmp = SvnDumpFile()

    # Copy_from_rev casacading
    oldRevToNewRev = dict()

    # open source file
    srcdmp.open(srcfile)

    hasrev = srcdmp.read_next_rev()
    if hasrev:
        # create the dump file
        dstdmp.create_like(dstfile, srcdmp)
        # now copy all the revisions
        while hasrev:
            if transformer != None:
                transformer.transform(srcdmp)
            for node in srcdmp.get_nodes_iter():
                if node.has_copy_from():
                    if oldRevToNewRev.has_key(node.get_copy_from_rev()):
                        node.set_copy_from_rev(
                            oldRevToNewRev[node.get_copy_from_rev()])
                    else:
                        #We have a problem, the copy from revision is missing.
                        #We look for a previous revision containing the file
                        found = False
                        candidate = node.get_copy_from_rev()
                        while candidate > 0 and not found:
                            candidate = candidate - 1
                            found = oldRevToNewRev.has_key(candidate)
                        if found:
                            oldRevToNewRev[
                                node.get_copy_from_rev()] = candidate
                            node.set_copy_from_rev(candidate)
            dstdmp.add_rev_from_dump(srcdmp)
            oldRevToNewRev[srcdmp.get_rev_nr()] = dstdmp.get_rev_nr()
            hasrev = srcdmp.read_next_rev()
    else:
        print "no revisions in the source dump '%s' ???" % srcfile

    # cleanup
    srcdmp.close()
    dstdmp.close()
예제 #6
0
    def execute(self, dumpfilename, directory):
        """
        Executes the export.

        @type dumpfilename: string
        @param dumpfilename: Name of the svn dump file.
        @type directory: string
        @param directory: Directory to store the exported files.
        """

        dump = SvnDumpFile()
        dump.open(dumpfilename)

        while dump.read_next_rev():
            revnr = dump.get_rev_nr()
            if self.__exports.has_key(revnr):
                for path, filename in self.__exports[revnr].iteritems():
                    print "r%-6d %s" % (revnr, path)
                    nodes = dump.get_nodes_by_path(path, "ACR")
                    saved = False
                    for node in nodes:
                        if node.has_text():
                            outfile = open(filename, "wb")
                            node.write_text_to_file(outfile)
                            outfile.close()
                            saved = True
                            print "  saved as %s" % filename
                    if not saved:
                        if len(nodes) == 0:
                            print "  not found"
                        else:
                            print "  has no text"
        dump.close()
        return 0
예제 #7
0
    def execute(self):
        """
        Executes the EolFix.
        """

        # +++ catch exception and return errorcode
        srcdmp = SvnDumpFile()
        srcdmp.open(self.__in_file)

        dstdmp = None

        hasrev = srcdmp.read_next_rev()
        if hasrev:
            if not self.__dry_run:
                dstdmp = SvnDumpFile()
                if srcdmp.get_rev_nr() == 0:
                    # create new dump with revision 0
                    dstdmp.create_with_rev_0(self.__out_file,
                                             srcdmp.get_uuid(),
                                             srcdmp.get_rev_date_str())
                    hasrev = srcdmp.read_next_rev()
                else:
                    # create new dump starting with the same revNr
                    # as the input dump file
                    dstdmp.create_with_rev_n(self.__out_file,
                                             srcdmp.get_uuid(),
                                             srcdmp.get_rev_nr())
            # now copy all the revisions
            while hasrev:
                print("\n\n*** r%d ***\n" % srcdmp.get_rev_nr())
                self.__process_rev(srcdmp, dstdmp)
                hasrev = srcdmp.read_next_rev()
        if self.__warning_file is not None:
            self.__warning_file.write(
                "\n\n# %d warnings\n" % self.__warning_count)
            self.__warning_file.close()
            self.__warning_file = None
            self.__warning_count = 0
예제 #8
0
    def execute(self, dumpfilename):
        """
        Print log of a dump file.

        @type dumpfilename: string
        @param dumpfilename: Name of the file to log.
        """

        print "\n\n" + "=" * 72
        line = "-" * 72
        print "Dumpfile: " + dumpfilename
        dump = SvnDumpFile()
        dump.open(dumpfilename)
        actions = {"add": "A", "change": "M", "delete": "D", "replace": "R"}

        while dump.read_next_rev():
            revnr = dump.get_rev_nr()
            if revnr >= self.__from_rev and revnr <= self.__to_rev:
                author = dump.get_rev_author()
                date = dump.get_rev_date_str()
                log = dump.get_rev_log()
                linecnt = len(log.split("\n"))
                lines = "%d line" % linecnt
                if linecnt > 1:
                    lines += "s"
                print line
                print "r%d | %s | %s | %s" % (revnr, author, date, lines)
                if self.__verbose:
                    print "Changed paths:"
                    for node in dump.get_nodes_iter():
                        action = actions[node.get_action()]
                        path = node.get_path()
                        if path == "" or path[0] != "/":
                            path = "/" + path
                        if node.has_copy_from():
                            fpath = node.get_copy_from_path()
                            frev = node.get_copy_from_rev()
                            if fpath == "" or fpath[0] != "/":
                                fpath = "/" + fpath
                            path += " (from %s:%d)" % (fpath, frev)
                        print "   %s %s" % (action, path)
                print "\n" + log.rstrip() + "\n"

        print line
        dump.close()
        return 0
예제 #9
0
    def old_execute(self, dumpfilename):
        """
        Print file list of a dump file.

        @type dumpfilename: string
        @param dumpfilename: Name of the file to log.
        """

        dump = SvnDumpFile()
        dump.open(dumpfilename)
        actions = {"add": "A", "change": "M", "delete": "D", "replace": "R"}
        lines = ""

        while dump.read_next_rev():
            revnr = dump.get_rev_nr()
            if revnr == self.revNr or self.revNr == -1:
                lines = ""
                for node in dump.get_nodes_iter():
                    action = actions[node.get_action()]
                    path = node.get_path()
                    if path == "" or path[0] != "/":
                        path = "/" + path
                    if node.has_copy_from():
                        fpath = node.get_copy_from_path()
                        frev = node.get_copy_from_rev()
                        if fpath == "" or fpath[0] != "/":
                            fpath = "/" + fpath
                        path += " (from %s:%d)" % (fpath, frev)
                    lines += "   %s %s\n" % (action, path)
                if revnr == self.revNr:
                    print lines,
                    lines = ""
                    break
        if len(lines) > 0:
            print lines,

        dump.close()
        return 0
예제 #10
0
def split_dumpfiles(inputfilename, outlist):
    """
    Splits a dump file.

    @type inputfilename: string
    @param inputfilename: Name of the input file.
    @type outlist: list
    @param outlist: List of tuples containing start revnr, end revnr and filename.
    @rtype: int
    @return: 0 for success.
    """

    if len(outlist) == 0:
        return 0

    outlist = outlist[:]
    outlist.sort()
    parallel = False
    for i in range(0, len(outlist) - 1):
        if outlist[i][1] > outlist[i + 1][0]:
            parallel = True
            break

    if not parallel:
        indump = SvnDumpFile()
        indump.open(inputfilename)
        index = 0
        startrev = outlist[index][0]
        endrev = outlist[index][1]
        outfile = outlist[index][2]
        outdump = None
        while indump.read_next_rev():
            revnr = indump.get_rev_nr()
            if outdump == None:
                if revnr >= startrev:
                    outdump = SvnDumpFile()
                    if revnr == 0:
                        # create new dump with revision 0
                        outdump.create_with_rev_0(outfile, indump.get_uuid(),
                                                  indump.get_rev_date_str())
                    else:
                        # create new dump starting with the
                        # same revNr as the original dump
                        outdump.create_with_rev_n(outfile, indump.get_uuid(),
                                                  indump.get_rev_nr())
            if outdump != None:
                # have an output file, copy the revision if revnr > 0
                if revnr > 0:
                    outdump.add_rev_from_dump(indump)
                if revnr >= endrev:
                    # end revision reached
                    outdump.close()
                    outdump = None
                    index += 1
                    if index >= len(outlist):
                        # done.
                        break
                    # next range
                    startrev = outlist[index][0]
                    endrev = outlist[index][1]
                    outfile = outlist[index][2]
        if outdump != None:
            outdump.close()
        indump.close()
    else:
        print "overlapping revision ranges not supported (yet)."
        return 1
    return 0
예제 #11
0
    def execute(self, dumpfilename):
        """
        Print file list of a dump file.

        @type dumpfilename: string
        @param dumpfilename: Name of the file to log.
        """

        # pass 1: search copy-from revisions
        dump = SvnDumpFile()
        dump.open(dumpfilename)
        copyfromrevs = {}
        filedict = {}

        while dump.read_next_rev():
            revnr = dump.get_rev_nr()
            if revnr > self.revNr:
                break
            for node in dump.get_nodes_iter():
                #action = actions[node.get_action()]
                action = node.get_action()
                path = node.get_path()
                if path == "" or path[0] != "/":
                    path = "/" + path
                if action == "add" and node.has_copy_from():
                    copyfromrevs[node.get_copy_from_rev()] = True
        dump.close()

        # pass 2: do the work
        dump = SvnDumpFile()
        dump.open(dumpfilename)
        filedict = {}

        prevrevnr = 0
        while dump.read_next_rev():
            revnr = dump.get_rev_nr()
            # loop over missing revisions
            prevrevnr += 1
            while prevrevnr < revnr:
                if copyfromrevs.has_key(prevrevnr):
                    copyfromrevs[prevrevnr] = filedict.keys()[:]
                prevrevnr += 1
            if revnr > self.revNr:
                break
            for node in dump.get_nodes_iter():
                action = node.get_action()
                path = node.get_path()
                if path == "" or path[0] != "/":
                    path = "/" + path
                if action == "add":
                    filedict[path] = path
                    if node.has_copy_from():
                        frompath = node.get_copy_from_path() + "/"
                        if frompath[0] != "/":
                            frompath = "/" + frompath
                        fromlen = len(frompath)
                        topath = path + "/"
                        for path in copyfromrevs[node.get_copy_from_rev()]:
                            if path.startswith(frompath):
                                newpath = topath + path[fromlen:]
                                filedict[newpath] = newpath
                elif action == "delete":
                    del filedict[path]
                    if path[-1] != "/":
                        path = path + "/"
                    for subpath in filedict.keys()[:]:
                        if subpath.startswith(path):
                            del filedict[subpath]
            if copyfromrevs.has_key(revnr):
                copyfromrevs[revnr] = filedict.keys()[:]
        dump.close()

        filelist = []
        for path in filedict:
            filelist.append(path)
        filelist.sort()
        for path in filelist:
            print path

        return 0
예제 #12
0
    def merge(self):
        """
        Executes the merge.
        """

        if len(self.__in_files) == 0:
            print "merge: no input files specified"
            return
        if len(self.__out_file) == 0:
            print "merge: no output file specified"
            return

        # open input dump files
        for inFile in self.__in_files:
            inDump = SvnDumpFile()
            inDump.open(inFile)
            inDump.read_next_rev()
            self.__in_dumps = self.__in_dumps + [inDump]
            if inDump.get_rev_date_str() < self.__out_r0_date:
                self.__out_r0_date = inDump.get_rev_date_str()

        # remove empty dumps
        dumpCount = self.__remove_empty_dumps()
        if dumpCount == 0:
            return

        # open output file
        self.outDump = SvnDumpFile()
        if self.outStartRev == 0:
            self.outDump.create_with_rev_0(self.__out_file,
                                           self.__in_dumps[0].get_uuid(),
                                           self.__out_r0_date)
        else:
            self.outDump.create_with_rev_n(self.__out_file,
                                           self.__in_dumps[0].get_uuid(),
                                           self.outStartRev)

        # skip revision 0 of all dumps
        for inDump in self.__in_dumps:
            if inDump.get_rev_nr() == 0:
                # +++ what about r0 revprops?
                inDump.read_next_rev()

        # remove empty dumps
        dumpCount = self.__remove_empty_dumps()
        if dumpCount == 0:
            self.outDump.close()
            return

        # get revision dates
        oldest = None
        oldestStr = ""
        for index in range(len(self.__in_dumps)):
            revDat = self.__in_dumps[index].get_rev_date()
            self.__in_rev_dates.append(revDat)
            if oldest == None or revDat < oldest:
                oldest = revDat
                oldestStr = self.__in_dumps[index].get_rev_date_str()

        # add additional directories
        if len(self.__out_dirs) > 0:
            self.outDump.add_rev({
                "svn:log": self.__out_message,
                "svn:author": self.__out_author,
                "svn:date": oldestStr
            })
            for dirName in self.__out_dirs:
                node = SvnDumpNode(dirName, "add", "dir")
                self.outDump.add_node(node)

        # loop over all revisions
        while dumpCount > 0:
            # find index of the oldest revision
            oldestIndex = 0
            for index in range(1, dumpCount):
                if self.__in_rev_dates[index] < self.__in_rev_dates[
                        oldestIndex]:
                    oldestIndex = index
            # copy revision
            self.__copy_revision(oldestIndex)
            print "Revision: %-8d from r%-8d %s" % (
                self.outDump.get_rev_nr(),
                self.__in_dumps[oldestIndex].get_rev_nr(),
                self.__in_files[oldestIndex])
            # read next revision
            srcDump = self.__in_dumps[oldestIndex]
            if srcDump.read_next_rev():
                self.__in_rev_dates[oldestIndex] = srcDump.get_rev_date()
            else:
                dumpCount = self.__remove_empty_dumps()

        # close output
        print "created %d revisions" % self.outDump.get_rev_nr()
        self.outDump.close()
예제 #13
0
    def execute(self, callback):
        """
        Execute the diff.

        @type callback: SvnDumpDiffCallback
        @param callback: Callback object for diffs found.
        """

        # diff started
        callback.comparing(self.__filename1, self.__filename2)

        # open files
        dump1 = SvnDumpFile()
        dump2 = SvnDumpFile()
        dump1.open(self.__filename1)
        dump2.open(self.__filename2)

        # compare uuid
        if dump1.get_uuid() != dump2.get_uuid():
            callback.rev_diff("UUID", dump1.get_uuid(), dump2.get_uuid())

        hasrev1 = dump1.read_next_rev()
        hasrev2 = dump2.read_next_rev()

        while hasrev1 and hasrev2:
            # compare rev numbers
            if dump1.get_rev_nr() != dump2.get_rev_nr():
                callback.rev_diff("RevNr", dump1.get_rev_nr(),
                                  dump2.get_rev_nr())
                # error has been reported so set both flags to false
                hasrev1 = False
                hasrev2 = False
                break

            # next revision...
            callback.next_revision(dump1.get_rev_nr(), dump2.get_rev_nr())

            # compare rev date
            if dump1.get_rev_date() != dump2.get_rev_date():
                callback.rev_diff("RevDate", str(dump1.get_rev_date()),
                                  str(dump2.get_rev_date()))
            if dump1.get_rev_date_str() != dump2.get_rev_date_str():
                callback.rev_diff("RevDateStr", dump1.get_rev_date_str(),
                                  dump2.get_rev_date_str())

            # compare rev author
            # compare rev log
            # compare rev props
            self.__compare_properties(True, dump1.get_rev_props(),
                                      dump2.get_rev_props(), callback)
            # compare nodes
            self.__compare_nodes(dump1, dump2, callback)

            # read next revision
            hasrev1 = dump1.read_next_rev()
            hasrev2 = dump2.read_next_rev()

        if hasrev1 or hasrev2:
            print "random error ;-) (different rev nr or EOF of one file)"

        # done.
        callback.compare_done()