better git checkout

This commit is contained in:
Jeff Carr 2025-01-18 23:25:55 -06:00
parent cbbd43f7b5
commit 39f72d2034
10 changed files with 219 additions and 92 deletions

View File

@ -92,6 +92,7 @@ type FindCmd struct {
Favorites bool `arg:"--favorites" help:"your repos configured as favorites"` Favorites bool `arg:"--favorites" help:"your repos configured as favorites"`
Private bool `arg:"--private" help:"your private repos from your .config/forge/"` Private bool `arg:"--private" help:"your private repos from your .config/forge/"`
Dirty bool `arg:"--dirty" help:"only use dirty git repos"` Dirty bool `arg:"--dirty" help:"only use dirty git repos"`
User bool `arg:"--user" help:"show repos on the user branch"`
// ReadOnly bool `arg:"--readonly" help:"include read-only repos"` // ReadOnly bool `arg:"--readonly" help:"include read-only repos"`
} }

View File

@ -1,41 +1,76 @@
package main package main
import ( import (
"fmt"
"go.wit.com/lib/protobuf/forgepb" "go.wit.com/lib/protobuf/forgepb"
"go.wit.com/lib/protobuf/gitpb" "go.wit.com/lib/protobuf/gitpb"
"go.wit.com/log" "go.wit.com/log"
) )
func IsEverythingOnDevel() bool { var ErrorNotAllReposOnMaster error = fmt.Errorf("not all repos on are on the master branch")
me.found = new(gitpb.Repos) var ErrorNotAllReposOnDevel error = fmt.Errorf("not all repos on are on the devel branch")
all := me.forge.Repos.SortByFullPath() var ErrorNotAllReposOnUser error = fmt.Errorf("not all repos on are on the user branch")
func IsEverythingOnMaster() error {
var total int
var count int
// first make sure every repo is on the master branch
all := me.forge.Repos.All()
for all.Scan() { for all.Scan() {
repo := all.Next() repo := all.Next()
if repo.GetCurrentBranchName() != repo.GetDevelBranchName() { total += 1
// log.Info(repo.GetFullPath(), repo.GetCurrentBranchName(), repo.GetDevelBranchName()) if repo.GetMasterBranchName() == repo.GetCurrentBranchName() {
// add this to the list of "found" repos count += 1
me.found.AppendByGoPath(repo)
} }
} }
if len(me.found.Repos) == 0 { log.Printf("Master branch check. %d total repos. %d repos on the master branch\n", total, count)
return true if total != count {
// log.Info(ErrorNotAllReposOnMaster)
return ErrorNotAllReposOnMaster
} }
return false return nil
} }
func IsEverythingOnUser() bool { func IsEverythingOnDevel() error {
me.found = new(gitpb.Repos) var total int
all := me.forge.Repos.SortByFullPath() var count int
// first make sure every repo is on the master branch
all := me.forge.Repos.All()
for all.Scan() { for all.Scan() {
repo := all.Next() repo := all.Next()
if repo.GetCurrentBranchName() != repo.GetUserBranchName() { total += 1
me.found.AppendByGoPath(repo) if repo.GetDevelBranchName() == repo.GetCurrentBranchName() {
count += 1
} }
} }
if len(me.found.Repos) == 0 { log.Printf("Devel branch check. %d total repos. %d repos on the devel branch\n", total, count)
return true if total != count {
return ErrorNotAllReposOnDevel
} }
return false return nil
}
func IsEverythingOnUser() error {
var total int
var count int
// first make sure every repo is on the master branch
all := me.forge.Repos.All()
for all.Scan() {
repo := all.Next()
total += 1
if repo.GetUserBranchName() == repo.GetUserBranchName() {
count += 1
}
}
log.Printf("User branch check. %d total repos. %d repos on the user branch\n", total, count)
if total != count {
return ErrorNotAllReposOnUser
}
return nil
} }
func doGitReset() { func doGitReset() {
@ -55,6 +90,7 @@ func doGitReset() {
} }
} }
/*
func checkoutBranches(repo *gitpb.Repo) error { func checkoutBranches(repo *gitpb.Repo) error {
dname := repo.GetDevelBranchName() dname := repo.GetDevelBranchName()
if dname == "" { if dname == "" {
@ -73,34 +109,108 @@ func checkoutBranches(repo *gitpb.Repo) error {
} }
return nil return nil
} }
*/
func doAllCheckoutDevel() bool { func doAllCheckoutUser() error {
me.forge.CheckoutDevel()
me.forge = forgepb.Init()
if !IsEverythingOnDevel() {
log.Info("switching to devel branch failed")
me.forge.PrintHumanTable(me.found)
badExit(nil)
return false
}
return true
}
func doAllCheckoutUser() bool {
me.forge.CheckoutUser() me.forge.CheckoutUser()
me.forge = forgepb.Init() // me.forge = forgepb.Init()
if !IsEverythingOnUser() { count := me.forge.RillReload()
log.Info("switching to user branch failed") log.Info("CHECKOUT USER COUNT", count)
me.forge.PrintHumanTable(me.found) if count != 0 {
return false me.forge.ConfigSave()
} }
return true if err := IsEverythingOnUser(); err != nil {
return err
}
return nil
} }
func doCheckoutMaster() { func doAllCheckoutDevel() error {
me.forge.CheckoutMaster() me.forge.CheckoutDevel()
// me.forge = forgepb.Init()
count := me.forge.RillReload()
log.Info("CHECKOUT DEVEL COUNT", count)
if count != 0 {
me.forge.ConfigSave()
}
if err := IsEverythingOnDevel(); err != nil {
return err
}
return nil
}
func rillCheckoutMaster(repo *gitpb.Repo) error {
if repo.GetUserVersion() != repo.GetDevelVersion() {
// don't switch braches if the user branch has uncommitted patches
return nil
}
if repo.GetCurrentBranchName() == repo.GetMasterBranchName() {
// repo is already on master
return nil
}
repo.CheckoutMaster()
return nil
}
// trys to figure out if there is still something to update
// todo: redo this logic as it is terrible
func doAllCheckoutMaster() error {
me.forge.RillFuncError(rillCheckoutMaster)
count := me.forge.RillReload()
log.Info("CHECKOUT MASTER COUNT", count)
if count != 0 {
me.forge.ConfigSave()
}
if err := IsEverythingOnMaster(); err != nil {
// display all repos not on master
me.found = new(gitpb.Repos)
all := me.forge.Repos.SortByFullPath()
for all.Scan() {
repo := all.Next()
if repo.GetCurrentBranchName() != repo.GetMasterBranchName() {
me.found.AppendByGoPath(repo)
}
}
me.forge.PrintHumanTable(me.found)
log.Printf("There are %d repos that are NOT on the master branch\n", me.found.Len())
return err
}
return nil
}
// trys to figure out if there is still something to update
// todo: redo this logic as it is terrible
func doCheckout() error {
if argv.Checkout.User != nil {
if argv.Force {
me.forge.CheckoutUserForce()
} else {
me.forge.CheckoutUser()
}
me.forge = forgepb.Init() me.forge = forgepb.Init()
me.found = new(gitpb.Repos) me.found = new(gitpb.Repos)
argv.Checkout.Master.findRepos() argv.Checkout.User.findRepos()
me.forge.PrintHumanTable(me.found) me.forge.PrintHumanTable(me.found)
if err := IsEverythingOnUser(); err != nil {
badExit(err)
}
okExit("")
}
if argv.Checkout.Devel != nil {
me.forge.CheckoutDevel()
me.forge = forgepb.Init()
me.found = new(gitpb.Repos)
argv.Checkout.Devel.findRepos()
me.forge.PrintHumanTable(me.found)
okExit("")
}
if argv.Checkout.Master != nil {
doAllCheckoutMaster()
}
return nil
} }

