|
56 | 56 |
|
57 | 57 | p4_access_checked = False |
58 | 58 |
|
| 59 | +re_ko_keywords = re.compile(br'\$(Id|Header)(:[^$\n]+)?\$') |
| 60 | +re_k_keywords = re.compile(br'\$(Id|Header|Author|Date|DateTime|Change|File|Revision)(:[^$\n]+)?\$') |
| 61 | + |
59 | 62 | def p4_build_cmd(cmd): |
60 | 63 | """Build a suitable p4 command line. |
61 | 64 |
|
@@ -337,17 +340,19 @@ def p4_read_pipe(c, ignore_error=False, raw=False): |
337 | 340 | real_cmd = p4_build_cmd(c) |
338 | 341 | return read_pipe(real_cmd, ignore_error, raw=raw) |
339 | 342 |
|
340 | | -def read_pipe_lines(c): |
| 343 | +def read_pipe_lines(c, raw=False): |
341 | 344 | if verbose: |
342 | 345 | sys.stderr.write('Reading pipe: %s\n' % str(c)) |
343 | 346 |
|
344 | 347 | expand = not isinstance(c, list) |
345 | 348 | p = subprocess.Popen(c, stdout=subprocess.PIPE, shell=expand) |
346 | 349 | pipe = p.stdout |
347 | | - val = [decode_text_stream(line) for line in pipe.readlines()] |
| 350 | + lines = pipe.readlines() |
| 351 | + if not raw: |
| 352 | + lines = [decode_text_stream(line) for line in lines] |
348 | 353 | if pipe.close() or p.wait(): |
349 | 354 | die('Command failed: %s' % str(c)) |
350 | | - return val |
| 355 | + return lines |
351 | 356 |
|
352 | 357 | def p4_read_pipe_lines(c): |
353 | 358 | """Specifically invoke p4 on the command supplied. """ |
@@ -577,20 +582,12 @@ def p4_type(f): |
577 | 582 | # |
578 | 583 | def p4_keywords_regexp_for_type(base, type_mods): |
579 | 584 | if base in ("text", "unicode", "binary"): |
580 | | - kwords = None |
581 | 585 | if "ko" in type_mods: |
582 | | - kwords = 'Id|Header' |
| 586 | + return re_ko_keywords |
583 | 587 | elif "k" in type_mods: |
584 | | - kwords = 'Id|Header|Author|Date|DateTime|Change|File|Revision' |
| 588 | + return re_k_keywords |
585 | 589 | else: |
586 | 590 | 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 |
594 | 591 | else: |
595 | 592 | return None |
596 | 593 |
|
@@ -1753,18 +1750,13 @@ def prepareLogMessage(self, template, message, jobs): |
1753 | 1750 |
|
1754 | 1751 | return result |
1755 | 1752 |
|
1756 | | - def patchRCSKeywords(self, file, pattern): |
1757 | | - # Attempt to zap the RCS keywords in a p4 controlled file matching the given pattern |
| 1753 | + def patchRCSKeywords(self, file, regexp): |
| 1754 | + # Attempt to zap the RCS keywords in a p4 controlled file matching the given regex |
1758 | 1755 | (handle, outFileName) = tempfile.mkstemp(dir='.') |
1759 | 1756 | try: |
1760 | | - outFile = os.fdopen(handle, "w+") |
1761 | | - inFile = open(file, "r") |
1762 | | - regexp = re.compile(pattern, re.VERBOSE) |
1763 | | - for line in inFile.readlines(): |
1764 | | - line = regexp.sub(r'$\1$', line) |
1765 | | - outFile.write(line) |
1766 | | - inFile.close() |
1767 | | - outFile.close() |
| 1757 | + with os.fdopen(handle, "wb") as outFile, open(file, "rb") as inFile: |
| 1758 | + for line in inFile.readlines(): |
| 1759 | + outFile.write(regexp.sub(br'$\1$', line)) |
1768 | 1760 | # Forcibly overwrite the original file |
1769 | 1761 | os.unlink(file) |
1770 | 1762 | shutil.move(outFileName, file) |
@@ -2091,25 +2083,24 @@ def applyCommit(self, id): |
2091 | 2083 | # the patch to see if that's possible. |
2092 | 2084 | if gitConfigBool("git-p4.attemptRCSCleanup"): |
2093 | 2085 | file = None |
2094 | | - pattern = None |
2095 | 2086 | kwfiles = {} |
2096 | 2087 | for file in editedFiles | filesToDelete: |
2097 | 2088 | # did this file's delta contain RCS keywords? |
2098 | | - pattern = p4_keywords_regexp_for_file(file) |
2099 | | - |
2100 | | - if pattern: |
| 2089 | + regexp = p4_keywords_regexp_for_file(file) |
| 2090 | + if regexp: |
2101 | 2091 | # this file is a possibility...look for RCS keywords. |
2102 | | - regexp = re.compile(pattern, re.VERBOSE) |
2103 | | - for line in read_pipe_lines(["git", "diff", "%s^..%s" % (id, id), file]): |
| 2092 | + for line in read_pipe_lines( |
| 2093 | + ["git", "diff", "%s^..%s" % (id, id), file], |
| 2094 | + raw=True): |
2104 | 2095 | if regexp.search(line): |
2105 | 2096 | if verbose: |
2106 | | - print("got keyword match on %s in %s in %s" % (pattern, line, file)) |
2107 | | - kwfiles[file] = pattern |
| 2097 | + print("got keyword match on %s in %s in %s" % (regex.pattern, line, file)) |
| 2098 | + kwfiles[file] = regexp |
2108 | 2099 | break |
2109 | 2100 |
|
2110 | | - for file in kwfiles: |
| 2101 | + for file, regexp in kwfiles.items(): |
2111 | 2102 | if verbose: |
2112 | | - print("zapping %s with %s" % (line,pattern)) |
| 2103 | + print("zapping %s with %s" % (line, regexp.pattern)) |
2113 | 2104 | # File is being deleted, so not open in p4. Must |
2114 | 2105 | # disable the read-only bit on windows. |
2115 | 2106 | if self.isWindows and file not in editedFiles: |
@@ -3029,12 +3020,9 @@ def streamOneP4File(self, file, contents): |
3029 | 3020 |
|
3030 | 3021 | # Note that we do not try to de-mangle keywords on utf16 files, |
3031 | 3022 | # even though in theory somebody may want that. |
3032 | | - pattern = p4_keywords_regexp_for_type(type_base, type_mods) |
3033 | | - if pattern: |
3034 | | - regexp = re.compile(pattern, re.VERBOSE) |
3035 | | - text = ''.join(decode_text_stream(c) for c in contents) |
3036 | | - text = regexp.sub(r'$\1$', text) |
3037 | | - contents = [ encode_text_stream(text) ] |
| 3023 | + regexp = p4_keywords_regexp_for_type(type_base, type_mods) |
| 3024 | + if regexp: |
| 3025 | + contents = [regexp.sub(br'$\1$', c) for c in contents] |
3038 | 3026 |
|
3039 | 3027 | if self.largeFileSystem: |
3040 | 3028 | (git_mode, contents) = self.largeFileSystem.processContent(git_mode, relPath, contents) |
|
0 commit comments