218 lines
5.4 KiB
Go
218 lines
5.4 KiB
Go
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
|
// Use of this source code is governed by the GPL 3.0
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
|
|
"go.wit.com/lib/protobuf/gitpb"
|
|
"go.wit.com/log"
|
|
)
|
|
|
|
var ErrorReposHasLocalBranches error = fmt.Errorf("repo still has local branches")
|
|
var ErrorMergeBranch error = fmt.Errorf("trunk has things not in the branch")
|
|
var ErrorMergeTrunk error = fmt.Errorf("branch has things not in trunk")
|
|
|
|
func doClean() error {
|
|
if argv.Clean.Pub != nil {
|
|
if err := doCleanPub(); err != nil {
|
|
badExit(err)
|
|
}
|
|
log.Info("finished attempt at cleaning devel branches")
|
|
return nil
|
|
}
|
|
if argv.Clean.Devel != nil {
|
|
if err := doCleanDevel(); err != nil {
|
|
badExit(err)
|
|
}
|
|
log.Info("finished attempt at cleaning devel branches")
|
|
return nil
|
|
}
|
|
if argv.Clean.User != nil {
|
|
if err := doCleanUser(); err != nil {
|
|
log.Info(err)
|
|
okExit("")
|
|
}
|
|
return nil
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func doCleanUser() error {
|
|
if _, count, _, err := IsEverythingOnMaster(); err != nil {
|
|
if count == 0 {
|
|
log.Info("No repos are on the master branch")
|
|
return nil
|
|
}
|
|
log.Info("Not all repos are on the master branch")
|
|
// return err
|
|
}
|
|
|
|
var anyerr error
|
|
|
|
all := me.forge.Repos.SortByFullPath()
|
|
for all.Scan() {
|
|
repo := all.Next()
|
|
if err := doCleanUserRepo(repo); err != nil {
|
|
log.Info(repo.GetGoPath(), err)
|
|
anyerr = err
|
|
}
|
|
}
|
|
return anyerr
|
|
}
|
|
|
|
/*
|
|
func doesLocalBranchExist(repo *gitpb.Repo, branch string) bool {
|
|
return repo.Exists(filepath.Join(".git/refs/heads", branch))
|
|
}
|
|
*/
|
|
|
|
func doCleanDevel() error {
|
|
var total int
|
|
var count int
|
|
all := me.forge.Repos.SortByFullPath()
|
|
for all.Scan() {
|
|
repo := all.Next()
|
|
total += 1
|
|
// devel := repo.GetDevelBranchName()
|
|
if repo.GetDevelVersion() == "derr" {
|
|
// already deleted
|
|
return nil
|
|
}
|
|
/*
|
|
if !doesLocalBranchExist(repo, devel) {
|
|
if argv.Verbose {
|
|
log.Info("local branch was already deleted:", repo.GetGoPath())
|
|
}
|
|
continue
|
|
}
|
|
*/
|
|
if repo.GetCurrentBranchName() != repo.GetMasterBranchName() {
|
|
log.Info("Repo not on master branch:", repo.GetGoPath())
|
|
continue
|
|
}
|
|
if repo.IsDirty() {
|
|
log.Info("Repo is dirty:", repo.GetGoPath())
|
|
continue
|
|
}
|
|
count += 1
|
|
if err := justDeleteTheDevelBranchAlready(repo); err != nil {
|
|
log.Info("justDeleteTheDevel() err", repo.GetGoPath(), err)
|
|
}
|
|
}
|
|
log.Info("")
|
|
log.Printf("attempted cleaning %d devel branches of %d total branches\n", count, total)
|
|
return nil
|
|
}
|
|
|
|
/*
|
|
func checkhashes(repo *gitpb.Repo, hashes []string, refpath string) ([]string, error) {
|
|
if !repo.Exists(refpath) {
|
|
return hashes, nil
|
|
}
|
|
r, err := repo.RunStrict([]string{"cat", refpath})
|
|
if err != nil {
|
|
return hashes, err
|
|
}
|
|
newhash := r.Stdout[0]
|
|
for _, hash := range hashes {
|
|
if newhash != hash {
|
|
return hashes, fmt.Errorf("%s hash broke %s %s", repo.GetGoPath(), newhash, hash)
|
|
}
|
|
}
|
|
hashes = append(hashes, newhash)
|
|
return hashes, nil
|
|
}
|
|
*/
|
|
|
|
// removes all local branches
|
|
func doCleanUserRepo(repo *gitpb.Repo) error {
|
|
if repo.IsDirty() {
|
|
return nil
|
|
}
|
|
|
|
bruser := repo.GetUserBranchName()
|
|
brdevel := repo.GetDevelBranchName()
|
|
|
|
if repo.GetUserVersion() == "uerr" {
|
|
// already deleted
|
|
return nil
|
|
}
|
|
log.Info("trying", bruser, repo.GetUserVersion())
|
|
|
|
if repo.IsBranchRemote(bruser) {
|
|
log.Info("forge is designed to always have local only user branches", bruser)
|
|
return fmt.Errorf("forge is designed to always have local only user branches")
|
|
}
|
|
|
|
b1 := repo.CountDiffObjects(bruser, brdevel) // should be zero
|
|
if b1 == 0 {
|
|
cmd := []string{"git", "branch", "-D", bruser}
|
|
log.Info("USER IS IN DEVEL", repo.GetGoPath(), cmd)
|
|
err := repo.RunVerbose(cmd)
|
|
return err
|
|
}
|
|
|
|
return fmt.Errorf("%s branch has things not in %s count=%d", bruser, brdevel, b1)
|
|
}
|
|
|
|
func doCleanPub() error {
|
|
total := 0
|
|
all := me.forge.Repos.SortByFullPath()
|
|
for all.Scan() {
|
|
repo := all.Next()
|
|
if repo.GetTargetVersion() != "" {
|
|
repo.SetTargetVersion("")
|
|
configSave = true
|
|
total += 1
|
|
}
|
|
}
|
|
log.Printf("clearing %d total repos\n", total)
|
|
return nil
|
|
}
|
|
|
|
// if you call this, there is no going back. no checks anymore. nothing
|
|
// it deletes the 'devel' branch. git branch -D "devel". END OF STORY
|
|
func justDeleteTheDevelBranchAlready(repo *gitpb.Repo) error {
|
|
branch := repo.GetDevelBranchName()
|
|
remote := filepath.Join("origin", branch)
|
|
|
|
if me.forge.Config.IsReadOnly(repo.GetGoPath()) {
|
|
if repo.IsDevelRemote() {
|
|
// just make sure the remote & local branches are the same
|
|
return repo.DeleteLocalDevelBranch()
|
|
}
|
|
}
|
|
|
|
// check against remote if it exists
|
|
if repo.IsDevelRemote() {
|
|
b1 := repo.CountDiffObjects(branch, remote) // should be zero
|
|
if b1 == 0 {
|
|
cmd := []string{"git", "branch", "-D", repo.GetDevelBranchName()}
|
|
log.Info("DEVEL IS IN REMOTE", repo.GetGoPath(), cmd)
|
|
err := repo.RunVerbose(cmd)
|
|
return err
|
|
}
|
|
cmd := []string{"git", "push"}
|
|
log.Info("DEVEL LOCAL NEEDS GIT PUSH TO REMOTE", repo.GetGoPath(), cmd)
|
|
err := repo.RunVerbose(cmd)
|
|
return err
|
|
}
|
|
|
|
// remote doesn't exist, check against master
|
|
master := repo.GetMasterBranchName()
|
|
b1 := repo.CountDiffObjects(branch, master) // should be zero
|
|
if b1 == 0 {
|
|
cmd := []string{"git", "branch", "-D", repo.GetDevelBranchName()}
|
|
log.Info("DEVEL IS IN REMOTE", repo.GetGoPath(), cmd)
|
|
err := repo.RunVerbose(cmd)
|
|
return err
|
|
}
|
|
cmd := []string{"git", "merge something somehow"}
|
|
log.Info("DEVEL LOCAL NEEDS GIT MERGE TO MASTER", repo.GetGoPath(), cmd, b1)
|
|
// _, err := repo.RunVerbose(cmd)
|
|
return nil
|
|
}
|