diff --git a/Makefile b/Makefile index 3534d50..72c6a89 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,8 @@ BUILDTIME = $(shell date +%Y.%m.%d_%H%M) info: install # forge dirty - forge examine + # forge examine + forge clean vet: @GO111MODULE=off go vet diff --git a/argv.go b/argv.go index 5c7c345..0bd593e 100644 --- a/argv.go +++ b/argv.go @@ -22,6 +22,7 @@ type args struct { Rescan *EmptyCmd `arg:"subcommand:rescan" help:"recreate the git protobuf repos.pb file"` Delete *EmptyCmd `arg:"subcommand:delete" help:"untrack a repo"` Commit *EmptyCmd `arg:"subcommand:commit" help:"smart 'git commit' (errors out if on wrong branch)"` + Clean *CleanCmd `arg:"subcommand:clean" help:"clean out all local branches (safely)"` Examine *ExamineCmd `arg:"subcommand:examine" help:"examine branches"` URL string `arg:"--connect" help:"gowebd url"` All bool `arg:"--all" help:"git commit --all"` @@ -42,6 +43,10 @@ type ExamineCmd struct { Submit string `arg:"--submit" help:"name of patchset"` } +type CleanCmd struct { + Force *EmptyCmd `arg:"subcommand:force" help:"dangerously delete things that are not pushed upstream"` +} + type PatchCmd struct { List *EmptyCmd `arg:"subcommand:list" help:"list available patches"` Show *EmptyCmd `arg:"subcommand:show" help:"show a specific patch"` diff --git a/argvAutoshell.go b/argvAutoshell.go index a32c2fd..9b7d818 100644 --- a/argvAutoshell.go +++ b/argvAutoshell.go @@ -23,6 +23,8 @@ func (args) doBashAuto() { case "checkout": usr, _ := user.Current() fmt.Println("user devel master " + usr.Username) + case "clean": + fmt.Println("") case "commit": fmt.Println("--all") case "config": @@ -48,7 +50,7 @@ func (args) doBashAuto() { default: if argv.BashAuto[0] == ARGNAME { // list the subcommands here - fmt.Println("--bash checkout commit config dirty delete examine hard-reset list patch pull rescan") + fmt.Println("--bash checkout clean commit config dirty delete examine hard-reset list patch pull rescan") } } os.Exit(0) diff --git a/doClean.go b/doClean.go new file mode 100644 index 0000000..11e4b7e --- /dev/null +++ b/doClean.go @@ -0,0 +1,35 @@ +package main + +import ( + "fmt" + + "go.wit.com/lib/protobuf/gitpb" + "go.wit.com/log" +) + +func doClean() error { + all := me.forge.Repos.SortByFullPath() + for all.Scan() { + repo := all.Next() + if err := doCleanRepo(repo); err != nil { + badExit(err) + } + } + return nil +} + +func doCleanRepo(repo *gitpb.Repo) error { + log.Info("Cleaning:", repo.GetGoPath()) + if repo.GitConfig == nil { + return fmt.Errorf("GitConfig == nil") + } + + for _, l := range repo.GitConfig.Local { + log.Info("\tlocal branch name:", l.Name) + } + + for name, b := range repo.GitConfig.Branches { + log.Info("\tlocal branch name:", name, b.Merge, b.Remote) + } + return nil +} diff --git a/doExamine.go b/doExamine.go index 20610da..8cac9d8 100644 --- a/doExamine.go +++ b/doExamine.go @@ -78,7 +78,30 @@ func isNormal(repo *gitpb.Repo) bool { func examineBranch(repo *gitpb.Repo) error { if !isLocal(repo) { - repo.RunVerbose([]string{"ls", "-l", ".git/refs/remotes/origin"}) + base := filepath.Base(repo.CurrentTag.Refname) + if base == repo.GetUserBranchName() { + log.Info("The user branch also has a remote branch", repo.CurrentTag.Refname) + log.Info("TODO: verify the remote branch is out of date", repo.CurrentTag.Refname) + log.Info("TODO: delete the remote branch", repo.CurrentTag.Refname) + return nil + } + + if repo.Exists(filepath.Join(".git/refs/heads", base)) { + repo.RunVerbose([]string{"ls", "-l", ".git/refs/remotes/origin"}) + repo.RunVerbose([]string{"cat", filepath.Join(".git/refs/remotes/origin", base)}) + repo.RunVerbose([]string{"cat", filepath.Join(".git/refs/heads", base)}) + log.Info("why is this local branch a problem?", repo.CurrentTag.Refname) + } else { + repo.RunVerbose([]string{"ls", "-l", ".git/refs/remotes/origin"}) + log.Info("why is this non-local branch a problem?", repo.CurrentTag.Refname) + r, err := repo.RunVerbose([]string{"cat", filepath.Join(".git/refs/remotes/origin", base)}) + if err == nil { + cmd := []string{"git", "show", "-s", "--format=\"%H %ae %as %s\"", r.Stdout[0]} + repo.RunVerbose(cmd) + log.Info(cmd) + return nil + } + } return fmt.Errorf("%s repo.CurrentTag is not local: %s. Don't proceed yet", repo.GetGoPath(), repo.CurrentTag.Refname) } dcount, err := showNotMaster(repo) diff --git a/main.go b/main.go index 24213d0..395a318 100644 --- a/main.go +++ b/main.go @@ -117,6 +117,11 @@ func main() { okExit("") } + if argv.Clean != nil { + doClean() + okExit("") + } + if argv.Dirty != nil { doDirty() okExit("")