diff --git a/segment_git.go b/segment_git.go index 5d75b356..e4dbcea8 100755 --- a/segment_git.go +++ b/segment_git.go @@ -16,6 +16,7 @@ type gitRepo struct { HEAD string upstream string stashCount string + root string } type gitStatus struct { @@ -105,7 +106,7 @@ func (g *git) enabled() bool { } func (g *git) string() string { - g.getGitStatus() + g.setGitStatus() buffer := new(bytes.Buffer) // branchName if g.repo.upstream != "" && g.props.getBool(DisplayUpstreamIcon, false) { @@ -163,8 +164,9 @@ func (g *git) getUpstreamSymbol() string { return g.props.getString(GitIcon, "GIT") } -func (g *git) getGitStatus() { +func (g *git) setGitStatus() { g.repo = &gitRepo{} + g.repo.root = g.getGitCommandOutput("rev-parse", "--show-toplevel") output := g.getGitCommandOutput("status", "--porcelain", "-b", "--ignore-submodules") splittedOutput := strings.Split(output, "\n") g.repo.working = g.parseGitStats(splittedOutput, true) @@ -192,7 +194,7 @@ func (g *git) getGitHEADContext(ref string) string { ref = fmt.Sprintf("%s%s", branchIcon, ref) } // rebase - if g.env.hasFolder(".git/rebase-merge") { + if g.hasGitFolder("rebase-merge") { origin := g.getGitRefFileSymbolicName("rebase-merge/orig-head") onto := g.getGitRefFileSymbolicName("rebase-merge/onto") step := g.getGitFileContents("rebase-merge/msgnum") @@ -200,7 +202,7 @@ func (g *git) getGitHEADContext(ref string) string { icon := g.props.getString(RebaseIcon, "REBASE:") return fmt.Sprintf("%s%s%s onto %s%s (%s/%s) at %s", icon, branchIcon, origin, branchIcon, onto, step, total, ref) } - if g.env.hasFolder(".git/rebase-apply") { + if g.hasGitFolder("rebase-apply") { head := g.getGitFileContents("rebase-apply/head-name") origin := strings.Replace(head, "refs/heads/", "", 1) step := g.getGitFileContents("rebase-apply/next") @@ -209,13 +211,13 @@ func (g *git) getGitHEADContext(ref string) string { return fmt.Sprintf("%s%s%s (%s/%s) at %s", icon, branchIcon, origin, step, total, ref) } // merge - if g.env.hasFiles(".git/MERGE_HEAD") { + if g.hasGitFile("MERGE_HEAD") { mergeHEAD := g.getGitRefFileSymbolicName("MERGE_HEAD") icon := g.props.getString(MergeIcon, "MERGING:") return fmt.Sprintf("%s%s%s into %s", icon, branchIcon, mergeHEAD, ref) } // cherry-pick - if g.env.hasFiles(".git/CHERRY_PICK_HEAD") { + if g.hasGitFile("CHERRY_PICK_HEAD") { sha := g.getGitRefFileSymbolicName("CHERRY_PICK_HEAD") icon := g.props.getString(CherryPickIcon, "CHERRY PICK:") return fmt.Sprintf("%s%s onto %s", icon, sha, ref) @@ -223,6 +225,26 @@ func (g *git) getGitHEADContext(ref string) string { return ref } +func (g *git) hasGitFile(file string) bool { + files := fmt.Sprintf("%s/.git/%s", g.repo.root, file) + return g.env.hasFiles(files) +} + +func (g *git) hasGitFolder(folder string) bool { + path := fmt.Sprintf("%s/.git/%s", g.repo.root, folder) + return g.env.hasFolder(path) +} + +func (g *git) getGitFileContents(file string) string { + content := g.env.getFileContent(fmt.Sprintf("%s/.git/%s", g.repo.root, file)) + return strings.Trim(content, " \r\n") +} + +func (g *git) getGitRefFileSymbolicName(refFile string) string { + ref := g.getGitFileContents(refFile) + return g.getGitCommandOutput("name-rev", "--name-only", "--exclude=tags/*", ref) +} + func (g *git) getPrettyHEADName() string { // check for tag ref := g.getGitCommandOutput("describe", "--tags", "--exact-match") @@ -234,16 +256,6 @@ func (g *git) getPrettyHEADName() string { return fmt.Sprintf("%s%s", g.props.getString(CommitIcon, "COMMIT:"), ref) } -func (g *git) getGitFileContents(file string) string { - content := g.env.getFileContent(fmt.Sprintf(".git/%s", file)) - return strings.Trim(content, " \r\n") -} - -func (g *git) getGitRefFileSymbolicName(refFile string) string { - ref := g.getGitFileContents(refFile) - return g.getGitCommandOutput("name-rev", "--name-only", "--exclude=tags/*", ref) -} - func (g *git) parseGitStats(output []string, working bool) *gitStatus { status := gitStatus{} if len(output) <= 1 { diff --git a/segment_git_test.go b/segment_git_test.go index 40709131..cc60dda8 100755 --- a/segment_git_test.go +++ b/segment_git_test.go @@ -55,28 +55,34 @@ type detachedContext struct { mergeHEAD string } -func setupHEADContextEnv(context *detachedContext) environmentInfo { +func setupHEADContextEnv(context *detachedContext) *git { env := new(MockedEnvironment) - env.On("hasFolder", ".git/rebase-merge").Return(context.rebaseMerge) - env.On("hasFolder", ".git/rebase-apply").Return(context.rebaseApply) - env.On("getFileContent", ".git/rebase-merge/orig-head").Return(context.origin) - env.On("getFileContent", ".git/rebase-merge/onto").Return(context.onto) - env.On("getFileContent", ".git/rebase-merge/msgnum").Return(context.step) - env.On("getFileContent", ".git/rebase-apply/next").Return(context.step) - env.On("getFileContent", ".git/rebase-merge/end").Return(context.total) - env.On("getFileContent", ".git/rebase-apply/last").Return(context.total) - env.On("getFileContent", ".git/rebase-apply/head-name").Return(context.origin) - env.On("getFileContent", ".git/CHERRY_PICK_HEAD").Return(context.cherryPickSHA) - env.On("getFileContent", ".git/MERGE_HEAD").Return(context.mergeHEAD) - env.On("hasFiles", ".git/CHERRY_PICK_HEAD").Return(context.cherryPick) - env.On("hasFiles", ".git/MERGE_HEAD").Return(context.merge) + env.On("hasFolder", "/.git/rebase-merge").Return(context.rebaseMerge) + env.On("hasFolder", "/.git/rebase-apply").Return(context.rebaseApply) + env.On("getFileContent", "/.git/rebase-merge/orig-head").Return(context.origin) + env.On("getFileContent", "/.git/rebase-merge/onto").Return(context.onto) + env.On("getFileContent", "/.git/rebase-merge/msgnum").Return(context.step) + env.On("getFileContent", "/.git/rebase-apply/next").Return(context.step) + env.On("getFileContent", "/.git/rebase-merge/end").Return(context.total) + env.On("getFileContent", "/.git/rebase-apply/last").Return(context.total) + env.On("getFileContent", "/.git/rebase-apply/head-name").Return(context.origin) + env.On("getFileContent", "/.git/CHERRY_PICK_HEAD").Return(context.cherryPickSHA) + env.On("getFileContent", "/.git/MERGE_HEAD").Return(context.mergeHEAD) + env.On("hasFiles", "/.git/CHERRY_PICK_HEAD").Return(context.cherryPick) + env.On("hasFiles", "/.git/MERGE_HEAD").Return(context.merge) env.On("runCommand", "git", []string{"-c", "core.quotepath=false", "-c", "color.status=false", "rev-parse", "--short", "HEAD"}).Return(context.currentCommit) env.On("runCommand", "git", []string{"-c", "core.quotepath=false", "-c", "color.status=false", "describe", "--tags", "--exact-match"}).Return(context.tagName) env.On("runCommand", "git", []string{"-c", "core.quotepath=false", "-c", "color.status=false", "name-rev", "--name-only", "--exclude=tags/*", context.origin}).Return(context.origin) env.On("runCommand", "git", []string{"-c", "core.quotepath=false", "-c", "color.status=false", "name-rev", "--name-only", "--exclude=tags/*", context.onto}).Return(context.onto) env.On("runCommand", "git", []string{"-c", "core.quotepath=false", "-c", "color.status=false", "name-rev", "--name-only", "--exclude=tags/*", context.cherryPickSHA}).Return(context.cherryPickSHA) env.On("runCommand", "git", []string{"-c", "core.quotepath=false", "-c", "color.status=false", "name-rev", "--name-only", "--exclude=tags/*", context.mergeHEAD}).Return(context.mergeHEAD) - return env + g := &git{ + env: env, + repo: &gitRepo{ + root: "", + }, + } + return g } func TestGetGitDetachedCommitHash(t *testing.T) { @@ -84,10 +90,7 @@ func TestGetGitDetachedCommitHash(t *testing.T) { context := &detachedContext{ currentCommit: "lalasha1", } - env := setupHEADContextEnv(context) - g := &git{ - env: env, - } + g := setupHEADContextEnv(context) got := g.getGitHEADContext("") assert.Equal(t, want, got) } @@ -98,10 +101,7 @@ func TestGetGitHEADContextTagName(t *testing.T) { currentCommit: "whatever", tagName: "lalasha1", } - env := setupHEADContextEnv(context) - g := &git{ - env: env, - } + g := setupHEADContextEnv(context) got := g.getGitHEADContext("") assert.Equal(t, want, got) } @@ -117,10 +117,7 @@ func TestGetGitHEADContextRebaseMerge(t *testing.T) { step: "2", total: "3", } - env := setupHEADContextEnv(context) - g := &git{ - env: env, - } + g := setupHEADContextEnv(context) got := g.getGitHEADContext("") assert.Equal(t, want, got) } @@ -135,10 +132,7 @@ func TestGetGitHEADContextRebaseApply(t *testing.T) { step: "2", total: "3", } - env := setupHEADContextEnv(context) - g := &git{ - env: env, - } + g := setupHEADContextEnv(context) got := g.getGitHEADContext("") assert.Equal(t, want, got) } @@ -149,10 +143,7 @@ func TestGetGitHEADContextRebaseUnknown(t *testing.T) { currentCommit: "whatever", rebase: "true", } - env := setupHEADContextEnv(context) - g := &git{ - env: env, - } + g := setupHEADContextEnv(context) got := g.getGitHEADContext("") assert.Equal(t, want, got) } @@ -165,10 +156,7 @@ func TestGetGitHEADContextCherryPickOnBranch(t *testing.T) { cherryPick: true, cherryPickSHA: "pickme", } - env := setupHEADContextEnv(context) - g := &git{ - env: env, - } + g := setupHEADContextEnv(context) got := g.getGitHEADContext("main") assert.Equal(t, want, got) } @@ -181,10 +169,7 @@ func TestGetGitHEADContextCherryPickOnTag(t *testing.T) { cherryPick: true, cherryPickSHA: "pickme", } - env := setupHEADContextEnv(context) - g := &git{ - env: env, - } + g := setupHEADContextEnv(context) got := g.getGitHEADContext("") assert.Equal(t, want, got) } @@ -195,10 +180,7 @@ func TestGetGitHEADContextMerge(t *testing.T) { merge: true, mergeHEAD: "feat", } - env := setupHEADContextEnv(context) - g := &git{ - env: env, - } + g := setupHEADContextEnv(context) got := g.getGitHEADContext("main") assert.Equal(t, want, got) } @@ -210,10 +192,7 @@ func TestGetGitHEADContextMergeTag(t *testing.T) { merge: true, mergeHEAD: "feat", } - env := setupHEADContextEnv(context) - g := &git{ - env: env, - } + g := setupHEADContextEnv(context) got := g.getGitHEADContext("") assert.Equal(t, want, got) }