[arch-commits] Commit in git/repos/testing-x86_64 (12 files)
Christian Hesse
eworm at archlinux.org
Tue Apr 14 18:40:23 UTC 2020
Date: Tuesday, April 14, 2020 @ 18:40:22
Author: eworm
Revision: 380320
archrelease: copy trunk to testing-x86_64
Added:
git/repos/testing-x86_64/0001-git-p4-python.patch
(from rev 380319, git/trunk/0001-git-p4-python.patch)
git/repos/testing-x86_64/PKGBUILD
(from rev 380319, git/trunk/PKGBUILD)
git/repos/testing-x86_64/git-daemon.socket
(from rev 380319, git/trunk/git-daemon.socket)
git/repos/testing-x86_64/git-daemon at .service
(from rev 380319, git/trunk/git-daemon at .service)
git/repos/testing-x86_64/git-sysusers.conf
(from rev 380319, git/trunk/git-sysusers.conf)
git/repos/testing-x86_64/git.install
(from rev 380319, git/trunk/git.install)
Deleted:
git/repos/testing-x86_64/0001-git-p4-python.patch
git/repos/testing-x86_64/PKGBUILD
git/repos/testing-x86_64/git-daemon.socket
git/repos/testing-x86_64/git-daemon at .service
git/repos/testing-x86_64/git-sysusers.conf
git/repos/testing-x86_64/git.install
--------------------------+
0001-git-p4-python.patch | 1262 ++++++++++++++++++++++-----------------------
PKGBUILD | 272 ++++-----
git-daemon.socket | 18
git-daemon at .service | 28
git-sysusers.conf | 2
git.install | 28
6 files changed, 805 insertions(+), 805 deletions(-)
Deleted: 0001-git-p4-python.patch
===================================================================
--- 0001-git-p4-python.patch 2020-04-14 18:38:12 UTC (rev 380319)
+++ 0001-git-p4-python.patch 2020-04-14 18:40:22 UTC (rev 380320)
@@ -1,631 +0,0 @@
-diff --git a/git-p4.py b/git-p4.py
-index 40d9e7c594..ca0a874501 100755
---- a/git-p4.py
-+++ b/git-p4.py
-@@ -8,12 +8,12 @@
- # License: MIT <http://www.opensource.org/licenses/mit-license.php>
- #
- import sys
--if sys.hexversion < 0x02040000:
-- # The limiter is the subprocess module
-- sys.stderr.write("git-p4: requires Python 2.4 or later.\n")
-+if sys.version_info.major < 3 and sys.version_info.minor < 7:
-+ sys.stderr.write("git-p4: requires Python 2.7 or later.\n")
- sys.exit(1)
- import os
- import optparse
-+import functools
- import marshal
- import subprocess
- import tempfile
-@@ -27,36 +27,15 @@
- import ctypes
- import errno
-
-+# On python2.7 where raw_input() and input() are both availble,
-+# we want raw_input's semantics, but aliased to input for python3
-+# compatibility
- # support basestring in python3
- try:
-- unicode = unicode
--except NameError:
-- # 'unicode' is undefined, must be Python 3
-- str = str
-- unicode = str
-- bytes = bytes
-- basestring = (str,bytes)
--else:
-- # 'unicode' exists, must be Python 2
-- str = str
-- unicode = unicode
-- bytes = str
-- basestring = basestring
--
--try:
-- from subprocess import CalledProcessError
--except ImportError:
-- # from python2.7:subprocess.py
-- # Exception classes used by this module.
-- class CalledProcessError(Exception):
-- """This exception is raised when a process run by check_call() returns
-- a non-zero exit status. The exit status will be stored in the
-- returncode attribute."""
-- def __init__(self, returncode, cmd):
-- self.returncode = returncode
-- self.cmd = cmd
-- def __str__(self):
-- return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
-+ if raw_input and input:
-+ input = raw_input
-+except:
-+ pass
-
- verbose = False
-
-@@ -105,7 +84,7 @@ def p4_build_cmd(cmd):
- # Provide a way to not pass this option by setting git-p4.retries to 0
- real_cmd += ["-r", str(retries)]
-
-- if isinstance(cmd,basestring):
-+ if not isinstance(cmd, list):
- real_cmd = ' '.join(real_cmd) + ' ' + cmd
- else:
- real_cmd += cmd
-@@ -175,18 +154,48 @@ def prompt(prompt_text):
- """
- choices = set(m.group(1) for m in re.finditer(r"\[(.)\]", prompt_text))
- while True:
-- response = raw_input(prompt_text).strip().lower()
-+ response = input(prompt_text).strip().lower()
- if not response:
- continue
- response = response[0]
- if response in choices:
- return response
-
-+# We need different encoding/decoding strategies for text data being passed
-+# around in pipes depending on python version
-+if bytes is not str:
-+ # For python3, always encode and decode as appropriate
-+ def decode_text_stream(s):
-+ return s.decode() if isinstance(s, bytes) else s
-+ def encode_text_stream(s):
-+ return s.encode() if isinstance(s, str) else s
-+else:
-+ # For python2.7, pass read strings as-is, but also allow writing unicode
-+ def decode_text_stream(s):
-+ return s
-+ def encode_text_stream(s):
-+ return s.encode('utf_8') if isinstance(s, unicode) else s
-+
-+def decode_path(path):
-+ """Decode a given string (bytes or otherwise) using configured path encoding options
-+ """
-+ encoding = gitConfig('git-p4.pathEncoding') or 'utf_8'
-+ if bytes is not str:
-+ return path.decode(encoding, errors='replace') if isinstance(path, bytes) else path
-+ else:
-+ try:
-+ path.decode('ascii')
-+ except:
-+ path = path.decode(encoding, errors='replace')
-+ if verbose:
-+ print('Path with non-ASCII characters detected. Used {} to decode: {}'.format(encoding, path))
-+ return path
-+
- def write_pipe(c, stdin):
- if verbose:
- sys.stderr.write('Writing pipe: %s\n' % str(c))
-
-- expand = isinstance(c,basestring)
-+ expand = not isinstance(c, list)
- p = subprocess.Popen(c, stdin=subprocess.PIPE, shell=expand)
- pipe = p.stdin
- val = pipe.write(stdin)
-@@ -198,6 +207,8 @@ def write_pipe(c, stdin):
-
- def p4_write_pipe(c, stdin):
- real_cmd = p4_build_cmd(c)
-+ if bytes is not str and isinstance(stdin, str):
-+ stdin = encode_text_stream(stdin)
- return write_pipe(real_cmd, stdin)
-
- def read_pipe_full(c):
-@@ -208,15 +219,17 @@ def read_pipe_full(c):
- if verbose:
- sys.stderr.write('Reading pipe: %s\n' % str(c))
-
-- expand = isinstance(c,basestring)
-+ expand = not isinstance(c, list)
- p = subprocess.Popen(c, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=expand)
- (out, err) = p.communicate()
-- return (p.returncode, out, err)
-+ return (p.returncode, out, decode_text_stream(err))
-
--def read_pipe(c, ignore_error=False):
-+def read_pipe(c, ignore_error=False, raw=False):
- """ Read output from command. Returns the output text on
- success. On failure, terminates execution, unless
- ignore_error is True, when it returns an empty string.
-+
-+ If raw is True, do not attempt to decode output text.
- """
- (retcode, out, err) = read_pipe_full(c)
- if retcode != 0:
-@@ -224,6 +237,8 @@ def read_pipe(c, ignore_error=False):
- out = ""
- else:
- die('Command failed: %s\nError: %s' % (str(c), err))
-+ if not raw:
-+ out = decode_text_stream(out)
- return out
-
- def read_pipe_text(c):
-@@ -234,23 +249,22 @@ def read_pipe_text(c):
- if retcode != 0:
- return None
- else:
-- return out.rstrip()
-+ return decode_text_stream(out).rstrip()
-
--def p4_read_pipe(c, ignore_error=False):
-+def p4_read_pipe(c, ignore_error=False, raw=False):
- real_cmd = p4_build_cmd(c)
-- return read_pipe(real_cmd, ignore_error)
-+ return read_pipe(real_cmd, ignore_error, raw=raw)
-
- def read_pipe_lines(c):
- if verbose:
- sys.stderr.write('Reading pipe: %s\n' % str(c))
-
-- expand = isinstance(c, basestring)
-+ expand = not isinstance(c, list)
- p = subprocess.Popen(c, stdout=subprocess.PIPE, shell=expand)
- pipe = p.stdout
-- val = pipe.readlines()
-+ val = [decode_text_stream(line) for line in pipe.readlines()]
- if pipe.close() or p.wait():
- die('Command failed: %s' % str(c))
--
- return val
-
- def p4_read_pipe_lines(c):
-@@ -278,6 +292,7 @@ def p4_has_move_command():
- cmd = p4_build_cmd(["move", "-k", "@from", "@to"])
- p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- (out, err) = p.communicate()
-+ err = decode_text_stream(err)
- # return code will be 1 in either case
- if err.find("Invalid option") >= 0:
- return False
-@@ -287,7 +302,7 @@ def p4_has_move_command():
- return True
-
- def system(cmd, ignore_error=False):
-- expand = isinstance(cmd,basestring)
-+ expand = not isinstance(cmd, list)
- if verbose:
- sys.stderr.write("executing %s\n" % str(cmd))
- retcode = subprocess.call(cmd, shell=expand)
-@@ -299,7 +314,7 @@ def system(cmd, ignore_error=False):
- def p4_system(cmd):
- """Specifically invoke p4 as the system command. """
- real_cmd = p4_build_cmd(cmd)
-- expand = isinstance(real_cmd, basestring)
-+ expand = not isinstance(real_cmd, list)
- retcode = subprocess.call(real_cmd, shell=expand)
- if retcode:
- raise CalledProcessError(retcode, real_cmd)
-@@ -537,7 +552,7 @@ def getP4OpenedType(file):
- # Return the set of all p4 labels
- def getP4Labels(depotPaths):
- labels = set()
-- if isinstance(depotPaths,basestring):
-+ if not isinstance(depotPaths, list):
- depotPaths = [depotPaths]
-
- for l in p4CmdList(["labels"] + ["%s..." % p for p in depotPaths]):
-@@ -554,12 +569,7 @@ def getGitTags():
- gitTags.add(tag)
- return gitTags
-
--def diffTreePattern():
-- # This is a simple generator for the diff tree regex pattern. This could be
-- # a class variable if this and parseDiffTreeEntry were a part of a class.
-- pattern = re.compile(':(\d+) (\d+) (\w+) (\w+) ([A-Z])(\d+)?\t(.*?)((\t(.*))|$)')
-- while True:
-- yield pattern
-+_diff_tree_pattern = None
-
- def parseDiffTreeEntry(entry):
- """Parses a single diff tree entry into its component elements.
-@@ -580,7 +590,11 @@ def parseDiffTreeEntry(entry):
-
- If the pattern is not matched, None is returned."""
-
-- match = diffTreePattern().next().match(entry)
-+ global _diff_tree_pattern
-+ if not _diff_tree_pattern:
-+ _diff_tree_pattern = re.compile(':(\d+) (\d+) (\w+) (\w+) ([A-Z])(\d+)?\t(.*?)((\t(.*))|$)')
-+
-+ match = _diff_tree_pattern.match(entry)
- if match:
- return {
- 'src_mode': match.group(1),
-@@ -624,7 +638,7 @@ def isModeExecChanged(src_mode, dst_mode):
- def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False,
- errors_as_exceptions=False):
-
-- if isinstance(cmd,basestring):
-+ if not isinstance(cmd, list):
- cmd = "-G " + cmd
- expand = True
- else:
-@@ -641,11 +655,12 @@ def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False,
- stdin_file = None
- if stdin is not None:
- stdin_file = tempfile.TemporaryFile(prefix='p4-stdin', mode=stdin_mode)
-- if isinstance(stdin,basestring):
-+ if not isinstance(stdin, list):
- stdin_file.write(stdin)
- else:
- for i in stdin:
-- stdin_file.write(i + '\n')
-+ stdin_file.write(encode_text_stream(i))
-+ stdin_file.write(b'\n')
- stdin_file.flush()
- stdin_file.seek(0)
-
-@@ -658,6 +673,20 @@ def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False,
- try:
- while True:
- entry = marshal.load(p4.stdout)
-+ if bytes is not str:
-+ # Decode unmarshalled dict to use str keys and values, except for:
-+ # - `data` which may contain arbitrary binary data
-+ # - `depotFile[0-9]*`, `path`, or `clientFile` which may contain non-UTF8 encoded text
-+ decoded_entry = {}
-+ for key, value in entry.items():
-+ key = key.decode()
-+ if isinstance(value, bytes) and not (key in ('data', 'path', 'clientFile') or key.startswith('depotFile')):
-+ value = value.decode()
-+ decoded_entry[key] = value
-+ # Parse out data if it's an error response
-+ if decoded_entry.get('code') == 'error' and 'data' in decoded_entry:
-+ decoded_entry['data'] = decoded_entry['data'].decode()
-+ entry = decoded_entry
- if skip_info:
- if 'code' in entry and entry['code'] == 'info':
- continue
-@@ -708,7 +737,8 @@ def p4Where(depotPath):
- if "depotFile" in entry:
- # Search for the base client side depot path, as long as it starts with the branch's P4 path.
- # The base path always ends with "/...".
-- if entry["depotFile"].find(depotPath) == 0 and entry["depotFile"][-4:] == "/...":
-+ entry_path = decode_path(entry['depotFile'])
-+ if entry_path.find(depotPath) == 0 and entry_path[-4:] == "/...":
- output = entry
- break
- elif "data" in entry:
-@@ -723,11 +753,11 @@ def p4Where(depotPath):
- return ""
- clientPath = ""
- if "path" in output:
-- clientPath = output.get("path")
-+ clientPath = decode_path(output['path'])
- elif "data" in output:
- data = output.get("data")
-- lastSpace = data.rfind(" ")
-- clientPath = data[lastSpace + 1:]
-+ lastSpace = data.rfind(b" ")
-+ clientPath = decode_path(data[lastSpace + 1:])
-
- if clientPath.endswith("..."):
- clientPath = clientPath[:-3]
-@@ -875,6 +905,7 @@ def branch_exists(branch):
- cmd = [ "git", "rev-parse", "--symbolic", "--verify", branch ]
- p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, _ = p.communicate()
-+ out = decode_text_stream(out)
- if p.returncode:
- return False
- # expect exactly one line of output: the branch name
-@@ -1152,7 +1183,7 @@ def pushFile(self, localLargeFile):
- assert False, "Method 'pushFile' required in " + self.__class__.__name__
-
- def hasLargeFileExtension(self, relPath):
-- return reduce(
-+ return functools.reduce(
- lambda a, b: a or b,
- [relPath.endswith('.' + e) for e in gitConfigList('git-p4.largeFileExtensions')],
- False
-@@ -1259,7 +1290,7 @@ def generatePointer(self, contentFile):
- ['git', 'lfs', 'pointer', '--file=' + contentFile],
- stdout=subprocess.PIPE
- )
-- pointerFile = pointerProcess.stdout.read()
-+ pointerFile = decode_text_stream(pointerProcess.stdout.read())
- if pointerProcess.wait():
- os.remove(contentFile)
- die('git-lfs pointer command failed. Did you install the extension?')
-@@ -1395,14 +1426,14 @@ def getUserMapFromPerforceServer(self):
- for (key, val) in self.users.items():
- s += "%s\t%s\n" % (key.expandtabs(1), val.expandtabs(1))
-
-- open(self.getUserCacheFilename(), "wb").write(s)
-+ open(self.getUserCacheFilename(), 'w').write(s)
- self.userMapFromPerforceServer = True
-
- def loadUserMapFromCache(self):
- self.users = {}
- self.userMapFromPerforceServer = False
- try:
-- cache = open(self.getUserCacheFilename(), "rb")
-+ cache = open(self.getUserCacheFilename(), 'r')
- lines = cache.readlines()
- cache.close()
- for line in lines:
-@@ -1679,7 +1710,8 @@ def modifyChangelistUser(self, changelist, newUser):
- c = changes[0]
- if c['User'] == newUser: return # nothing to do
- c['User'] = newUser
-- input = marshal.dumps(c)
-+ # p4 does not understand format version 3 and above
-+ input = marshal.dumps(c, 2)
-
- result = p4CmdList("change -f -i", stdin=input)
- for r in result:
-@@ -1743,7 +1775,7 @@ def prepareSubmitTemplate(self, changelist=None):
- break
- if not change_entry:
- die('Failed to decode output of p4 change -o')
-- for key, value in change_entry.iteritems():
-+ for key, value in change_entry.items():
- if key.startswith('File'):
- if 'depot-paths' in settings:
- if not [p for p in settings['depot-paths']
-@@ -2023,7 +2055,7 @@ def applyCommit(self, id):
- tmpFile = os.fdopen(handle, "w+b")
- if self.isWindows:
- submitTemplate = submitTemplate.replace("\n", "\r\n")
-- tmpFile.write(submitTemplate)
-+ tmpFile.write(encode_text_stream(submitTemplate))
- tmpFile.close()
-
- if self.prepare_p4_only:
-@@ -2070,7 +2102,7 @@ def applyCommit(self, id):
- if self.edit_template(fileName):
- # read the edited message and submit
- tmpFile = open(fileName, "rb")
-- message = tmpFile.read()
-+ message = decode_text_stream(tmpFile.read())
- tmpFile.close()
- if self.isWindows:
- message = message.replace("\r\n", "\n")
-@@ -2490,7 +2522,7 @@ def append(self, view_line):
-
- def convert_client_path(self, clientFile):
- # chop off //client/ part to make it relative
-- if not clientFile.startswith(self.client_prefix):
-+ if not decode_path(clientFile).startswith(self.client_prefix):
- die("No prefix '%s' on clientFile '%s'" %
- (self.client_prefix, clientFile))
- return clientFile[len(self.client_prefix):]
-@@ -2499,7 +2531,7 @@ def update_client_spec_path_cache(self, files):
- """ Caching file paths by "p4 where" batch query """
-
- # List depot file paths exclude that already cached
-- fileArgs = [f['path'] for f in files if f['path'] not in self.client_spec_path_cache]
-+ fileArgs = [f['path'] for f in files if decode_path(f['path']) not in self.client_spec_path_cache]
-
- if len(fileArgs) == 0:
- return # All files in cache
-@@ -2514,16 +2546,18 @@ def update_client_spec_path_cache(self, files):
- if "unmap" in res:
- # it will list all of them, but only one not unmap-ped
- continue
-+ depot_path = decode_path(res['depotFile'])
- if gitConfigBool("core.ignorecase"):
-- res['depotFile'] = res['depotFile'].lower()
-- self.client_spec_path_cache[res['depotFile']] = self.convert_client_path(res["clientFile"])
-+ depot_path = depot_path.lower()
-+ self.client_spec_path_cache[depot_path] = self.convert_client_path(res["clientFile"])
-
- # not found files or unmap files set to ""
- for depotFile in fileArgs:
-+ depotFile = decode_path(depotFile)
- if gitConfigBool("core.ignorecase"):
- depotFile = depotFile.lower()
- if depotFile not in self.client_spec_path_cache:
-- self.client_spec_path_cache[depotFile] = ""
-+ self.client_spec_path_cache[depotFile] = b''
-
- def map_in_client(self, depot_path):
- """Return the relative location in the client where this
-@@ -2628,6 +2662,7 @@ def __init__(self):
- def checkpoint(self):
- self.gitStream.write("checkpoint\n\n")
- self.gitStream.write("progress checkpoint\n\n")
-+ self.gitStream.flush()
- out = self.gitOutput.readline()
- if self.verbose:
- print("checkpoint finished: " + out)
-@@ -2641,7 +2676,7 @@ def isPathWanted(self, path):
- elif path.lower() == p.lower():
- return False
- for p in self.depotPaths:
-- if p4PathStartsWith(path, p):
-+ if p4PathStartsWith(path, decode_path(p)):
- return True
- return False
-
-@@ -2650,7 +2685,7 @@ def extractFilesFromCommit(self, commit, shelved=False, shelved_cl = 0):
- fnum = 0
- while "depotFile%s" % fnum in commit:
- path = commit["depotFile%s" % fnum]
-- found = self.isPathWanted(path)
-+ found = self.isPathWanted(decode_path(path))
- if not found:
- fnum = fnum + 1
- continue
-@@ -2684,7 +2719,7 @@ def stripRepoPath(self, path, prefixes):
- if self.useClientSpec:
- # branch detection moves files up a level (the branch name)
- # from what client spec interpretation gives
-- path = self.clientSpecDirs.map_in_client(path)
-+ path = decode_path(self.clientSpecDirs.map_in_client(path))
- if self.detectBranches:
- for b in self.knownBranches:
- if p4PathStartsWith(path, b + "/"):
-@@ -2718,14 +2753,15 @@ def splitFilesIntoBranches(self, commit):
- branches = {}
- fnum = 0
- while "depotFile%s" % fnum in commit:
-- path = commit["depotFile%s" % fnum]
-+ raw_path = commit["depotFile%s" % fnum]
-+ path = decode_path(raw_path)
- found = self.isPathWanted(path)
- if not found:
- fnum = fnum + 1
- continue
-
- file = {}
-- file["path"] = path
-+ file["path"] = raw_path
- file["rev"] = commit["rev%s" % fnum]
- file["action"] = commit["action%s" % fnum]
- file["type"] = commit["type%s" % fnum]
-@@ -2734,7 +2770,7 @@ def splitFilesIntoBranches(self, commit):
- # start with the full relative path where this file would
- # go in a p4 client
- if self.useClientSpec:
-- relPath = self.clientSpecDirs.map_in_client(path)
-+ relPath = decode_path(self.clientSpecDirs.map_in_client(path))
- else:
- relPath = self.stripRepoPath(path, self.depotPaths)
-
-@@ -2750,7 +2786,7 @@ def splitFilesIntoBranches(self, commit):
- return branches
-
- def writeToGitStream(self, gitMode, relPath, contents):
-- self.gitStream.write('M %s inline %s\n' % (gitMode, relPath))
-+ self.gitStream.write(encode_text_stream(u'M {} inline {}\n'.format(gitMode, relPath)))
- self.gitStream.write('data %d\n' % sum(len(d) for d in contents))
- for d in contents:
- self.gitStream.write(d)
-@@ -2772,14 +2808,15 @@ def encodeWithUTF8(self, path):
- # - helper for streamP4Files
-
- def streamOneP4File(self, file, contents):
-- relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes)
-- relPath = self.encodeWithUTF8(relPath)
-+ file_path = file['depotFile']
-+ relPath = self.stripRepoPath(decode_path(file_path), self.branchPrefixes)
-+
- if verbose:
- if 'fileSize' in self.stream_file:
- 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['depotFile'], relPath, size/1024/1024))
-+ sys.stdout.write('\r%s --> %s (%i MB)\n' % (file_path, relPath, size/1024/1024))
- sys.stdout.flush()
-
- (type_base, type_mods) = split_p4_type(file["type"])
-@@ -2791,13 +2828,13 @@ def streamOneP4File(self, file, contents):
- git_mode = "120000"
- # p4 print on a symlink sometimes contains "target\n";
- # if it does, remove the newline
-- data = ''.join(contents)
-+ data = ''.join(decode_text_stream(c) for c in contents)
- if not data:
- # Some version of p4 allowed creating a symlink that pointed
- # to nothing. This causes p4 errors when checking out such
- # a change, and errors here too. Work around it by ignoring
- # the bad symlink; hopefully a future change fixes it.
-- print("\nIgnoring empty symlink in %s" % file['depotFile'])
-+ print("\nIgnoring empty symlink in %s" % file_path)
- return
- elif data[-1] == '\n':
- contents = [data[:-1]]
-@@ -2816,7 +2853,7 @@ def streamOneP4File(self, file, contents):
- # just the native "NT" type.
- #
- try:
-- text = p4_read_pipe(['print', '-q', '-o', '-', '%s@%s' % (file['depotFile'], file['change'])])
-+ text = p4_read_pipe(['print', '-q', '-o', '-', '%s@%s' % (decode_path(file['depotFile']), file['change'])], raw=True)
- except Exception as e:
- if 'Translation of file content failed' in str(e):
- type_base = 'binary'
-@@ -2824,7 +2861,7 @@ def streamOneP4File(self, file, contents):
- raise e
- else:
- if p4_version_string().find('/NT') >= 0:
-- text = text.replace('\r\n', '\n')
-+ text = text.replace(b'\r\n', b'\n')
- contents = [ text ]
-
- if type_base == "apple":
-@@ -2845,7 +2882,7 @@ def streamOneP4File(self, file, contents):
- pattern = p4_keywords_regexp_for_type(type_base, type_mods)
- if pattern:
- regexp = re.compile(pattern, re.VERBOSE)
-- text = ''.join(contents)
-+ text = ''.join(decode_text_stream(c) for c in contents)
- text = regexp.sub(r'$\1$', text)
- contents = [ text ]
-
-@@ -2855,12 +2892,11 @@ def streamOneP4File(self, file, contents):
- self.writeToGitStream(git_mode, relPath, contents)
-
- def streamOneP4Deletion(self, file):
-- relPath = self.stripRepoPath(file['path'], self.branchPrefixes)
-- relPath = self.encodeWithUTF8(relPath)
-+ relPath = self.stripRepoPath(decode_path(file['path']), self.branchPrefixes)
- if verbose:
- sys.stdout.write("delete %s\n" % relPath)
- sys.stdout.flush()
-- self.gitStream.write("D %s\n" % relPath)
-+ self.gitStream.write(encode_text_stream(u'D {}\n'.format(relPath)))
-
- if self.largeFileSystem and self.largeFileSystem.isLargeFile(relPath):
- self.largeFileSystem.removeLargeFile(relPath)
-@@ -2960,9 +2996,9 @@ def streamP4FilesCbSelf(entry):
- if 'shelved_cl' in f:
- # Handle shelved CLs using the "p4 print file@=N" syntax to print
- # the contents
-- fileArg = '%s@=%d' % (f['path'], f['shelved_cl'])
-+ fileArg = f['path'] + encode_text_stream('@={}'.format(f['shelved_cl']))
- else:
-- fileArg = '%s#%s' % (f['path'], f['rev'])
-+ fileArg = f['path'] + encode_text_stream('#{}'.format(f['rev']))
-
- fileArgs.append(fileArg)
-
-@@ -3043,8 +3079,8 @@ def commit(self, details, files, branch, parent = "", allow_empty=False):
- if self.clientSpecDirs:
- self.clientSpecDirs.update_client_spec_path_cache(files)
-
-- files = [f for f in files
-- if self.inClientSpec(f['path']) and self.hasBranchPrefix(f['path'])]
-+ files = [f for (f, path) in ((f, decode_path(f['path'])) for f in files)
-+ if self.inClientSpec(path) and self.hasBranchPrefix(path)]
-
- if gitConfigBool('git-p4.keepEmptyCommits'):
- allow_empty = True
-@@ -3548,6 +3584,15 @@ def openStreams(self):
- self.gitStream = self.importProcess.stdin
- self.gitError = self.importProcess.stderr
-
-+ if bytes is not str:
-+ # Wrap gitStream.write() so that it can be called using `str` arguments
-+ def make_encoded_write(write):
-+ def encoded_write(s):
-+ return write(s.encode() if isinstance(s, str) else s)
-+ return encoded_write
-+
-+ self.gitStream.write = make_encoded_write(self.gitStream.write)
-+
- def closeStreams(self):
- self.gitStream.close()
- if self.importProcess.wait() != 0:
Copied: git/repos/testing-x86_64/0001-git-p4-python.patch (from rev 380319, git/trunk/0001-git-p4-python.patch)
===================================================================
--- 0001-git-p4-python.patch (rev 0)
+++ 0001-git-p4-python.patch 2020-04-14 18:40:22 UTC (rev 380320)
@@ -0,0 +1,631 @@
+diff --git a/git-p4.py b/git-p4.py
+index 40d9e7c594..ca0a874501 100755
+--- a/git-p4.py
++++ b/git-p4.py
+@@ -8,12 +8,12 @@
+ # License: MIT <http://www.opensource.org/licenses/mit-license.php>
+ #
+ import sys
+-if sys.hexversion < 0x02040000:
+- # The limiter is the subprocess module
+- sys.stderr.write("git-p4: requires Python 2.4 or later.\n")
++if sys.version_info.major < 3 and sys.version_info.minor < 7:
++ sys.stderr.write("git-p4: requires Python 2.7 or later.\n")
+ sys.exit(1)
+ import os
+ import optparse
++import functools
+ import marshal
+ import subprocess
+ import tempfile
+@@ -27,36 +27,15 @@
+ import ctypes
+ import errno
+
++# On python2.7 where raw_input() and input() are both availble,
++# we want raw_input's semantics, but aliased to input for python3
++# compatibility
+ # support basestring in python3
+ try:
+- unicode = unicode
+-except NameError:
+- # 'unicode' is undefined, must be Python 3
+- str = str
+- unicode = str
+- bytes = bytes
+- basestring = (str,bytes)
+-else:
+- # 'unicode' exists, must be Python 2
+- str = str
+- unicode = unicode
+- bytes = str
+- basestring = basestring
+-
+-try:
+- from subprocess import CalledProcessError
+-except ImportError:
+- # from python2.7:subprocess.py
+- # Exception classes used by this module.
+- class CalledProcessError(Exception):
+- """This exception is raised when a process run by check_call() returns
+- a non-zero exit status. The exit status will be stored in the
+- returncode attribute."""
+- def __init__(self, returncode, cmd):
+- self.returncode = returncode
+- self.cmd = cmd
+- def __str__(self):
+- return "Command '%s' returned non-zero exit status %d" % (self.cmd, self.returncode)
++ if raw_input and input:
++ input = raw_input
++except:
++ pass
+
+ verbose = False
+
+@@ -105,7 +84,7 @@ def p4_build_cmd(cmd):
+ # Provide a way to not pass this option by setting git-p4.retries to 0
+ real_cmd += ["-r", str(retries)]
+
+- if isinstance(cmd,basestring):
++ if not isinstance(cmd, list):
+ real_cmd = ' '.join(real_cmd) + ' ' + cmd
+ else:
+ real_cmd += cmd
+@@ -175,18 +154,48 @@ def prompt(prompt_text):
+ """
+ choices = set(m.group(1) for m in re.finditer(r"\[(.)\]", prompt_text))
+ while True:
+- response = raw_input(prompt_text).strip().lower()
++ response = input(prompt_text).strip().lower()
+ if not response:
+ continue
+ response = response[0]
+ if response in choices:
+ return response
+
++# We need different encoding/decoding strategies for text data being passed
++# around in pipes depending on python version
++if bytes is not str:
++ # For python3, always encode and decode as appropriate
++ def decode_text_stream(s):
++ return s.decode() if isinstance(s, bytes) else s
++ def encode_text_stream(s):
++ return s.encode() if isinstance(s, str) else s
++else:
++ # For python2.7, pass read strings as-is, but also allow writing unicode
++ def decode_text_stream(s):
++ return s
++ def encode_text_stream(s):
++ return s.encode('utf_8') if isinstance(s, unicode) else s
++
++def decode_path(path):
++ """Decode a given string (bytes or otherwise) using configured path encoding options
++ """
++ encoding = gitConfig('git-p4.pathEncoding') or 'utf_8'
++ if bytes is not str:
++ return path.decode(encoding, errors='replace') if isinstance(path, bytes) else path
++ else:
++ try:
++ path.decode('ascii')
++ except:
++ path = path.decode(encoding, errors='replace')
++ if verbose:
++ print('Path with non-ASCII characters detected. Used {} to decode: {}'.format(encoding, path))
++ return path
++
+ def write_pipe(c, stdin):
+ if verbose:
+ sys.stderr.write('Writing pipe: %s\n' % str(c))
+
+- expand = isinstance(c,basestring)
++ expand = not isinstance(c, list)
+ p = subprocess.Popen(c, stdin=subprocess.PIPE, shell=expand)
+ pipe = p.stdin
+ val = pipe.write(stdin)
+@@ -198,6 +207,8 @@ def write_pipe(c, stdin):
+
+ def p4_write_pipe(c, stdin):
+ real_cmd = p4_build_cmd(c)
++ if bytes is not str and isinstance(stdin, str):
++ stdin = encode_text_stream(stdin)
+ return write_pipe(real_cmd, stdin)
+
+ def read_pipe_full(c):
+@@ -208,15 +219,17 @@ def read_pipe_full(c):
+ if verbose:
+ sys.stderr.write('Reading pipe: %s\n' % str(c))
+
+- expand = isinstance(c,basestring)
++ expand = not isinstance(c, list)
+ p = subprocess.Popen(c, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=expand)
+ (out, err) = p.communicate()
+- return (p.returncode, out, err)
++ return (p.returncode, out, decode_text_stream(err))
+
+-def read_pipe(c, ignore_error=False):
++def read_pipe(c, ignore_error=False, raw=False):
+ """ Read output from command. Returns the output text on
+ success. On failure, terminates execution, unless
+ ignore_error is True, when it returns an empty string.
++
++ If raw is True, do not attempt to decode output text.
+ """
+ (retcode, out, err) = read_pipe_full(c)
+ if retcode != 0:
+@@ -224,6 +237,8 @@ def read_pipe(c, ignore_error=False):
+ out = ""
+ else:
+ die('Command failed: %s\nError: %s' % (str(c), err))
++ if not raw:
++ out = decode_text_stream(out)
+ return out
+
+ def read_pipe_text(c):
+@@ -234,23 +249,22 @@ def read_pipe_text(c):
+ if retcode != 0:
+ return None
+ else:
+- return out.rstrip()
++ return decode_text_stream(out).rstrip()
+
+-def p4_read_pipe(c, ignore_error=False):
++def p4_read_pipe(c, ignore_error=False, raw=False):
+ real_cmd = p4_build_cmd(c)
+- return read_pipe(real_cmd, ignore_error)
++ return read_pipe(real_cmd, ignore_error, raw=raw)
+
+ def read_pipe_lines(c):
+ if verbose:
+ sys.stderr.write('Reading pipe: %s\n' % str(c))
+
+- expand = isinstance(c, basestring)
++ expand = not isinstance(c, list)
+ p = subprocess.Popen(c, stdout=subprocess.PIPE, shell=expand)
+ pipe = p.stdout
+- val = pipe.readlines()
++ val = [decode_text_stream(line) for line in pipe.readlines()]
+ if pipe.close() or p.wait():
+ die('Command failed: %s' % str(c))
+-
+ return val
+
+ def p4_read_pipe_lines(c):
+@@ -278,6 +292,7 @@ def p4_has_move_command():
+ cmd = p4_build_cmd(["move", "-k", "@from", "@to"])
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ (out, err) = p.communicate()
++ err = decode_text_stream(err)
+ # return code will be 1 in either case
+ if err.find("Invalid option") >= 0:
+ return False
+@@ -287,7 +302,7 @@ def p4_has_move_command():
+ return True
+
+ def system(cmd, ignore_error=False):
+- expand = isinstance(cmd,basestring)
++ expand = not isinstance(cmd, list)
+ if verbose:
+ sys.stderr.write("executing %s\n" % str(cmd))
+ retcode = subprocess.call(cmd, shell=expand)
+@@ -299,7 +314,7 @@ def system(cmd, ignore_error=False):
+ def p4_system(cmd):
+ """Specifically invoke p4 as the system command. """
+ real_cmd = p4_build_cmd(cmd)
+- expand = isinstance(real_cmd, basestring)
++ expand = not isinstance(real_cmd, list)
+ retcode = subprocess.call(real_cmd, shell=expand)
+ if retcode:
+ raise CalledProcessError(retcode, real_cmd)
+@@ -537,7 +552,7 @@ def getP4OpenedType(file):
+ # Return the set of all p4 labels
+ def getP4Labels(depotPaths):
+ labels = set()
+- if isinstance(depotPaths,basestring):
++ if not isinstance(depotPaths, list):
+ depotPaths = [depotPaths]
+
+ for l in p4CmdList(["labels"] + ["%s..." % p for p in depotPaths]):
+@@ -554,12 +569,7 @@ def getGitTags():
+ gitTags.add(tag)
+ return gitTags
+
+-def diffTreePattern():
+- # This is a simple generator for the diff tree regex pattern. This could be
+- # a class variable if this and parseDiffTreeEntry were a part of a class.
+- pattern = re.compile(':(\d+) (\d+) (\w+) (\w+) ([A-Z])(\d+)?\t(.*?)((\t(.*))|$)')
+- while True:
+- yield pattern
++_diff_tree_pattern = None
+
+ def parseDiffTreeEntry(entry):
+ """Parses a single diff tree entry into its component elements.
+@@ -580,7 +590,11 @@ def parseDiffTreeEntry(entry):
+
+ If the pattern is not matched, None is returned."""
+
+- match = diffTreePattern().next().match(entry)
++ global _diff_tree_pattern
++ if not _diff_tree_pattern:
++ _diff_tree_pattern = re.compile(':(\d+) (\d+) (\w+) (\w+) ([A-Z])(\d+)?\t(.*?)((\t(.*))|$)')
++
++ match = _diff_tree_pattern.match(entry)
+ if match:
+ return {
+ 'src_mode': match.group(1),
+@@ -624,7 +638,7 @@ def isModeExecChanged(src_mode, dst_mode):
+ def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False,
+ errors_as_exceptions=False):
+
+- if isinstance(cmd,basestring):
++ if not isinstance(cmd, list):
+ cmd = "-G " + cmd
+ expand = True
+ else:
+@@ -641,11 +655,12 @@ def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False,
+ stdin_file = None
+ if stdin is not None:
+ stdin_file = tempfile.TemporaryFile(prefix='p4-stdin', mode=stdin_mode)
+- if isinstance(stdin,basestring):
++ if not isinstance(stdin, list):
+ stdin_file.write(stdin)
+ else:
+ for i in stdin:
+- stdin_file.write(i + '\n')
++ stdin_file.write(encode_text_stream(i))
++ stdin_file.write(b'\n')
+ stdin_file.flush()
+ stdin_file.seek(0)
+
+@@ -658,6 +673,20 @@ def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False,
+ try:
+ while True:
+ entry = marshal.load(p4.stdout)
++ if bytes is not str:
++ # Decode unmarshalled dict to use str keys and values, except for:
++ # - `data` which may contain arbitrary binary data
++ # - `depotFile[0-9]*`, `path`, or `clientFile` which may contain non-UTF8 encoded text
++ decoded_entry = {}
++ for key, value in entry.items():
++ key = key.decode()
++ if isinstance(value, bytes) and not (key in ('data', 'path', 'clientFile') or key.startswith('depotFile')):
++ value = value.decode()
++ decoded_entry[key] = value
++ # Parse out data if it's an error response
++ if decoded_entry.get('code') == 'error' and 'data' in decoded_entry:
++ decoded_entry['data'] = decoded_entry['data'].decode()
++ entry = decoded_entry
+ if skip_info:
+ if 'code' in entry and entry['code'] == 'info':
+ continue
+@@ -708,7 +737,8 @@ def p4Where(depotPath):
+ if "depotFile" in entry:
+ # Search for the base client side depot path, as long as it starts with the branch's P4 path.
+ # The base path always ends with "/...".
+- if entry["depotFile"].find(depotPath) == 0 and entry["depotFile"][-4:] == "/...":
++ entry_path = decode_path(entry['depotFile'])
++ if entry_path.find(depotPath) == 0 and entry_path[-4:] == "/...":
+ output = entry
+ break
+ elif "data" in entry:
+@@ -723,11 +753,11 @@ def p4Where(depotPath):
+ return ""
+ clientPath = ""
+ if "path" in output:
+- clientPath = output.get("path")
++ clientPath = decode_path(output['path'])
+ elif "data" in output:
+ data = output.get("data")
+- lastSpace = data.rfind(" ")
+- clientPath = data[lastSpace + 1:]
++ lastSpace = data.rfind(b" ")
++ clientPath = decode_path(data[lastSpace + 1:])
+
+ if clientPath.endswith("..."):
+ clientPath = clientPath[:-3]
+@@ -875,6 +905,7 @@ def branch_exists(branch):
+ cmd = [ "git", "rev-parse", "--symbolic", "--verify", branch ]
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, _ = p.communicate()
++ out = decode_text_stream(out)
+ if p.returncode:
+ return False
+ # expect exactly one line of output: the branch name
+@@ -1152,7 +1183,7 @@ def pushFile(self, localLargeFile):
+ assert False, "Method 'pushFile' required in " + self.__class__.__name__
+
+ def hasLargeFileExtension(self, relPath):
+- return reduce(
++ return functools.reduce(
+ lambda a, b: a or b,
+ [relPath.endswith('.' + e) for e in gitConfigList('git-p4.largeFileExtensions')],
+ False
+@@ -1259,7 +1290,7 @@ def generatePointer(self, contentFile):
+ ['git', 'lfs', 'pointer', '--file=' + contentFile],
+ stdout=subprocess.PIPE
+ )
+- pointerFile = pointerProcess.stdout.read()
++ pointerFile = decode_text_stream(pointerProcess.stdout.read())
+ if pointerProcess.wait():
+ os.remove(contentFile)
+ die('git-lfs pointer command failed. Did you install the extension?')
+@@ -1395,14 +1426,14 @@ def getUserMapFromPerforceServer(self):
+ for (key, val) in self.users.items():
+ s += "%s\t%s\n" % (key.expandtabs(1), val.expandtabs(1))
+
+- open(self.getUserCacheFilename(), "wb").write(s)
++ open(self.getUserCacheFilename(), 'w').write(s)
+ self.userMapFromPerforceServer = True
+
+ def loadUserMapFromCache(self):
+ self.users = {}
+ self.userMapFromPerforceServer = False
+ try:
+- cache = open(self.getUserCacheFilename(), "rb")
++ cache = open(self.getUserCacheFilename(), 'r')
+ lines = cache.readlines()
+ cache.close()
+ for line in lines:
+@@ -1679,7 +1710,8 @@ def modifyChangelistUser(self, changelist, newUser):
+ c = changes[0]
+ if c['User'] == newUser: return # nothing to do
+ c['User'] = newUser
+- input = marshal.dumps(c)
++ # p4 does not understand format version 3 and above
++ input = marshal.dumps(c, 2)
+
+ result = p4CmdList("change -f -i", stdin=input)
+ for r in result:
+@@ -1743,7 +1775,7 @@ def prepareSubmitTemplate(self, changelist=None):
+ break
+ if not change_entry:
+ die('Failed to decode output of p4 change -o')
+- for key, value in change_entry.iteritems():
++ for key, value in change_entry.items():
+ if key.startswith('File'):
+ if 'depot-paths' in settings:
+ if not [p for p in settings['depot-paths']
+@@ -2023,7 +2055,7 @@ def applyCommit(self, id):
+ tmpFile = os.fdopen(handle, "w+b")
+ if self.isWindows:
+ submitTemplate = submitTemplate.replace("\n", "\r\n")
+- tmpFile.write(submitTemplate)
++ tmpFile.write(encode_text_stream(submitTemplate))
+ tmpFile.close()
+
+ if self.prepare_p4_only:
+@@ -2070,7 +2102,7 @@ def applyCommit(self, id):
+ if self.edit_template(fileName):
+ # read the edited message and submit
+ tmpFile = open(fileName, "rb")
+- message = tmpFile.read()
++ message = decode_text_stream(tmpFile.read())
+ tmpFile.close()
+ if self.isWindows:
+ message = message.replace("\r\n", "\n")
+@@ -2490,7 +2522,7 @@ def append(self, view_line):
+
+ def convert_client_path(self, clientFile):
+ # chop off //client/ part to make it relative
+- if not clientFile.startswith(self.client_prefix):
++ if not decode_path(clientFile).startswith(self.client_prefix):
+ die("No prefix '%s' on clientFile '%s'" %
+ (self.client_prefix, clientFile))
+ return clientFile[len(self.client_prefix):]
+@@ -2499,7 +2531,7 @@ def update_client_spec_path_cache(self, files):
+ """ Caching file paths by "p4 where" batch query """
+
+ # List depot file paths exclude that already cached
+- fileArgs = [f['path'] for f in files if f['path'] not in self.client_spec_path_cache]
++ fileArgs = [f['path'] for f in files if decode_path(f['path']) not in self.client_spec_path_cache]
+
+ if len(fileArgs) == 0:
+ return # All files in cache
+@@ -2514,16 +2546,18 @@ def update_client_spec_path_cache(self, files):
+ if "unmap" in res:
+ # it will list all of them, but only one not unmap-ped
+ continue
++ depot_path = decode_path(res['depotFile'])
+ if gitConfigBool("core.ignorecase"):
+- res['depotFile'] = res['depotFile'].lower()
+- self.client_spec_path_cache[res['depotFile']] = self.convert_client_path(res["clientFile"])
++ depot_path = depot_path.lower()
++ self.client_spec_path_cache[depot_path] = self.convert_client_path(res["clientFile"])
+
+ # not found files or unmap files set to ""
+ for depotFile in fileArgs:
++ depotFile = decode_path(depotFile)
+ if gitConfigBool("core.ignorecase"):
+ depotFile = depotFile.lower()
+ if depotFile not in self.client_spec_path_cache:
+- self.client_spec_path_cache[depotFile] = ""
++ self.client_spec_path_cache[depotFile] = b''
+
+ def map_in_client(self, depot_path):
+ """Return the relative location in the client where this
+@@ -2628,6 +2662,7 @@ def __init__(self):
+ def checkpoint(self):
+ self.gitStream.write("checkpoint\n\n")
+ self.gitStream.write("progress checkpoint\n\n")
++ self.gitStream.flush()
+ out = self.gitOutput.readline()
+ if self.verbose:
+ print("checkpoint finished: " + out)
+@@ -2641,7 +2676,7 @@ def isPathWanted(self, path):
+ elif path.lower() == p.lower():
+ return False
+ for p in self.depotPaths:
+- if p4PathStartsWith(path, p):
++ if p4PathStartsWith(path, decode_path(p)):
+ return True
+ return False
+
+@@ -2650,7 +2685,7 @@ def extractFilesFromCommit(self, commit, shelved=False, shelved_cl = 0):
+ fnum = 0
+ while "depotFile%s" % fnum in commit:
+ path = commit["depotFile%s" % fnum]
+- found = self.isPathWanted(path)
++ found = self.isPathWanted(decode_path(path))
+ if not found:
+ fnum = fnum + 1
+ continue
+@@ -2684,7 +2719,7 @@ def stripRepoPath(self, path, prefixes):
+ if self.useClientSpec:
+ # branch detection moves files up a level (the branch name)
+ # from what client spec interpretation gives
+- path = self.clientSpecDirs.map_in_client(path)
++ path = decode_path(self.clientSpecDirs.map_in_client(path))
+ if self.detectBranches:
+ for b in self.knownBranches:
+ if p4PathStartsWith(path, b + "/"):
+@@ -2718,14 +2753,15 @@ def splitFilesIntoBranches(self, commit):
+ branches = {}
+ fnum = 0
+ while "depotFile%s" % fnum in commit:
+- path = commit["depotFile%s" % fnum]
++ raw_path = commit["depotFile%s" % fnum]
++ path = decode_path(raw_path)
+ found = self.isPathWanted(path)
+ if not found:
+ fnum = fnum + 1
+ continue
+
+ file = {}
+- file["path"] = path
++ file["path"] = raw_path
+ file["rev"] = commit["rev%s" % fnum]
+ file["action"] = commit["action%s" % fnum]
+ file["type"] = commit["type%s" % fnum]
+@@ -2734,7 +2770,7 @@ def splitFilesIntoBranches(self, commit):
+ # start with the full relative path where this file would
+ # go in a p4 client
+ if self.useClientSpec:
+- relPath = self.clientSpecDirs.map_in_client(path)
++ relPath = decode_path(self.clientSpecDirs.map_in_client(path))
+ else:
+ relPath = self.stripRepoPath(path, self.depotPaths)
+
+@@ -2750,7 +2786,7 @@ def splitFilesIntoBranches(self, commit):
+ return branches
+
+ def writeToGitStream(self, gitMode, relPath, contents):
+- self.gitStream.write('M %s inline %s\n' % (gitMode, relPath))
++ self.gitStream.write(encode_text_stream(u'M {} inline {}\n'.format(gitMode, relPath)))
+ self.gitStream.write('data %d\n' % sum(len(d) for d in contents))
+ for d in contents:
+ self.gitStream.write(d)
+@@ -2772,14 +2808,15 @@ def encodeWithUTF8(self, path):
+ # - helper for streamP4Files
+
+ def streamOneP4File(self, file, contents):
+- relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes)
+- relPath = self.encodeWithUTF8(relPath)
++ file_path = file['depotFile']
++ relPath = self.stripRepoPath(decode_path(file_path), self.branchPrefixes)
++
+ if verbose:
+ if 'fileSize' in self.stream_file:
+ 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['depotFile'], relPath, size/1024/1024))
++ sys.stdout.write('\r%s --> %s (%i MB)\n' % (file_path, relPath, size/1024/1024))
+ sys.stdout.flush()
+
+ (type_base, type_mods) = split_p4_type(file["type"])
+@@ -2791,13 +2828,13 @@ def streamOneP4File(self, file, contents):
+ git_mode = "120000"
+ # p4 print on a symlink sometimes contains "target\n";
+ # if it does, remove the newline
+- data = ''.join(contents)
++ data = ''.join(decode_text_stream(c) for c in contents)
+ if not data:
+ # Some version of p4 allowed creating a symlink that pointed
+ # to nothing. This causes p4 errors when checking out such
+ # a change, and errors here too. Work around it by ignoring
+ # the bad symlink; hopefully a future change fixes it.
+- print("\nIgnoring empty symlink in %s" % file['depotFile'])
++ print("\nIgnoring empty symlink in %s" % file_path)
+ return
+ elif data[-1] == '\n':
+ contents = [data[:-1]]
+@@ -2816,7 +2853,7 @@ def streamOneP4File(self, file, contents):
+ # just the native "NT" type.
+ #
+ try:
+- text = p4_read_pipe(['print', '-q', '-o', '-', '%s@%s' % (file['depotFile'], file['change'])])
++ text = p4_read_pipe(['print', '-q', '-o', '-', '%s@%s' % (decode_path(file['depotFile']), file['change'])], raw=True)
+ except Exception as e:
+ if 'Translation of file content failed' in str(e):
+ type_base = 'binary'
+@@ -2824,7 +2861,7 @@ def streamOneP4File(self, file, contents):
+ raise e
+ else:
+ if p4_version_string().find('/NT') >= 0:
+- text = text.replace('\r\n', '\n')
++ text = text.replace(b'\r\n', b'\n')
+ contents = [ text ]
+
+ if type_base == "apple":
+@@ -2845,7 +2882,7 @@ def streamOneP4File(self, file, contents):
+ pattern = p4_keywords_regexp_for_type(type_base, type_mods)
+ if pattern:
+ regexp = re.compile(pattern, re.VERBOSE)
+- text = ''.join(contents)
++ text = ''.join(decode_text_stream(c) for c in contents)
+ text = regexp.sub(r'$\1$', text)
+ contents = [ text ]
+
+@@ -2855,12 +2892,11 @@ def streamOneP4File(self, file, contents):
+ self.writeToGitStream(git_mode, relPath, contents)
+
+ def streamOneP4Deletion(self, file):
+- relPath = self.stripRepoPath(file['path'], self.branchPrefixes)
+- relPath = self.encodeWithUTF8(relPath)
++ relPath = self.stripRepoPath(decode_path(file['path']), self.branchPrefixes)
+ if verbose:
+ sys.stdout.write("delete %s\n" % relPath)
+ sys.stdout.flush()
+- self.gitStream.write("D %s\n" % relPath)
++ self.gitStream.write(encode_text_stream(u'D {}\n'.format(relPath)))
+
+ if self.largeFileSystem and self.largeFileSystem.isLargeFile(relPath):
+ self.largeFileSystem.removeLargeFile(relPath)
+@@ -2960,9 +2996,9 @@ def streamP4FilesCbSelf(entry):
+ if 'shelved_cl' in f:
+ # Handle shelved CLs using the "p4 print file@=N" syntax to print
+ # the contents
+- fileArg = '%s@=%d' % (f['path'], f['shelved_cl'])
++ fileArg = f['path'] + encode_text_stream('@={}'.format(f['shelved_cl']))
+ else:
+- fileArg = '%s#%s' % (f['path'], f['rev'])
++ fileArg = f['path'] + encode_text_stream('#{}'.format(f['rev']))
+
+ fileArgs.append(fileArg)
+
+@@ -3043,8 +3079,8 @@ def commit(self, details, files, branch, parent = "", allow_empty=False):
+ if self.clientSpecDirs:
+ self.clientSpecDirs.update_client_spec_path_cache(files)
+
+- files = [f for f in files
+- if self.inClientSpec(f['path']) and self.hasBranchPrefix(f['path'])]
++ files = [f for (f, path) in ((f, decode_path(f['path'])) for f in files)
++ if self.inClientSpec(path) and self.hasBranchPrefix(path)]
+
+ if gitConfigBool('git-p4.keepEmptyCommits'):
+ allow_empty = True
+@@ -3548,6 +3584,15 @@ def openStreams(self):
+ self.gitStream = self.importProcess.stdin
+ self.gitError = self.importProcess.stderr
+
++ if bytes is not str:
++ # Wrap gitStream.write() so that it can be called using `str` arguments
++ def make_encoded_write(write):
++ def encoded_write(s):
++ return write(s.encode() if isinstance(s, str) else s)
++ return encoded_write
++
++ self.gitStream.write = make_encoded_write(self.gitStream.write)
++
+ def closeStreams(self):
+ self.gitStream.close()
+ if self.importProcess.wait() != 0:
Deleted: PKGBUILD
===================================================================
--- PKGBUILD 2020-04-14 18:38:12 UTC (rev 380319)
+++ PKGBUILD 2020-04-14 18:40:22 UTC (rev 380320)
@@ -1,136 +0,0 @@
-# Maintainer: Christian Hesse <mail at eworm.de>
-# Maintainer: Dan McGee <dan at archlinux.org>
-
-pkgname=git
-pkgver=2.26.1
-pkgrel=1
-pkgdesc='the fast distributed version control system'
-arch=('x86_64')
-url='https://git-scm.com/'
-license=('GPL2')
-depends=('curl' 'expat' 'perl' 'perl-error' 'perl-mailtools'
- 'openssl' 'pcre2' 'grep' 'shadow')
-makedepends=('python' 'libgnome-keyring' 'xmlto' 'asciidoc')
-optdepends=('tk: gitk and git gui'
- 'perl-libwww: git svn'
- 'perl-term-readkey: git svn and interactive.singlekey setting'
- 'perl-mime-tools: git send-email'
- 'perl-net-smtp-ssl: git send-email TLS support'
- 'perl-authen-sasl: git send-email TLS support'
- 'perl-mediawiki-api: git mediawiki support'
- 'perl-datetime-format-iso8601: git mediawiki support'
- 'perl-lwp-protocol-https: git mediawiki https support'
- 'perl-cgi: gitweb (web interface) support'
- 'python: git svn & git p4'
- 'subversion: git svn'
- 'org.freedesktop.secrets: keyring credential helper'
- 'libsecret: libsecret credential helper')
-install=git.install
-validpgpkeys=('96E07AF25771955980DAD10020D04E5A713660A7') # Junio C Hamano
-source=("https://www.kernel.org/pub/software/scm/git/git-$pkgver.tar."{xz,sign}
- '0001-git-p4-python.patch'
- 'git-daemon at .service'
- 'git-daemon.socket'
- 'git-sysusers.conf')
-sha256sums=('888228408f254634330234df3cece734d190ef6381063821f31ec020538f0368'
- 'SKIP'
- '0d19345aaeaeb374f8bfc30b823e8f53cb128c56b68c6504bbdd8766c03d1df9'
- '14c0b67cfe116b430645c19d8c4759419657e6809dfa28f438c33a005245ad91'
- 'ac4c90d62c44926e6d30d18d97767efc901076d4e0283ed812a349aece72f203'
- '7630e8245526ad80f703fac9900a1328588c503ce32b37b9f8811674fcda4a45')
-
-_make_paths=(
- prefix='/usr'
- gitexecdir='/usr/lib/git-core'
- perllibdir="$(/usr/bin/perl -MConfig -wle 'print $Config{installvendorlib}')"
-)
-
-_make_options=(
- CFLAGS="$CFLAGS"
- LDFLAGS="$LDFLAGS"
- INSTALL_SYMLINKS=1
- MAN_BOLD_LITERAL=1
- NO_PERL_CPAN_FALLBACKS=1
- USE_LIBPCRE2=1
-)
-
-prepare() {
- cd "$srcdir/$pkgname-$pkgver"
-
- patch -Np1 < ../0001-git-p4-python.patch
-}
-
-build() {
- cd "$srcdir/$pkgname-$pkgver"
-
- make \
- "${_make_paths[@]}" \
- "${_make_options[@]}" \
- all man
-
- make -C contrib/credential/gnome-keyring
- make -C contrib/credential/libsecret
- make -C contrib/subtree "${_make_paths[@]}" all man
- make -C contrib/mw-to-git "${_make_paths[@]}" all
- make -C contrib/diff-highlight "${_make_paths[@]}"
-}
-
-check() {
- cd "$srcdir/$pkgname-$pkgver"
-
- local jobs
- jobs=$(expr "$MAKEFLAGS" : '.*\(-j[0-9]*\).*') || true
- mkdir -p /dev/shm/git-test
- # explicitly specify SHELL to avoid a test failure in t/t9903-bash-prompt.sh
- # which is caused by 'git rebase' trying to use builduser's SHELL inside the
- # build chroot (i.e.: /usr/bin/nologin)
- SHELL=/bin/sh \
- make \
- "${_make_paths[@]}" \
- "${_make_options[@]}" \
- NO_SVN_TESTS=y \
- DEFAULT_TEST_TARGET=prove \
- GIT_PROVE_OPTS="$jobs -Q" \
- GIT_TEST_OPTS="--root=/dev/shm/git-test" \
- test
-}
-
-package() {
- cd "$srcdir/$pkgname-$pkgver"
-
- make \
- "${_make_paths[@]}" \
- "${_make_options[@]}" \
- DESTDIR="$pkgdir" \
- install install-man
-
- # bash completion
- mkdir -p "$pkgdir"/usr/share/bash-completion/completions/
- install -m 0644 ./contrib/completion/git-completion.bash "$pkgdir"/usr/share/bash-completion/completions/git
- # fancy git prompt
- mkdir -p "$pkgdir"/usr/share/git/
- install -m 0644 ./contrib/completion/git-prompt.sh "$pkgdir"/usr/share/git/git-prompt.sh
- # gnome credentials helper (deprecated, but we will keep it as long there is no extra cost)
- # https://gitlab.gnome.org/GNOME/libgnome-keyring/commit/6a5adea4aec93
- install -m 0755 contrib/credential/gnome-keyring/git-credential-gnome-keyring \
- "$pkgdir"/usr/lib/git-core/git-credential-gnome-keyring
- make -C contrib/credential/gnome-keyring clean
- # libsecret credentials helper
- install -m 0755 contrib/credential/libsecret/git-credential-libsecret \
- "$pkgdir"/usr/lib/git-core/git-credential-libsecret
- make -C contrib/credential/libsecret clean
- # subtree installation
- make -C contrib/subtree "${_make_paths[@]}" DESTDIR="$pkgdir" install install-man
- # mediawiki installation
- make -C contrib/mw-to-git "${_make_paths[@]}" DESTDIR="$pkgdir" install
- # the rest of the contrib stuff
- find contrib/ -name '.gitignore' -delete
- cp -a ./contrib/* "$pkgdir"/usr/share/git/
-
- # git-daemon via systemd socket activation
- install -D -m 0644 "$srcdir"/git-daemon at .service "$pkgdir"/usr/lib/systemd/system/git-daemon at .service
- install -D -m 0644 "$srcdir"/git-daemon.socket "$pkgdir"/usr/lib/systemd/system/git-daemon.socket
-
- # sysusers file
- install -D -m 0644 "$srcdir"/git-sysusers.conf "$pkgdir"/usr/lib/sysusers.d/git.conf
-}
Copied: git/repos/testing-x86_64/PKGBUILD (from rev 380319, git/trunk/PKGBUILD)
===================================================================
--- PKGBUILD (rev 0)
+++ PKGBUILD 2020-04-14 18:40:22 UTC (rev 380320)
@@ -0,0 +1,136 @@
+# Maintainer: Christian Hesse <mail at eworm.de>
+# Maintainer: Dan McGee <dan at archlinux.org>
+
+pkgname=git
+pkgver=2.26.1
+pkgrel=1
+pkgdesc='the fast distributed version control system'
+arch=('x86_64')
+url='https://git-scm.com/'
+license=('GPL2')
+depends=('curl' 'expat' 'perl' 'perl-error' 'perl-mailtools'
+ 'openssl' 'pcre2' 'grep' 'shadow')
+makedepends=('python' 'libgnome-keyring' 'xmlto' 'asciidoc')
+optdepends=('tk: gitk and git gui'
+ 'perl-libwww: git svn'
+ 'perl-term-readkey: git svn and interactive.singlekey setting'
+ 'perl-mime-tools: git send-email'
+ 'perl-net-smtp-ssl: git send-email TLS support'
+ 'perl-authen-sasl: git send-email TLS support'
+ 'perl-mediawiki-api: git mediawiki support'
+ 'perl-datetime-format-iso8601: git mediawiki support'
+ 'perl-lwp-protocol-https: git mediawiki https support'
+ 'perl-cgi: gitweb (web interface) support'
+ 'python: git svn & git p4'
+ 'subversion: git svn'
+ 'org.freedesktop.secrets: keyring credential helper'
+ 'libsecret: libsecret credential helper')
+install=git.install
+validpgpkeys=('96E07AF25771955980DAD10020D04E5A713660A7') # Junio C Hamano
+source=("https://www.kernel.org/pub/software/scm/git/git-$pkgver.tar."{xz,sign}
+ '0001-git-p4-python.patch'
+ 'git-daemon at .service'
+ 'git-daemon.socket'
+ 'git-sysusers.conf')
+sha256sums=('888228408f254634330234df3cece734d190ef6381063821f31ec020538f0368'
+ 'SKIP'
+ '0d19345aaeaeb374f8bfc30b823e8f53cb128c56b68c6504bbdd8766c03d1df9'
+ '14c0b67cfe116b430645c19d8c4759419657e6809dfa28f438c33a005245ad91'
+ 'ac4c90d62c44926e6d30d18d97767efc901076d4e0283ed812a349aece72f203'
+ '7630e8245526ad80f703fac9900a1328588c503ce32b37b9f8811674fcda4a45')
+
+_make_paths=(
+ prefix='/usr'
+ gitexecdir='/usr/lib/git-core'
+ perllibdir="$(/usr/bin/perl -MConfig -wle 'print $Config{installvendorlib}')"
+)
+
+_make_options=(
+ CFLAGS="$CFLAGS"
+ LDFLAGS="$LDFLAGS"
+ INSTALL_SYMLINKS=1
+ MAN_BOLD_LITERAL=1
+ NO_PERL_CPAN_FALLBACKS=1
+ USE_LIBPCRE2=1
+)
+
+prepare() {
+ cd "$srcdir/$pkgname-$pkgver"
+
+ patch -Np1 < ../0001-git-p4-python.patch
+}
+
+build() {
+ cd "$srcdir/$pkgname-$pkgver"
+
+ make \
+ "${_make_paths[@]}" \
+ "${_make_options[@]}" \
+ all man
+
+ make -C contrib/credential/gnome-keyring
+ make -C contrib/credential/libsecret
+ make -C contrib/subtree "${_make_paths[@]}" all man
+ make -C contrib/mw-to-git "${_make_paths[@]}" all
+ make -C contrib/diff-highlight "${_make_paths[@]}"
+}
+
+check() {
+ cd "$srcdir/$pkgname-$pkgver"
+
+ local jobs
+ jobs=$(expr "$MAKEFLAGS" : '.*\(-j[0-9]*\).*') || true
+ mkdir -p /dev/shm/git-test
+ # explicitly specify SHELL to avoid a test failure in t/t9903-bash-prompt.sh
+ # which is caused by 'git rebase' trying to use builduser's SHELL inside the
+ # build chroot (i.e.: /usr/bin/nologin)
+ SHELL=/bin/sh \
+ make \
+ "${_make_paths[@]}" \
+ "${_make_options[@]}" \
+ NO_SVN_TESTS=y \
+ DEFAULT_TEST_TARGET=prove \
+ GIT_PROVE_OPTS="$jobs -Q" \
+ GIT_TEST_OPTS="--root=/dev/shm/git-test" \
+ test
+}
+
+package() {
+ cd "$srcdir/$pkgname-$pkgver"
+
+ make \
+ "${_make_paths[@]}" \
+ "${_make_options[@]}" \
+ DESTDIR="$pkgdir" \
+ install install-man
+
+ # bash completion
+ mkdir -p "$pkgdir"/usr/share/bash-completion/completions/
+ install -m 0644 ./contrib/completion/git-completion.bash "$pkgdir"/usr/share/bash-completion/completions/git
+ # fancy git prompt
+ mkdir -p "$pkgdir"/usr/share/git/
+ install -m 0644 ./contrib/completion/git-prompt.sh "$pkgdir"/usr/share/git/git-prompt.sh
+ # gnome credentials helper (deprecated, but we will keep it as long there is no extra cost)
+ # https://gitlab.gnome.org/GNOME/libgnome-keyring/commit/6a5adea4aec93
+ install -m 0755 contrib/credential/gnome-keyring/git-credential-gnome-keyring \
+ "$pkgdir"/usr/lib/git-core/git-credential-gnome-keyring
+ make -C contrib/credential/gnome-keyring clean
+ # libsecret credentials helper
+ install -m 0755 contrib/credential/libsecret/git-credential-libsecret \
+ "$pkgdir"/usr/lib/git-core/git-credential-libsecret
+ make -C contrib/credential/libsecret clean
+ # subtree installation
+ make -C contrib/subtree "${_make_paths[@]}" DESTDIR="$pkgdir" install install-man
+ # mediawiki installation
+ make -C contrib/mw-to-git "${_make_paths[@]}" DESTDIR="$pkgdir" install
+ # the rest of the contrib stuff
+ find contrib/ -name '.gitignore' -delete
+ cp -a ./contrib/* "$pkgdir"/usr/share/git/
+
+ # git-daemon via systemd socket activation
+ install -D -m 0644 "$srcdir"/git-daemon at .service "$pkgdir"/usr/lib/systemd/system/git-daemon at .service
+ install -D -m 0644 "$srcdir"/git-daemon.socket "$pkgdir"/usr/lib/systemd/system/git-daemon.socket
+
+ # sysusers file
+ install -D -m 0644 "$srcdir"/git-sysusers.conf "$pkgdir"/usr/lib/sysusers.d/git.conf
+}
Deleted: git-daemon.socket
===================================================================
--- git-daemon.socket 2020-04-14 18:38:12 UTC (rev 380319)
+++ git-daemon.socket 2020-04-14 18:40:22 UTC (rev 380320)
@@ -1,9 +0,0 @@
-[Unit]
-Description=Git Daemon Socket
-
-[Socket]
-ListenStream=9418
-Accept=true
-
-[Install]
-WantedBy=sockets.target
Copied: git/repos/testing-x86_64/git-daemon.socket (from rev 380319, git/trunk/git-daemon.socket)
===================================================================
--- git-daemon.socket (rev 0)
+++ git-daemon.socket 2020-04-14 18:40:22 UTC (rev 380320)
@@ -0,0 +1,9 @@
+[Unit]
+Description=Git Daemon Socket
+
+[Socket]
+ListenStream=9418
+Accept=true
+
+[Install]
+WantedBy=sockets.target
Deleted: git-daemon at .service
===================================================================
--- git-daemon at .service 2020-04-14 18:38:12 UTC (rev 380319)
+++ git-daemon at .service 2020-04-14 18:40:22 UTC (rev 380320)
@@ -1,14 +0,0 @@
-[Unit]
-Description=Git Daemon Instance
-
-[Service]
-User=git
-# The '-' is to ignore non-zero exit statuses
-ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git
-StandardInput=socket
-StandardOutput=inherit
-StandardError=journal
-ProtectSystem=full
-ProtectHome=on
-PrivateDevices=on
-NoNewPrivileges=on
Copied: git/repos/testing-x86_64/git-daemon at .service (from rev 380319, git/trunk/git-daemon at .service)
===================================================================
--- git-daemon at .service (rev 0)
+++ git-daemon at .service 2020-04-14 18:40:22 UTC (rev 380320)
@@ -0,0 +1,14 @@
+[Unit]
+Description=Git Daemon Instance
+
+[Service]
+User=git
+# The '-' is to ignore non-zero exit statuses
+ExecStart=-/usr/lib/git-core/git-daemon --inetd --export-all --base-path=/srv/git
+StandardInput=socket
+StandardOutput=inherit
+StandardError=journal
+ProtectSystem=full
+ProtectHome=on
+PrivateDevices=on
+NoNewPrivileges=on
Deleted: git-sysusers.conf
===================================================================
--- git-sysusers.conf 2020-04-14 18:38:12 UTC (rev 380319)
+++ git-sysusers.conf 2020-04-14 18:40:22 UTC (rev 380320)
@@ -1 +0,0 @@
-u git - "git daemon user" / /usr/bin/git-shell
Copied: git/repos/testing-x86_64/git-sysusers.conf (from rev 380319, git/trunk/git-sysusers.conf)
===================================================================
--- git-sysusers.conf (rev 0)
+++ git-sysusers.conf 2020-04-14 18:40:22 UTC (rev 380320)
@@ -0,0 +1 @@
+u git - "git daemon user" / /usr/bin/git-shell
Deleted: git.install
===================================================================
--- git.install 2020-04-14 18:38:12 UTC (rev 380319)
+++ git.install 2020-04-14 18:40:22 UTC (rev 380320)
@@ -1,14 +0,0 @@
-#!/bin/sh
-
-post_install() {
- # make git-shell a valid shell
- if ! grep -qe '^/usr/bin/git-shell$' etc/shells; then
- echo '/usr/bin/git-shell' >> etc/shells
- fi
-}
-
-# do not modify user settings (shell) in post-upgrade function!
-
-post_remove() {
- sed -i -r '/^\/usr\/bin\/git-shell$/d' etc/shells
-}
Copied: git/repos/testing-x86_64/git.install (from rev 380319, git/trunk/git.install)
===================================================================
--- git.install (rev 0)
+++ git.install 2020-04-14 18:40:22 UTC (rev 380320)
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+post_install() {
+ # make git-shell a valid shell
+ if ! grep -qe '^/usr/bin/git-shell$' etc/shells; then
+ echo '/usr/bin/git-shell' >> etc/shells
+ fi
+}
+
+# do not modify user settings (shell) in post-upgrade function!
+
+post_remove() {
+ sed -i -r '/^\/usr\/bin\/git-shell$/d' etc/shells
+}
More information about the arch-commits
mailing list