Merge pull request #205 from seeduvax/issue-178

Michael Muré created

issue 178: fetch the repo dir with rev-parse --git-dir

Change summary

cache/repo_cache.go       |  6 +++---
commands/select/select.go |  2 +-
input/input.go            |  6 +++---
repository/git.go         | 26 ++++++++++++++++++--------
repository/git_testing.go | 13 +++++++++++++
5 files changed, 38 insertions(+), 15 deletions(-)

Detailed changes

cache/repo_cache.go 🔗

@@ -350,11 +350,11 @@ func (c *RepoCache) writeIdentityCache() error {
 }
 
 func bugCacheFilePath(repo repository.Repo) string {
-	return path.Join(repo.GetPath(), ".git", "git-bug", bugCacheFile)
+	return path.Join(repo.GetPath(), "git-bug", bugCacheFile)
 }
 
 func identityCacheFilePath(repo repository.Repo) string {
-	return path.Join(repo.GetPath(), ".git", "git-bug", identityCacheFile)
+	return path.Join(repo.GetPath(), "git-bug", identityCacheFile)
 }
 
 func (c *RepoCache) buildCache() error {
@@ -706,7 +706,7 @@ func (c *RepoCache) Pull(remote string) error {
 }
 
 func repoLockFilePath(repo repository.Repo) string {
-	return path.Join(repo.GetPath(), ".git", "git-bug", lockfile)
+	return path.Join(repo.GetPath(), "git-bug", lockfile)
 }
 
 // repoIsAvailable check is the given repository is locked by a Cache.

commands/select/select.go 🔗

@@ -137,5 +137,5 @@ func selected(repo *cache.RepoCache) (*cache.BugCache, error) {
 }
 
 func selectFilePath(repo repository.RepoCommon) string {
-	return path.Join(repo.GetPath(), ".git", "git-bug", selectFile)
+	return path.Join(repo.GetPath(), "git-bug", selectFile)
 }

input/input.go 🔗

@@ -239,7 +239,7 @@ func QueryEditorInput(repo repository.RepoCommon, preQuery string) (string, erro
 // launchEditorWithTemplate will launch an editor as launchEditor do, but with a
 // provided template.
 func launchEditorWithTemplate(repo repository.RepoCommon, fileName string, template string) (string, error) {
-	path := fmt.Sprintf("%s/.git/%s", repo.GetPath(), fileName)
+	path := fmt.Sprintf("%s/%s", repo.GetPath(), fileName)
 
 	err := ioutil.WriteFile(path, []byte(template), 0644)
 
@@ -254,13 +254,13 @@ func launchEditorWithTemplate(repo repository.RepoCommon, fileName string, templ
 // method blocks until the editor command has returned.
 //
 // The specified filename should be a temporary file and provided as a relative path
-// from the repo (e.g. "FILENAME" will be converted to ".git/FILENAME"). This file
+// from the repo (e.g. "FILENAME" will be converted to "[<reporoot>/].git/FILENAME"). This file
 // will be deleted after the editor is closed and its contents have been read.
 //
 // This method returns the text that was read from the temporary file, or
 // an error if any step in the process failed.
 func launchEditor(repo repository.RepoCommon, fileName string) (string, error) {
-	path := fmt.Sprintf("%s/.git/%s", repo.GetPath(), fileName)
+	path := fmt.Sprintf("%s/%s", repo.GetPath(), fileName)
 	defer os.Remove(path)
 
 	editor, err := repo.GetCoreEditor()

repository/git.go 🔗

@@ -18,8 +18,8 @@ import (
 	"github.com/MichaelMure/git-bug/util/lamport"
 )
 
-const createClockFile = "/.git/git-bug/create-clock"
-const editClockFile = "/.git/git-bug/edit-clock"
+const createClockFile = "/git-bug/create-clock"
+const editClockFile = "/git-bug/edit-clock"
 
 // ErrNotARepo is the error returned when the git repo root wan't be found
 var ErrNotARepo = errors.New("not a git repository")
@@ -35,10 +35,19 @@ type GitRepo struct {
 
 // Run the given git command with the given I/O reader/writers, returning an error if it fails.
 func (repo *GitRepo) runGitCommandWithIO(stdin io.Reader, stdout, stderr io.Writer, args ...string) error {
-	// fmt.Printf("[%s] Running git %s\n", repo.Path, strings.Join(args, " "))
+	repopath:=repo.Path
+	if repopath==".git" {
+		// seeduvax> trangely the git command sometimes fail for very unknown
+		// reason wihtout this replacement.
+		// observed with rev-list command when git-bug is called from git
+		// hook script, even the same command with same args runs perfectly
+		// when called directly from the same hook script. 
+		repopath=""
+	}
+	// fmt.Printf("[%s] Running git %s\n", repopath, strings.Join(args, " "))
 
 	cmd := exec.Command("git", args...)
-	cmd.Dir = repo.Path
+	cmd.Dir = repopath
 	cmd.Stdin = stdin
 	cmd.Stdout = stdout
 	cmd.Stderr = stderr
@@ -77,10 +86,11 @@ func NewGitRepo(path string, witnesser Witnesser) (*GitRepo, error) {
 	repo := &GitRepo{Path: path}
 
 	// Check the repo and retrieve the root path
-	stdout, err := repo.runGitCommand("rev-parse", "--show-toplevel")
+	stdout, err := repo.runGitCommand("rev-parse", "--git-dir")
 
-	// for some reason, "git rev-parse --show-toplevel" return nothing
-	// and no error when inside a ".git" dir
+	// Now dir is fetched with "git rev-parse --git-dir". May be it can
+	// still return nothing in some cases. Then empty stdout check is
+	// kept.
 	if err != nil || stdout == "" {
 		return nil, ErrNotARepo
 	}
@@ -115,7 +125,7 @@ func NewGitRepo(path string, witnesser Witnesser) (*GitRepo, error) {
 
 // InitGitRepo create a new empty git repo at the given path
 func InitGitRepo(path string) (*GitRepo, error) {
-	repo := &GitRepo{Path: path}
+	repo := &GitRepo{Path: path+"/.git"}
 	err := repo.createClocks()
 	if err != nil {
 		return nil, err

repository/git_testing.go 🔗

@@ -4,6 +4,7 @@ import (
 	"io/ioutil"
 	"log"
 	"os"
+	"strings"
 	"testing"
 )
 
@@ -44,6 +45,18 @@ func CleanupTestRepos(t testing.TB, repos ...Repo) {
 	var firstErr error
 	for _, repo := range repos {
 		path := repo.GetPath()
+		if strings.HasSuffix(path, "/.git") {
+			// for a normal repository (not --bare), we want to remove everything
+			// including the parent directory where files are checked out
+			path = strings.TrimSuffix(path, "/.git")
+
+			// Testing non-bare repo should also check path is
+			// only .git (i.e. ./.git), but doing so, we should
+			// try to remove the current directory and hav some
+			// trouble. In the present case, this case should not
+			// occur.
+			// TODO consider warning or error when path == ".git"
+		}
 		// fmt.Println("Cleaning repo:", path)
 		err := os.RemoveAll(path)
 		if err != nil {