Merge branch 'pw/p4-symlinked-root'

"git p4" did not behave well when the path to the root of the P4
client was not its real path.

* pw/p4-symlinked-root:
  git p4: avoid expanding client paths in chdir
  git p4 test: should honor symlink in p4 client root
  git p4 test: make sure P4CONFIG relative path works
maint
Junio C Hamano 2013-03-25 14:00:49 -07:00
commit 9b12c6ed77
2 changed files with 63 additions and 7 deletions

View File

@ -79,12 +79,27 @@ def p4_build_cmd(cmd):
real_cmd += cmd real_cmd += cmd
return real_cmd return real_cmd


def chdir(dir): def chdir(path, is_client_path=False):
# P4 uses the PWD environment variable rather than getcwd(). Since we're """Do chdir to the given path, and set the PWD environment
# not using the shell, we have to set it ourselves. This path could variable for use by P4. It does not look at getcwd() output.
# be relative, so go there first, then figure out where we ended up. Since we're not using the shell, it is necessary to set the
os.chdir(dir) PWD environment variable explicitly.
os.environ['PWD'] = os.getcwd()
Normally, expand the path to force it to be absolute. This
addresses the use of relative path names inside P4 settings,
e.g. P4CONFIG=.p4config. P4 does not simply open the filename
as given; it looks for .p4config using PWD.

If is_client_path, the path was handed to us directly by p4,
and may be a symbolic link. Do not call os.getcwd() in this
case, because it will cause p4 to think that PWD is not inside
the client path.
"""

os.chdir(path)
if not is_client_path:
path = os.getcwd()
os.environ['PWD'] = path


def die(msg): def die(msg):
if verbose: if verbose:
@ -1624,7 +1639,7 @@ class P4Submit(Command, P4UserMap):
new_client_dir = True new_client_dir = True
os.makedirs(self.clientPath) os.makedirs(self.clientPath)


chdir(self.clientPath) chdir(self.clientPath, is_client_path=True)
if self.dry_run: if self.dry_run:
print "Would synchronize p4 checkout in %s" % self.clientPath print "Would synchronize p4 checkout in %s" % self.clientPath
else: else:

View File

@ -42,6 +42,47 @@ test_expect_success 'P4CONFIG and relative dir clone' '
) )
' '


# Common setup using .p4config to set P4CLIENT and P4PORT breaks
# if clone destination is relative. Make sure that chdir() expands
# the relative path in --dest to absolute.
test_expect_success 'p4 client root would be relative due to clone --dest' '
test_when_finished cleanup_git &&
(
echo P4PORT=$P4PORT >git/.p4config &&
P4CONFIG=.p4config &&
export P4CONFIG &&
unset P4PORT &&
git p4 clone --dest="git" //depot
)
'

# When the p4 client Root is a symlink, make sure chdir() does not use
# getcwd() to convert it to a physical path.
test_expect_success SYMLINKS 'p4 client root symlink should stay symbolic' '
physical="$TRASH_DIRECTORY/physical" &&
symbolic="$TRASH_DIRECTORY/symbolic" &&
test_when_finished "rm -rf \"$physical\"" &&
test_when_finished "rm \"$symbolic\"" &&
mkdir -p "$physical" &&
ln -s "$physical" "$symbolic" &&
test_when_finished cleanup_git &&
(
P4CLIENT=client-sym &&
p4 client -i <<-EOF &&
Client: $P4CLIENT
Description: $P4CLIENT
Root: $symbolic
LineEnd: unix
View: //depot/... //$P4CLIENT/...
EOF
git p4 clone --dest="$git" //depot &&
cd "$git" &&
test_commit file2 &&
git config git-p4.skipSubmitEdit true &&
git p4 submit
)
'

test_expect_success 'kill p4d' ' test_expect_success 'kill p4d' '
kill_p4d kill_p4d
' '