summaryrefslogtreecommitdiffstats
path: root/git-p4.py
diff options
context:
space:
mode:
Diffstat (limited to 'git-p4.py')
-rwxr-xr-xgit-p4.py93
1 files changed, 48 insertions, 45 deletions
diff --git a/git-p4.py b/git-p4.py
index a7cb321f75..cb37545455 100755
--- a/git-p4.py
+++ b/git-p4.py
@@ -56,6 +56,21 @@ defaultBlockSize = 1<<20
p4_access_checked = False
+re_ko_keywords = re.compile(br'\$(Id|Header)(:[^$\n]+)?\$')
+re_k_keywords = re.compile(br'\$(Id|Header|Author|Date|DateTime|Change|File|Revision)(:[^$\n]+)?\$')
+
+def format_size_human_readable(num):
+ """ Returns a number of units (typically bytes) formatted as a human-readable
+ string.
+ """
+ if num < 1024:
+ return '{:d} B'.format(num)
+ for unit in ["Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]:
+ num /= 1024.0
+ if num < 1024.0:
+ return "{:3.1f} {}B".format(num, unit)
+ return "{:.1f} YiB".format(num)
+
def p4_build_cmd(cmd):
"""Build a suitable p4 command line.
@@ -337,17 +352,19 @@ def p4_read_pipe(c, ignore_error=False, raw=False):
real_cmd = p4_build_cmd(c)
return read_pipe(real_cmd, ignore_error, raw=raw)
-def read_pipe_lines(c):
+def read_pipe_lines(c, raw=False):
if verbose:
sys.stderr.write('Reading pipe: %s\n' % str(c))
expand = not isinstance(c, list)
p = subprocess.Popen(c, stdout=subprocess.PIPE, shell=expand)
pipe = p.stdout
- val = [decode_text_stream(line) for line in pipe.readlines()]
+ lines = pipe.readlines()
+ if not raw:
+ lines = [decode_text_stream(line) for line in lines]
if pipe.close() or p.wait():
die('Command failed: %s' % str(c))
- return val
+ return lines
def p4_read_pipe_lines(c):
"""Specifically invoke p4 on the command supplied. """
@@ -577,20 +594,12 @@ def p4_type(f):
#
def p4_keywords_regexp_for_type(base, type_mods):
if base in ("text", "unicode", "binary"):
- kwords = None
if "ko" in type_mods:
- kwords = 'Id|Header'
+ return re_ko_keywords
elif "k" in type_mods:
- kwords = 'Id|Header|Author|Date|DateTime|Change|File|Revision'
+ return re_k_keywords
else:
return None
- pattern = r"""
- \$ # Starts with a dollar, followed by...
- (%s) # one of the keywords, followed by...
- (:[^$\n]+)? # possibly an old expansion, followed by...
- \$ # another dollar
- """ % kwords
- return pattern
else:
return None
@@ -1679,18 +1688,13 @@ class P4Submit(Command, P4UserMap):
return result
- def patchRCSKeywords(self, file, pattern):
- # Attempt to zap the RCS keywords in a p4 controlled file matching the given pattern
+ def patchRCSKeywords(self, file, regexp):
+ # Attempt to zap the RCS keywords in a p4 controlled file matching the given regex
(handle, outFileName) = tempfile.mkstemp(dir='.')
try:
- outFile = os.fdopen(handle, "w+")
- inFile = open(file, "r")
- regexp = re.compile(pattern, re.VERBOSE)
- for line in inFile.readlines():
- line = regexp.sub(r'$\1$', line)
- outFile.write(line)
- inFile.close()
- outFile.close()
+ with os.fdopen(handle, "wb") as outFile, open(file, "rb") as inFile:
+ for line in inFile.readlines():
+ outFile.write(regexp.sub(br'$\1$', line))
# Forcibly overwrite the original file
os.unlink(file)
shutil.move(outFileName, file)
@@ -2017,25 +2021,24 @@ class P4Submit(Command, P4UserMap):
# the patch to see if that's possible.
if gitConfigBool("git-p4.attemptRCSCleanup"):
file = None
- pattern = None
kwfiles = {}
for file in editedFiles | filesToDelete:
# did this file's delta contain RCS keywords?
- pattern = p4_keywords_regexp_for_file(file)
-
- if pattern:
+ regexp = p4_keywords_regexp_for_file(file)
+ if regexp:
# this file is a possibility...look for RCS keywords.
- regexp = re.compile(pattern, re.VERBOSE)
- for line in read_pipe_lines(["git", "diff", "%s^..%s" % (id, id), file]):
+ for line in read_pipe_lines(
+ ["git", "diff", "%s^..%s" % (id, id), file],
+ raw=True):
if regexp.search(line):
if verbose:
- print("got keyword match on %s in %s in %s" % (pattern, line, file))
- kwfiles[file] = pattern
+ print("got keyword match on %s in %s in %s" % (regex.pattern, line, file))
+ kwfiles[file] = regexp
break
- for file in kwfiles:
+ for file, regexp in kwfiles.items():
if verbose:
- print("zapping %s with %s" % (line,pattern))
+ print("zapping %s with %s" % (line, regexp.pattern))
# File is being deleted, so not open in p4. Must
# disable the read-only bit on windows.
if self.isWindows and file not in editedFiles:
@@ -2892,7 +2895,8 @@ class P4Sync(Command, P4UserMap):
size = int(self.stream_file['fileSize'])
else:
size = 0 # deleted files don't get a fileSize apparently
- sys.stdout.write('\r%s --> %s (%i MB)\n' % (file_path, relPath, size/1024/1024))
+ sys.stdout.write('\r%s --> %s (%s)\n' % (
+ file_path, relPath, format_size_human_readable(size)))
sys.stdout.flush()
(type_base, type_mods) = split_p4_type(file["type"])
@@ -2955,12 +2959,9 @@ class P4Sync(Command, P4UserMap):
# Note that we do not try to de-mangle keywords on utf16 files,
# even though in theory somebody may want that.
- pattern = p4_keywords_regexp_for_type(type_base, type_mods)
- if pattern:
- regexp = re.compile(pattern, re.VERBOSE)
- text = ''.join(decode_text_stream(c) for c in contents)
- text = regexp.sub(r'$\1$', text)
- contents = [ encode_text_stream(text) ]
+ regexp = p4_keywords_regexp_for_type(type_base, type_mods)
+ if regexp:
+ contents = [regexp.sub(br'$\1$', c) for c in contents]
if self.largeFileSystem:
(git_mode, contents) = self.largeFileSystem.processContent(git_mode, relPath, contents)
@@ -2990,9 +2991,8 @@ class P4Sync(Command, P4UserMap):
if not err and 'fileSize' in self.stream_file:
required_bytes = int((4 * int(self.stream_file["fileSize"])) - calcDiskFree())
if required_bytes > 0:
- err = 'Not enough space left on %s! Free at least %i MB.' % (
- os.getcwd(), required_bytes/1024/1024
- )
+ err = 'Not enough space left on %s! Free at least %s.' % (
+ os.getcwd(), format_size_human_readable(required_bytes))
if err:
f = None
@@ -3036,7 +3036,9 @@ class P4Sync(Command, P4UserMap):
size = int(self.stream_file["fileSize"])
if size > 0:
progress = 100*self.stream_file['streamContentSize']/size
- sys.stdout.write('\r%s %d%% (%i MB)' % (self.stream_file['depotFile'], progress, int(size/1024/1024)))
+ sys.stdout.write('\r%s %d%% (%s)' % (
+ self.stream_file['depotFile'], progress,
+ format_size_human_readable(size)))
sys.stdout.flush()
self.stream_have_file_info = True
@@ -3549,7 +3551,8 @@ class P4Sync(Command, P4UserMap):
self.updateOptionDict(description)
if not self.silent:
- sys.stdout.write("\rImporting revision %s (%s%%)" % (change, cnt * 100 / len(changes)))
+ sys.stdout.write("\rImporting revision %s (%d%%)" % (
+ change, (cnt * 100) // len(changes)))
sys.stdout.flush()
cnt = cnt + 1