Compare commits

..

No commits in common. "master" and "v0.0.121" have entirely different histories.

15 changed files with 104 additions and 218 deletions

View File

@ -2,6 +2,7 @@ package gitpb
import ( import (
"fmt" "fmt"
"os"
"os/user" "os/user"
"path/filepath" "path/filepath"
@ -10,6 +11,20 @@ import (
func (repo *Repo) CheckoutMaster() bool { func (repo *Repo) CheckoutMaster() bool {
bName := repo.GetMasterBranchName() bName := repo.GetMasterBranchName()
if bName == "giterr" {
cmd := []string{"git", "checkout", "main"} // todo: figure out main
repo.RunVerboseOnError(cmd)
os.Exit(-1)
// TODO: try to fix this
if repo.checkoutBranch("main") {
repo.MasterBranchName = "main"
return true
} else {
cmd := []string{"git", "checkout", "main"} // todo: figure out main
repo.RunVerboseOnError(cmd)
return false
}
}
if repo.checkoutBranch(bName) { if repo.checkoutBranch(bName) {
return true return true
} }
@ -112,7 +127,7 @@ func (repo *Repo) createUserBranch(branch string) error {
if repo.GetCurrentBranchName() != repo.GetDevelBranchName() { if repo.GetCurrentBranchName() != repo.GetDevelBranchName() {
repo.CheckoutDevel() repo.CheckoutDevel()
} }
repo.ReloadCheck() repo.Reload()
if repo.GetCurrentBranchName() != repo.GetDevelBranchName() { if repo.GetCurrentBranchName() != repo.GetDevelBranchName() {
log.Info("create user branch will probably fail", repo.GetGoPath()) log.Info("create user branch will probably fail", repo.GetGoPath())

View File

@ -14,10 +14,7 @@ func (repo *Repo) SetMasterBranchName(s string) {
func (repo *Repo) GetGoPath() string { func (repo *Repo) GetGoPath() string {
if repo.GoInfo == nil { if repo.GoInfo == nil {
return repo.Namespace return ""
}
if repo.GoInfo.GoPath == "" {
return repo.Namespace
} }
return repo.GoInfo.GoPath return repo.GoInfo.GoPath
} }

View File

@ -12,40 +12,36 @@ import (
"go.wit.com/log" "go.wit.com/log"
) )
// write to ~/.config/forge/ unless ENV{FORGE_REPOSDIR} is set // write to ~/.config/forge/ unless ENV{FORGE_GOSRC} is set
func (all *Repos) ConfigSave(fname string) error { func (all *Repos) ConfigSave() error {
if all == nil { if os.Getenv("FORGE_GOSRC") == "" {
log.Warn("gitpb repos == nil") homeDir, _ := os.UserHomeDir()
return errors.New("gitpb.ConfigSave() repos == nil") fullpath := filepath.Join(homeDir, ".config/forge")
os.Setenv("FORGE_GOSRC", fullpath)
} }
if all == nil {
if _, s := filepath.Split(fname); s != "repos.pb" { log.Warn("gitpb all == nil")
log.Infof("ConfigSave() filename '%s' invalid\n", fname) return errors.New("gitpb.ConfigSave() all == nil")
return log.Errorf("ConfigSave() filename '%s' invalid\n", fname)
} }
data, err := all.Marshal() data, err := all.Marshal()
if err != nil { if err != nil {
log.Info("gitpb proto.Marshal() failed len", len(data), err) log.Info("gitpb proto.Marshal() failed len", len(data), err)
// often this is because strings have invalid UTF-8. This should probably be fixed in the protobuf code // often this is because strings have invalid UTF-8. This should probably be fixed in the protobuf code
// this might be fixed in the create code, but it can't hurt to try this as a last ditch effort here
log.Info("gitpb.ConfigSave() ATTEMPTING TO VALIDATE UTF-8 strings in the protobuf file")
if err := all.tryValidate(); err != nil { if err := all.tryValidate(); err != nil {
log.Info("gitpb.ConfigSave() STILL FAILEd", err)
return err return err
} else { } else {
// re-attempt Marshal() here // re-attempt Marshal() here
data, err = all.Marshal() data, err = all.Marshal()
if err == nil { if err == nil {
// validate & sanitize strings worked // validate & sanitize strings worked
configWrite(fname, data) configWrite("repos.pb", data)
return nil return nil
} }
log.Info("gitpb.ConfigSave() STILL FAILEd", err)
} }
return err return err
} }
configWrite(fname, data) configWrite("repos.pb", data)
return nil return nil
} }
@ -85,43 +81,16 @@ func (all *Repos) tryValidate() error {
// load the repos.pb file. I shouldn't really matter if this // load the repos.pb file. I shouldn't really matter if this
// fails. the file should be autogenerated. This is used // fails. the file should be autogenerated. This is used
// locally just for speed // locally just for speed
func (all *Repos) ConfigLoadOld() error { func (all *Repos) ConfigLoad() error {
if os.Getenv("FORGE_REPOSDIR") == "" { if os.Getenv("FORGE_GOSRC") == "" {
homeDir, _ := os.UserHomeDir() homeDir, _ := os.UserHomeDir()
fullpath := filepath.Join(homeDir, ".config/forge") fullpath := filepath.Join(homeDir, ".config/forge")
os.Setenv("FORGE_REPOSDIR", fullpath) os.Setenv("FORGE_GOSRC", fullpath)
} }
var data []byte var data []byte
var err error var err error
cfgname := filepath.Join(os.Getenv("FORGE_REPOSDIR"), "repos.pb") cfgname := filepath.Join(os.Getenv("FORGE_GOSRC"), "repos.pb")
if data, err = loadFile(cfgname); err != nil {
// something went wrong loading the file
// all.sampleConfig() // causes nil panic
return err
}
// this means the forge.pb file exists and was read
if len(data) == 0 {
return errors.New("gitpb.ConfigLoad() repos.pb is empty")
}
err = all.Unmarshal(data)
test := NewRepos()
if test.Uuid != all.Uuid {
log.Log(WARN, "uuids do not match", test.Uuid, all.Uuid)
deleteProtobufFile(cfgname)
}
if test.Version != all.Version {
log.Log(WARN, "versions do not match", test.Version, all.Version)
deleteProtobufFile(cfgname)
}
log.Log(INFO, cfgname, "protobuf versions and uuid match", all.Uuid, all.Version)
return err
}
func (all *Repos) ConfigLoad(cfgname string) error {
var data []byte
var err error
if data, err = loadFile(cfgname); err != nil { if data, err = loadFile(cfgname); err != nil {
// something went wrong loading the file // something went wrong loading the file
// all.sampleConfig() // causes nil panic // all.sampleConfig() // causes nil panic
@ -129,6 +98,7 @@ func (all *Repos) ConfigLoad(cfgname string) error {
} }
// this means the forge.pb file exists and was read // this means the forge.pb file exists and was read
if len(data) == 0 { if len(data) == 0 {
all.sampleConfig() // causes nil panic
return errors.New("gitpb.ConfigLoad() repos.pb is empty") return errors.New("gitpb.ConfigLoad() repos.pb is empty")
} }
err = all.Unmarshal(data) err = all.Unmarshal(data)
@ -176,7 +146,9 @@ func loadFile(fullname string) ([]byte, error) {
return data, nil return data, nil
} }
func configWrite(fullname string, data []byte) error { func configWrite(filename string, data []byte) error {
fullname := filepath.Join(os.Getenv("FORGE_GOSRC"), filename)
log.Infof("%s your repos have changed state. cached state. (%d) bytes\n", fullname, len(data)) log.Infof("%s your repos have changed state. cached state. (%d) bytes\n", fullname, len(data))
cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) cfgfile, err := os.OpenFile(fullname, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
defer cfgfile.Close() defer cfgfile.Close()
@ -184,6 +156,16 @@ func configWrite(fullname string, data []byte) error {
log.Warn("open config file :", err) log.Warn("open config file :", err)
return err return err
} }
if filename == "forge.text" {
// add header
cfgfile.Write([]byte("# this file is automatically re-generated from forge.pb, however,\n"))
cfgfile.Write([]byte("# if you want to edit it by hand, you can:\n"))
cfgfile.Write([]byte("# stop forge; remove forge.pb; edit forge.text; start forge\n"))
cfgfile.Write([]byte("# this will cause the default behavior to fallback to parsing this file for the config\n"))
cfgfile.Write([]byte("\n"))
cfgfile.Write([]byte("# this file is intended to be used to customize settings on what\n"))
cfgfile.Write([]byte("# git repos you have write access to. That is, where you can run 'git push'\n"))
}
cfgfile.Write(data) cfgfile.Write(data)
return nil return nil
} }

View File

@ -38,6 +38,7 @@ func (repo *Repo) setMasterVersion() {
repo.MasterVersion = v repo.MasterVersion = v
} else { } else {
log.Log(WARN, "gitpb.GitMasterVersion() error:", err) log.Log(WARN, "gitpb.GitMasterVersion() error:", err)
repo.MasterVersion = "giterr"
} }
} }
@ -89,11 +90,11 @@ func (repo *Repo) gitDescribeByHash(hash string) (string, error) {
if hash == "" { if hash == "" {
return "", errors.New("hash was blank") return "", errors.New("hash was blank")
} }
r, err := repo.RunQuiet([]string{"git", "describe", "--tags", hash}) r, err := repo.RunQuiet([]string{"git", "describe", "--tags", "--always", hash})
out := strings.Join(r.Stdout, "\n") out := strings.Join(r.Stdout, "\n")
if err != nil { if err != nil {
// log.Warn("not in a git repo or bad hash?", err, repo.GetGoPath()) log.Warn("not in a git repo or bad hash?", err, repo.GetGoPath())
return "gitpb err", err return out, err
} }
return out, err return out, err
} }
@ -133,27 +134,28 @@ func (repo *Repo) gitVersionByName(name string) (string, error) {
if name == "" { if name == "" {
// git will return the current tag // git will return the current tag
cmd := []string{"git", "describe", "--tags"} r, err := repo.RunQuiet([]string{"git", "describe", "--tags", "--always"})
r, err := repo.RunQuiet(cmd)
output := strings.Join(r.Stdout, "\n") output := strings.Join(r.Stdout, "\n")
if err != nil { if err != nil {
log.Log(WARN, repo.FullPath, "gitDescribeByName() ", output, err, cmd) log.Log(WARN, "gitDescribeByName() output might have worked anyway:", output)
log.Log(WARN, "gitDescribeByName() not in a git repo?", err, repo.GetGoPath())
return "", err return "", err
} }
return strings.TrimSpace(output), nil return strings.TrimSpace(output), nil
} }
if !repo.IsBranch(name) { if !repo.IsBranch(name) {
// branch does not exist // tag does not exist
// log.Log(WARN, "LocalTagExists()", name, "did not exist")
return "", errors.New("gitDescribeByName() git fatal: Not a valid object name: " + name) return "", errors.New("gitDescribeByName() git fatal: Not a valid object name: " + name)
} }
cmd := []string{"git", "describe", "--tags", name} cmd := []string{"git", "describe", "--tags", "--always", name}
result, err := repo.RunQuiet(cmd) result, err := repo.RunQuiet(cmd)
output := strings.Join(result.Stdout, "\n") output := strings.Join(result.Stdout, "\n")
if err != nil { if err != nil {
//log.Log(WARN, "cmd =", cmd) log.Log(WARN, "cmd =", cmd)
//log.Log(WARN, "err =", err) log.Log(WARN, "err =", err)
//log.Log(WARN, "output (might have worked with error?) =", output) log.Log(WARN, "output (might have worked with error?) =", output)
//log.Log(WARN, "not in a git repo or bad tag?", repo.GetGoPath()) log.Log(WARN, "not in a git repo or bad tag?", repo.GetGoPath())
return "", result.Error return "", result.Error
} }

View File

@ -83,6 +83,8 @@ func (repo *Repo) IsDevelRemote() bool {
// eventually this will be worked out by forge in some future code that hasn't been made yet // eventually this will be worked out by forge in some future code that hasn't been made yet
func (repo *Repo) IsBranch(findname string) bool { func (repo *Repo) IsBranch(findname string) bool {
for t := range repo.Tags.IterAll() { for t := range repo.Tags.IterAll() {
// log.Info("LocalTagExists() tag:", t.Refname)
tagname := t.Refname tagname := t.Refname
if strings.HasPrefix(tagname, "refs/remotes") { if strings.HasPrefix(tagname, "refs/remotes") {
continue continue
@ -101,8 +103,10 @@ func (repo *Repo) IsBranch(findname string) bool {
func (repo *Repo) IsLocalBranch(findname string) bool { func (repo *Repo) IsLocalBranch(findname string) bool {
for t := range repo.Tags.IterAll() { for t := range repo.Tags.IterAll() {
if !strings.HasPrefix(t.Refname, "refs/heads") { if !strings.HasPrefix(t.Refname, "refs/heads") {
// log.Info("LocalTagExists() skip tag:", t.Refname)
continue continue
} }
// log.Info("LocalTagExists() check tag:", t.Refname)
path, filename := filepath.Split(t.Refname) path, filename := filepath.Split(t.Refname)
log.Log(INFO, "gitpb.IsBranch() tag:", path, filename, "from", repo.GetGoPath()) log.Log(INFO, "gitpb.IsBranch() tag:", path, filename, "from", repo.GetGoPath())
if filename == findname { if filename == findname {

View File

@ -1,21 +0,0 @@
// Code generated by go.wit.com/apps/autogenpb DO NOT EDIT.
// This file was autogenerated with autogenpb v0.5.1 2025-09-12_15:24:32_UTC
// go install go.wit.com/apps/autogenpb@latest
//
// define which structs (messages) you want to use in the .proto file
// Then sort.pb.go and marshal.pb.go files are autogenerated
//
// autogenpb uses it and has an example .proto file with instructions
//
package gitpb
import (
"go.wit.com/lib/cobol"
)
func (mt *GitTagsTable) PrintTable() {
// log.Info("ShowTable() SENDING TO GUI")
mt.MakeTable()
cobol.PrintTable(mt.pb)
}

View File

@ -15,6 +15,7 @@ message GitBranch { // `autogenpb:nomutex`
string name = 3; // the branch name from the config file string name = 3; // the branch name from the config file
} }
// readGitConfig reads and parses the .git/config file
message GitConfig { // `autogenpb:nomutex` message GitConfig { // `autogenpb:nomutex`
map<string, string> core = 1; // map[origin] = "https:/git.wit.org/gui/gadgets" map<string, string> core = 1; // map[origin] = "https:/git.wit.org/gui/gadgets"
map<string, GitRemote> remotes = 2; // map[origin] = "https:/git.wit.org/gui/gadgets" map<string, GitRemote> remotes = 2; // map[origin] = "https:/git.wit.org/gui/gadgets"
@ -33,7 +34,7 @@ message GitTag { // `autogenpb:nomutex`
string subject = 5; // git tag subject string subject = 5; // git tag subject
} }
message GitTags { // `autogenpb:marshal` `autogenpb:nomutex` `autogenpb:gui` message GitTags { // `autogenpb:marshal` `autogenpb:nomutex`
string uuid = 1; // `autogenpb:uuid:ffdff813-0316-4372-9e82-4c1c7d202526` string uuid = 1; // `autogenpb:uuid:ffdff813-0316-4372-9e82-4c1c7d202526`
string version = 2; // `autogenpb:version:v0.0.47` string version = 2; // `autogenpb:version:v0.0.47`
repeated GitTag gitTags = 3; repeated GitTag gitTags = 3;

View File

@ -4,42 +4,23 @@ import (
"strings" "strings"
"time" "time"
"go.wit.com/lib/config"
"go.wit.com/log" "go.wit.com/log"
timestamppb "google.golang.org/protobuf/types/known/timestamppb" timestamppb "google.golang.org/protobuf/types/known/timestamppb"
) )
// sets a flag that the repos have changed
// used later by applications on exit to test if
// the protobuf needs to be written to disk
func reposChanged(b bool) {
config.SetChanged("repos", true)
}
// returns true based on os.Stat() only checks
// seems to kinda work ok. goal is to avoid os.Exec() here for speed
// this might be the 1 place where libgit2 would be a good idea
func (repo *Repo) HasChanged() bool {
return repo.DidRepoChange()
}
// does a fast check with os.Stat() // does a fast check with os.Stat()
// if the mtimes changed, does a full repo.ReloadForce() // if the mtimes changed, does a full repo.Reload()
func (repo *Repo) ReloadCheck() error { func (repo *Repo) ReloadCheck() error {
if !repo.DidRepoChange() { if !repo.DidRepoChange() {
return nil return nil
} }
reposChanged(true) // f.configSave = true
err := repo.ReloadForce() err := repo.Reload()
if err != nil { return err
return err
}
return log.Errorf("gitpb.ReloadCheck() detected a change in the repo")
} }
// TODO: clean this up more, but it is working now more or less // TODO: clean this up more, but it is working now more or less
func (repo *Repo) ReloadForce() error { func (repo *Repo) Reload() error {
reposChanged(true)
// sometimes, on new repos, if .git/HEAD does not exist // sometimes, on new repos, if .git/HEAD does not exist
// defective git daemons or badly configured repos, 'git clone' can fail // defective git daemons or badly configured repos, 'git clone' can fail
// if so, 'git fetch origin' can repair the state // if so, 'git fetch origin' can repair the state
@ -73,30 +54,12 @@ func (repo *Repo) ReloadForce() error {
} }
} }
repo.VerifyRemoteAndLocalBranches(repo.GetDevelBranchName())
repo.VerifyRemoteAndLocalBranches(repo.GetMasterBranchName())
// LastUpdate should always be the newest time // LastUpdate should always be the newest time
repo.Times.LastUpdate = timestamppb.New(time.Now()) repo.Times.LastUpdate = timestamppb.New(time.Now())
repo.ValidateUTF8() repo.ValidateUTF8()
return nil return nil
} }
func (repo *Repo) VerifyRemoteAndLocalBranches(bname string) bool {
if !repo.IsBranchRemote(bname) {
return true
}
lh := repo.GetLocalHash(bname)
rh := repo.GetRemoteHash(bname)
if lh == rh {
// log.Info(r.FullPath, "local devel == remote devel", lh, rh)
return true
} else {
log.Info(lh, rh, "local != remote", repo.FullPath, bname)
}
return false
}
func (repo *Repo) SetDevelBranchName(bname string) { func (repo *Repo) SetDevelBranchName(bname string) {
repo.DevelBranchName = bname repo.DevelBranchName = bname
} }
@ -128,13 +91,11 @@ func (repo *Repo) setCurrentBranchVersion() {
log.Info("repo.GetCurrentBranchVersion() repo == nil") log.Info("repo.GetCurrentBranchVersion() repo == nil")
return return
} }
r, err := repo.RunQuiet([]string{"git", "describe", "--tags"}) r, err := repo.RunQuiet([]string{"git", "describe", "--tags", "--always"})
output := strings.Join(r.Stdout, "\n") output := strings.Join(r.Stdout, "\n")
if err != nil { if err != nil {
// log.Log(WARN, "GetCurrentBranchVersion() not in a git repo?", err, repo.GetGoPath()) log.Log(WARN, "GetCurrentBranchVersion() not in a git repo?", err, repo.GetGoPath())
// log.Log(WARN, "GetCurrentBranchVersion() output might have worked anyway:", output) log.Log(WARN, "GetCurrentBranchVersion() output might have worked anyway:", output)
repo.CurrentBranchVersion = "gitpb err"
return
} }
repo.CurrentBranchVersion = strings.TrimSpace(output) repo.CurrentBranchVersion = strings.TrimSpace(output)
} }

View File

@ -27,28 +27,16 @@ func (repo *Repo) updateGitConfig() error {
repo.GitConfig.Submodules = make(map[string]string) repo.GitConfig.Submodules = make(map[string]string)
repo.GitConfig.Versions = make(map[string]string) repo.GitConfig.Versions = make(map[string]string)
repo.GitConfig.Hashes = make(map[string]string) repo.GitConfig.Hashes = make(map[string]string)
url, err := repo.readGitConfig() return repo.readGitConfig()
if repo.URL != "" {
log.Info("gitpb: url already set", url, repo.URL)
}
if url == "" {
log.Info(repo.FullPath, "url was blank. warn user this repo is only on the local disk")
} else {
repo.URL = url
}
return err
} }
// readGitConfig reads and parses the .git/config file // readGitConfig reads and parses the .git/config file
func (repo *Repo) readGitConfig() (string, error) { func (repo *Repo) readGitConfig() error {
var foundURL string
filename := filepath.Join(repo.GetFullPath(), ".git/config") filename := filepath.Join(repo.GetFullPath(), ".git/config")
file, err := os.Open(filename) file, err := os.Open(filename)
defer file.Close() defer file.Close()
if err != nil { if err != nil {
return "", err return err
} }
var currentSection string = "" var currentSection string = ""
@ -104,13 +92,6 @@ func (repo *Repo) readGitConfig() (string, error) {
log.Log(INFO, "switch currentSection", currentSection, currentName) log.Log(INFO, "switch currentSection", currentSection, currentName)
switch key { switch key {
case "url": case "url":
if foundURL == "" {
foundURL = value
} else {
if foundURL != value {
log.Info("TODO: gitpb: handle multiple remotes in the parser", foundURL, value)
}
}
if test.Url == value { if test.Url == value {
continue continue
} }
@ -183,10 +164,10 @@ func (repo *Repo) readGitConfig() (string, error) {
} }
if err := scanner.Err(); err != nil { if err := scanner.Err(); err != nil {
return "", err return err
} }
return foundURL, nil return nil
} }
func (repo *Repo) processBranch(branch string) { func (repo *Repo) processBranch(branch string) {

View File

@ -168,16 +168,11 @@ func (repo *Repo) NewestTag() *GitTag {
} }
// this should just do is.Exists(".git/refs/heads/findname") // this should just do is.Exists(".git/refs/heads/findname")
// this is a simple check and doesn't work all the time
func (repo *Repo) LocalTagExists(findname string) bool { func (repo *Repo) LocalTagExists(findname string) bool {
fname := filepath.Join(".git/refs/heads", findname) fname := filepath.Join(".git/refs/heads", findname)
if repo.Exists(fname) { if repo.Exists(fname) {
return true return true
} }
fname = filepath.Join(".git/refs/tags", findname)
if repo.Exists(fname) {
return true
}
/* /*
loop := repo.Tags.SortByRefname() loop := repo.Tags.SortByRefname()
for loop.Scan() { for loop.Scan() {

View File

@ -10,7 +10,7 @@
package gitpb package gitpb
func (t *ReposTable) MyMasterBranch() *RepoAnyFunc { func (t *ReposTable) MyMasterBranch() *RepoStringFunc {
sf := t.AddStringFunc("master", func(m *Repo) string { sf := t.AddStringFunc("master", func(m *Repo) string {
return m.MasterBranchName return m.MasterBranchName
}) })

View File

@ -8,7 +8,7 @@ import (
) )
func (r *Repo) MergeToDevel() (*cmd.Status, error) { func (r *Repo) MergeToDevel() (*cmd.Status, error) {
r.ReloadCheck() r.Reload()
if r.GetCurrentBranchName() != r.GetDevelBranchName() { if r.GetCurrentBranchName() != r.GetDevelBranchName() {
return nil, fmt.Errorf("repo not on devel branch") return nil, fmt.Errorf("repo not on devel branch")
} }
@ -28,10 +28,15 @@ func (r *Repo) MergeToDevel() (*cmd.Status, error) {
} }
if !r.IsBranchRemote(devel) { if !r.IsBranchRemote(devel) {
r.ReloadCheck() // rescan the repo r.Reload() // rescan the repo
// devel branch is not remote. do not try 'git push' // devel branch is not remote. do not try 'git push'
return nil, nil return nil, nil
} }
if r.GetReadOnly() {
r.Reload() // rescan the repo
// devel branch is read only. you can not git push
return nil, nil
}
// it seems like we have write access. lets find out! // it seems like we have write access. lets find out!
cmd = []string{"git", "push"} cmd = []string{"git", "push"}
@ -40,31 +45,21 @@ func (r *Repo) MergeToDevel() (*cmd.Status, error) {
log.Log(WARN, "GitPushToDevel() failed", r.GetFullPath()) log.Log(WARN, "GitPushToDevel() failed", r.GetFullPath())
return nil, result.Error return nil, result.Error
} }
r.ReloadCheck() // rescan the repo r.Reload() // rescan the repo
return nil, nil return nil, nil
} }
func (r *Repo) MergeToMaster() (*cmd.Status, error) { func (r *Repo) MergeToMaster() (*cmd.Status, error) {
r.ReloadCheck() r.Reload()
if r.GetCurrentBranchName() != r.GetMasterBranchName() { if r.GetCurrentBranchName() != r.GetMasterBranchName() {
return nil, fmt.Errorf("repo not on master branch") return nil, fmt.Errorf("repo not on master branch")
} }
/* if r.GetReadOnly() {
if r.GetReadOnly() { r.Reload() // rescan the repo
r.ReloadCheck() // rescan the repo // master branch is read only. you can not git push
// master branch is read only. you can not git push return nil, fmt.Errorf("can't merge to master on read only() repos")
lh := r.GetLocalHash("devel") }
rh := r.GetRemoteHash("devel")
if lh == rh {
// log.Info(r.FullPath, "local devel == remote devel", lh, rh)
} else {
log.Info(r.FullPath, "local devel != remote devel", lh, rh)
}
log.Info("can't merge to master on read only() repos. trying anyway")
// return nil, fmt.Errorf("can't merge to master on read only() repos")
}
*/
if r.CheckDirty() { if r.CheckDirty() {
return nil, fmt.Errorf("repo is dirty") return nil, fmt.Errorf("repo is dirty")
} }
@ -80,6 +75,12 @@ func (r *Repo) MergeToMaster() (*cmd.Status, error) {
return nil, result.Error return nil, result.Error
} }
if r.GetReadOnly() {
r.Reload() // rescan the repo
// master branch is read only. you can not git push
return nil, nil
}
// it seems like we have write access. lets find out! // it seems like we have write access. lets find out!
cmd = []string{"git", "push"} cmd = []string{"git", "push"}
result = r.RunRealtimeVerbose(cmd) result = r.RunRealtimeVerbose(cmd)
@ -87,6 +88,6 @@ func (r *Repo) MergeToMaster() (*cmd.Status, error) {
log.Log(WARN, "GitPushToMaster() failed", r.GetFullPath()) log.Log(WARN, "GitPushToMaster() failed", r.GetFullPath())
return nil, result.Error return nil, result.Error
} }
r.ReloadCheck() // rescan the repo r.Reload() // rescan the repo
return nil, nil return nil, nil
} }

View File

@ -2,8 +2,6 @@ package gitpb
import ( import (
"errors" "errors"
"net/url"
"path/filepath"
"go.wit.com/log" "go.wit.com/log"
) )
@ -35,7 +33,7 @@ func (all *Repos) NewGoRepo(fullpath string, gopath string) (*Repo, error) {
newr.GoInfo = new(GoInfo) newr.GoInfo = new(GoInfo)
newr.GoInfo.GoPath = gopath newr.GoInfo.GoPath = gopath
// everything happens in here // everything happens in here
newr.ReloadForce() newr.Reload()
newr.ValidateUTF8() newr.ValidateUTF8()
if all.AppendByFullPath(&newr) { if all.AppendByFullPath(&newr) {
@ -91,7 +89,7 @@ func (all *Repos) NewRepo(fullpath string, namespace string) (*Repo, error) {
newr.Times = new(GitTimes) newr.Times = new(GitTimes)
// everything happens in here // everything happens in here
newr.ReloadForce() newr.Reload()
newr.ValidateUTF8() newr.ValidateUTF8()
if all.AppendByFullPath(&newr) { if all.AppendByFullPath(&newr) {
@ -102,32 +100,3 @@ func (all *Repos) NewRepo(fullpath string, namespace string) (*Repo, error) {
// todo: use Repos.Lock() // todo: use Repos.Lock()
return nil, errors.New("gitpb.NewRepo() append failed " + fullpath) return nil, errors.New("gitpb.NewRepo() append failed " + fullpath)
} }
func NewRepo(fullpath string) (*Repo, error) {
// add a new one here
repo := Repo{
FullPath: fullpath,
}
repo.Times = new(GitTimes)
// everything happens in here
repo.ReloadForce()
repo.ValidateUTF8()
if repo.Namespace == "" {
giturl := repo.GetURL()
if giturl == "" {
log.Info(repo.FullPath, "Namespace & URL are both blank. Warn the user of a local repo.")
return &repo, nil
}
// log.Info("GET Namespace from URL", giturl)
tmpURL, err := url.Parse(giturl)
if err != nil {
log.Info(repo.FullPath, "URL parse failed", giturl, err)
return &repo, nil
}
// log.Info(repo.FullPath, "namespace might be:", tmpURL.Hostname(), tmpURL.Path)
repo.Namespace = filepath.Join(tmpURL.Hostname(), tmpURL.Path)
// log.Info(repo.FullPath, "Namesapce =", repo.Namespace)
}
return &repo, nil
}

View File

@ -70,7 +70,6 @@ message Repo { // `autogenpb
GitConfig gitConfig = 25; // protobuf of the current .git/config GitConfig gitConfig = 25; // protobuf of the current .git/config
string MasterHash = 26; // hash of the current master branch string MasterHash = 26; // hash of the current master branch
string DevelHash = 27; // hash of the current devel branch string DevelHash = 27; // hash of the current devel branch
map<string, string> control = 28; // control values. can be used to make packages (like .deb or .rpm)
} }
message Repos { // `autogenpb:marshal` `autogenpb:sort` `autogenpb:gui` `autogenpb:nomutex` `autogenpb:http` message Repos { // `autogenpb:marshal` `autogenpb:sort` `autogenpb:gui` `autogenpb:nomutex` `autogenpb:http`

View File

@ -33,7 +33,7 @@ func (repo *Repo) RevertMasterToDevel() bool {
if repo.RunAll(all) { if repo.RunAll(all) {
log.Info("EVERYTHING OK. RERELEASED", repo.GetGoPath()) log.Info("EVERYTHING OK. RERELEASED", repo.GetGoPath())
repo.ReloadCheck() repo.Reload()
return true return true
} }