Skip to content

Commit 9b12c6e

Browse files
committed
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
2 parents 63868f6 + bbd8486 commit 9b12c6e

File tree

2 files changed

+63
-7
lines changed

2 files changed

+63
-7
lines changed

git-p4.py

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,27 @@ def p4_build_cmd(cmd):
7979
real_cmd += cmd
8080
return real_cmd
8181

82-
def chdir(dir):
83-
# P4 uses the PWD environment variable rather than getcwd(). Since we're
84-
# not using the shell, we have to set it ourselves. This path could
85-
# be relative, so go there first, then figure out where we ended up.
86-
os.chdir(dir)
87-
os.environ['PWD'] = os.getcwd()
82+
def chdir(path, is_client_path=False):
83+
"""Do chdir to the given path, and set the PWD environment
84+
variable for use by P4. It does not look at getcwd() output.
85+
Since we're not using the shell, it is necessary to set the
86+
PWD environment variable explicitly.
87+
88+
Normally, expand the path to force it to be absolute. This
89+
addresses the use of relative path names inside P4 settings,
90+
e.g. P4CONFIG=.p4config. P4 does not simply open the filename
91+
as given; it looks for .p4config using PWD.
92+
93+
If is_client_path, the path was handed to us directly by p4,
94+
and may be a symbolic link. Do not call os.getcwd() in this
95+
case, because it will cause p4 to think that PWD is not inside
96+
the client path.
97+
"""
98+
99+
os.chdir(path)
100+
if not is_client_path:
101+
path = os.getcwd()
102+
os.environ['PWD'] = path
88103

89104
def die(msg):
90105
if verbose:
@@ -1624,7 +1639,7 @@ def run(self, args):
16241639
new_client_dir = True
16251640
os.makedirs(self.clientPath)
16261641

1627-
chdir(self.clientPath)
1642+
chdir(self.clientPath, is_client_path=True)
16281643
if self.dry_run:
16291644
print "Would synchronize p4 checkout in %s" % self.clientPath
16301645
else:

t/t9808-git-p4-chdir.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,47 @@ test_expect_success 'P4CONFIG and relative dir clone' '
4242
)
4343
'
4444

45+
# Common setup using .p4config to set P4CLIENT and P4PORT breaks
46+
# if clone destination is relative. Make sure that chdir() expands
47+
# the relative path in --dest to absolute.
48+
test_expect_success 'p4 client root would be relative due to clone --dest' '
49+
test_when_finished cleanup_git &&
50+
(
51+
echo P4PORT=$P4PORT >git/.p4config &&
52+
P4CONFIG=.p4config &&
53+
export P4CONFIG &&
54+
unset P4PORT &&
55+
git p4 clone --dest="git" //depot
56+
)
57+
'
58+
59+
# When the p4 client Root is a symlink, make sure chdir() does not use
60+
# getcwd() to convert it to a physical path.
61+
test_expect_success SYMLINKS 'p4 client root symlink should stay symbolic' '
62+
physical="$TRASH_DIRECTORY/physical" &&
63+
symbolic="$TRASH_DIRECTORY/symbolic" &&
64+
test_when_finished "rm -rf \"$physical\"" &&
65+
test_when_finished "rm \"$symbolic\"" &&
66+
mkdir -p "$physical" &&
67+
ln -s "$physical" "$symbolic" &&
68+
test_when_finished cleanup_git &&
69+
(
70+
P4CLIENT=client-sym &&
71+
p4 client -i <<-EOF &&
72+
Client: $P4CLIENT
73+
Description: $P4CLIENT
74+
Root: $symbolic
75+
LineEnd: unix
76+
View: //depot/... //$P4CLIENT/...
77+
EOF
78+
git p4 clone --dest="$git" //depot &&
79+
cd "$git" &&
80+
test_commit file2 &&
81+
git config git-p4.skipSubmitEdit true &&
82+
git p4 submit
83+
)
84+
'
85+
4586
test_expect_success 'kill p4d' '
4687
kill_p4d
4788
'

0 commit comments

Comments
 (0)