git-p4: pre-compile RCS keyword regexes
Previously git-p4.py would compile one of two regular expressions for ever RCS keyword-enabled file. This patch improves simplifies the code by pre-compiling the two regular expressions when the script first loads. Signed-off-by: Joel Holdsworth <jholdsworth@nvidia.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Joel Holdsworth committed
Dec 16, 2021 at 13:46 UTC
e665e98ec1d1558a55a3e7e5fd5e88d70396ec96
1 file changed
+18
-30
git-p4.py
+18
-30
@@ -56,6 +56,9 @@ defaultBlockSize = 1<<20
56
57
p4_access_checked = False
58
59
+re_ko_keywords = re.compile(r'\$(Id|Header)(:[^$\n]+)?\$')
60
+re_k_keywords = re.compile(r'\$(Id|Header|Author|Date|DateTime|Change|File|Revision)(:[^$\n]+)?\$')
61
+
62
def p4_build_cmd(cmd):
63
"""Build a suitable p4 command line.
64
@@ -577,20 +580,12 @@ def p4_type(f):
580
#
581
def p4_keywords_regexp_for_type(base, type_mods):
582
if base in ("text", "unicode", "binary"):
580
- kwords = None
583
if "ko" in type_mods:
582
- kwords = 'Id|Header'
584
+ return re_ko_keywords
585
elif "k" in type_mods:
584
- kwords = 'Id|Header|Author|Date|DateTime|Change|File|Revision'
586
+ return re_k_keywords
587
else:
588
return None
587
- pattern = r"""
588
- \$ # Starts with a dollar, followed by...
589
- (%s) # one of the keywords, followed by...
590
- (:[^$\n]+)? # possibly an old expansion, followed by...
591
- \$ # another dollar
592
- """ % kwords
593
- return pattern
589
else:
590
return None
591
@@ -1753,15 +1748,13 @@ class P4Submit(Command, P4UserMap):
1748
1749
return result
1750
1756
- def patchRCSKeywords(self, file, pattern):
1757
- # Attempt to zap the RCS keywords in a p4 controlled file matching the given pattern
1751
+ def patchRCSKeywords(self, file, regexp):
1752
+ # Attempt to zap the RCS keywords in a p4 controlled file matching the given regex
1753
(handle, outFileName) = tempfile.mkstemp(dir='.')
1754
try:
1755
with os.fdopen(handle, "w+") as outFile, open(file, "r") as inFile:
1761
- regexp = re.compile(pattern, re.VERBOSE)
1756
for line in inFile.readlines():
1763
- line = regexp.sub(r'$\1$', line)
1764
- outFile.write(line)
1757
+ outFile.write(regexp.sub(r'$\1$', line))
1758
# Forcibly overwrite the original file
1759
os.unlink(file)
1760
shutil.move(outFileName, file)
@@ -2088,25 +2081,22 @@ class P4Submit(Command, P4UserMap):
2081
# the patch to see if that's possible.
2082
if gitConfigBool("git-p4.attemptRCSCleanup"):
2083
file = None
2091
- pattern = None
2084
kwfiles = {}
2085
for file in editedFiles | filesToDelete:
2086
# did this file's delta contain RCS keywords?
2095
- pattern = p4_keywords_regexp_for_file(file)
2096
-
2097
- if pattern:
2087
+ regexp = p4_keywords_regexp_for_file(file)
2088
+ if regexp:
2089
# this file is a possibility...look for RCS keywords.
2099
- regexp = re.compile(pattern, re.VERBOSE)
2090
for line in read_pipe_lines(["git", "diff", "%s^..%s" % (id, id), file]):
2091
if regexp.search(line):
2092
if verbose:
2103
- print("got keyword match on %s in %s in %s" % (pattern, line, file))
2104
- kwfiles[file] = pattern
2093
+ print("got keyword match on %s in %s in %s" % (regex.pattern, line, file))
2094
+ kwfiles[file] = regexp
2095
break
2096
2107
- for file in kwfiles:
2097
+ for file, regexp in kwfiles.items():
2098
if verbose:
2109
- print("zapping %s with %s" % (line,pattern))
2099
+ print("zapping %s with %s" % (line, regexp.pattern))
2100
# File is being deleted, so not open in p4. Must
2101
# disable the read-only bit on windows.
2102
if self.isWindows and file not in editedFiles:
@@ -3026,12 +3016,10 @@ class P4Sync(Command, P4UserMap):
3016
3017
# Note that we do not try to de-mangle keywords on utf16 files,
3018
# even though in theory somebody may want that.
3029
- pattern = p4_keywords_regexp_for_type(type_base, type_mods)
3030
- if pattern:
3031
- regexp = re.compile(pattern, re.VERBOSE)
3032
- text = ''.join(decode_text_stream(c) for c in contents)
3033
- text = regexp.sub(r'$\1$', text)
3034
- contents = [ encode_text_stream(text) ]
3019
+ regexp = p4_keywords_regexp_for_type(type_base, type_mods)
3020
+ if regexp:
3021
+ contents = [encode_text_stream(regexp.sub(
3022
+ r'$\1$', ''.join(decode_text_stream(c) for c in contents)))]
3023
3024
if self.largeFileSystem:
3025
(git_mode, contents) = self.largeFileSystem.processContent(git_mode, relPath, contents)