Compare commits

..

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

12 changed files with 178 additions and 198 deletions

16
argv.go
View File

@ -155,7 +155,7 @@ func DoAutoComplete(pb *prep.Auto) {
case "checkout": case "checkout":
pb.Autocomplete2("devel master user") pb.Autocomplete2("devel master user")
case "clean": case "clean":
pb.Autocomplete2("") fmt.Println("--force verify --repo")
case "commit": case "commit":
pb.Autocomplete2("--all") pb.Autocomplete2("--all")
case "config": case "config":
@ -171,18 +171,26 @@ func DoAutoComplete(pb *prep.Auto) {
case "merge": case "merge":
pb.Autocomplete2("devel master --all") pb.Autocomplete2("devel master --all")
case "normal": case "normal":
pb.Autocomplete2("on off") fmt.Println("on off")
case "pull": case "pull":
pb.Autocomplete2("--force check") fmt.Println("--force check")
case "patch": case "patch":
fmt.Println("check get list repos submit show") fmt.Println("check get list repos submit show")
case "user":
fmt.Println("--force")
case "devel":
fmt.Println("--force")
case "master":
fmt.Println("")
case "verify":
fmt.Println("user devel master")
case "tag": case "tag":
fmt.Println("list --delete clean") fmt.Println("list --delete clean")
default: default:
if pb.Cmd == "" { if pb.Cmd == "" {
pb.Autocomplete2("help list checkout clean commit dirty fetch gui normal merge patch pull tag --gui") pb.Autocomplete2("help list checkout clean commit dirty fetch gui normal merge patch pull tag --gui")
} else { } else {
pb.Autocomplete2("list checkout clean commit dirty normal merge tag") pb.Autocomplete2("list checkout clean commit dirty normal merge")
} }
} }
os.Exit(0) os.Exit(0)

View File

