File: status.go

package info (click to toggle)
lazygit 0.50.0%2Bds1-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,808 kB
  • sloc: sh: 128; makefile: 76
file content (94 lines) | stat: -rw-r--r-- 3,277 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package git_commands

import (
	"os"
	"path/filepath"
	"strings"

	"github.com/jesseduffield/lazygit/pkg/commands/models"
)

type StatusCommands struct {
	*GitCommon
}

func NewStatusCommands(
	gitCommon *GitCommon,
) *StatusCommands {
	return &StatusCommands{
		GitCommon: gitCommon,
	}
}

func (self *StatusCommands) WorkingTreeState() models.WorkingTreeState {
	result := models.WorkingTreeState{}
	result.Rebasing, _ = self.IsInRebase()
	result.Merging, _ = self.IsInMergeState()
	result.CherryPicking, _ = self.IsInCherryPick()
	result.Reverting, _ = self.IsInRevert()
	return result
}

func (self *StatusCommands) IsBareRepo() bool {
	return self.repoPaths.isBareRepo
}

func (self *StatusCommands) IsInRebase() (bool, error) {
	exists, err := self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge"))
	if err == nil && exists {
		return true, nil
	}
	return self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-apply"))
}

// IsInMergeState states whether we are still mid-merge
func (self *StatusCommands) IsInMergeState() (bool, error) {
	return self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "MERGE_HEAD"))
}

func (self *StatusCommands) IsInCherryPick() (bool, error) {
	exists, err := self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "CHERRY_PICK_HEAD"))
	if err != nil || !exists {
		return exists, err
	}
	// Sometimes, CHERRY_PICK_HEAD is present during rebases even if no
	// cherry-pick is in progress. I suppose this is because rebase used to be
	// implemented as a series of cherry-picks, so this could be remnants of
	// code that is shared between cherry-pick and rebase, or something. The way
	// to tell if this is the case is to check for the presence of the
	// stopped-sha file, which records the sha of the last pick that was
	// executed before the rebase stopped, and seeing if the sha in that file is
	// the same as the one in CHERRY_PICK_HEAD.
	cherryPickHead, err := os.ReadFile(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "CHERRY_PICK_HEAD"))
	if err != nil {
		return false, err
	}
	stoppedSha, err := os.ReadFile(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge", "stopped-sha"))
	if err != nil {
		// If we get an error we assume the file doesn't exist
		return true, nil
	}
	cherryPickHeadStr := strings.TrimSpace(string(cherryPickHead))
	stoppedShaStr := strings.TrimSpace(string(stoppedSha))
	// Need to use HasPrefix here because the cherry-pick HEAD is a full sha1,
	// but stopped-sha is an abbreviated sha1
	if strings.HasPrefix(cherryPickHeadStr, stoppedShaStr) {
		return false, nil
	}
	return true, nil
}

func (self *StatusCommands) IsInRevert() (bool, error) {
	return self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "REVERT_HEAD"))
}

// Full ref (e.g. "refs/heads/mybranch") of the branch that is currently
// being rebased, or empty string when we're not in a rebase
func (self *StatusCommands) BranchBeingRebased() string {
	for _, dir := range []string{"rebase-merge", "rebase-apply"} {
		if bytesContent, err := os.ReadFile(filepath.Join(self.repoPaths.WorktreeGitDirPath(), dir, "head-name")); err == nil {
			return strings.TrimSpace(string(bytesContent))
		}
	}
	return ""
}