Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions pkg/commands/branches.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,50 @@ func (c *GitCommand) GetBranchUpstreamDifferenceCount(branchName string) (string
return c.GetCommitDifferences(branchName, branchName+"@{u}")
}

// TryGetMainBranch tries to get the main branch
// For old repo's this is usually master and for newer once it is main
// Note that this function might return a branch name that does not exist
func (c *GitCommand) TryGetMainBranch() string {
// Firstly try to get the main branch from the origins
cmdStr := `git branch --remotes --list '*/HEAD' --format '%(symref:short)'`
output, _ := c.OSCommand.RunCommandWithOutput(cmdStr)
lines := strings.Split(strings.TrimSpace(output), "\n")
for _, line := range lines {
parts := strings.SplitN(line, "/", 2)
if len(parts) == 2 {
return parts[len(parts)-1]
}
}

// If we didn't find a main branch from the remotes we check if there is a main or master branch
cmdStr = `git branch --format "%(refname:short)" --list "master" --list "main"`
output, _ = c.OSCommand.RunCommandWithOutput(cmdStr)
lines = append(lines[:0], strings.Split(strings.TrimSpace(output), "\n")...)

// Some repo's use "master" while having a "main" branch
// so we favor "master" over "main"
foundMainBranch := false
for _, line := range lines {
if line == "master" {
return line
}
if line == "main" {
foundMainBranch = true
}
}
if foundMainBranch {
return "main"
}

return "master"
}

func (c *GitCommand) HasDevelopmentBranch() bool {
cmdStr := `git branch --format "%(refname:short)" --list "develop"`
output, _ := c.OSCommand.RunCommandWithOutput(cmdStr)
return strings.TrimSpace(output) == "develop"
}

// GetCommitDifferences checks how many pushables/pullables there are for the
// current branch
func (c *GitCommand) GetCommitDifferences(from, to string) (string, string) {
Expand Down
2 changes: 2 additions & 0 deletions pkg/commands/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ type GitCommand struct {

// Push to current determines whether the user has configured to push to the remote branch of the same name as the current or not
PushToCurrent bool

MainBranch string // Usually "master" or "main"
}

// NewGitCommand it runs git commands
Expand Down
9 changes: 6 additions & 3 deletions pkg/commands/loading_commits.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,13 +312,16 @@ func (c *CommitListBuilder) setCommitMergedStatuses(refName string, commits []*m
}

func (c *CommitListBuilder) getMergeBase(refName string) (string, error) {
if c.GitCommand.MainBranch == "" {
c.GitCommand.MainBranch = c.GitCommand.TryGetMainBranch()
}
baseBranch := c.GitCommand.MainBranch

currentBranch, _, err := c.GitCommand.CurrentBranchName()
if err != nil {
return "", err
}

baseBranch := "master"
if strings.HasPrefix(currentBranch, "feature/") {
if strings.HasPrefix(currentBranch, "feature/") && c.GitCommand.HasDevelopmentBranch() {
baseBranch = "develop"
}

Expand Down
14 changes: 14 additions & 0 deletions pkg/commands/loading_commits_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ func TestCommitListBuilderGetMergeBase(t *testing.T) {
assert.EqualValues(t, "git", cmd)

switch args[0] {
case "branch":
assert.EqualValues(t, []string{"branch", "--remotes", "--list", "*/HEAD", "--format", "%(symref:short)"}, args)
return secureexec.Command("echo", "origin/master")
case "symbolic-ref":
assert.EqualValues(t, []string{"symbolic-ref", "--short", "HEAD"}, args)
return secureexec.Command("echo", "master")
Expand All @@ -58,6 +61,9 @@ func TestCommitListBuilderGetMergeBase(t *testing.T) {
assert.EqualValues(t, "git", cmd)

switch args[0] {
case "branch":
assert.EqualValues(t, []string{"branch", "--remotes", "--list", "*/HEAD", "--format", "%(symref:short)"}, args)
return secureexec.Command("echo", "origin/master")
case "symbolic-ref":
assert.EqualValues(t, []string{"symbolic-ref", "--short", "HEAD"}, args)
return secureexec.Command("echo", "master")
Expand All @@ -78,6 +84,14 @@ func TestCommitListBuilderGetMergeBase(t *testing.T) {
assert.EqualValues(t, "git", cmd)

switch args[0] {
case "branch":
if args[1] == "--format" {
assert.EqualValues(t, []string{"branch", "--format", "%(refname:short)", "--list", "develop"}, args)
return secureexec.Command("echo", "develop")
} else {
assert.EqualValues(t, []string{"branch", "--remotes", "--list", "*/HEAD", "--format", "%(symref:short)"}, args)
return secureexec.Command("echo", "origin/master")
}
case "symbolic-ref":
assert.EqualValues(t, []string{"symbolic-ref", "--short", "HEAD"}, args)
return secureexec.Command("echo", "feature/test")
Expand Down