Skip to content

Commit

Permalink
feat: [MER-1493] show up to date info about branches in stack tree (#96)
Browse files Browse the repository at this point in the history
add the following info about each branch for `av stack tree` (will probably need some UI improvements)
- is it up to date with parent branch
- is it up to date with upstream/remote branch
- if PR link if it exists

<img width="619" alt="Screen Shot 2023-05-01 at 2 12 32 PM" src="https://user-images.githubusercontent.com/13113118/235532267-3ffbcad9-2e67-4f53-a6df-cc38bae4173f.png">
  • Loading branch information
doratzeng authored May 8, 2023
1 parent 3ef3a16 commit e3a26cd
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 2 deletions.
77 changes: 75 additions & 2 deletions cmd/av/stack_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,87 @@ func printStackTree(repo *git.Repo, branches map[string]meta.Branch, currentBran
fmt.Printf("%s<ERROR: unknown branch: %s>\n", indent, root)
return
}

branchInfo, err := getBranchInfo(repo, branch)
if err != nil {
fmt.Printf("<ERROR: cannot get branch info: %v>\n", err)
return
}

if currentBranch == branch.Name {
_, _ = fmt.Print(
indent, colors.Success("* "), colors.Success(branch.Name), "\n",
indent, colors.Success("* "), colors.Success(branch.Name), " ", colors.Faint(branchInfo), "\n",
)
} else {
_, _ = fmt.Printf("%s%s\n", indent, branch.Name)
_, _ = fmt.Print(indent, branch.Name, " ", colors.Faint(branchInfo), "\n")
}
for _, next := range branch.Children {
printStackTree(repo, branches, currentBranch, next, depth+1)
}
}

func getBranchInfo(repo *git.Repo, branch meta.Branch) (string, error) {
var branchInfo string

parentStatus, err := getParentStatus(repo, branch)
if err != nil {
return "", err
}

upstreamStatus, err := getUpstreamStatus(repo, branch)
if err != nil {
return "", err
}

branchStatus := strings.Trim(fmt.Sprintf("%s, %s", parentStatus, upstreamStatus), ", ")
if branchStatus != "" {
branchInfo = fmt.Sprintf("(%s)", branchStatus)
}

if branch.PullRequest != nil && branch.PullRequest.Permalink != "" {
branchInfo = branch.PullRequest.Permalink + " " + branchInfo
}

return branchInfo, nil
}

// Check if branch is up to date with the parent branch.
func getParentStatus(repo *git.Repo, branch meta.Branch) (string, error) {
parentHead, err := repo.RevParse(&git.RevParse{Rev: branch.Parent.Name})
if err != nil {
return "", err
}

mergeBase, err := repo.MergeBase(&git.MergeBase{
Revs: []string{parentHead, branch.Name},
})
if err != nil {
return "", err
}
if mergeBase == parentHead {
return "", nil
}

return "needs sync", nil
}

// Check if branch is up to date with the upstream branch.
// This is doing `git diff <givenBranch> remotes/origin/<givenBranch>`
func getUpstreamStatus(repo *git.Repo, branch meta.Branch) (string, error) {
upstreamExists, err := repo.DoesRemoteBranchExist(branch.Name)
if err != nil || !upstreamExists {
return "not pushed", nil
}

upstreamBranch := fmt.Sprintf("remotes/origin/%s", branch.Name)
upstreamDiff, err := repo.Diff(&git.DiffOpts{Quiet: true, Branch1: branch.Name, Branch2: upstreamBranch})
if err != nil {
return "", err
}

if upstreamDiff.Empty {
return "", nil
}

return "not pushed", nil
}
8 changes: 8 additions & 0 deletions internal/git/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ type DiffOpts struct {
Quiet bool
// If true, shows the colored diff.
Color bool
// Both branches need to be specified in order to find the diff between the two branches.
// If a Commit is specified, the branches will not be used.
Branch1 string
Branch2 string
}

type Diff struct {
Expand All @@ -31,7 +35,11 @@ func (r *Repo) Diff(d *DiffOpts) (*Diff, error) {
}
if d.Commit != "" {
args = append(args, d.Commit)
} else if d.Branch1 != "" && d.Branch2 != "" {
args = append(args, d.Branch1)
args = append(args, d.Branch2)
}

if d.Color {
args = append(args, "--color=always")
}
Expand Down
16 changes: 16 additions & 0 deletions internal/git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package git

import (
"bytes"
"fmt"
"io"
"net/url"
"os"
Expand Down Expand Up @@ -192,6 +193,21 @@ func (r *Repo) HasChangesToBeCommitted() (bool, error) {
return out.ExitCode == 1, nil
}

func (r *Repo) DoesRemoteBranchExist(branch string) (bool, error) {
remoteBranch := fmt.Sprintf("refs/remotes/origin/%s", branch)
out, err := r.Run(&RunOpts{
Args: []string{"show-ref", remoteBranch},
})
if err != nil {
return false, errors.Errorf("remote branch does not exist: %v", err)
}

if len(out.Stdout) > 0 {
return true, nil
}
return false, nil
}

type CheckoutBranch struct {
// The name of the branch to checkout.
Name string
Expand Down

0 comments on commit e3a26cd

Please sign in to comment.