diff options
| -rw-r--r-- | compare.go | 79 | ||||
| -rw-r--r-- | generate.go | 1 | ||||
| -rw-r--r-- | stat.proto | 32 |
3 files changed, 112 insertions, 0 deletions
@@ -1,5 +1,12 @@ package gitpb +import ( + "strings" + + "go.wit.com/lib/config" + "go.wit.com/log" +) + type RepoTag struct { r *Repo t *GitTag @@ -53,6 +60,25 @@ func (t1 *RepoTag) CompareBranch(t2 *RepoTag) ([]string, []string, []string, []s return lines1, lines2, cmd1, cmd2, nil } +func (r *Repo) CompareHashes(keepHash string, deleteHash string) ([]string, []string, []string, []string, error) { + lines1, cmd1, err1 := r.CountDiffObjectsNEWNEW(keepHash, deleteHash) + // log.Info("lessthan", t1.t.Refname, t2.t.Refname, count, t1.r.FullPath) + if err1 != nil { + // log.Info("lessthan", t1.t.Refname, t2.t.Refname, count, t1.r.FullPath, err) + return nil, nil, cmd1, nil, err1 + } + lines2, cmd2, err2 := r.CountDiffObjectsNEWNEW(deleteHash, keepHash) + // log.Info("lessthan", t1.t.Refname, t2.t.Refname, count, t1.r.FullPath) + if err2 != nil { + // log.Info("lessthan", t1.t.Refname, t2.t.Refname, count, t1.r.FullPath, err) + return nil, nil, cmd1, cmd2, err2 + } + if (len(lines1) != 0) || (len(lines2) != 0) { + return lines1, lines2, cmd1, cmd2, nil + } + return lines1, lines2, cmd1, cmd2, nil +} + /* func (t1 *RepoTag) LessThanVerbose(t2 *RepoTag) []string { count, err := t1.r.CountDiffObjectsNew(t1.t.Refname, t2.t.Refname) @@ -96,3 +122,56 @@ func (r *Repo) GetLocalDevelRef() *GitTag { func (r *Repo) GetLocalMasterRef() *GitTag { return r.IsBranchLocal(r.GetMasterBranchName()) } + +// It's safe to remove a tag if the deleteHash is completely contained in the keepHash +// This determines the git PatchId's for each hash and finds out if they are there +// brute force so it can be slow, but it worth it because it works (todo: detect rare duplicate patchId's) +func (repo *Repo) SafeDelete(deleteHash string, keepHash string) error { + // compare the branches + hashok, hashbad, cmd1, cmd2, err := repo.CompareHashes(keepHash, deleteHash) + + if err != nil { + // things are really really messed up. might be 'branchless' at this point (?) + 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 + } + + // things only in the master branch (safe to ignore) + for _, line := range hashok { + log.Info("OK", repo.Namespace, "in keepHash", cmd1, line) + } + + // things still only in the local branch (bad to delete) + for _, line := range hashbad { + // notes.addTextNote("BAD", repo, localRef.GetRef(), cmd2, line) + log.Info("BAD", repo.Namespace, "in deleteHash", cmd2, line) + parts := strings.Split(line, "%00") // git log doesn't actually convert %00 to NULL + if len(parts) != 4 { + log.Info("len", len(parts)) + panic("nope") + } + findThisHash := parts[0] + log.Info(findThisHash, deleteHash, "need to figure out the patchID for this to be deleted hash") + } + + if len(hashbad) == 0 { + // todo: force checkout to local master branch + // before doing this + cmd := []string{"git", "update-ref", "-d", deleteHash} + 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 config.Get("Fix") == "true" { + err := repo.RunVerbose(cmd) + if err != nil { + log.Info(deleteHash, repo.FullPath) + s := "local user branch could not be deleted" + config.BadExit(s, err) + } + } + return config.ErrdKeyFalse("Fix") + } + + return log.Errorf("NOT SAFE") +} diff --git a/generate.go b/generate.go index 501bb5c..ba9804c 100644 --- a/generate.go +++ b/generate.go @@ -10,4 +10,5 @@ package gitpb //go:generate autogenpb --proto repo.proto //go:generate autogenpb --proto goDep.proto //go:generate autogenpb --proto gitTag.proto +//go:generate autogenpb --proto stat.proto //go:generate bash -c "goimports -w *.go" diff --git a/stat.proto b/stat.proto new file mode 100644 index 0000000..c6ee078 --- /dev/null +++ b/stat.proto @@ -0,0 +1,32 @@ +// Copyright 2025 WIT.COM Inc Licensed GPL 3.0 + +syntax = "proto3"; + +package gitpb; + +import "google/protobuf/timestamp.proto"; // Import the well-known type for Timestamp + +message Stat { + enum RefType { + UNKNOWN = 0; + LOCAL = 1; + REMOTE = 2; + TAG = 3; + } + + string hash = 1; // `autogenpb:unique` // git hash + string patchId = 2; // `autogenpb:unique` // git hash + google.protobuf.Timestamp mtime = 3; // mtime for the .git/config file + string name = 4; // + string remote = 5; // blank unless REMOTE + RefType type = 6; // is set by git as the master branch + string subject = 7; // git tag subject +} +// .git/ stats +message Stats { // `autogenpb:marshal` `autogenpb:gui` `autogenpb:http` + string uuid = 1; // `autogenpb:uuid:ba236558-f8a1-4c47-a14a-8856a24d3f72` + string version = 2; // `autogenpb:version:v0.0.1` + repeated Stat stats = 3; + string head = 4; // the current origin hash + google.protobuf.Timestamp mtime = 5; // mtime for the .git/config file +} |
