用svn export
来做到这一点,但我发现没有办法用
svn checkout
或svn update
来做到这一点。svn export
在我的情况下还不够,因为它似乎不适用于已移动的文件(传递 PEG 的语法
@
似乎没有帮助)。删除属性不起作用,因为我想避免提交(并且无论如何我都需要处理文件的过去版本,以便需要分支......)。 使用
git-svn
可能有用,但在过去的实验中,我发现它太慢了,无法在像我正在开发的那样大的存储库上使用。
),但似乎尚未实现。有
可能有一种使用svn patch
的方法(但它比仅仅传递一个标志更复杂)。我最终编写了这个 Python 脚本,该脚本使用
svn:keyword
属性修改文件。我从这个答案得到了帮助
警告:就地修改文件,因此请在干净的状态下工作(以便能够恢复)并且之后不要提交,除非您真的想要它!
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)