@ -8,7 +8,6 @@ import (
"go.wit.com/lib/config" "go.wit.com/lib/config"
"go.wit.com/lib/protobuf/forgepb" "go.wit.com/lib/protobuf/forgepb"
"go.wit.com/log"
) )
func forgeConfigSave() error { func forgeConfigSave() error {
@ -19,7 +18,6 @@ func setForgeMode(fmode forgepb.ForgeMode) {
if me.forge.Config.Mode == fmode { if me.forge.Config.Mode == fmode {
return return
} }
log.Info("changing mode", me.forge.Config.Mode, fmode)
me.forge.Config.Mode = fmode me.forge.Config.Mode = fmode
config.SetChanged("forge", true) config.SetChanged("forge", true)
me.forge.Config.ConfigSave() me.forge.Config.ConfigSave()

View File

@ -27,7 +27,6 @@ func doCheckout() error {
} }
if argv.Checkout.Devel != nil { if argv.Checkout.Devel != nil {
// setForgeMode(forgepb.ForgeMode_DEVEL)
if err := me.forge.DoAllCheckoutDevelNew(argv.Force); err != nil { if err := me.forge.DoAllCheckoutDevelNew(argv.Force); err != nil {
badExit(err) badExit(err)
} }
@ -35,7 +34,7 @@ func doCheckout() error {
} }
if argv.Checkout.Master != nil { if argv.Checkout.Master != nil {
setForgeMode(forgepb.ForgeMode_MASTER) // disable "normal" mode if set setForgeMode(forgepb.ForgeMode_CLEAN) // disable "normal" mode if set
if err := me.forge.DoAllCheckoutMaster(); err != nil { if err := me.forge.DoAllCheckoutMaster(); err != nil {
badExit(err) badExit(err)

View File

@ -4,61 +4,12 @@
package main package main
import ( import (
"time"
"go.wit.com/lib/config" "go.wit.com/lib/config"
"go.wit.com/lib/gui/shell"
"go.wit.com/lib/protobuf/forgepb" "go.wit.com/lib/protobuf/forgepb"
"go.wit.com/lib/protobuf/gitpb" "go.wit.com/lib/protobuf/gitpb"
"go.wit.com/log" "go.wit.com/log"
) )
func doMerge() error {
if argv.All == true {
start := time.Now()
repos, err := doMergeDevel()
dur := time.Since(start)
if err != nil {
badExit(err)
}
log.Printf("Merged %d devel branches in %s\n", repos.Len(), shell.FormatDuration(dur))
start = time.Now()
repos, err = doMergeMaster()
dur = time.Since(start)
if err != nil {
badExit(err)
}
log.Printf("Merged %d master branches in %s\n", repos.Len(), shell.FormatDuration(dur))
okExit("")
}
if argv.Merge.Devel != nil {
start := time.Now()
repos, err := doMergeDevel()
dur := time.Since(start)
if err != nil {
badExit(err)
}
log.Printf("Merged %d devel branches in %s\n", repos.Len(), shell.FormatDuration(dur))
okExit("")
}
if argv.Merge.Master != nil {
start := time.Now()
repos, err := doMergeMaster()
dur := time.Since(start)
if err != nil {
badExit(err)
}
log.Printf("Merged %d master branches in %s\n", repos.Len(), shell.FormatDuration(dur))
okExit("")
}
repo := findCurrentPwdRepoOrDie()
if err := repoMergeToDevel(repo); err != nil {
badRepoExit(repo, err)
}
return nil
}
func doMergeReport() *forgepb.Patches { func doMergeReport() *forgepb.Patches {
found := forgepb.NewPatches() found := forgepb.NewPatches()
for repo := range me.forge.Repos.IterAll() { for repo := range me.forge.Repos.IterAll() {

View File

@ -75,15 +75,12 @@ func checkNormalRepoState(repo *gitpb.Repo) error {
log.Info("ABNORMAL: master branch name was blank in", repo.GetFullPath()) log.Info("ABNORMAL: master branch name was blank in", repo.GetFullPath())
} }
if repo.GetMasterBranchName() == "" { if repo.GetMasterBranchName() == "" {
me.forge.VerifyBranchNames(repo)
err = log.Errorf("master branch name blank") err = log.Errorf("master branch name blank")
} }
if repo.GetDevelBranchName() == "" { if repo.GetDevelBranchName() == "" {
me.forge.VerifyBranchNames(repo)
err = log.Errorf("devel branch name blank") err = log.Errorf("devel branch name blank")
} }
if repo.GetUserBranchName() == "" { if repo.GetUserBranchName() == "" {
me.forge.VerifyBranchNames(repo)
err = log.Errorf("user branch name blank") err = log.Errorf("user branch name blank")
} }
if repo.GetGoPath() == repo.GetNamespace() { if repo.GetGoPath() == repo.GetNamespace() {

View File

@ -45,16 +45,7 @@ func doPatchSubmit() error {
if err != nil { if err != nil {
return err return err
} }
if pset.Patches == nil { _, _, err = pset.Patches.HttpPostVerbose(myServer(), "new")
log.Info("pset.Patches == nil")
return err
}
if pset.Patches.Len() == 0 {
log.Info("did not find any patches")
return nil
}
pset.PrintTable()
_, _, err = pset.HttpPost(myServer(), "new")
return err return err
} }
@ -73,7 +64,7 @@ func doPatch() error {
} }
if argv.Patch.Get != nil { if argv.Patch.Get != nil {
psets := forgepb.NewSets() psets := forgepb.NewPatchsets()
newpb, _, _ := psets.HttpPostVerbose(myServer(), "get") newpb, _, _ := psets.HttpPostVerbose(myServer(), "get")
newpb.PrintTable() newpb.PrintTable()
me.forge.Patchsets = newpb me.forge.Patchsets = newpb
@ -101,80 +92,66 @@ func doPatch() error {
if argv.Patch.List != nil { if argv.Patch.List != nil {
var changed bool var changed bool
newpatches := new(forgepb.Set) newpatches := forgepb.NewPatches()
newpatches.Patches = forgepb.NewPatches()
for pset := range me.forge.Patchsets.IterAll() { for pset := range me.forge.Patchsets.IterAll() {
pset.PrintTable() log.Info(pset.Uuid)
for patch := range pset.Patches.IterAll() { for patch := range pset.Patches.IterAll() {
changed = true if setNewCommitHash(patch) {
if patch.NewHash == "" || patch.NewHash == "na" { changed = true
if newpatches.Patches.AppendByPatchId(patch) { }
log.Info("patchId added here", patch.PatchId) if patch.NewHash == "na" {
} else { newpatches.Append(patch)
log.Info("patchId already here", patch.PatchId) log.Info("apply this patch?")
}
} else {
if err := setNewCommitHash(patch); err != nil {
log.Infof("%s bad check on patch failure %v\n", patch.Filename, err)
return err
}
log.Info("newhash set already here", patch.PatchId, patch.NewHash)
} }
} }
/*
for patch := range pset.Patches.IterAll() {
if repo, ok := me.forge.IsPatchApplied(patch); ok {
log.Info("\tfound patch in repo", repo.Namespace, patch.Filename)
} else {
log.Info("\tdid not find patch", patch.CommitHash, patch.NewHash, patch.Filename)
}
}
*/
} }
if changed { if changed {
if err := me.forge.SavePatchsets(); err != nil { if err := me.forge.SavePatchsets(); err != nil {
log.Warn("savePatchsets() failed", err) log.Warn("savePatchsets() failed", err)
} }
} }
log.Info("NEW PATCHES TABLE") me.forge.Patchsets.PrintTable()
newpatches.PrintTable() if newpatches.Len() != 0 {
for patch := range newpatches.Patches.IterAll() { for patch := range newpatches.IterAll() {
if err := setNewCommitHash(patch); err == nil { log.Info("new patch:", patch.CommitHash, patch.NewHash, patch.Filename)
log.Info("newhash set already here", patch.PatchId, patch.NewHash) repo := me.forge.FindByGoPath(patch.Namespace)
continue if repo == nil {
} log.Info("\tCould not find namespace:", patch.Namespace)
log.Infof("%s is new\n", patch.Filename) continue
repo := me.forge.FindByGoPath(patch.Namespace) }
if repo == nil { if fhelp.QuestionUser("apply this patch?") {
log.Info("\tCould not find namespace:", patch.Namespace) newhash, err := applyAndTrackPatch(repo, patch)
continue log.Info("apply results:", newhash, err)
}
if fhelp.QuestionUser("apply this patch?") {
newhash, err := applyAndTrackPatch(repo, patch)
log.Info("apply results:", newhash, err)
}
}
return nil
/*
if newpatches.Len() != 0 {
for patch := range newpatches.IterAll() {
log.Info("new patch:", patch.CommitHash, patch.NewHash, patch.Filename)
repo := me.forge.FindByGoPath(patch.Namespace)
if repo == nil {
log.Info("\tCould not find namespace:", patch.Namespace)
continue
}
} }
return log.Errorf("patches need to be applied")
} }
return log.Errorf("patches need to be applied")
}
// return doPatchList() // return doPatchList()
applied := findApplied() applied := findApplied()
if applied == nil || applied.Len() == 0 { if applied == nil || applied.Len() == 0 {
log.Info("no patches have been appled to the devel branch yet") log.Info("no patches have been appled to the devel branch yet")
return nil
}
// for patch := range applied.IterAll() {
// log.Info("SEND APPLIED: newhash:", patch.NewHash, "commithash:", patch.CommitHash, "patch", patch.Namespace)
// }
newpb, _, err := applied.HttpPostVerbose(myServer(), "applied")
if err != nil {
return err
}
newpb.PrintTable()
return nil return nil
*/ }
// for patch := range applied.IterAll() {
// log.Info("SEND APPLIED: newhash:", patch.NewHash, "commithash:", patch.CommitHash, "patch", patch.Namespace)
// }
newpb, _, err := applied.HttpPostVerbose(myServer(), "applied")
if err != nil {
return err
}
newpb.PrintTable()
return nil
} }
// if nothing, show patches & dirty repos // if nothing, show patches & dirty repos
@ -207,7 +184,7 @@ func dumpWorkRepos() bool {
// returns bad if patches can not be applied // returns bad if patches can not be applied
// logic is not great here but it was a first pass // logic is not great here but it was a first pass
func dumpPatchset(pset *forgepb.Set) bool { func dumpPatchset(pset *forgepb.Patchset) bool {
// don't even bother to continue if we already know it's broken // don't even bother to continue if we already know it's broken
if pset.State == "BROKEN" { if pset.State == "BROKEN" {
log.Printf("Patchset Name: %-24s Author: %s <%s> IS BAD\n", pset.Name, pset.GetGitAuthorName(), pset.GetGitAuthorEmail()) log.Printf("Patchset Name: %-24s Author: %s <%s> IS BAD\n", pset.Name, pset.GetGitAuthorName(), pset.GetGitAuthorEmail())

View File

@ -39,7 +39,7 @@ func doTag() error {
if argv.Tag.List != nil { if argv.Tag.List != nil {
repo := findCurrentPwdRepoOrDie() repo := findCurrentPwdRepoOrDie()
tagTablePB := makeTagTablePB(repo, repo.Tags) tagTablePB := makeTagTablePB(repo.Tags)
// tbox := win.Bottom.Box().SetProgName("TBOX") // tbox := win.Bottom.Box().SetProgName("TBOX")
// t.SetParent(tbox) // t.SetParent(tbox)
tagTablePB.MakeTable() tagTablePB.MakeTable()
@ -56,15 +56,13 @@ func doTag() error {
} }
// check if the git tag already exists somehow // check if the git tag already exists somehow
/*
if !repo.LocalTagExists(testtag) {
log.Info("Tag", testtag, "does not exist")
return log.Errorf("%s TAG DOES NOT EXIST %s", repo.FullPath, testtag)
}
*/
testtag := argv.Tag.Delete testtag := argv.Tag.Delete
if !repo.LocalTagExists(testtag) {
log.Info("Tag", testtag, "does not exist")
return log.Errorf("%s TAG DOES NOT EXIST %s", repo.FullPath, testtag)
}
if !argv.Force { if !argv.Force {
if !fhelp.QuestionUser(log.Sprintf("delete tag '%s'?", testtag)) { if !fhelp.QuestionUser("delete this tag?") {
return nil return nil
} }
} }
@ -80,46 +78,40 @@ func doTag() error {
return nil return nil
} }
func makeTagTablePB(repo *gitpb.Repo, pb *gitpb.GitTags) *gitpb.GitTagsTable { func makeTagTablePB(pb *gitpb.GitTags) *gitpb.GitTagsTable {
t := pb.NewTable("tagList") t := pb.NewTable("tagList")
t.NewUuid() t.NewUuid()
col := t.AddHash() col := t.AddHash()
col.Width = 12 col.Width = 12
col = t.AddStringFunc("bashash", func(tag *gitpb.GitTag) string {
_, base := filepath.Split(tag.Refname)
cmd, err := repo.RunStrict([]string{"git", "log", "-1", base, "--format=%H"})
if err != nil {
return "err"
}
if len(cmd.Stdout) == 0 {
return ""
}
return cmd.Stdout[0]
})
col.Width = 12
col = t.AddTimeFunc("ctime", func(tag *gitpb.GitTag) time.Time {
// todo
return tag.Creatordate.AsTime()
})
col.Width = 4
col = t.AddTimeFunc("age", func(repo *gitpb.GitTag) time.Time {
// todo
return time.Now()
})
col.Width = 4
col = t.AddStringFunc("Ref Name", func(r *gitpb.GitTag) string { col = t.AddStringFunc("Ref Name", func(r *gitpb.GitTag) string {
_, ref := filepath.Split(r.GetRefname()) _, ref := filepath.Split(r.GetRefname())
return ref return ref
}) })
col.Width = 16 col.Width = 16
// col.Width = -1
col = t.AddTimeFunc("age", func(repo *gitpb.GitTag) time.Time {
// todo
return time.Now()
})
col.Width = 6
col = t.AddTimeFunc("ctime", func(tag *gitpb.GitTag) time.Time {
// todo
return tag.Creatordate.AsTime()
})
col.Width = 16
col = t.AddIntFunc("int", func(tag *gitpb.GitTag) int {
// todo
return 3
})
col.Width = 4
col = t.AddSubject() col = t.AddSubject()
col.Width = -1 col.Width = 16
return t return t
} }

19
doc.go
View File

@ -3,14 +3,20 @@ forge -- a tool to manage lots of git repos. forge includes a GUI and TUI.
forge only executes the 'git' command. Everything it does, you can run by hand with 'git'. forge only executes the 'git' command. Everything it does, you can run by hand with 'git'.
forge v0.22.138-6-gaea7f16 Built on 2025.09.03_1935
Usage: forge [--debugger] [--logger] [--no-gui] [--gui GUI] [--gui-file GUI-FILE] [--gui-build] [--gui-verbose] [--gui-check-plugin GUI-CHECK-PLUGIN] [--connect CONNECT] [--all] [--build BUILD] [--install INSTALL] [--forge-rebuild] [--force] [--verbose] [--bash] [--auto-complete AUTO-COMPLETE] <command> [<args>]
Options: Options:
--debugger open the debugger window --debugger open the debugger window
--logger open the log.* control window --logger open the log.* control window
--gui GUI select the plugin (andlabs,gocui,etc) --no-gui ignore all these gui problems
--gui GUI Use this gui toolkit [andlabs,gocui,nocui,stdin]
--gui-file GUI-FILE Use a specific plugin.so file
--gui-build attempt to build the GUI plugins
--gui-verbose enable all logging --gui-verbose enable all logging
--bash generate bash completion --gui-check-plugin GUI-CHECK-PLUGIN
--bash generate bash completion hack to verify GO plugins load
--connect CONNECT forge url --connect CONNECT forge url
--all git commit --all --all git commit --all
--build BUILD build a repo --build BUILD build a repo
@ -18,24 +24,25 @@ Options:
--forge-rebuild download and rebuild forge --forge-rebuild download and rebuild forge
--force try to strong arm things --force try to strong arm things
--verbose show more output --verbose show more output
--bash generate bash completion
--auto-complete AUTO-COMPLETE
todo: move this to go-arg
--help, -h display this help and exit --help, -h display this help and exit
--version display version and exit --version display version and exit
Commands: Commands:
help New to forge? This is for you.'
checkout switch branches using 'git checkout' checkout switch branches using 'git checkout'
clean start over at the beginning clean start over at the beginning
commit 'git commit' but errors out if on wrong branch commit 'git commit' but errors out if on wrong branch
config show your .config/forge/ settings config show your .config/forge/ settings
debug debug forge
dirty show dirty git repos dirty show dirty git repos
fetch run 'git fetch master' fetch run 'git fetch master'
gui open the gui
list print a table of the current repos list print a table of the current repos
merge merge branches merge merge branches
normal set every repo to the default state for software development normal set every repo to the default state for software development
patch make patchsets patch make patchsets
pull run 'git pull' pull run 'git pull'
tag manage git tags
*/ */
package main package main

View File

@ -38,7 +38,7 @@ type stdPatchsetTableWin struct {
sync.Mutex sync.Mutex
win *gadgets.GenericWindow // the machines gui window win *gadgets.GenericWindow // the machines gui window
box *gui.Node // the machines gui parent box widget box *gui.Node // the machines gui parent box widget
TB *forgepb.SetsTable // the gui table buffer TB *forgepb.PatchsetsTable // the gui table buffer
update bool // if the window should be updated update bool // if the window should be updated
} }
@ -54,7 +54,7 @@ func (w *stdPatchsetTableWin) Toggle() {
*/ */
/* /*
etimef := func(e *forgepb.Set) string { etimef := func(e *forgepb.Patchset) string {
etime := e.Etime.AsTime() etime := e.Etime.AsTime()
s := etime.Format("2006/01/02 15:04") s := etime.Format("2006/01/02 15:04")
if strings.HasPrefix(s, "1970/") { if strings.HasPrefix(s, "1970/") {
@ -67,14 +67,14 @@ func (w *stdPatchsetTableWin) Toggle() {
*/ */
/* /*
ctimef := func(p *forgepb.Set) string { ctimef := func(p *forgepb.Patchset) string {
ctime := p.Ctime.AsTime() ctime := p.Ctime.AsTime()
return ctime.Format("2006/01/02 15:04") return ctime.Format("2006/01/02 15:04")
} }
} }
*/ */
func setPatchsetState(p *forgepb.Set) { func setPatchsetState(p *forgepb.Patchset) {
var bad bool var bad bool
var good bool var good bool
var done bool = true var done bool = true
@ -173,33 +173,53 @@ func findCommitBySubject(subject string) (string, error) {
} }
// returns true if PB changed // returns true if PB changed
func setNewCommitHash(patch *forgepb.Patch) error { func setNewCommitHash(patch *forgepb.Patch) bool {
// parts := strings.Fields(patch.Comment)
repo := me.forge.FindByGoPath(patch.Namespace) repo := me.forge.FindByGoPath(patch.Namespace)
if repo == nil { if repo == nil {
return log.Errorf("could not find repo %s", patch.Namespace) log.Info("could not find repo", patch.Namespace)
return false
} }
comment := cleanSubject(patch.Comment) comment := cleanSubject(patch.Comment)
if patch.NewHash == "" {
log.Info("init() new patch to 'na' ", patch.NewHash, "commithash:", patch.CommitHash, patch.Namespace, comment)
patch.NewHash = "na"
return true
}
os.Chdir(repo.GetFullPath()) os.Chdir(repo.GetFullPath())
newhash, err := findCommitBySubject(comment) newhash, err := findCommitBySubject(comment)
if err != nil { if err != nil {
return log.Errorf("patch: not found hash: %s %s %s %s %v", patch.CommitHash, patch.Namespace, comment, newhash, err) log.Info("patch: not found hash:", patch.CommitHash, patch.Namespace, comment, newhash, err)
return false
} }
if patch.NewHash == newhash {
patchId, err := repo.FindPatchId(newhash) // patch was already set
if err != nil { return false
return err }
if patch.NewHash != "na" {
log.Infof("patch: hash MISMATCH %s old=%s new=%s name=%s\n", patch.Namespace, patch.NewHash, newhash, comment)
return false
} }
patch.PatchId = patchId
patch.NewHash = newhash patch.NewHash = newhash
log.Info("patch: found hash:", patch.CommitHash, newhash, patch.Namespace, comment) log.Info("patch: found hash:", patch.CommitHash, newhash, patch.Namespace, comment)
return nil return true
} }
func AddAllPatches(notdone *forgepb.Patches, pset *forgepb.Set, full bool) { /*
func setNewCommitHashLoop(p *forgepb.Patchset) bool {
var done bool = true
for patch := range p.Patches.IterAll() {
setNewCommitHashLoop(patch)
}
return done
}
*/
func AddAllPatches(notdone *forgepb.Patches, pset *forgepb.Patchset, full bool) {
for patch := range pset.Patches.IterAll() { for patch := range pset.Patches.IterAll() {
comment := cleanSubject(patch.Comment) comment := cleanSubject(patch.Comment)
@ -213,7 +233,7 @@ func AddAllPatches(notdone *forgepb.Patches, pset *forgepb.Set, full bool) {
} }
} }
func AddNotDonePatches(notdone *forgepb.Patches, pset *forgepb.Set, full bool) { func AddNotDonePatches(notdone *forgepb.Patches, pset *forgepb.Patchset, full bool) {
for patch := range pset.Patches.IterAll() { for patch := range pset.Patches.IterAll() {
comment := cleanSubject(patch.Comment) comment := cleanSubject(patch.Comment)
@ -231,7 +251,7 @@ func AddNotDonePatches(notdone *forgepb.Patches, pset *forgepb.Set, full bool) {
continue continue
} }
if patch.NewHash != "" { if patch.NewHash != "na" {
log.Info("already applied patch", patch.Namespace, ": newhash:", patch.NewHash, "commithash:", patch.CommitHash, comment) log.Info("already applied patch", patch.Namespace, ": newhash:", patch.NewHash, "commithash:", patch.CommitHash, comment)
continue continue
} }
@ -281,7 +301,7 @@ func findExpired() *forgepb.Patches {
continue continue
} }
if patch.NewHash != "" { if patch.NewHash != "na" {
log.Info("already applied patch", patch.Namespace, ": newhash:", patch.NewHash, "commithash:", patch.CommitHash, comment) log.Info("already applied patch", patch.Namespace, ": newhash:", patch.NewHash, "commithash:", patch.CommitHash, comment)
found.AppendByCommitHash(patch) // double check to ensure the commit hash isn't added twice found.AppendByCommitHash(patch) // double check to ensure the commit hash isn't added twice
continue continue

32
main.go
View File

@ -8,8 +8,10 @@ package main
import ( import (
"embed" "embed"
"strings" "strings"
"time"
"go.wit.com/lib/gui/prep" "go.wit.com/lib/gui/prep"
"go.wit.com/lib/gui/shell"
"go.wit.com/lib/protobuf/forgepb" "go.wit.com/lib/protobuf/forgepb"
"go.wit.com/lib/protobuf/gitpb" "go.wit.com/lib/protobuf/gitpb"
"go.wit.com/log" "go.wit.com/log"
@ -71,6 +73,7 @@ func main() {
} }
if argv.Checkout != nil { if argv.Checkout != nil {
setForgeMode(forgepb.ForgeMode_DEVEL)
if err := doCheckout(); err != nil { if err := doCheckout(); err != nil {
badExit(err) badExit(err)
} }
@ -155,8 +158,33 @@ func main() {
} }
if argv.Merge != nil { if argv.Merge != nil {
if err := doMerge(); err != nil { if argv.All == true {
badExit(err)
if argv.Merge.Devel != nil {
start := time.Now()
repos, err := doMergeDevel()
dur := time.Since(start)
if err != nil {
badExit(err)
}
log.Printf("Merged %d devel branches in %s\n", repos.Len(), shell.FormatDuration(dur))
okExit("")
}
if argv.Merge.Master != nil {
start := time.Now()
repos, err := doMergeMaster()
dur := time.Since(start)
if err != nil {
badExit(err)
}
log.Printf("Merged %d master branches in %s\n", repos.Len(), shell.FormatDuration(dur))
okExit("")
}
}
repo := findCurrentPwdRepoOrDie()
if err := repoMergeToDevel(repo); err != nil {
badRepoExit(repo, err)
} }
okExit("") okExit("")
} }

View File

@ -117,9 +117,12 @@ func applyPatchLabel(p *forgepb.Patch) string {
// log.Info("Could not figure out repo path", rn) // log.Info("Could not figure out repo path", rn)
return "" return ""
} }
if p.NewHash == "" { if p.NewHash == "na" {
return "git am" return "git am"
} }
if p.NewHash == "" {
return "new"
}
return "done" return "done"
} }

View File

@ -21,8 +21,8 @@ type repoPatchWindow struct {
shelf *gui.Node // the first box in the stack, set as horizontal shelf *gui.Node // the first box in the stack, set as horizontal
grid *gui.Node // the list of available patches grid *gui.Node // the list of available patches
// summary *patchSummary // summary of current patches // summary *patchSummary // summary of current patches
setgrid *gui.Node // the list of each patchset setgrid *gui.Node // the list of each patchset
pset *forgepb.Set // the patchset in question pset *forgepb.Patchset // the patchset in question
} }
// todo: autogenerate these or make them standared 'gui' package functions // todo: autogenerate these or make them standared 'gui' package functions
@ -109,7 +109,7 @@ func makeRepoPatchWindow(repo *gitpb.Repo, fset []*forgepb.Patch) *repoPatchWind
return pw return pw
} }
func (r *repoPatchWindow) addPatchset(grid *gui.Node, pset *forgepb.Set) { func (r *repoPatchWindow) addPatchset(grid *gui.Node, pset *forgepb.Patchset) {
repomap := make(map[*gitpb.Repo][]*forgepb.Patch) repomap := make(map[*gitpb.Repo][]*forgepb.Patch)
repohash := make(map[*gitpb.Repo]string) repohash := make(map[*gitpb.Repo]string)