Example #1
0
    def __convert_eol(self, node, revnr):
        """
        Convert EOL of a node.

        @type node: SvnDumpNode
        @param node: The node to convert.
        @type revnr: integer
        @param revnr: The current revision number.
        @rtype: SvnDumpNode
        @return: The converted node.
        """

        if not node.has_text():
            # no text
            print("    selected file, no text changes")
            return node

        # search for CR
        need_conv = False
        handle = node.text_open()
        data = node.text_read(handle)
        while len(data) > 0:
            if data.find("\r") != -1:
                # found one, need to convert the file
                need_conv = True
                break
            data = node.text_read(handle)
        fix = self.__fix
        if need_conv:
            # special fix option for rev/file ?
            key = (revnr, node.get_path())
            if self.__fix_rev_path.has_key(key):
                fix = self.__fix_rev_path[key]
            print("    selected file, convert (fix option %d)" % fix)
            if self.__dry_run or fix == 0:
                # do not convert with --dry-run or when there's nothing to fix
                need_conv = False
        else:
            print("    selected file, no conversion required")
        if need_conv:
            # do the conversion
            node.text_reopen(handle)
            outfilename = self.__temp_file_name()
            outfile = open(outfilename, "wb")
            outlen = 0
            md = sdt_md5()
            data = node.text_read(handle)
            carry = ""
            warning_printed = False
            while len(data) > 0:
                if len(carry) != 0:
                    data = carry + data
                n = len(data) - 1
                carry = data[n]
                if carry == "\r":
                    data = data[:n]
                else:
                    carry = ""
                if fix & 1 != 0:
                    data = data.replace("\r\n", "\n")
                if fix & 2 != 0:
                    data = data.replace("\r", "\n")
                if fix & 4 != 0:
                    data = data.replace("\r", "")
                if not warning_printed and data.find("\r") >= 0:
                    warning_printed = True
                    print("    WARNING: file still contains CR")
                    print("      file: '%s'" % node.get_path())
                    if self.__warning_file is not None:
                        self.__warning_file.write(
                            "# WARNING: file still contains CR\n")
                        file = node.get_path()
                        while file[0] == "/":
                            file = file[1:]
                        tmpfile = file.replace("/", "__")
                        cmd = '$SVN cat -r %d "$REPOS/%s" > "%s"\n' % \
                              (revnr, node.get_path(), tmpfile)
                        self.__warning_file.write(cmd)
                        self.__warning_count += 1
                md.update(data)
                outfile.write(data)
                outlen = outlen + len(data)
                data = node.text_read(handle)
            if len(carry) != 0:
                if fix & 2 != 0:
                    carry = "\n"
                elif fix & 4 != 0:
                    carry = ""
                outfile.write(carry)
                md.update(carry)
                outlen += len(carry)
            outfile.close()
            newnode = SvnDumpNode(node.get_path(), node.get_action(),
                                  node.get_kind())
            if node.has_copy_from():
                newnode.set_copy_from(node.get_copy_from_path(),
                                      node.get_copy_from_rev())
            if node.has_properties():
                newnode.set_properties(node.get_properties())
            newnode.set_text_file(outfilename, outlen, md.hexdigest())
        else:
            newnode = node

        node.text_close(handle)
        return newnode
