1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-03 23:36:11 +02:00

git-p4: avoid crash adding symlinked directory

When submitting to P4, if git-p4 came across a symlinked
directory, then during the generation of the submit diff, it would
try to open it as a normal file and fail.

Spot symlinks (of any type) and output a description of the symlink
instead.

Add a test case.

Signed-off-by: Luke Diamand <luke@diamand.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Luke Diamand 2016-12-17 01:00:40 +00:00 committed by Junio C Hamano
parent 454cb6bd52
commit df8a9e86db
2 changed files with 63 additions and 6 deletions

View File

@ -25,6 +25,7 @@
import zipfile
import zlib
import ctypes
import errno
try:
from subprocess import CalledProcessError
@ -1538,7 +1539,7 @@ def edit_template(self, template_file):
if response == 'n':
return False
def get_diff_description(self, editedFiles, filesToAdd):
def get_diff_description(self, editedFiles, filesToAdd, symlinks):
# diff
if os.environ.has_key("P4DIFF"):
del(os.environ["P4DIFF"])
@ -1553,10 +1554,17 @@ def get_diff_description(self, editedFiles, filesToAdd):
newdiff += "==== new file ====\n"
newdiff += "--- /dev/null\n"
newdiff += "+++ %s\n" % newFile
f = open(newFile, "r")
for line in f.readlines():
newdiff += "+" + line
f.close()
is_link = os.path.islink(newFile)
expect_link = newFile in symlinks
if is_link and expect_link:
newdiff += "+%s\n" % os.readlink(newFile)
else:
f = open(newFile, "r")
for line in f.readlines():
newdiff += "+" + line
f.close()
return (diff + newdiff).replace('\r\n', '\n')
@ -1574,6 +1582,7 @@ def applyCommit(self, id):
filesToDelete = set()
editedFiles = set()
pureRenameCopy = set()
symlinks = set()
filesToChangeExecBit = {}
for line in diff:
@ -1590,6 +1599,11 @@ def applyCommit(self, id):
filesToChangeExecBit[path] = diff['dst_mode']
if path in filesToDelete:
filesToDelete.remove(path)
dst_mode = int(diff['dst_mode'], 8)
if dst_mode == 0120000:
symlinks.add(path)
elif modifier == "D":
filesToDelete.add(path)
if path in filesToAdd:
@ -1727,7 +1741,7 @@ def applyCommit(self, id):
separatorLine = "######## everything below this line is just the diff #######\n"
if not self.prepare_p4_only:
submitTemplate += separatorLine
submitTemplate += self.get_diff_description(editedFiles, filesToAdd)
submitTemplate += self.get_diff_description(editedFiles, filesToAdd, symlinks)
(handle, fileName) = tempfile.mkstemp()
tmpFile = os.fdopen(handle, "w+b")

43
t/t9830-git-p4-symlink-dir.sh Executable file
View File

@ -0,0 +1,43 @@
#!/bin/sh
test_description='git p4 symlinked directories'
. ./lib-git-p4.sh
test_expect_success 'start p4d' '
start_p4d
'
test_expect_success 'symlinked directory' '
(
cd "$cli" &&
: >first_file.t &&
p4 add first_file.t &&
p4 submit -d "first change"
) &&
git p4 clone --dest "$git" //depot &&
(
cd "$git" &&
mkdir -p some/sub/directory &&
mkdir -p other/subdir2 &&
: > other/subdir2/file.t &&
(cd some/sub/directory && ln -s ../../../other/subdir2 .) &&
git add some other &&
git commit -m "symlinks" &&
git config git-p4.skipSubmitEdit true &&
git p4 submit -v
) &&
(
cd "$cli" &&
p4 sync &&
test -L some/sub/directory/subdir2
test_path_is_file some/sub/directory/subdir2/file.t
)
'
test_expect_success 'kill p4d' '
kill_p4d
'
test_done