git-codereview: fix hook installation in git 2.13.0
git 2.13.0 changed the behavior of git rev-parse --git-path from
printing a path relative to the repo root to printing a path relative
to the working directory. This breaks git-codereview's hook
installation when a git-codereview command is invoked from a directory
other than the repo root, since it will try to resolve this path as
relative to the repo root.
Fix this by running git rev-parse from the repo root, so it behaves
the same either way.
Fixes golang/go#19477.
Change-Id: Ia5e1b81da5041365d817daf9f5979df0772ede4b
Reviewed-on: https://go-review.googlesource.com/38010
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/git-codereview/hook.go b/git-codereview/hook.go
index 0e8f075..f953478 100644
--- a/git-codereview/hook.go
+++ b/git-codereview/hook.go
@@ -77,13 +77,18 @@
// all other path relocations, e.g. hooks for linked worktrees
// are not kept in their gitdir, but shared in the main one.
func gitPath(path string) string {
- p, err := trimErr(cmdOutputErr("git", "rev-parse", "--git-path", path))
+ root := repoRoot()
+ // git 2.13.0 changed the behavior of --git-path from printing
+ // a path relative to the repo root to printing a path
+ // relative to the working directory (issue #19477). Normalize
+ // both behaviors by running the command from the repo root.
+ p, err := trimErr(cmdOutputErr("git", "-C", root, "rev-parse", "--git-path", path))
if err != nil {
// When --git-path is not available, assume the common case.
p = filepath.Join(".git", path)
}
if !filepath.IsAbs(p) {
- p = filepath.Join(repoRoot(), p)
+ p = filepath.Join(root, p)
}
return p
}
diff --git a/git-codereview/hook_test.go b/git-codereview/hook_test.go
index 0d171c0..8cb04f9 100644
--- a/git-codereview/hook_test.go
+++ b/git-codereview/hook_test.go
@@ -440,6 +440,27 @@
}
}
+func TestHooksInSubdir(t *testing.T) {
+ gt := newGitTest(t)
+ defer gt.done()
+
+ gt.removeStubHooks()
+ if err := os.MkdirAll(gt.client+"/test", 0755); err != nil {
+ t.Fatal(err)
+ }
+ chdir(t, gt.client+"/test")
+
+ testMain(t, "hooks") // install hooks
+
+ data, err := ioutil.ReadFile(gt.client + "/.git/hooks/commit-msg")
+ if err != nil {
+ t.Fatalf("hooks did not write commit-msg hook: %v", err)
+ }
+ if string(data) != "#!/bin/sh\nexec git-codereview hook-invoke commit-msg \"$@\"\n" {
+ t.Fatalf("invalid commit-msg hook:\n%s", string(data))
+ }
+}
+
func TestHooksOverwriteOldCommitMsg(t *testing.T) {
gt := newGitTest(t)
defer gt.done()