218 lines
5.7 KiB
Go
218 lines
5.7 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"
|
|
)
|
|
|
|
// reverts all repos back to the original master branches
|
|
// automatically deletes local devel and user branches
|
|
func doClean() error {
|
|
// fix this to work, then delete all the other options for "forge clean'
|
|
if err := doAllCheckoutMaster(); err != nil {
|
|
// badExit(err)
|
|
}
|
|
|
|
all := me.forge.Repos.SortByFullPath()
|
|
for all.Scan() {
|
|
repo := all.Next()
|
|
if repo.GetCurrentBranchName() != repo.GetMasterBranchName() {
|
|
continue
|
|
}
|
|
if repo.IsDirty() {
|
|
continue
|
|
}
|
|
|
|
// when publishing, clean out the details of that if it's still there
|
|
if repo.GetTargetVersion() != "" {
|
|
repo.SetTargetVersion("")
|
|
configSave = true
|
|
}
|
|
|
|
// try to delete user
|
|
if err := doRepoCleanUser(repo); err != nil {
|
|
log.Info(repo.GetGoPath(), err)
|
|
}
|
|
|
|
// try to delete devel
|
|
doRepoCleanDevel(repo)
|
|
}
|
|
|
|
found := gitpb.NewRepos()
|
|
|
|
total := 0
|
|
// find all repos that aren't "clean"
|
|
all = me.forge.Repos.SortByFullPath()
|
|
for all.Scan() {
|
|
repo := all.Next()
|
|
total += 1
|
|
|
|
// find repos not on master branch
|
|
if repo.GetCurrentBranchName() != repo.GetMasterBranchName() {
|
|
found.AppendByGoPath(repo)
|
|
continue
|
|
}
|
|
|
|
// find dirty repos
|
|
if repo.IsDirty() {
|
|
found.AppendByGoPath(repo)
|
|
continue
|
|
}
|
|
|
|
// find repos that still have a local user branch
|
|
if repo.IsLocalBranch(repo.GetUserBranchName()) {
|
|
found.AppendByGoPath(repo)
|
|
continue
|
|
}
|
|
|
|
// find repos that still have a local devel branch
|
|
if repo.IsLocalBranch(repo.GetDevelBranchName()) {
|
|
found.AppendByGoPath(repo)
|
|
continue
|
|
}
|
|
}
|
|
|
|
// display all the repos that aren't clean to the user
|
|
log.Printf("\n") // padding for now
|
|
if argv.Verbose {
|
|
me.forge.PrintHumanTableDirty(found)
|
|
} else {
|
|
me.forge.PrintHumanTable(found)
|
|
}
|
|
log.Printf("\n") // padding for now
|
|
|
|
if found.Len() == 0 {
|
|
log.Printf("%d repos are not clean\n", found.Len())
|
|
} else {
|
|
log.Info("All repos are clean", total, found.Len())
|
|
}
|
|
return nil
|
|
}
|
|
|
|
/*
|
|
func doesLocalBranchExist(repo *gitpb.Repo, branch string) bool {
|
|
return repo.Exists(filepath.Join(".git/refs/heads", branch))
|
|
}
|
|
*/
|
|
func doRepoCleanDevel(repo *gitpb.Repo) error {
|
|
if !repo.IsLocalBranch(repo.GetDevelBranchName()) {
|
|
// there is no local branch named 'devel'
|
|
return nil
|
|
}
|
|
|
|
if repo.GetCurrentBranchName() != repo.GetMasterBranchName() {
|
|
return log.Errorf("%s not on master branch:", repo.GetFullPath())
|
|
}
|
|
if repo.IsDirty() {
|
|
return log.Errorf("%s is dirty:", repo.GetFullPath())
|
|
}
|
|
if err := justDeleteTheDevelBranchAlready(repo); err != nil {
|
|
log.Info("justDeleteTheDevel() err", repo.GetGoPath(), err)
|
|
configSave = true
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// removes all local user branches
|
|
func doRepoCleanUser(repo *gitpb.Repo) error {
|
|
if repo.IsDirty() {
|
|
return nil
|
|
}
|
|
|
|
bruser := repo.GetUserBranchName()
|
|
brdevel := repo.GetDevelBranchName()
|
|
|
|
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")
|
|
}
|
|
|
|
if !repo.IsLocalBranch(bruser) {
|
|
// there is no local user branch
|
|
return nil
|
|
}
|
|
|
|
// will you loose work if you delete your user branch?
|
|
// if DevelBranchExists()
|
|
// then if UserBranchCommits exist in DevelBranch
|
|
// DeleteUserBranch is safe
|
|
if repo.IsLocalBranch(brdevel) {
|
|
b1 := repo.CountDiffObjects(bruser, "refs/heads/"+brdevel) // should be zero
|
|
if b1 == 0 {
|
|
// every user branch exists in devel. delete user branch
|
|
cmd := []string{"git", "branch", "-D", bruser}
|
|
// log.Info("USER IS IN DEVEL", repo.GetGoPath(), cmd)
|
|
err := repo.RunVerbose(cmd)
|
|
return err
|
|
}
|
|
}
|
|
|
|
brmaster := repo.GetMasterBranchName()
|
|
|
|
// will you loose work if you delete your user branch?
|
|
// if master branch exists()
|
|
// then if all user commits exist in master
|
|
// delete user branch is safe
|
|
if repo.IsLocalBranch(brmaster) {
|
|
b1 := repo.CountDiffObjects(bruser, "refs/heads/"+brmaster) // 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 unique commits", bruser)
|
|
}
|
|
|
|
// 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, "refs/heads/"+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
|
|
}
|