Subversion diff for zipped xml file

前端 未结 2 1615
攒了一身酷
攒了一身酷 2020-12-31 11:27

I\'m using MySQL Workbench to maintain the database schema for an application. The .mwb file that Workbench uses, which is a zipped XML document, is kept in a S

相关标签:
2条回答
  • 2020-12-31 12:01

    Subversion allows you to use external differencing tools . What you can do is write a wrapper script, and tell Subversion to use it as its "diff" command. Your wrapper would parse the arguments it gets from Subversion to pick out the "left" and "right" filenames, operate on them, and return an error code that Subversion will interpret as success or failure. In your case, the wrapper could unzip the XML files, and pass the unzipped results to "diff" or another tool of your choice.

    Subversion will balk at diff-ing files that were detected as "binary" when they were checked in. The "--force" option lets you override this check, so your wrapper script will be be run even if the input files are checked in as binaries.

    0 讨论(0)
  • 2020-12-31 12:11

    I've written a diff script for workbench files which can be integrated with TortoiseSVN and TortoiseGit, which will exactly do what Jim Lewis suggests: Extract the actual XML from the archive and diff it.

    The script will also eliminate all the ptr-Attribute noise in the diff. Merging is not possible and would be a bit more complicated (discover how the ptr-attributes would behave, re-pack the XML into the archive, what's with the other metadata in the archive?, ...)

    The python script is available at pastebin under CC-BY 3.0:

    http://pastebin.com/AcD7dBNH

    # extensions: mwb
    # TortoiseSVN Diff script for MySQL Workbench scheme files
    # 2012 by Oliver Iking, Z-Software GmbH, oliverikingREPLACETHISWITHANATz-software.net, http://www.z-software.net/
    # This work is licensed under a Creative Commons Attribution 3.0 Unported License - http://creativecommons.org/licenses/by/3.0/
    
    # Will produce two diffable documents, which don't resemble the FULL MWB content, but the scheme relevant data. 
    # Merging is not possible
    
    # Open your TortoiseSVN (or TortoiseSomething) settings, go to the "Diff Viewer" tab and click on "Advanced". Add 
    # a row with the extension ".mwb" and a command line of 
    # "path\to\python.exe" "path\to\diff-mwb.py" %base %mine
    # Apply changes and now you can diff mysql workbench scheme files
    
    import sys
    import zipfile
    import os
    import time
    import tempfile
    import re
    
    # mysql workbench XML will have _ptr_ attributes which are modified on each save for almost each XML node. Remove the visual litter, 
    # make actual changes stand out.
    def sanitizeMwbXml( xml ):
        return re.sub('_ptr_="([0-9a-fA-F]{8})"', '', xml)
    
    try:
        if len(sys.argv) < 2:
            print("Not enough parameters, cannot diff documents!")
            sys.exit(1)
    
        docOld = sys.argv[1]
        docNew = sys.argv[2]
    
        if not os.path.exists(docOld) or not os.path.exists(docNew):
            print("Documents don't exist, cannot diff!")
            sys.exit(1)
    
        # Workbench files are actually zip archives
        zipA = zipfile.ZipFile( docOld, 'r' )
        zipB = zipfile.ZipFile( docNew, 'r' )
    
        tempSubpath = os.tempnam(None,"mwbcompare")
    
        docA = os.path.join( tempSubpath, "mine.document.mwb.xml" )
        docB = os.path.join( tempSubpath, "theirs.document.mwb.xml" )
    
        os.makedirs( tempSubpath )
    
        if os.path.exists(docA) or os.path.exists(docB):
            print("Cannot extract documents, files exist!")
            sys.exit(1)
    
        # Read, sanitize and write actual scheme XML contents to temporary files
    
        docABytes = sanitizeMwbXml(zipA.read("document.mwb.xml" ))
        docBBytes = sanitizeMwbXml(zipB.read("document.mwb.xml" ))
    
        docAFile = open(docA, "w")
        docBFile = open(docB, "w")
    
        docAFile.write(docABytes)
        docBFile.write(docBBytes)
    
        docAFile.close()
        docBFile.close()
    
        os.system("TortoiseProc /command:diff /path:\"" + docA + "\" /path2:\"" + docB + "\"");
    
        # TortoiseProc will spawn a subprocess so we can't delete the files. They're in the tempdir, so they
        # will be cleaned up eventually
        #os.unlink(docA)
        #os.unlink(docB)
    
        sys.exit(0)
    except Exception as e:
        print str(e)
        # Sleep, or the command window will close
        time.sleep(5)
    
    0 讨论(0)
提交回复
热议问题