From 8516f60136ead0156cf1f6d2784206bb584a5d82 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Mon, 6 Oct 2025 06:26:36 -0500 Subject: delete local only user branch --- README.md | 3 ++ doDev.go | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 915c72a..30a0796 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,9 @@ intent of simplifying federated git development. a) The git upstream master/main branch b) A "devel" branch that is published c) a "user" branch that can be local only to the developer +4) although 'master' usage is frowned upon, it's used here because 'main' + is already a reserved word in GO and this program has to also know + about 'main' in the context of C and GO language constructs. ## Development Goals diff --git a/doDev.go b/doDev.go index 3b23cd7..27b76e5 100644 --- a/doDev.go +++ b/doDev.go @@ -5,6 +5,7 @@ package main import ( "errors" + "fmt" "strings" "go.wit.com/lib/protobuf/forgepb" @@ -33,6 +34,20 @@ func doDev() (string, error) { for repo := range me.forge.Repos.IterByNamespace() { uremoteref := repo.GetRemoteTag(repo.GetUserBranchName()) if uremoteref == nil { + localRef := repo.IsBranchLocal(repo.GetUserBranchName()) + if localRef == nil { + // user branches don't exist + continue + } + log.Info("branch is only local") + if err, _ := doFixDeleteLocalUserByDevel(repo, localRef); err == nil { + // must have deleted it by devel + continue + } + if err, _ := doFixDeleteLocalUserByMaster(repo, localRef); err == nil { + // must have deleted it by master + continue + } continue } found.Repos = append(found.Repos, repo) @@ -51,12 +66,16 @@ func doDev() (string, error) { return "", nil } +func doFixPrint(s string, path string, cmd string) { + log.Printf("%-13.13s %-55.55s %s\n", s, path, cmd) +} + func doFixDeleteUserBranches(repo *gitpb.Repo, remoteRef *gitpb.GitTag) *notesList { // log.Info("delete remote user", repo.FullPath) localTag := repo.IsBranchLocal(repo.GetUserBranchName()) if localTag != nil { // log.Info("THERE IS local user", repo.FullPath, localTag.Refname) - log.Printf("%-13.13s %-55.55s %v\n", "LOCAL USER", repo.FullPath, localTag.Refname+" local branch exists") + doFixPrint("LOCAL USER", repo.FullPath, localTag.Refname+" local branch exists") err, notes := doFixDeleteUserLocalBranch(repo, remoteRef, localTag) if err != nil { log.Printf("%-13.13s %-55.55s %v noteslen(%d)\n", "need --fix", repo.FullPath, err, len(notes.all)) @@ -221,3 +240,91 @@ func doFixDeleteRemoteUserBranch(repo *gitpb.Repo, remoteRef *gitpb.GitTag) (err } return log.Errorf("NOT SAFE"), notes } + +// deletes local user branch if it's entirely in devel +func doFixDeleteLocalUserByDevel(repo *gitpb.Repo, localRef *gitpb.GitTag) (error, *notesList) { + notes := new(notesList) + + localUser := repo.NewCompareRef(localRef) + dref := repo.GetLocalDevelRef() + if dref == nil { + return fmt.Errorf("no local devel"), notes + } + localDevel := repo.NewCompareRef(dref) + + // Is the localUser completely inside the localDevel branch? + hashok, hashbad, cmd1, cmd2, err := localDevel.CompareBranch(localUser) + for _, line := range hashok { + notes.addNote("OK", repo, localDevel.GetRef(), cmd1, line) + } + for _, line := range hashbad { + notes.addNote("BAD", repo, localUser.GetRef(), cmd2, line) + } + if err != nil { + log.Printf("%-13.13s %-55.55s err='%v' %s %v\n", "CMD ERR", repo.FullPath, err, "NOT SAFE TO DELETE. Reload()?", cmd1) + log.Printf("%-13.13s %-55.55s err='%v' %s %v\n", "CMD ERR", repo.FullPath, err, "NOT SAFE TO DELETE. Reload()?", cmd2) + return err, notes + } + if len(hashbad) == 0 { + cmd := []string{"git", "update-ref", "-d", localUser.GetRefname()} + log.Printf("%-13.13s %-55.55s %v %s\n", "CMD OK", repo.FullPath, cmd1, "") + log.Printf("%-13.13s %-55.55s %v %s\n", "CMD OK", repo.FullPath, cmd2, "") + log.Printf("%-13.13s %-55.55s %v %s\n", "SAFE TO DELETE", repo.FullPath, cmd, "add --fix") + if argv.Fix { + err := repo.RunVerbose(cmd) + if err != nil { + log.Info(localUser.GetRefname(), repo.FullPath) + s := "local user branch could not be deleted" + me.sh.BadExit(s, err) + } + } + return ErrorNeedArgvFix, notes + } + return log.Errorf("NOT SAFE"), notes +} + +// deletes local user branch if it's entirely in master +func doFixDeleteLocalUserByMaster(repo *gitpb.Repo, localRef *gitpb.GitTag) (error, *notesList) { + notes := new(notesList) + + localUser := repo.NewCompareRef(localRef) + mref := repo.GetLocalMasterRef() + if mref == nil { + return fmt.Errorf("no local master"), notes + } + localMaster := repo.NewCompareRef(mref) + + // Is the localUser completely inside the localMaster branch? + hashok, hashbad, cmd1, cmd2, err := localMaster.CompareBranch(localUser) + for _, line := range hashok { + notes.addNote("OK", repo, localMaster.GetRef(), cmd1, line) + } + + for _, line := range hashbad { + notes.addNote("BAD", repo, localUser.GetRef(), cmd2, line) + } + + if err != nil { + log.Printf("%-13.13s %-55.55s err='%v' %s %v\n", "CMD ERR", repo.FullPath, err, "NOT SAFE TO DELETE. Reload()?", cmd1) + log.Printf("%-13.13s %-55.55s err='%v' %s %v\n", "CMD ERR", repo.FullPath, err, "NOT SAFE TO DELETE. Reload()?", cmd2) + return err, notes + } + + if len(hashbad) == 0 { + cmd := []string{"git", "update-ref", "-d", localUser.GetRefname()} + log.Printf("%-13.13s %-55.55s %v %s\n", "CMD OK", repo.FullPath, cmd1, "") + log.Printf("%-13.13s %-55.55s %v %s\n", "CMD OK", repo.FullPath, cmd2, "") + log.Printf("%-13.13s %-55.55s %v %s\n", "SAFE TO DELETE", repo.FullPath, cmd, "add --fix") + if argv.Fix { + err := repo.RunVerbose(cmd) + if err != nil { + log.Info(localUser.GetRefname(), repo.FullPath) + s := "local user branch could not be deleted" + me.sh.BadExit(s, err) + } + } + return ErrorNeedArgvFix, notes + } + + return log.Errorf("NOT SAFE"), notes +} -- cgit v1.2.3