Example #2
0
    def __compare_node(self, node1, node2, callback):
        """
        Compare two nodes.

        @type node1: SvnDumpNode
        @param node1: First dump node.
        @type node2: SvnDumpNode
        @param node2: Second dump node.
        @type callback: SvnDumpDiffCallback
        @param callback: Callback object for diffs found.
        """

        # compare path
        if node1.get_path() != node2.get_path():
            callback.node_diff("Path", node1.get_path(), node2.get_path())
            return
        # compare action
        if node1.get_action() != node2.get_action():
            callback.node_diff("Action", node1.get_action(), node2.get_action())
            return
        # compare kind
        if node1.get_kind() != node2.get_kind():
            callback.node_diff("Kind", node1.get_kind(), node2.get_kind())
            return
        # compare copy-from-path
        if node1.get_copy_from_path() != node2.get_copy_from_path():
            callback.node_diff("CopyFromPath", node1.get_copy_from_path(), node2.get_copy_from_path())
            return
        # compare copy-from-rev
        if node1.get_copy_from_rev() != node2.get_copy_from_rev():
            callback.node_diff("CopyFromRev", node1.get_copy_from_rev(), node2.get_copy_from_rev())
            return
        # compare props
        self.__compare_properties(False, node1.get_properties(),
                                  node2.get_properties(), callback)
        # compare text
        if node1.has_text() != node2.has_text():
            callback.node_diff("HasText", node1.has_text(), node2.has_text())
            return
        if not node1.has_text():
            # no text to compare
            return
        if node1.get_text_length() != node2.get_text_length():
            callback.node_diff("TextLen", node1.get_text_length(), node2.get_text_length())
        if node1.get_text_md5() != node2.get_text_md5():
            callback.node_diff("TextMD5", node1.get_text_md5(), node2.get_text_md5())
        md1 = sdt_md5()
        md2 = sdt_md5()
        handle1 = node1.text_open()
        handle2 = node2.text_open()
        str1 = node1.text_read(handle1)
        str2 = node2.text_read(handle2)
        n1 = len(str1)
        n2 = len(str2)
        cmpstr1 = ""
        cmpstr2 = ""
        defreadcount = 16384
        readcount1 = defreadcount
        readcount2 = defreadcount
        # how to compare: 0=normal, 1=eol-check, 2=had a diff
        cmpmode = 0
        forceloop = False
        while n1 > 0 or n2 > 0 or forceloop:
            forceloop = False
            if n1 > 0:
                md1.update(str1)
                cmpstr1 += str1
            if n2 > 0:
                md2.update(str2)
                cmpstr2 += str2
            if cmpstr1 == cmpstr2:
                # save last char for possible eol compare
                cmpstr1 = cmpstr1[-1:]
                cmpstr2 = cmpstr2[-1:]
            elif cmpmode == 0:
                # binary compare had a diff
                if self.__check_eol:
                    # start doing eol checks
                    cmpmode = 1
                    forceloop = True
                else:
                    # no eol check so files differ
                    cmpmode = 2
                    cmpstr1 = ""
                    cmpstr2 = ""
            elif cmpmode == 1:
                # eol-diff or real diff?
                cn1 = len(cmpstr1) - 1
                cn2 = len(cmpstr2) - 1
                i1 = 0
                i2 = 0
                while i1 < cn1 and i2 < cn2:
                    if ((cmpstr1[i1] == '\n' or cmpstr1[i1] == '\r') and
                            (cmpstr2[i2] == '\n' or cmpstr2[i2] == '\r')):
                        # check for LF/CRLF/CR sequence
                        if cmpstr1[i1] == '\r' and cmpstr1[i1 + 1] == '\n':
                            i1 += 1
                        if cmpstr2[i2] == '\r' and cmpstr2[i2 + 1] == '\n':
                            i2 += 1
                    elif cmpstr1[i1] != cmpstr2[i2]:
                        # found a diff
                        cmpmode = 2
                        cmpstr1 = ""
                        cmpstr2 = ""
                        break
                    # next...
                    i1 += 1
                    i2 += 1
                # remove processed data from cmpstr and adjust readcount
                cmpstr1 = cmpstr1[i1:]
                cmpstr2 = cmpstr2[i2:]
                cn1 = len(cmpstr1)
                cn2 = len(cmpstr2)
                if cmpmode == 1:
                    # adjust readcount
                    if cn1 > cn2:
                        readcount1 = defreadcount + cn1 - cn2
                        readcount2 = defreadcount
                    else:
                        readcount1 = defreadcount
                        readcount2 = defreadcount + cn2 - cn1
                    # if n1 > 0 and n2 > 0 and cn1 > 0 and cn2 > 0:
                    if n1 > 0 or n2 > 0:
                        forceloop = True
                else:
                    # reset readcount
                    readcount1 = defreadcount
                    readcount2 = defreadcount
            else:
                # cmpmode = 2: just clear compare strings
                cmpstr1 = ""
                cmpstr2 = ""
            # read more text...
            if n1 > 0:
                str1 = node1.text_read(handle1, readcount1)
                n1 = len(str1)
            if n2 > 0:
                str2 = node2.text_read(handle2, readcount2)
                n2 = len(str2)
        if cmpmode == 1:
            # compare trailing data (can only occur in eol-check mode)
            cmpstr1 = cmpstr1.replace("\r\n", "\n").replace("\r", "\n")
            cmpstr2 = cmpstr2.replace("\r\n", "\n").replace("\r", "\n")
            if cmpstr1 != cmpstr2:
                cmpmode = 2
        mdstr1 = md1.hexdigest()
        mdstr2 = md2.hexdigest()
        if node1.get_text_md5() != mdstr1:
            callback.wrong_md5(1, node1.get_text_md5(), mdstr1)
        if node2.get_text_md5() != mdstr2:
            callback.wrong_md5(2, node2.get_text_md5(), mdstr2)
        if cmpmode == 1:
            callback.text_diff("EOL")
        elif cmpmode == 2:
            callback.text_diff("Text")
