git-p4: support git worktrees

git-p4 would attempt to find the git directory using its own specific code, which did not know about git worktrees. Rework it to use "git rev-parse --git-dir" instead. Add test cases for worktree usage and specifying git directory via --git-dir and $GIT_DIR. Signed-off-by: Luke Diamand <luke@diamand.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Luke Diamand committed Dec 13, 2016 at 21:51 UTC 378f7be1e74661ff1480cc44a5f039ef85da7288
3 files changed +65 -4
git-p4.py
+13 -4
@@ -85,6 +85,16 @@ def p4_build_cmd(cmd):
85 real_cmd += cmd
86 return real_cmd
87
88 +def git_dir(path):
89 + """ Return TRUE if the given path is a git directory (/path/to/dir/.git).
90 + This won't automatically add ".git" to a directory.
91 + """
92 + d = read_pipe(["git", "--git-dir", path, "rev-parse", "--git-dir"], True).strip()
93 + if not d or len(d) == 0:
94 + return None
95 + else:
96 + return d
97 +
98 def chdir(path, is_client_path=False):
99 """Do chdir to the given path, and set the PWD environment
100 variable for use by P4. It does not look at getcwd() output.
@@ -563,10 +573,7 @@ def currentGitBranch():
573 return read_pipe(["git", "name-rev", "HEAD"]).split(" ")[1].strip()
574
575 def isValidGitDir(path):
566 - if (os.path.exists(path + "/HEAD")
567 - and os.path.exists(path + "/refs") and os.path.exists(path + "/objects")):
568 - return True;
569 - return False
576 + return git_dir(path) != None
577
578 def parseRevision(ref):
579 return read_pipe("git rev-parse %s" % ref).strip()
@@ -3682,6 +3689,7 @@ def main():
3689 if cmd.gitdir == None:
3690 cmd.gitdir = os.path.abspath(".git")
3691 if not isValidGitDir(cmd.gitdir):
3692 + # "rev-parse --git-dir" without arguments will try $PWD/.git
3693 cmd.gitdir = read_pipe("git rev-parse --git-dir").strip()
3694 if os.path.exists(cmd.gitdir):
3695 cdup = read_pipe("git rev-parse --show-cdup").strip()
@@ -3694,6 +3702,7 @@ def main():
3702 else:
3703 die("fatal: cannot locate git repository at %s" % cmd.gitdir)
3704
3705 + # so git commands invoked from the P4 workspace will succeed
3706 os.environ["GIT_DIR"] = cmd.gitdir
3707
3708 if not cmd.run(args):
t/t9800-git-p4-basic.sh
+20
@@ -257,6 +257,26 @@ test_expect_success 'submit from detached head' '
257 )
258 '
259
260 +test_expect_success 'submit from worktree' '
261 + test_when_finished cleanup_git &&
262 + git p4 clone --dest="$git" //depot &&
263 + (
264 + cd "$git" &&
265 + git worktree add ../worktree-test
266 + ) &&
267 + (
268 + cd "$git/../worktree-test" &&
269 + test_commit "worktree-commit" &&
270 + git config git-p4.skipSubmitEdit true &&
271 + git p4 submit
272 + ) &&
273 + (
274 + cd "$cli" &&
275 + p4 sync &&
276 + test_path_is_file worktree-commit.t
277 + )
278 +'
279 +
280 test_expect_success 'kill p4d' '
281 kill_p4d
282 '
t/t9806-git-p4-options.sh
+32
@@ -269,6 +269,38 @@ test_expect_success 'submit works with two branches' '
269 )
270 '
271
272 +test_expect_success 'use --git-dir option and GIT_DIR' '
273 + test_when_finished cleanup_git &&
274 + git p4 clone //depot --destination="$git" &&
275 + (
276 + cd "$git" &&
277 + git config git-p4.skipSubmitEdit true &&
278 + test_commit first-change &&
279 + git p4 submit --git-dir "$git"
280 + ) &&
281 + (
282 + cd "$cli" &&
283 + p4 sync &&
284 + test_path_is_file first-change.t &&
285 + echo "cli_file" >cli_file.t &&
286 + p4 add cli_file.t &&
287 + p4 submit -d "cli change"
288 + ) &&
289 + (git --git-dir "$git" p4 sync) &&
290 + (cd "$git" && git checkout -q p4/master) &&
291 + test_path_is_file "$git"/cli_file.t &&
292 + (
293 + cd "$cli" &&
294 + echo "cli_file2" >cli_file2.t &&
295 + p4 add cli_file2.t &&
296 + p4 submit -d "cli change2"
297 + ) &&
298 + (GIT_DIR="$git" git p4 sync) &&
299 + (cd "$git" && git checkout -q p4/master) &&
300 + test_path_is_file "$git"/cli_file2.t
301 +'
302 +
303 +
304 test_expect_success 'kill p4d' '
305 kill_p4d
306 '