View File

@ -7,18 +7,31 @@ import (
"go.wit.com/log" "go.wit.com/log"
) )
var ErrorReposHasLocalBranches error = fmt.Errorf("repo still has local branches")
func doClean() error { func doClean() error {
if err := IsEverythingOnMaster(); err != nil {
log.Info("Not all repos are on the master branch")
// return err
}
all := me.forge.Repos.SortByFullPath() all := me.forge.Repos.SortByFullPath()
for all.Scan() { for all.Scan() {
repo := all.Next() repo := all.Next()
if repo.GetCurrentBranchName() != repo.GetMasterBranchName() {
continue
}
if err := doCleanRepo(repo); err != nil { if err := doCleanRepo(repo); err != nil {
badExit(err) badRepoExit(repo, err)
} }
} }
log.Info("All repos on the master branch are clean")
return nil return nil
} }
// removes all local branches
func doCleanRepo(repo *gitpb.Repo) error { func doCleanRepo(repo *gitpb.Repo) error {
var hasLocal bool
log.Info("Cleaning:", repo.GetGoPath()) log.Info("Cleaning:", repo.GetGoPath())
if repo.GitConfig == nil { if repo.GitConfig == nil {
return fmt.Errorf("GitConfig == nil") return fmt.Errorf("GitConfig == nil")
@ -30,6 +43,17 @@ func doCleanRepo(repo *gitpb.Repo) error {
for name, b := range repo.GitConfig.Branches { for name, b := range repo.GitConfig.Branches {
log.Info("\tlocal branch name:", name, b.Merge, b.Remote) log.Info("\tlocal branch name:", name, b.Merge, b.Remote)
if name == repo.GetMasterBranchName() {
continue
}
hasLocal = true
}
if hasLocal {
return ErrorReposHasLocalBranches
} }
return nil return nil
} }
func verifyLocalBranchIsMerged(repo *gitpb.Repo, branch *gitpb.GitBranch) error {
return nil
}

View File

@ -49,7 +49,7 @@ func doCheckDirtyAndConfigSave() {
*/ */
// this might work? // this might work?
now := time.Now() now := time.Now()
me.forge.RillFuncError(20, 10, doCheckDirty) me.forge.RillFuncError(doCheckDirty)
end := straightCheckDirty() end := straightCheckDirty()
log.Printf("dirty check (%d dirty repos) (%d total repos) took:%s\n", end, me.found.Len(), shell.FormatDuration(time.Since(now))) log.Printf("dirty check (%d dirty repos) (%d total repos) took:%s\n", end, me.found.Len(), shell.FormatDuration(time.Since(now)))

View File

@ -12,7 +12,7 @@ import (
"go.wit.com/log" "go.wit.com/log"
) )
func doExamine() bool { func doExamine() error {
me.found = new(gitpb.Repos) me.found = new(gitpb.Repos)
all := me.forge.Repos.SortByFullPath() all := me.forge.Repos.SortByFullPath()
for all.Scan() { for all.Scan() {
@ -28,7 +28,7 @@ func doExamine() bool {
} }
} }
if len(me.found.Repos) == 0 { if len(me.found.Repos) == 0 {
return true return nil
} }
// slices.Reverse(me.found.Repos) // slices.Reverse(me.found.Repos)
slices.SortFunc(me.found.Repos, func(a, b *gitpb.Repo) int { slices.SortFunc(me.found.Repos, func(a, b *gitpb.Repo) int {
@ -63,7 +63,7 @@ func doExamine() bool {
me.found.AppendByGoPath(repo) me.found.AppendByGoPath(repo)
} }
me.forge.PrintHumanTableDirty(me.found) me.forge.PrintHumanTableDirty(me.found)
return false return nil
} }
func isNormal(repo *gitpb.Repo) bool { func isNormal(repo *gitpb.Repo) bool {

View File

@ -3,6 +3,7 @@ package main
import ( import (
"os" "os"
"go.wit.com/lib/protobuf/gitpb"
"go.wit.com/log" "go.wit.com/log"
) )
@ -21,3 +22,8 @@ func badExit(err error) {
log.Info("forge failed: ", err, me.forge.GetGoSrc()) log.Info("forge failed: ", err, me.forge.GetGoSrc())
os.Exit(-1) os.Exit(-1)
} }
func badRepoExit(repo *gitpb.Repo, err error) {
log.Printf("forge failed on %s with %v", repo.GetGoPath(), err)
os.Exit(-1)
}

15
find.go
View File

@ -42,6 +42,11 @@ func (f *FindCmd) findRepos() {
return return
} }
if f.User {
findUser()
return
}
findAll() findAll()
} }
@ -98,3 +103,13 @@ func findAll() {
me.found.AppendByGoPath(repo) me.found.AppendByGoPath(repo)
} }
} }
func findUser() {
all := me.forge.Repos.SortByFullPath()
for all.Scan() {
repo := all.Next()
if repo.GetCurrentBranchName() == repo.GetUserBranchName() {
me.found.AppendByGoPath(repo)
}
}
}

