1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-11-24 08:52:21 +02:00

More stuff

This commit is contained in:
Jesse Duffield 2018-06-02 13:51:03 +10:00
parent a0c8fc8899
commit 80bcc7c16e
6 changed files with 105 additions and 30 deletions

View File

@ -24,6 +24,19 @@ func handleForceCheckout(g *gocui.Gui, v *gocui.View) error {
}, nil) }, nil)
} }
func handleNewBranch(g *gocui.Gui, v *gocui.View) error {
branch := state.Branches[0]
createPromptPanel(g, v, "New Branch Name (Branch is off of "+branch.Name+")", func(g *gocui.Gui, v *gocui.View) error {
// TODO: make sure the buffer is stripped of whitespace
if output, err := gitNewBranch(v.Buffer()); err != nil {
return createSimpleConfirmationPanel(g, v, "Error", output)
}
refreshSidePanels(g, v)
return handleCommitSelect(g, v)
})
return nil
}
func getSelectedBranch(v *gocui.View) Branch { func getSelectedBranch(v *gocui.View) Branch {
lineNumber := getItemPosition(v) lineNumber := getItemPosition(v)
return state.Branches[lineNumber] return state.Branches[lineNumber]

View File

@ -13,8 +13,8 @@ var (
) )
func refreshCommits(g *gocui.Gui) error { func refreshCommits(g *gocui.Gui) error {
state.Commits = getCommits()
g.Update(func(*gocui.Gui) error { g.Update(func(*gocui.Gui) error {
state.Commits = getCommits()
v, err := g.View("commits") v, err := g.View("commits")
if err != nil { if err != nil {
panic(err) panic(err)
@ -33,14 +33,36 @@ func refreshCommits(g *gocui.Gui) error {
shaColor.Fprint(v, commit.Sha+" ") shaColor.Fprint(v, commit.Sha+" ")
white.Fprintln(v, commit.Name) white.Fprintln(v, commit.Name)
} }
refreshStatus(g)
return nil return nil
}) })
return nil return nil
} }
func handleResetToCommit(g *gocui.Gui, commitView *gocui.View) error {
return createConfirmationPanel(g, commitView, "Reset To Commit", "Are you sure you want to reset to this commit? (y/n)", func(g *gocui.Gui, v *gocui.View) error {
commit, err := getSelectedCommit(g)
devLog(commit)
if err != nil {
panic(err)
}
if output, err := gitResetToCommit(commit.Sha); err != nil {
return createSimpleConfirmationPanel(g, commitView, "Error", output)
}
if err := refreshCommits(g); err != nil {
panic(err)
}
if err := refreshFiles(g); err != nil {
panic(err)
}
resetOrigin(commitView)
return handleCommitSelect(g, nil)
}, nil)
}
func handleCommitSelect(g *gocui.Gui, v *gocui.View) error { func handleCommitSelect(g *gocui.Gui, v *gocui.View) error {
renderString(g, "options", "s: squash down, r: rename") renderString(g, "options", "s: squash down, r: rename, g: reset to this commit")
commit, err := getSelectedCommit(v) commit, err := getSelectedCommit(g)
if err != nil { if err != nil {
if err != ErrNoCommits { if err != ErrNoCommits {
return err return err
@ -55,7 +77,10 @@ func handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
if getItemPosition(v) != 0 { if getItemPosition(v) != 0 {
return createSimpleConfirmationPanel(g, v, "Error", "Can only squash topmost commit") return createSimpleConfirmationPanel(g, v, "Error", "Can only squash topmost commit")
} }
commit, err := getSelectedCommit(v) if len(state.Commits) == 1 {
return createSimpleConfirmationPanel(g, v, "Error", "You have no commits to squash with")
}
commit, err := getSelectedCommit(g)
if err != nil { if err != nil {
return err return err
} }
@ -65,6 +90,7 @@ func handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
if err := refreshCommits(g); err != nil { if err := refreshCommits(g); err != nil {
panic(err) panic(err)
} }
refreshStatus(g)
return handleCommitSelect(g, v) return handleCommitSelect(g, v)
} }
@ -84,10 +110,18 @@ func handleRenameCommit(g *gocui.Gui, v *gocui.View) error {
return nil return nil
} }
func getSelectedCommit(v *gocui.View) (Commit, error) { func getSelectedCommit(g *gocui.Gui) (Commit, error) {
v, err := g.View("commits")
if err != nil {
panic(err)
}
if len(state.Commits) == 0 { if len(state.Commits) == 0 {
return Commit{}, ErrNoCommits return Commit{}, ErrNoCommits
} }
lineNumber := getItemPosition(v) lineNumber := getItemPosition(v)
if lineNumber > len(state.Commits)-1 {
colorLog(color.FgRed, "potential error in getSelected Commit (mismatched ui and state)", state.Commits, lineNumber)
return state.Commits[len(state.Commits)-1], nil
}
return state.Commits[lineNumber], nil return state.Commits[lineNumber], nil
} }

View File

@ -357,8 +357,19 @@ func gitRenameCommit(message string) (string, error) {
return runDirectCommand("git commit --allow-empty --amend -m \"" + message + "\"") return runDirectCommand("git commit --allow-empty --amend -m \"" + message + "\"")
} }
func gitFetch() (string, error) {
return runDirectCommand("git fetch")
}
func gitResetToCommit(sha string) (string, error) {
return runDirectCommand("git reset " + sha)
}
func gitNewBranch(name string) (string, error) {
return runDirectCommand("git checkout -b " + name)
}
func gitUpstreamDifferenceCount() (string, string) { func gitUpstreamDifferenceCount() (string, string) {
// TODO: deal with these errors which appear when we haven't yet pushed a feature branch
pushableCount, err := runDirectCommand("git rev-list @{u}..head --count") pushableCount, err := runDirectCommand("git rev-list @{u}..head --count")
if err != nil { if err != nil {
return "?", "?" return "?", "?"
@ -367,7 +378,7 @@ func gitUpstreamDifferenceCount() (string, string) {
if err != nil { if err != nil {
return "?", "?" return "?", "?"
} }
return strings.Trim(pullableCount, " \n"), strings.Trim(pushableCount, " \n") return strings.Trim(pushableCount, " \n"), strings.Trim(pullableCount, " \n")
} }
func gitCommitsToPush() []string { func gitCommitsToPush() []string {

27
gui.go
View File

@ -6,6 +6,7 @@ import (
// "io/ioutil" // "io/ioutil"
"log" "log"
"time"
// "strings" // "strings"
"github.com/jroimartin/gocui" "github.com/jroimartin/gocui"
@ -155,22 +156,26 @@ func keybindings(g *gocui.Gui) error {
if err := g.SetKeybinding("branches", 'F', gocui.ModNone, handleForceCheckout); err != nil { if err := g.SetKeybinding("branches", 'F', gocui.ModNone, handleForceCheckout); err != nil {
return err return err
} }
if err := g.SetKeybinding("branches", 'n', gocui.ModNone, handleNewBranch); err != nil {
return err
}
if err := g.SetKeybinding("commits", 's', gocui.ModNone, handleCommitSquashDown); err != nil { if err := g.SetKeybinding("commits", 's', gocui.ModNone, handleCommitSquashDown); err != nil {
return err return err
} }
if err := g.SetKeybinding("commits", 'r', gocui.ModNone, handleRenameCommit); err != nil { if err := g.SetKeybinding("commits", 'r', gocui.ModNone, handleRenameCommit); err != nil {
return err return err
} }
if err := g.SetKeybinding("", '∑', gocui.ModNone, handleLogState); err != nil { if err := g.SetKeybinding("commits", 'g', gocui.ModNone, handleResetToCommit); err != nil {
return err
}
if err := g.SetKeybinding("", 'S', gocui.ModNone, genericTest); err != nil {
return err return err
} }
return nil return nil
} }
func handleLogState(g *gocui.Gui, v *gocui.View) error { func genericTest(g *gocui.Gui, v *gocui.View) error {
devLog("state is:", state) pushFiles(g, v)
devLog("previous view:", state.PreviousView)
refreshBranches(g)
return nil return nil
} }
@ -247,6 +252,11 @@ func layout(g *gocui.Gui) error {
return nil return nil
} }
func fetch(g *gocui.Gui) {
gitFetch()
refreshStatus(g)
}
func run() { func run() {
g, err := gocui.NewGui(gocui.OutputNormal) g, err := gocui.NewGui(gocui.OutputNormal)
if err != nil { if err != nil {
@ -254,6 +264,13 @@ func run() {
} }
defer g.Close() defer g.Close()
// periodically fetching to check for upstream differences
go func() {
for range time.Tick(time.Second * 60) {
fetch(g)
}
}()
g.SetManagerFunc(layout) g.SetManagerFunc(layout)
if err := keybindings(g); err != nil { if err := keybindings(g); err != nil {

View File

@ -11,20 +11,26 @@ import (
func refreshStatus(g *gocui.Gui) error { func refreshStatus(g *gocui.Gui) error {
v, err := g.View("status") v, err := g.View("status")
if err != nil { if err != nil {
return err panic(err)
} }
v.Clear() // for some reason if this isn't wrapped in an update the clear seems to
up, down := gitUpstreamDifferenceCount() // be applied after the other things or something like that; the panel's
fmt.Fprint(v, "↑"+up+"↓"+down) // contents end up cleared
branches := state.Branches g.Update(func(*gocui.Gui) error {
if len(branches) == 0 { v.Clear()
pushables, pullables := gitUpstreamDifferenceCount()
fmt.Fprint(v, "↑"+pushables+"↓"+pullables)
branches := state.Branches
if len(branches) == 0 {
return nil
}
branch := branches[0]
// utilising the fact these all have padding to only grab the name
// from the display string with the existing coloring applied
fmt.Fprint(v, " "+branch.DisplayString[4:])
colorLog(color.FgCyan, time.Now().Sub(StartTime))
return nil return nil
} })
branch := branches[0]
// utilising the fact these all have padding to only grab the name
// from the display string with the existing coloring applied
fmt.Fprint(v, " "+branch.DisplayString[4:])
colorLog(color.FgCyan, time.Now().Sub(StartTime))
return nil return nil
} }

View File

@ -1,9 +1,3 @@
// lots of this has been directly ported from one of the example files, will brush up later
// Copyright 2014 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main package main
import ( import (