0

While it is possible to do it with svn export, I found no way to do it with svn checkout or svn update.

svn export is not sufficient in my case because it does not seem to work with files that have been moved (syntax @ to pass a PEG does not seem to help).

Deleting the property does not work because I want to avoid committing (and I need to work on past versions of the files anyway so that would require branching ...).

Using git-svn might work but in past experiments I found it too slow to be usable on repos as big as the one I am working on.

Gabriel Devillers
  • 3,155
  • 2
  • 30
  • 53

1 Answers1

0

People have been asking for this feature for a long time (and also for svn diff) but it does not seem to have been implemented.

There might be a way to use svn patch for that (but it would be more complex than just passing a flag).

I ended up writing this Python script that modifies the files in place with the svn:keyword property. I got help from this answer

Warning: modifies files in place so do work on a clean state (to be able to revert) and do not commit afterward, unless you really want it!

import subprocess
from xml.dom import minidom
import re

def undo_svn_keywords_expansions(root_dir_or_file):
    """ Modify files in place to change $Id: blahblah$ into $Id$ (for example)
        root_dir_or_file must be a file or directory within a svn checkout
        root_dir_or_file can be relative to current working directory
        this file (or, if it is a dir, all the files recursively contained
        inside of it) will be modified in place, using a regex on bytes
        (to avoid any text encoding problem)

        I tried hard to not need this, but:
        - I found no way to disable this expansion at checkout time
        - `svn export` does not work on urls that do not exists anymore (@rev
          does not seem to help)
        - unsetting the svn:keywords property is not sufficient: you need to
          commit the change (not possible in our case)
    """
    files_with_keywords_xml = subprocess.run(["svn", "propget", "svn:keywords", "--xml", "-R", root_dir_or_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    if len(files_with_keywords_xml.stderr) != 0:
        print("stdout: ", files_with_keywords_xml.stdout)
        print("stderr: ", files_with_keywords_xml.stderr)
        assert(False)
    files_with_keywords_xml.check_returncode()

    files_with_keywords = minidom.parseString(files_with_keywords_xml.stdout.decode("utf-8"))
    for file in files_with_keywords.getElementsByTagName('target'):
        file_path = file.getAttribute('path')
        properties = file.getElementsByTagName('property')
        svn_keyword_property = [p for p in properties if p.getAttribute('name') == "svn:keywords"]
        assert(len(svn_keyword_property) == 1)
        keywords = svn_keyword_property[0].firstChild.nodeValue.split(" ")
        keywords_as_bytes = [keyword.encode('utf-8') for keyword in keywords]
        keywords_sub_re = b'|'.join(keywords_as_bytes)

        with open(file_path, 'rb') as file_to_read:
            file_contents = file_to_read.read()
            file_to_read.close()

            new_contents = re.sub(b"\$("+keywords_sub_re+b"):.*\$",
                                  b"$\\1$",
                                  file_contents)

            with open(file_path, 'wb') as file_to_write:
                file_to_write.write(new_contents)
Gabriel Devillers
  • 3,155
  • 2
  • 30
  • 53