35
main.go
View File

@ -88,37 +88,16 @@ func main() {
} }
if argv.Checkout != nil { if argv.Checkout != nil {
if argv.Checkout.User != nil { if err := doCheckout(); err != nil {
if argv.Force { badExit(err)
me.forge.CheckoutUserForce()
} else {
me.forge.CheckoutUser()
} }
me.forge = forgepb.Init()
me.found = new(gitpb.Repos)
argv.Checkout.User.findRepos()
me.forge.PrintHumanTable(me.found)
okExit("")
}
if argv.Checkout.Devel != nil {
me.forge.CheckoutDevel()
me.forge = forgepb.Init()
me.found = new(gitpb.Repos)
argv.Checkout.Devel.findRepos()
me.forge.PrintHumanTable(me.found)
okExit("")
}
if argv.Checkout.Master != nil {
doCheckoutMaster()
}
log.Info("make 'user' the default here?")
okExit("") okExit("")
} }
if argv.Clean != nil { if argv.Clean != nil {
doClean() if err := doClean(); err != nil {
badExit(err)
}
okExit("") okExit("")
} }
@ -128,7 +107,9 @@ func main() {
} }
if argv.Examine != nil { if argv.Examine != nil {
doExamine() if err := doExamine(); err != nil {
badExit(err)
}
okExit("") okExit("")
} }

