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
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")
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")