提交 5a4fcc28 编写于 作者: J Junio C Hamano

Merge branch 'pw/p4-update'

* pw/p4-update:
  git-p4: handle files with shell metacharacters
  git-p4: keyword flattening fixes
  git-p4: stop ignoring apple filetype
  git-p4: recognize all p4 filetypes
  git-p4: handle utf16 filetype properly
  git-p4 tests: refactor and cleanup
......@@ -22,36 +22,39 @@ def p4_build_cmd(cmd):
location. It means that hooking into the environment, or other configuration
can be done more easily.
"""
real_cmd = "%s " % "p4"
real_cmd = ["p4"]
user = gitConfig("git-p4.user")
if len(user) > 0:
real_cmd += "-u %s " % user
real_cmd += ["-u",user]
password = gitConfig("git-p4.password")
if len(password) > 0:
real_cmd += "-P %s " % password
real_cmd += ["-P", password]
port = gitConfig("git-p4.port")
if len(port) > 0:
real_cmd += "-p %s " % port
real_cmd += ["-p", port]
host = gitConfig("git-p4.host")
if len(host) > 0:
real_cmd += "-h %s " % host
real_cmd += ["-h", host]
client = gitConfig("git-p4.client")
if len(client) > 0:
real_cmd += "-c %s " % client
real_cmd += ["-c", client]
real_cmd += "%s" % (cmd)
if verbose:
print real_cmd
if isinstance(cmd,basestring):
real_cmd = ' '.join(real_cmd) + ' ' + cmd
else:
real_cmd += cmd
return real_cmd
def chdir(dir):
if os.name == 'nt':
os.environ['PWD']=dir
# P4 uses the PWD environment variable rather than getcwd(). Since we're
# not using the shell, we have to set it ourselves.
os.environ['PWD']=dir
os.chdir(dir)
def die(msg):
......@@ -61,29 +64,34 @@ def die(msg):
sys.stderr.write(msg + "\n")
sys.exit(1)
def write_pipe(c, str):
def write_pipe(c, stdin):
if verbose:
sys.stderr.write('Writing pipe: %s\n' % c)
sys.stderr.write('Writing pipe: %s\n' % str(c))
pipe = os.popen(c, 'w')
val = pipe.write(str)
if pipe.close():
die('Command failed: %s' % c)
expand = isinstance(c,basestring)
p = subprocess.Popen(c, stdin=subprocess.PIPE, shell=expand)
pipe = p.stdin
val = pipe.write(stdin)
pipe.close()
if p.wait():
die('Command failed: %s' % str(c))
return val
def p4_write_pipe(c, str):
def p4_write_pipe(c, stdin):
real_cmd = p4_build_cmd(c)
return write_pipe(real_cmd, str)
return write_pipe(real_cmd, stdin)
def read_pipe(c, ignore_error=False):
if verbose:
sys.stderr.write('Reading pipe: %s\n' % c)
sys.stderr.write('Reading pipe: %s\n' % str(c))
pipe = os.popen(c, 'rb')
expand = isinstance(c,basestring)
p = subprocess.Popen(c, stdout=subprocess.PIPE, shell=expand)
pipe = p.stdout
val = pipe.read()
if pipe.close() and not ignore_error:
die('Command failed: %s' % c)
if p.wait() and not ignore_error:
die('Command failed: %s' % str(c))
return val
......@@ -93,12 +101,14 @@ def p4_read_pipe(c, ignore_error=False):
def read_pipe_lines(c):
if verbose:
sys.stderr.write('Reading pipe: %s\n' % c)
## todo: check return status
pipe = os.popen(c, 'rb')
sys.stderr.write('Reading pipe: %s\n' % str(c))
expand = isinstance(c, basestring)
p = subprocess.Popen(c, stdout=subprocess.PIPE, shell=expand)
pipe = p.stdout
val = pipe.readlines()
if pipe.close():
die('Command failed: %s' % c)
if pipe.close() or p.wait():
die('Command failed: %s' % str(c))
return val
......@@ -108,23 +118,73 @@ def p4_read_pipe_lines(c):
return read_pipe_lines(real_cmd)
def system(cmd):
expand = isinstance(cmd,basestring)
if verbose:
sys.stderr.write("executing %s\n" % cmd)
if os.system(cmd) != 0:
die("command failed: %s" % cmd)
sys.stderr.write("executing %s\n" % str(cmd))
subprocess.check_call(cmd, shell=expand)
def p4_system(cmd):
"""Specifically invoke p4 as the system command. """
real_cmd = p4_build_cmd(cmd)
return system(real_cmd)
expand = isinstance(real_cmd, basestring)
subprocess.check_call(real_cmd, shell=expand)
def p4_integrate(src, dest):
p4_system(["integrate", "-Dt", src, dest])
def p4_sync(path):
p4_system(["sync", path])
def isP4Exec(kind):
"""Determine if a Perforce 'kind' should have execute permission
def p4_add(f):
p4_system(["add", f])
def p4_delete(f):
p4_system(["delete", f])
def p4_edit(f):
p4_system(["edit", f])
def p4_revert(f):
p4_system(["revert", f])
def p4_reopen(type, file):
p4_system(["reopen", "-t", type, file])
#
# Canonicalize the p4 type and return a tuple of the
# base type, plus any modifiers. See "p4 help filetypes"
# for a list and explanation.
#
def split_p4_type(p4type):
p4_filetypes_historical = {
"ctempobj": "binary+Sw",
"ctext": "text+C",
"cxtext": "text+Cx",
"ktext": "text+k",
"kxtext": "text+kx",
"ltext": "text+F",
"tempobj": "binary+FSw",
"ubinary": "binary+F",
"uresource": "resource+F",
"uxbinary": "binary+Fx",
"xbinary": "binary+x",
"xltext": "text+Fx",
"xtempobj": "binary+Swx",
"xtext": "text+x",
"xunicode": "unicode+x",
"xutf16": "utf16+x",
}
if p4type in p4_filetypes_historical:
p4type = p4_filetypes_historical[p4type]
mods = ""
s = p4type.split("+")
base = s[0]
mods = ""
if len(s) > 1:
mods = s[1]
return (base, mods)
'p4 help filetypes' gives a list of the types. If it starts with 'x',
or x follows one of a few letters. Otherwise, if there is an 'x' after
a plus sign, it is also executable"""
return (re.search(r"(^[cku]?x)|\+.*x", kind) != None)
def setP4ExecBit(file, mode):
# Reopens an already open file and changes the execute bit to match
......@@ -139,12 +199,12 @@ def setP4ExecBit(file, mode):
if p4Type[-1] == "+":
p4Type = p4Type[0:-1]
p4_system("reopen -t %s %s" % (p4Type, file))
p4_reopen(p4Type, file)
def getP4OpenedType(file):
# Returns the perforce file type for the given file.
result = p4_read_pipe("opened %s" % file)
result = p4_read_pipe(["opened", file])
match = re.match(".*\((.+)\)\r?$", result)
if match:
return match.group(1)
......@@ -200,9 +260,17 @@ def isModeExecChanged(src_mode, dst_mode):
return isModeExec(src_mode) != isModeExec(dst_mode)
def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None):
cmd = p4_build_cmd("-G %s" % (cmd))
if isinstance(cmd,basestring):
cmd = "-G " + cmd
expand = True
else:
cmd = ["-G"] + cmd
expand = False
cmd = p4_build_cmd(cmd)
if verbose:
sys.stderr.write("Opening pipe: %s\n" % cmd)
sys.stderr.write("Opening pipe: %s\n" % str(cmd))
# Use a temporary file to avoid deadlocks without
# subprocess.communicate(), which would put another copy
......@@ -210,11 +278,16 @@ def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None):
stdin_file = None
if stdin is not None:
stdin_file = tempfile.TemporaryFile(prefix='p4-stdin', mode=stdin_mode)
stdin_file.write(stdin)
if isinstance(stdin,basestring):
stdin_file.write(stdin)
else:
for i in stdin:
stdin_file.write(i + '\n')
stdin_file.flush()
stdin_file.seek(0)
p4 = subprocess.Popen(cmd, shell=True,
p4 = subprocess.Popen(cmd,
shell=expand,
stdin=stdin_file,
stdout=subprocess.PIPE)
......@@ -247,7 +320,7 @@ def p4Where(depotPath):
if not depotPath.endswith("/"):
depotPath += "/"
depotPath = depotPath + "..."
outputList = p4CmdList("where %s" % depotPath)
outputList = p4CmdList(["where", depotPath])
output = None
for entry in outputList:
if "depotFile" in entry:
......@@ -449,8 +522,10 @@ def originP4BranchesExist():
def p4ChangesForPaths(depotPaths, changeRange):
assert depotPaths
output = p4_read_pipe_lines("changes " + ' '.join (["%s...%s" % (p, changeRange)
for p in depotPaths]))
cmd = ['changes']
for p in depotPaths:
cmd += ["%s...%s" % (p, changeRange)]
output = p4_read_pipe_lines(cmd)
changes = {}
for line in output:
......@@ -533,7 +608,7 @@ class P4Debug(Command):
def run(self, args):
j = 0
for output in p4CmdList(" ".join(args)):
for output in p4CmdList(args):
print 'Element: %d' % j
j += 1
print output
......@@ -687,7 +762,7 @@ class P4Submit(Command, P4UserMap):
break
if not client:
die("could not get client spec")
results = p4CmdList("changes -c %s -m 1" % client)
results = p4CmdList(["changes", "-c", client, "-m", "1"])
for r in results:
if r.has_key('change'):
return r['change']
......@@ -750,7 +825,7 @@ class P4Submit(Command, P4UserMap):
# remove lines in the Files section that show changes to files outside the depot path we're committing into
template = ""
inFilesSection = False
for line in p4_read_pipe_lines("change -o"):
for line in p4_read_pipe_lines(['change', '-o']):
if line.endswith("\r\n"):
line = line[:-2] + "\n"
if inFilesSection:
......@@ -807,7 +882,7 @@ class P4Submit(Command, P4UserMap):
modifier = diff['status']
path = diff['src']
if modifier == "M":
p4_system("edit \"%s\"" % path)
p4_edit(path)
if isModeExecChanged(diff['src_mode'], diff['dst_mode']):
filesToChangeExecBit[path] = diff['dst_mode']
editedFiles.add(path)
......@@ -822,21 +897,21 @@ class P4Submit(Command, P4UserMap):
filesToAdd.remove(path)
elif modifier == "C":
src, dest = diff['src'], diff['dst']
p4_system("integrate -Dt \"%s\" \"%s\"" % (src, dest))
p4_integrate(src, dest)
if diff['src_sha1'] != diff['dst_sha1']:
p4_system("edit \"%s\"" % (dest))
p4_edit(dest)
if isModeExecChanged(diff['src_mode'], diff['dst_mode']):
p4_system("edit \"%s\"" % (dest))
p4_edit(dest)
filesToChangeExecBit[dest] = diff['dst_mode']
os.unlink(dest)
editedFiles.add(dest)
elif modifier == "R":
src, dest = diff['src'], diff['dst']
p4_system("integrate -Dt \"%s\" \"%s\"" % (src, dest))
p4_integrate(src, dest)
if diff['src_sha1'] != diff['dst_sha1']:
p4_system("edit \"%s\"" % (dest))
p4_edit(dest)
if isModeExecChanged(diff['src_mode'], diff['dst_mode']):
p4_system("edit \"%s\"" % (dest))
p4_edit(dest)
filesToChangeExecBit[dest] = diff['dst_mode']
os.unlink(dest)
editedFiles.add(dest)
......@@ -859,9 +934,9 @@ class P4Submit(Command, P4UserMap):
if response == "s":
print "Skipping! Good luck with the next patches..."
for f in editedFiles:
p4_system("revert \"%s\"" % f);
p4_revert(f)
for f in filesToAdd:
system("rm %s" %f)
os.remove(f)
return
elif response == "a":
os.system(applyPatchCmd)
......@@ -882,10 +957,10 @@ class P4Submit(Command, P4UserMap):
system(applyPatchCmd)
for f in filesToAdd:
p4_system("add \"%s\"" % f)
p4_add(f)
for f in filesToDelete:
p4_system("revert \"%s\"" % f)
p4_system("delete \"%s\"" % f)
p4_revert(f)
p4_delete(f)
# Set/clear executable bits
for f in filesToChangeExecBit.keys():
......@@ -907,7 +982,7 @@ class P4Submit(Command, P4UserMap):
del(os.environ["P4DIFF"])
diff = ""
for editedFile in editedFiles:
diff += p4_read_pipe("diff -du %r" % editedFile)
diff += p4_read_pipe(['diff', '-du', editedFile])
newdiff = ""
for newFile in filesToAdd:
......@@ -959,7 +1034,7 @@ class P4Submit(Command, P4UserMap):
submitTemplate = message[:message.index(separatorLine)]
if self.isWindows:
submitTemplate = submitTemplate.replace("\r\n", "\n")
p4_write_pipe("submit -i", submitTemplate)
p4_write_pipe(['submit', '-i'], submitTemplate)
if self.preserveUser:
if p4User:
......@@ -970,10 +1045,10 @@ class P4Submit(Command, P4UserMap):
else:
for f in editedFiles:
p4_system("revert \"%s\"" % f);
p4_revert(f)
for f in filesToAdd:
p4_system("revert \"%s\"" % f);
system("rm %s" %f)
p4_revert(f)
os.remove(f)
os.remove(fileName)
else:
......@@ -1026,8 +1101,7 @@ class P4Submit(Command, P4UserMap):
chdir(self.clientPath)
print "Synchronizing p4 checkout..."
p4_system("sync ...")
p4_sync("...")
self.check()
commits = []
......@@ -1219,38 +1293,53 @@ class P4Sync(Command, P4UserMap):
# - helper for streamP4Files
def streamOneP4File(self, file, contents):
if file["type"] == "apple":
print "\nfile %s is a strange apple file that forks. Ignoring" % \
file['depotFile']
return
relPath = self.stripRepoPath(file['depotFile'], self.branchPrefixes)
relPath = self.wildcard_decode(relPath)
if verbose:
sys.stderr.write("%s\n" % relPath)
mode = "644"
if isP4Exec(file["type"]):
mode = "755"
elif file["type"] == "symlink":
mode = "120000"
# p4 print on a symlink contains "target\n", so strip it off
(type_base, type_mods) = split_p4_type(file["type"])
git_mode = "100644"
if "x" in type_mods:
git_mode = "100755"
if type_base == "symlink":
git_mode = "120000"
# p4 print on a symlink contains "target\n"; remove the newline
data = ''.join(contents)
contents = [data[:-1]]
if self.isWindows and file["type"].endswith("text"):
if type_base == "utf16":
# p4 delivers different text in the python output to -G
# than it does when using "print -o", or normal p4 client
# operations. utf16 is converted to ascii or utf8, perhaps.
# But ascii text saved as -t utf16 is completely mangled.
# Invoke print -o to get the real contents.
text = p4_read_pipe(['print', '-q', '-o', '-', file['depotFile']])
contents = [ text ]
# Perhaps windows wants unicode, utf16 newlines translated too;
# but this is not doing it.
if self.isWindows and type_base == "text":
mangled = []
for data in contents:
data = data.replace("\r\n", "\n")
mangled.append(data)
contents = mangled
if file['type'] in ('text+ko', 'unicode+ko', 'binary+ko'):
contents = map(lambda text: re.sub(r'(?i)\$(Id|Header):[^$]*\$',r'$\1$', text), contents)
elif file['type'] in ('text+k', 'ktext', 'kxtext', 'unicode+k', 'binary+k'):
contents = map(lambda text: re.sub(r'\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$\n]*\$',r'$\1$', text), contents)
# Note that we do not try to de-mangle keywords on utf16 files,
# even though in theory somebody may want that.
if type_base in ("text", "unicode", "binary"):
if "ko" in type_mods:
text = ''.join(contents)
text = re.sub(r'\$(Id|Header):[^$]*\$', r'$\1$', text)
contents = [ text ]
elif "k" in type_mods:
text = ''.join(contents)
text = re.sub(r'\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$]*\$', r'$\1$', text)
contents = [ text ]
self.gitStream.write("M %s inline %s\n" % (mode, relPath))
self.gitStream.write("M %s inline %s\n" % (git_mode, relPath))
# total length...
length = 0
......@@ -1322,10 +1411,11 @@ class P4Sync(Command, P4UserMap):
def streamP4FilesCbSelf(entry):
self.streamP4FilesCb(entry)
p4CmdList("-x - print",
'\n'.join(['%s#%s' % (f['path'], f['rev'])
for f in filesToRead]),
cb=streamP4FilesCbSelf)
fileArgs = ['%s#%s' % (f['path'], f['rev']) for f in filesToRead]
p4CmdList(["-x", "-", "print"],
stdin=fileArgs,
cb=streamP4FilesCbSelf)
# do the last chunk
if self.stream_file.has_key('depotFile'):
......@@ -1386,8 +1476,8 @@ class P4Sync(Command, P4UserMap):
if self.verbose:
print "Change %s is labelled %s" % (change, labelDetails)
files = p4CmdList("files " + ' '.join (["%s...@%s" % (p, change)
for p in branchPrefixes]))
files = p4CmdList(["files"] + ["%s...@%s" % (p, change)
for p in branchPrefixes])
if len(files) == len(labelRevisions):
......@@ -1435,9 +1525,9 @@ class P4Sync(Command, P4UserMap):
newestChange = 0
if self.verbose:
print "Querying files for label %s" % label
for file in p4CmdList("files "
+ ' '.join (["%s...@%s" % (p, label)
for p in self.depotPaths])):
for file in p4CmdList(["files"] +
["%s...@%s" % (p, label)
for p in self.depotPaths]):
revisions[file["depotFile"]] = file["rev"]
change = int(file["change"])
if change > newestChange:
......@@ -1692,10 +1782,9 @@ class P4Sync(Command, P4UserMap):
newestRevision = 0
fileCnt = 0
for info in p4CmdList("files "
+ ' '.join(["%s...%s"
% (p, revision)
for p in self.depotPaths])):
fileArgs = ["%s...%s" % (p,revision) for p in self.depotPaths]
for info in p4CmdList(["files"] + fileArgs):
if 'code' in info and info['code'] == 'error':
sys.stderr.write("p4 returned an error: %s\n"
......
#
# Library code for git-p4 tests
#
. ./test-lib.sh
if ! test_have_prereq PYTHON; then
skip_all='skipping git-p4 tests; python not available'
test_done
fi
( p4 -h && p4d -h ) >/dev/null 2>&1 || {
skip_all='skipping git-p4 tests; no p4 or p4d'
test_done
}
GITP4="$GIT_BUILD_DIR/contrib/fast-import/git-p4"
# Try to pick a unique port: guess a large number, then hope
# no more than one of each test is running.
#
# This does not handle the case where somebody else is running the
# same tests and has chosen the same ports.
testid=${this_test#t}
git_p4_test_start=9800
P4DPORT=$((10669 + ($testid - $git_p4_test_start)))
export P4PORT=localhost:$P4DPORT
export P4CLIENT=client
db="$TRASH_DIRECTORY/db"
cli="$TRASH_DIRECTORY/cli"
git="$TRASH_DIRECTORY/git"
pidfile="$TRASH_DIRECTORY/p4d.pid"
start_p4d() {
mkdir -p "$db" "$cli" "$git" &&
(
p4d -q -r "$db" -p $P4DPORT &
echo $! >"$pidfile"
) &&
for i in 1 2 3 4 5 ; do
p4 info >/dev/null 2>&1 && break || true &&
echo waiting for p4d to start &&
sleep 1
done &&
# complain if it never started
p4 info >/dev/null &&
(
cd "$cli" &&
p4 client -i <<-EOF
Client: client
Description: client
Root: $cli
View: //depot/... //client/...
EOF
)
}
kill_p4d() {
pid=$(cat "$pidfile")
# it had better exist for the first kill
kill $pid &&
for i in 1 2 3 4 5 ; do
kill $pid >/dev/null 2>&1 || break
sleep 1
done &&
# complain if it would not die
test_must_fail kill $pid >/dev/null 2>&1 &&
rm -rf "$db" "$cli" "$pidfile"
}
cleanup_git() {
rm -rf "$git"
}
此差异已折叠。
#!/bin/sh
test_description='git-p4 p4 branching tests'
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
start_p4d
'
#
# 1: //depot/main/f1
# 2: //depot/main/f2
# 3: integrate //depot/main/... -> //depot/branch1/...
# 4: //depot/main/f4
# 5: //depot/branch1/f5
# .: named branch branch2
# 6: integrate -b branch2
# 7: //depot/branch2/f7
# 8: //depot/main/f8
#
test_expect_success 'basic p4 branches' '
(
cd "$cli" &&
mkdir -p main &&
echo f1 >main/f1 &&
p4 add main/f1 &&
p4 submit -d "main/f1" &&
echo f2 >main/f2 &&
p4 add main/f2 &&
p4 submit -d "main/f2" &&
p4 integrate //depot/main/... //depot/branch1/... &&
p4 submit -d "integrate main to branch1" &&
echo f4 >main/f4 &&
p4 add main/f4 &&
p4 submit -d "main/f4" &&
echo f5 >branch1/f5 &&
p4 add branch1/f5 &&
p4 submit -d "branch1/f5" &&
p4 branch -i <<-EOF &&
Branch: branch2
View: //depot/main/... //depot/branch2/...
EOF
p4 integrate -b branch2 &&
p4 submit -d "integrate main to branch2" &&
echo f7 >branch2/f7 &&
p4 add branch2/f7 &&
p4 submit -d "branch2/f7" &&
echo f8 >main/f8 &&
p4 add main/f8 &&
p4 submit -d "main/f8"
)
'
test_expect_success 'import main, no branch detection' '
test_when_finished cleanup_git &&
"$GITP4" clone --dest="$git" //depot/main@all &&
(
cd "$git" &&
git log --oneline --graph --decorate --all &&
git rev-list master >wc &&
test_line_count = 4 wc
)
'
test_expect_success 'import branch1, no branch detection' '
test_when_finished cleanup_git &&
"$GITP4" clone --dest="$git" //depot/branch1@all &&
(
cd "$git" &&
git log --oneline --graph --decorate --all &&
git rev-list master >wc &&
test_line_count = 2 wc
)
'
test_expect_success 'import branch2, no branch detection' '
test_when_finished cleanup_git &&
"$GITP4" clone --dest="$git" //depot/branch2@all &&
(
cd "$git" &&
git log --oneline --graph --decorate --all &&
git rev-list master >wc &&
test_line_count = 2 wc
)
'
test_expect_success 'import depot, no branch detection' '
test_when_finished cleanup_git &&
"$GITP4" clone --dest="$git" //depot@all &&
(
cd "$git" &&
git log --oneline --graph --decorate --all &&
git rev-list master >wc &&
test_line_count = 8 wc
)
'
test_expect_success 'import depot, branch detection' '
test_when_finished cleanup_git &&
"$GITP4" clone --dest="$git" --detect-branches //depot@all &&
(
cd "$git" &&
git log --oneline --graph --decorate --all &&
# 4 main commits
git rev-list master >wc &&
test_line_count = 4 wc &&
# 3 main, 1 integrate, 1 on branch2
git rev-list p4/depot/branch2 >wc &&
test_line_count = 5 wc &&
# no branch1, since no p4 branch created for it
test_must_fail git show-ref p4/depot/branch1
)
'
test_expect_success 'import depot, branch detection, branchList branch definition' '
test_when_finished cleanup_git &&
test_create_repo "$git" &&
(
cd "$git" &&
git config git-p4.branchList main:branch1 &&
"$GITP4" clone --dest=. --detect-branches //depot@all &&
git log --oneline --graph --decorate --all &&
# 4 main commits
git rev-list master >wc &&
test_line_count = 4 wc &&
# 3 main, 1 integrate, 1 on branch2
git rev-list p4/depot/branch2 >wc &&
test_line_count = 5 wc &&
# 2 main, 1 integrate, 1 on branch1
git rev-list p4/depot/branch1 >wc &&
test_line_count = 4 wc
)
'
test_expect_success 'restart p4d' '
kill_p4d &&
start_p4d
'
#
# 1: //depot/branch1/file1
# //depot/branch1/file2
# 2: integrate //depot/branch1/... -> //depot/branch2/...
# 3: //depot/branch1/file3
# 4: //depot/branch1/file2 (edit)
# 5: integrate //depot/branch1/... -> //depot/branch3/...
#
## Create a simple branch structure in P4 depot.
test_expect_success 'add simple p4 branches' '
(
cd "$cli" &&
mkdir branch1 &&
cd branch1 &&
echo file1 >file1 &&
echo file2 >file2 &&
p4 add file1 file2 &&
p4 submit -d "branch1" &&
p4 integrate //depot/branch1/... //depot/branch2/... &&
p4 submit -d "branch2" &&
echo file3 >file3 &&
p4 add file3 &&
p4 submit -d "add file3 in branch1" &&
p4 open file2 &&
echo update >>file2 &&
p4 submit -d "update file2 in branch1" &&
p4 integrate //depot/branch1/... //depot/branch3/... &&
p4 submit -d "branch3"
)
'
# Configure branches through git-config and clone them.
# All files are tested to make sure branches were cloned correctly.
# Finally, make an update to branch1 on P4 side to check if it is imported
# correctly by git-p4.
test_expect_success 'git-p4 clone simple branches' '
test_when_finished cleanup_git &&
test_create_repo "$git" &&
(
cd "$git" &&
git config git-p4.branchList branch1:branch2 &&
git config --add git-p4.branchList branch1:branch3 &&
"$GITP4" clone --dest=. --detect-branches //depot@all &&
git log --all --graph --decorate --stat &&
git reset --hard p4/depot/branch1 &&
test -f file1 &&
test -f file2 &&
test -f file3 &&
grep -q update file2 &&
git reset --hard p4/depot/branch2 &&
test -f file1 &&
test -f file2 &&
test ! -f file3 &&
test_must_fail grep -q update file2 &&
git reset --hard p4/depot/branch3 &&
test -f file1 &&
test -f file2 &&
test -f file3 &&
grep -q update file2 &&
cd "$cli" &&
cd branch1 &&
p4 edit file2 &&
echo file2_ >>file2 &&
p4 submit -d "update file2 in branch3" &&
cd "$git" &&
git reset --hard p4/depot/branch1 &&
"$GITP4" rebase &&
grep -q file2_ file2
)
'
test_expect_success 'kill p4d' '
kill_p4d
'
test_done
#!/bin/sh
test_description='git-p4 p4 filetype tests'
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
start_p4d
'
test_expect_success 'utf-16 file create' '
(
cd "$cli" &&
# p4 saves this verbatim
printf "three\nline\ntext\n" >f-ascii &&
p4 add -t text f-ascii &&
# p4 adds \377\376 header
cp f-ascii f-ascii-as-utf16 &&
p4 add -t utf16 f-ascii-as-utf16 &&
# p4 saves this exactly as iconv produced it
printf "three\nline\ntext\n" | iconv -f ascii -t utf-16 >f-utf16 &&
p4 add -t utf16 f-utf16 &&
# this also is unchanged
cp f-utf16 f-utf16-as-text &&
p4 add -t text f-utf16-as-text &&
p4 submit -d "f files" &&
# force update of client files
p4 sync -f
)
'
test_expect_success 'utf-16 file test' '
test_when_finished cleanup_git &&
"$GITP4" clone --dest="$git" //depot@all &&
(
cd "$git" &&
test_cmp "$cli/f-ascii" f-ascii &&
test_cmp "$cli/f-ascii-as-utf16" f-ascii-as-utf16 &&
test_cmp "$cli/f-utf16" f-utf16 &&
test_cmp "$cli/f-utf16-as-text" f-utf16-as-text
)
'
test_expect_success 'keyword file create' '
(
cd "$cli" &&
printf "id\n\$Id\$\n\$Author\$\ntext\n" >k-text-k &&
p4 add -t text+k k-text-k &&
cp k-text-k k-text-ko &&
p4 add -t text+ko k-text-ko &&
cat k-text-k | iconv -f ascii -t utf-16 >k-utf16-k &&
p4 add -t utf16+k k-utf16-k &&
cp k-utf16-k k-utf16-ko &&
p4 add -t utf16+ko k-utf16-ko &&
p4 submit -d "k files" &&
p4 sync -f
)
'
build_smush() {
cat >k_smush.py <<-\EOF &&
import re, sys
sys.stdout.write(re.sub(r'(?i)\$(Id|Header|Author|Date|DateTime|Change|File|Revision):[^$]*\$', r'$\1$', sys.stdin.read()))
EOF
cat >ko_smush.py <<-\EOF
import re, sys
sys.stdout.write(re.sub(r'(?i)\$(Id|Header):[^$]*\$', r'$\1$', sys.stdin.read()))
EOF
}
test_expect_success 'keyword file test' '
build_smush &&
test_when_finished rm -f k_smush.py ko_smush.py &&
test_when_finished cleanup_git &&
"$GITP4" clone --dest="$git" //depot@all &&
(
cd "$git" &&
# text, ensure unexpanded
"$PYTHON_PATH" "$TRASH_DIRECTORY/k_smush.py" <"$cli/k-text-k" >cli-k-text-k-smush &&
test_cmp cli-k-text-k-smush k-text-k &&
"$PYTHON_PATH" "$TRASH_DIRECTORY/ko_smush.py" <"$cli/k-text-ko" >cli-k-text-ko-smush &&
test_cmp cli-k-text-ko-smush k-text-ko &&
# utf16, even though p4 expands keywords, git-p4 does not
# try to undo that
test_cmp "$cli/k-utf16-k" k-utf16-k &&
test_cmp "$cli/k-utf16-ko" k-utf16-ko
)
'
test_expect_success 'kill p4d' '
kill_p4d
'
test_done
#!/bin/sh
test_description='git-p4 transparency to shell metachars in filenames'
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
start_p4d
'
test_expect_success 'init depot' '
(
cd "$cli" &&
echo file1 >file1 &&
p4 add file1 &&
p4 submit -d "file1"
)
'
test_expect_success 'shell metachars in filenames' '
"$GITP4" clone --dest="$git" //depot &&
test_when_finished cleanup_git &&
(
cd "$git" &&
git config git-p4.skipSubmitEditCheck true &&
echo f1 >foo\$bar &&
git add foo\$bar &&
echo f2 >"file with spaces" &&
git add "file with spaces" &&
git commit -m "add files" &&
P4EDITOR=touch "$GITP4" submit
) &&
(
cd "$cli" &&
p4 sync ... &&
test -e "file with spaces" &&
test -e "foo\$bar"
)
'
test_expect_success 'deleting with shell metachars' '
"$GITP4" clone --dest="$git" //depot &&
test_when_finished cleanup_git &&
(
cd "$git" &&
git config git-p4.skipSubmitEditCheck true &&
git rm foo\$bar &&
git rm file\ with\ spaces &&
git commit -m "remove files" &&
P4EDITOR=touch "$GITP4" submit
) &&
(
cd "$cli" &&
p4 sync ... &&
test ! -e "file with spaces" &&
test ! -e foo\$bar
)
'
test_expect_success 'kill p4d' '
kill_p4d
'
test_done
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册