Example #3
0
    def __compare_node(self, node1, node2, callback):
        """
        Compare two nodes.

        @type node1: SvnDumpNode
        @param node1: First dump node.
        @type node2: SvnDumpNode
        @param node2: Second dump node.
        @type callback: SvnDumpDiffCallback
        @param callback: Callback object for diffs found.
        """

        # compare path
        if node1.get_path() != node2.get_path():
            callback.node_diff("Path", node1.get_path(), node2.get_path())
            return
        # compare action
        if node1.get_action() != node2.get_action():
            callback.node_diff("Action", node1.get_action(),
                               node2.get_action())
            return
        # compare kind
        if node1.get_kind() != node2.get_kind():
            callback.node_diff("Kind", node1.get_kind(), node2.get_kind())
            return
        # compare copy-from-path
        if node1.get_copy_from_path() != node2.get_copy_from_path():
            callback.node_diff("CopyFromPath", node1.get_copy_from_path(),
                               node2.get_copy_from_path())
            return
        # compare copy-from-rev
        if node1.get_copy_from_rev() != node2.get_copy_from_rev():
            callback.node_diff("CopyFromRev", node1.get_copy_from_rev(),
                               node2.get_copy_from_rev())
            return
        # compare props
        self.__compare_properties(False, node1.get_properties(),
                                  node2.get_properties(), callback)
        # compare text
        if node1.has_text() != node2.has_text():
            callback.node_diff("HasText", node1.has_text(), node2.has_text())
            return
        if not node1.has_text():
            # no text to compare
            return
        if node1.get_text_length() != node2.get_text_length():
            callback.node_diff("TextLen", node1.get_text_length(),
                               node2.get_text_length())
        if node1.get_text_md5() != node2.get_text_md5():
            callback.node_diff("TextMD5", node1.get_text_md5(),
                               node2.get_text_md5())
        md1 = sdt_md5()
        md2 = sdt_md5()
        handle1 = node1.text_open()
        handle2 = node2.text_open()
        str1 = node1.text_read(handle1)
        str2 = node2.text_read(handle2)
        n1 = len(str1)
        n2 = len(str2)
        cmpstr1 = ""
        cmpstr2 = ""
        defreadcount = 16384
        readcount1 = defreadcount
        readcount2 = defreadcount
        # how to compare: 0=normal, 1=eol-check, 2=had a diff
        cmpmode = 0
        forceloop = False
        while n1 > 0 or n2 > 0 or forceloop:
            forceloop = False
            if n1 > 0:
                md1.update(str1)
                cmpstr1 += str1
            if n2 > 0:
                md2.update(str2)
                cmpstr2 += str2
            if cmpstr1 == cmpstr2:
                # save last char for possible eol compare
                cmpstr1 = cmpstr1[-1:]
                cmpstr2 = cmpstr2[-1:]
            elif cmpmode == 0:
                # binary compare had a diff
                if self.__check_eol:
                    # start doing eol checks
                    cmpmode = 1
                    forceloop = True
                else:
                    # no eol check so files differ
                    cmpmode = 2
                    cmpstr1 = ""
                    cmpstr2 = ""
            elif cmpmode == 1:
                # eol-diff or real diff?
                cn1 = len(cmpstr1) - 1
                cn2 = len(cmpstr2) - 1
                i1 = 0
                i2 = 0
                while i1 < cn1 and i2 < cn2:
                    if ((cmpstr1[i1] == '\n' or cmpstr1[i1] == '\r')
                            and (cmpstr2[i2] == '\n' or cmpstr2[i2] == '\r')):
                        # check for LF/CRLF/CR sequence
                        if cmpstr1[i1] == '\r' and cmpstr1[i1 + 1] == '\n':
                            i1 += 1
                        if cmpstr2[i2] == '\r' and cmpstr2[i2 + 1] == '\n':
                            i2 += 1
                    elif cmpstr1[i1] != cmpstr2[i2]:
                        # found a diff
                        cmpmode = 2
                        cmpstr1 = ""
                        cmpstr2 = ""
                        break
                    # next...
                    i1 += 1
                    i2 += 1
                # remove processed data from cmpstr and adjust readcount
                cmpstr1 = cmpstr1[i1:]
                cmpstr2 = cmpstr2[i2:]
                cn1 = len(cmpstr1)
                cn2 = len(cmpstr2)
                if cmpmode == 1:
                    # adjust readcount
                    if cn1 > cn2:
                        readcount1 = defreadcount + cn1 - cn2
                        readcount2 = defreadcount
                    else:
                        readcount1 = defreadcount
                        readcount2 = defreadcount + cn2 - cn1
                    #if n1 > 0 and n2 > 0 and cn1 > 0 and cn2 > 0:
                    if n1 > 0 or n2 > 0:
                        forceloop = True
                else:
                    # reset readcount
                    readcount1 = defreadcount
                    readcount2 = defreadcount
            else:
                # cmpmode = 2: just clear compare strings
                cmpstr1 = ""
                cmpstr2 = ""
            # read more text...
            if n1 > 0:
                str1 = node1.text_read(handle1, readcount1)
                n1 = len(str1)
            if n2 > 0:
                str2 = node2.text_read(handle2, readcount2)
                n2 = len(str2)
        if cmpmode == 1:
            # compare trailing data (can only occur in eol-check mode)
            cmpstr1 = cmpstr1.replace("\r\n", "\n").replace("\r", "\n")
            cmpstr2 = cmpstr2.replace("\r\n", "\n").replace("\r", "\n")
            if cmpstr1 != cmpstr2:
                cmpmode = 2
        mdstr1 = md1.hexdigest()
        mdstr2 = md2.hexdigest()
        if node1.get_text_md5() != mdstr1:
            callback.wrong_md5(1, node1.get_text_md5(), mdstr1)
        if node2.get_text_md5() != mdstr2:
            callback.wrong_md5(2, node2.get_text_md5(), mdstr2)
        if cmpmode == 1:
            callback.text_diff("EOL")
        elif cmpmode == 2:
            callback.text_diff("Text")