Search code examples
svnautomation

svn update to specified revision or HAVE revision, whichever is newer


I can use svn update -r 1000 to update to revision 1000, but if I submitted a file in r1001 it will roll back my file to revision 1000. How can I update to a specific revision without making any of my files go back in time?

I have a build system that's generating an exe for my project. I wrote a script to download the exe and svn update to the revision the exe was built on. But it rolls back people's work if they run the script right after submitting.


Solution

  • You can use svnversion to get the version of your working copy.

    It's impractical to try to find the revision of every file, but you can check the revision for the whole working copy and change your target revision based on that. In my case, syncing to the greater of the have revision and the target revision is good enough.

    For the question's scenario: if you target r1000, submitted a file in r1001, then svnversion will report 1001 and you instead update to r1001. That prevents rollback, but you may get newer than your target revision.

    svnversion may report single revisions or revision ranges and may append status characters.

    Here's how I'm parsing that data:

    def get_have_revision(proj_root):
        """Determine the have (working copy) revision for the project. This is the
        latest revision of all files.
    
        get_have_revision(Path) -> int
        """
        cmd = ["svnversion.exe", proj_root]
        rev = subprocess.check_output(cmd, text=True)
        # We want the last value out of output like:
        #   "511111M"
        #   "511111:522222M"
        match = re.search(r"(?:.*:)?(\d+)", rev)
        if match:
            rev = match.group(1)
    
        try:
            return int(rev)
        except ValueError as e:
            print("Failed to use HAVE revision: revision={} msg: {}".format(rev, e))
            return -1
    
    ...
    safe_rev = get_revision_from_build()
    have_rev = get_have_revision(proj_root)
    target_rev = max(safe_rev, have_rev)
    ...