View File

@ -85,31 +85,21 @@ func globalBuildOptions(vbox *gui.Node) {
targetName := me.newBranch.String() targetName := me.newBranch.String()
log.Warn("setting all branches to", targetName) log.Warn("setting all branches to", targetName)
if targetName == "devel" { if targetName == "devel" {
if !doAllCheckoutDevel() { if err := doAllCheckoutDevel(); err != nil {
okExit("") log.Info("switching to devel branches failed")
} }
return return
} }
if targetName == "master" { if targetName == "master" {
log.Info("Don't know how to set", targetName, "yet") if err := doAllCheckoutMaster(); err != nil {
log.Info("switching to master branches failed")
}
return return
} }
// just assume user // just assume user
if targetName == "jcarr" { if err := doAllCheckoutUser(); err != nil {
if doAllCheckoutUser() {
return
}
log.Info("switching to user branches failed") log.Info("switching to user branches failed")
return
} }
/*
loop := me.repos.View.ReposSortByName()
for loop.Scan() {
repo := loop.Repo()
repo.Status.CheckoutBranch(targetName)
repo.Scan()
}
*/
}) })
me.newBranch = grid.NewCombobox() me.newBranch = grid.NewCombobox()
me.newBranch.AddText("master") me.newBranch.AddText("master")

View File

@ -104,7 +104,7 @@ func submitPatchesBox(box *gui.Node) *patchSummary {
if err != nil { if err != nil {
return return
} }
if !IsEverythingOnDevel() { if err := IsEverythingOnDevel(); err != nil {
log.Info("You can only apply patches to the devel branch") log.Info("You can only apply patches to the devel branch")
return return
} }