Skip to content

Commit

Permalink
git p4: avoid expanding client paths in chdir
Browse files Browse the repository at this point in the history
The generic chdir() helper sets the PWD environment
variable, as that is what is used by p4 to know its
current working directory.  Normally the shell would
do this, but in git-p4, we must do it by hand.

However, when the path contains a symbolic link,
os.getcwd() will return the physical location.  If the
p4 client specification includes symlinks, setting PWD
to the physical location causes p4 to think it is not
inside the client workspace.  It complains, e.g.

    Path /vol/bar/projects/foo/... is not under client root /p/foo

One workaround is to use AltRoots in the p4 client specification,
but it is cleaner to handle it directly in git-p4.

Other uses of chdir still require setting PWD to an
absolute path so p4 features like P4CONFIG work.  See
bf1d68f (git-p4: use absolute directory for PWD env
var, 2011-12-09).

[ pw: tweak patch and commit message ]

Thanks-to: John Keeping <john@keeping.me.uk>
Signed-off-by: Pete Wyckoff <pw@padd.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Miklós Fazekas authored and Junio C Hamano committed Mar 11, 2013
1 parent 89773db commit bbd8486
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
29 changes: 22 additions & 7 deletions git-p4.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,27 @@ def p4_build_cmd(cmd):
real_cmd += cmd
return real_cmd

def chdir(dir):
# P4 uses the PWD environment variable rather than getcwd(). Since we're
# not using the shell, we have to set it ourselves. This path could
# be relative, so go there first, then figure out where we ended up.
os.chdir(dir)
os.environ['PWD'] = os.getcwd()
def chdir(path, is_client_path=False):
"""Do chdir to the given path, and set the PWD environment
variable for use by P4. It does not look at getcwd() output.
Since we're not using the shell, it is necessary to set the
PWD environment variable explicitly.
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):
if verbose:
Expand Down Expand Up @@ -1624,7 +1639,7 @@ def run(self, args):
new_client_dir = True
os.makedirs(self.clientPath)

chdir(self.clientPath)
chdir(self.clientPath, is_client_path=True)
if self.dry_run:
print "Would synchronize p4 checkout in %s" % self.clientPath
else:
Expand Down
2 changes: 1 addition & 1 deletion t/t9808-git-p4-chdir.sh
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ test_expect_success 'p4 client root would be relative due to clone --dest' '

# When the p4 client Root is a symlink, make sure chdir() does not use
# getcwd() to convert it to a physical path.
test_expect_failure SYMLINKS 'p4 client root symlink should stay symbolic' '
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\"" &&
Expand Down

0 comments on commit bbd8486

Please sign in to comment.