Skip to content

Commit 9cffb8c

Browse files
Pete Wyckoffgitster
authored andcommitted
git-p4: recognize all p4 filetypes
The previous code was approximate in the filetypes it recognized. Put in the canonical list and be more careful about matching elements of the file type. This might change behavior in some cases, hopefully for the better. Windows newline mangling will now happen on all text files. Previously some like "text+ko" were oddly exempt. Files with multiple combinations of modifiers, like "text+klx", are now recognized for keyword expansion. I expect these to be seen only rarely. Acked-by: Luke Diamand <[email protected]> Signed-off-by: Pete Wyckoff <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 55aa571 commit 9cffb8c

File tree

1 file changed

+52
-19
lines changed

1 file changed

+52
-19
lines changed

contrib/fast-import/git-p4

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,41 @@ def p4_system(cmd):
118118
real_cmd = p4_build_cmd(cmd)
119119
return system(real_cmd)
120120

121-
def isP4Exec(kind):
122-
"""Determine if a Perforce 'kind' should have execute permission
121+
#
122+
# Canonicalize the p4 type and return a tuple of the
123+
# base type, plus any modifiers. See "p4 help filetypes"
124+
# for a list and explanation.
125+
#
126+
def split_p4_type(p4type):
127+
128+
p4_filetypes_historical = {
129+
"ctempobj": "binary+Sw",
130+
"ctext": "text+C",
131+
"cxtext": "text+Cx",
132+
"ktext": "text+k",
133+
"kxtext": "text+kx",
134+
"ltext": "text+F",
135+
"tempobj": "binary+FSw",
136+
"ubinary": "binary+F",
137+
"uresource": "resource+F",
138+
"uxbinary": "binary+Fx",
139+
"xbinary": "binary+x",
140+
"xltext": "text+Fx",
141+
"xtempobj": "binary+Swx",
142+
"xtext": "text+x",
143+
"xunicode": "unicode+x",
144+
"xutf16": "utf16+x",
145+
}
146+
if p4type in p4_filetypes_historical:
147+
p4type = p4_filetypes_historical[p4type]
148+
mods = ""
149+
s = p4type.split("+")
150+
base = s[0]
151+
mods = ""
152+
if len(s) > 1:
153+
mods = s[1]
154+
return (base, mods)
123155

124-
'p4 help filetypes' gives a list of the types. If it starts with 'x',
125-
or x follows one of a few letters. Otherwise, if there is an 'x' after
126-
a plus sign, it is also executable"""
127-
return (re.search(r"(^[cku]?x)|\+.*x", kind) != None)
128156

129157
def setP4ExecBit(file, mode):
130158
# Reopens an already open file and changes the execute bit to match
@@ -1229,16 +1257,18 @@ class P4Sync(Command, P4UserMap):
12291257
if verbose:
12301258
sys.stderr.write("%s\n" % relPath)
12311259

1232-
mode = "644"
1233-
if isP4Exec(file["type"]):
1234-
mode = "755"
1235-
elif file["type"] == "symlink":
1236-
mode = "120000"
1237-
# p4 print on a symlink contains "target\n", so strip it off
1260+
(type_base, type_mods) = split_p4_type(file["type"])
1261+
1262+
git_mode = "100644"
1263+
if "x" in type_mods:
1264+
git_mode = "100755"
1265+
if type_base == "symlink":
1266+
git_mode = "120000"
1267+
# p4 print on a symlink contains "target\n"; remove the newline
12381268
data = ''.join(contents)
12391269
contents = [data[:-1]]
12401270

1241-
if file['type'].startswith("utf16"):
1271+
if type_base == "utf16":
12421272
# p4 delivers different text in the python output to -G
12431273
# than it does when using "print -o", or normal p4 client
12441274
# operations. utf16 is converted to ascii or utf8, perhaps.
@@ -1247,7 +1277,9 @@ class P4Sync(Command, P4UserMap):
12471277
text = p4_read_pipe('print -q -o - "%s"' % file['depotFile'])
12481278
contents = [ text ]
12491279

1250-
if self.isWindows and file["type"].endswith("text"):
1280+
# Perhaps windows wants unicode, utf16 newlines translated too;
1281+
# but this is not doing it.
1282+
if self.isWindows and type_base == "text":
12511283
mangled = []
12521284
for data in contents:
12531285
data = data.replace("\r\n", "\n")
@@ -1256,12 +1288,13 @@ class P4Sync(Command, P4UserMap):
12561288

12571289
# Note that we do not try to de-mangle keywords on utf16 files,
12581290
# even though in theory somebody may want that.
1259-
if file['type'] in ('text+ko', 'unicode+ko', 'binary+ko'):
1260-
contents = map(lambda text: re.sub(r'(?i)\$(Id|Header):[^$]*\$',r'$\1$', text), contents)
1261-
elif file['type'] in ('text+k', 'ktext', 'kxtext', 'unicode+k', 'binary+k'):
1262-
contents = map(lambda text: re.sub(r'\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$\n]*\$',r'$\1$', text), contents)
1291+
if type_base in ("text", "unicode", "binary"):
1292+
if "ko" in type_mods:
1293+
contents = map(lambda text: re.sub(r'(?i)\$(Id|Header):[^$]*\$', r'$\1$', text), contents)
1294+
elif "k" in type_mods:
1295+
contents = map(lambda text: re.sub(r'\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$\n]*\$', r'$\1$', text), contents)
12631296

1264-
self.gitStream.write("M %s inline %s\n" % (mode, relPath))
1297+
self.gitStream.write("M %s inline %s\n" % (git_mode, relPath))
12651298

12661299
# total length...
12671300
length = 0

0 commit comments

Comments
 (0)