aboutsummaryrefslogtreecommitdiff
path: root/pkg/prompt
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/prompt')
-rw-r--r--pkg/prompt/git.go58
-rw-r--r--pkg/prompt/main.go2
-rw-r--r--pkg/prompt/pwd.go10
3 files changed, 53 insertions, 17 deletions
diff --git a/pkg/prompt/git.go b/pkg/prompt/git.go
index 054df36..144beb5 100644
--- a/pkg/prompt/git.go
+++ b/pkg/prompt/git.go
@@ -19,30 +19,64 @@
package prompt
import (
+ "fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
)
-//Returns empty string if `path` is not inside a Git repo.
-func findRepoRootPath(path string) string {
- _, err := os.Stat(filepath.Join(path, ".git"))
- if err == nil {
- return path
+type gitRepo struct {
+ RootPath string
+ GitDir string
+}
+
+//Returns two empty strings if `path` is not inside a Git repo.
+func findRepo(path string) (*gitRepo, error) {
+ //find .git directory or file
+ gitEntry := filepath.Join(path, ".git")
+ fi, err := os.Stat(gitEntry)
+ switch {
+ case err == nil:
+ //found - continue below with further checks
+ case !os.IsNotExist(err):
+ return nil, err
+ case path == "/":
+ return nil, nil
+ default:
+ return findRepo(filepath.Dir(path))
}
- if path == "/" {
- return ""
+
+ //found .git - what is it?
+ if fi.Mode().IsDir() {
+ //normal case - .git is a directory
+ return &gitRepo{RootPath: path, GitDir: gitEntry}, nil
+ }
+
+ //.git is a file (e.g. for submodules) - it contains a line like "gitdir: path/to/gitdir"
+ bytes, err := ioutil.ReadFile(gitEntry)
+ if err != nil {
+ return nil, err
}
- return findRepoRootPath(filepath.Dir(path))
+ for _, line := range strings.Split(string(bytes), "\n") {
+ line = strings.TrimSpace(line)
+ if strings.HasPrefix(line, "gitdir:") {
+ return &gitRepo{
+ RootPath: path,
+ GitDir: filepath.Join(path, strings.TrimSpace(strings.TrimPrefix(line, "gitdir:"))),
+ }, nil
+ }
+ }
+
+ return nil, fmt.Errorf("read %s: missing gitdir directive", gitEntry)
}
-func getRepoStatusField(repoRootPath string) string {
- if repoRootPath == "" {
+func getRepoStatusField(repo *gitRepo) string {
+ if repo == nil {
return ""
}
- bytes, err := ioutil.ReadFile(filepath.Join(repoRootPath, ".git/HEAD"))
+ bytes, err := ioutil.ReadFile(filepath.Join(repo.GitDir, "HEAD"))
if err != nil {
handleError(err)
return withType("git", withColor("1;41", "unknown"))
@@ -60,7 +94,7 @@ func getRepoStatusField(repoRootPath string) string {
refSpecDisplay = strings.TrimPrefix(refSpecDisplay, "heads/")
//read file corresponding to refspec to find commit
- bytes, err = ioutil.ReadFile(filepath.Join(repoRootPath, ".git", refSpec))
+ bytes, err = ioutil.ReadFile(filepath.Join(repo.GitDir, refSpec))
commitID := strings.TrimSpace(string(bytes))
if err != nil {
if os.IsNotExist(err) {
diff --git a/pkg/prompt/main.go b/pkg/prompt/main.go
index 1dcbbc7..1fc60d9 100644
--- a/pkg/prompt/main.go
+++ b/pkg/prompt/main.go
@@ -37,7 +37,7 @@ func Exec(args []string) int {
cwd := CurrentDirectory()
fields = appendUnlessEmpty(fields, getDirectoryField(cwd))
fields = appendUnlessEmpty(fields, getDeletedMessageField(cwd))
- fields = appendUnlessEmpty(fields, getRepoStatusField(cwd.RepoRootPath))
+ fields = appendUnlessEmpty(fields, getRepoStatusField(cwd.Repo))
fields = appendUnlessEmpty(fields, getTerminalField())
fields = appendUnlessEmpty(fields, getOpenstackField())
fields = appendUnlessEmpty(fields, getKubernetesField())
diff --git a/pkg/prompt/pwd.go b/pkg/prompt/pwd.go
index 969a8ce..1b93987 100644
--- a/pkg/prompt/pwd.go
+++ b/pkg/prompt/pwd.go
@@ -30,7 +30,7 @@ type Directory struct {
DisplayPath string
InBuildTree bool
InRepoTree bool
- RepoRootPath string
+ Repo *gitRepo
NearestAccessiblePath string
}
@@ -78,7 +78,9 @@ func NewDirectory(path string) (dir Directory) {
dir.stripHomeDirFromDisplay()
//check if we are inside a Git repository
- dir.RepoRootPath = findRepoRootPath(dir.Path)
+ var err error
+ dir.Repo, err = findRepo(dir.Path)
+ handleError(err)
}
return
@@ -124,8 +126,8 @@ func getDirectoryField(dir Directory) string {
txt := withColor("1;36", dir.DisplayPath)
if dir.NearestAccessiblePath == "" {
//cwd accessible -> highlight path elements inside the repo (if any)
- if dir.RepoRootPath != "" && dir.RepoRootPath != dir.Path {
- rel, _ := filepath.Rel(dir.RepoRootPath, dir.Path)
+ if dir.Repo != nil && dir.Repo.RootPath != dir.Path {
+ rel, _ := filepath.Rel(dir.Repo.RootPath, dir.Path)
if strings.HasSuffix(dir.DisplayPath, rel) {
base := strings.TrimSuffix(dir.DisplayPath, rel)
txt = withColor("0;36", base) + withColor("1;36", rel)