summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/app/app.go2
-rw-r--r--pkg/git/branch.go6
-rw-r--r--pkg/git/stash.go11
-rw-r--r--pkg/git/status.go24
-rw-r--r--pkg/gui/diffview.go149
-rw-r--r--pkg/gui/gui.go3
-rw-r--r--pkg/gui/keybindings.go43
-rw-r--r--pkg/gui/queuehandler.go1
-rw-r--r--pkg/gui/statusview.go2
-rw-r--r--pkg/gui/textstyle.go25
10 files changed, 193 insertions, 73 deletions
diff --git a/pkg/app/app.go b/pkg/app/app.go
index 9082386..740e3ff 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -33,7 +33,7 @@ func Setup(setupConfig SetupConfig) (*App, error) {
log.Error(err)
return app, err
}
- directories := make([]string, 0)
+ var directories []string
if len(app.Config.Directories) <= 0 || setupConfig.IgnoreConfig {
directories = generateDirectories(setupConfig.Directories, setupConfig.Depth)
diff --git a/pkg/git/branch.go b/pkg/git/branch.go
index 0fbfdf0..ace5f79 100644
--- a/pkg/git/branch.go
+++ b/pkg/git/branch.go
@@ -130,10 +130,8 @@ func (entity *RepoEntity) Checkout(branch *Branch) error {
entity.Branch = branch
entity.RefreshPushPull()
// make this conditional on global scale
- if err := entity.Remote.SyncBranches(branch.Name); err != nil {
- return err
- }
- return nil
+ err = entity.Remote.SyncBranches(branch.Name)
+ return err
}
// checking the branch if it has any changes from its head revision. Initially
diff --git a/pkg/git/stash.go b/pkg/git/stash.go
index 66254c8..9d813a6 100644
--- a/pkg/git/stash.go
+++ b/pkg/git/stash.go
@@ -93,3 +93,14 @@ func (stashedItem *StashedItem) Pop() (output string, err error) {
output, err = GenericGitCommandWithErrorOutput(stashedItem.EntityPath, args)
return output, err
}
+
+// Show is the wrapper of "git stash show -p " command
+func (stashedItem *StashedItem) Show() (output string, err error) {
+ args := make([]string, 0)
+ args = append(args, stashCommand)
+ args = append(args, "show")
+ args = append(args, "-p")
+ args = append(args, "stash@{"+strconv.Itoa(stashedItem.StashID)+"}")
+ output, err = GenericGitCommandWithErrorOutput(stashedItem.EntityPath, args)
+ return output, err
+}
diff --git a/pkg/git/status.go b/pkg/git/status.go
index 8db2ec7..4cca604 100644
--- a/pkg/git/status.go
+++ b/pkg/git/status.go
@@ -25,21 +25,21 @@ var (
// StatusNotupdated says file not updated
StatusNotupdated FileStatus = ' '
// StatusModified says file is modifed
- StatusModified FileStatus = 'M'
+ StatusModified FileStatus = 'M'
// StatusAdded says file is added to index
- StatusAdded FileStatus = 'A'
+ StatusAdded FileStatus = 'A'
// StatusDeleted says file is deleted
- StatusDeleted FileStatus = 'D'
+ StatusDeleted FileStatus = 'D'
// StatusRenamed says file is renamed
- StatusRenamed FileStatus = 'R'
+ StatusRenamed FileStatus = 'R'
// StatusCopied says file is copied
- StatusCopied FileStatus = 'C'
+ StatusCopied FileStatus = 'C'
// StatusUpdated says file is updated
- StatusUpdated FileStatus = 'U'
+ StatusUpdated FileStatus = 'U'
// StatusUntracked says file is untraced
StatusUntracked FileStatus = '?'
// StatusIgnored says file is ignored
- StatusIgnored FileStatus = '!'
+ StatusIgnored FileStatus = '!'
)
func shortStatus(entity *RepoEntity, option string) string {
@@ -79,3 +79,13 @@ func (entity *RepoEntity) LoadFiles() ([]*File, error) {
}
return files, nil
}
+
+// Diff is a wrapper of "git diff" command for a file to compare with HEAD rev
+func (file *File) Diff() (output string, err error) {
+ args := make([]string, 0)
+ args = append(args, "diff")
+ args = append(args, "HEAD")
+ args = append(args, file.Name)
+ output, err = GenericGitCommandWithErrorOutput(strings.TrimSuffix(file.AbsPath, file.Name), args)
+ return output, err
+}
diff --git a/pkg/gui/diffview.go b/pkg/gui/diffview.go
index b775f95..f99d7f2 100644
--- a/pkg/gui/diffview.go
+++ b/pkg/gui/diffview.go
@@ -2,42 +2,121 @@ package gui
import (
"fmt"
- "regexp"
- "strings"
+ "github.com/isacikgoz/gitbatch/pkg/git"
"github.com/jroimartin/gocui"
)
-// open diff view for the selcted commit
-func (gui *Gui) openCommitDiffView(g *gocui.Gui, v *gocui.View) error {
+var diffReturnView string
+
+// renders the diff view
+func (gui *Gui) prepareDiffView(g *gocui.Gui, v *gocui.View, display []string) (out *gocui.View, err error) {
maxX, maxY := g.Size()
- v, err := g.SetView(commitDiffViewFeature.Name, 5, 3, maxX-5, maxY-3)
+ diffReturnView = v.Name()
+ out, err = g.SetView(diffViewFeature.Name, 5, 3, maxX-5, maxY-3)
+ if err != nil {
+ if err != gocui.ErrUnknownView {
+ return out, err
+ }
+ }
+ out.Title = diffViewFeature.Title
+ out.Overwrite = true
+ out.Wrap = true
+ gui.updateKeyBindingsView(g, diffViewFeature.Name)
+ if _, err = g.SetCurrentView(diffViewFeature.Name); err != nil {
+ return out, err
+ }
+ for _, line := range display {
+ fmt.Fprintln(out, line)
+ }
+ return out, err
+}
+
+// open diff view for the selcted commit
+// called from commitview, so initial view is commitview
+func (gui *Gui) openCommitDiffView(g *gocui.Gui, v *gocui.View) (err error) {
+ entity := gui.getSelectedRepository()
+ commit := entity.Commit
+ commitDetail := []string{("Hash: " + cyan.Sprint(commit.Hash) + "\n" + "Author: " + commit.Author +
+ "\n" + commit.Time + "\n" + "\n" + "\t\t" + commit.Message + "\n")}
+ diff, err := entity.Diff(entity.Commit.Hash)
+ if err != nil {
+ return err
+ }
+ colorized := colorizeDiff(diff)
+ commitDetail = append(commitDetail, colorized...)
+ out, err := gui.prepareDiffView(g, v, commitDetail)
if err != nil {
if err != gocui.ErrUnknownView {
return err
}
- v.Title = commitDiffViewFeature.Title
- v.Overwrite = true
- v.Wrap = true
+ }
+ out.Title = " Commit Detail "
+ return nil
+}
- entity := gui.getSelectedRepository()
- commit := entity.Commit
- commitDetail := "Hash: " + cyan.Sprint(commit.Hash) + "\n" + "Author: " + commit.Author +
- "\n" + commit.Time + "\n" + "\n" + "\t\t" + commit.Message + "\n"
- fmt.Fprintln(v, commitDetail)
- diff, err := entity.Diff(entity.Commit.Hash)
- if err != nil {
+// called from status, so initial view may be stagedview or unstaged view
+func (gui *Gui) openFileDiffView(g *gocui.Gui, v *gocui.View) (err error) {
+ entity := gui.getSelectedRepository()
+ _, cy := v.Cursor()
+ _, oy := v.Origin()
+ var files []*git.File
+ switch v.Name() {
+ case unstageViewFeature.Name:
+ _, files, err = generateFileLists(entity)
+ case stageViewFeature.Name:
+ files, _, err = generateFileLists(entity)
+ }
+ if err != nil {
+ return err
+ }
+ if len(files) <= 0 {
+ return nil
+ }
+ output, err := files[cy+oy].Diff()
+ if err != nil || len(output) <= 0 {
+ return nil
+ }
+ if err != nil {
+ if err = gui.openErrorView(g, output,
+ "You should manually resolve this issue",
+ diffReturnView); err != nil {
return err
}
- colorized := colorizeDiff(diff)
- for _, line := range colorized {
- fmt.Fprintln(v, line)
+ }
+ colorized := colorizeDiff(output)
+ _, err = gui.prepareDiffView(g, v, colorized)
+ if err != nil {
+ if err != gocui.ErrUnknownView {
+ return err
}
}
+ return nil
+}
- gui.updateKeyBindingsView(g, commitDiffViewFeature.Name)
- if _, err := g.SetCurrentView(commitDiffViewFeature.Name); err != nil {
- return err
+// called from stashview, so initial view is stashview
+func (gui *Gui) showStash(g *gocui.Gui, v *gocui.View) (err error) {
+ entity := gui.getSelectedRepository()
+ _, oy := v.Origin()
+ _, cy := v.Cursor()
+ if len(entity.Stasheds) <= 0 {
+ return nil
+ }
+ stashedItem := entity.Stasheds[oy+cy]
+ output, err := stashedItem.Show()
+ if err != nil {
+ if err = gui.openErrorView(g, output,
+ "You should manually resolve this issue",
+ stashViewFeature.Name); err != nil {
+ return err
+ }
+ }
+ colorized := colorizeDiff(output)
+ _, err = gui.prepareDiffView(g, v, colorized)
+ if err != nil {
+ if err != gocui.ErrUnknownView {
+ return err
+ }
}
return nil
}
@@ -47,33 +126,9 @@ func (gui *Gui) closeCommitDiffView(g *gocui.Gui, v *gocui.View) error {
if err := g.DeleteView(v.Name()); err != nil {
return nil
}
- if _, err := g.SetCurrentView(commitViewFeature.Name); err != nil {
+ if _, err := g.SetCurrentView(diffReturnView); err != nil {
return err
}
- gui.updateKeyBindingsView(g, commitViewFeature.Name)
+ gui.updateKeyBindingsView(g, diffReturnView)
return nil
}
-
-// colorize the plain diff text collected from system output
-// the style is near to original diff command
-func colorizeDiff(original string) (colorized []string) {
- colorized = strings.Split(original, "\n")
- re := regexp.MustCompile(`@@ .+ @@`)
- for i, line := range colorized {
- if len(line) > 0 {
- if line[0] == '-' {
- colorized[i] = red.Sprint(line)
- } else if line[0] == '+' {
- colorized[i] = green.Sprint(line)
- } else if re.MatchString(line) {
- s := re.FindString(line)
- colorized[i] = cyan.Sprint(s) + line[len(s):]
- } else {
- continue
- }
- } else {
- continue
- }
- }
- return colorized
-}
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 2e75b4a..290cb88 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -61,7 +61,7 @@ var (
commitViewFeature = viewFeature{Name: "commits", Title: " Commits "}
scheduleViewFeature = viewFeature{Name: "schedule", Title: " Schedule "}
keybindingsViewFeature = viewFeature{Name: "keybindings", Title: " Keybindings "}
- commitDiffViewFeature = viewFeature{Name: "commitdiff", Title: " Commit Detail "}
+ diffViewFeature = viewFeature{Name: "diff", Title: " Diff Detail "}
cheatSheetViewFeature = viewFeature{Name: "cheatsheet", Title: " Application Controls "}
errorViewFeature = viewFeature{Name: "error", Title: " Error "}
@@ -212,6 +212,7 @@ func (gui *Gui) previousMainView(g *gocui.Gui, v *gocui.View) error {
err := gui.previousViewOfGroup(g, v, mainViews)
return err
}
+
// quit from the gui and end its loop
func (gui *Gui) quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 1a6d6c9..a9cfe63 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -176,6 +176,14 @@ func (gui *Gui) generateKeybindings() error {
Display: "p",
Description: "Pop Item",
Vital: true,
+ }, {
+ View: stashViewFeature.Name,
+ Key: 'd',
+ Modifier: gocui.ModNone,
+ Handler: gui.showStash,
+ Display: "d",
+ Description: "Show diff",
+ Vital: true,
},
// staged view
{
@@ -194,6 +202,14 @@ func (gui *Gui) generateKeybindings() error {
Display: "ctrl+r",
Description: "Reset All Items",
Vital: true,
+ }, {
+ View: stageViewFeature.Name,
+ Key: 'd',
+ Modifier: gocui.ModNone,
+ Handler: gui.openFileDiffView,
+ Display: "d",
+ Description: "Show diff",
+ Vital: true,
},
// unstaged view
{
@@ -212,6 +228,14 @@ func (gui *Gui) generateKeybindings() error {
Display: "ctrl+a",
Description: "Add All Items",
Vital: true,
+ }, {
+ View: unstageViewFeature.Name,
+ Key: 'd',
+ Modifier: gocui.ModNone,
+ Handler: gui.openFileDiffView,
+ Display: "d",
+ Description: "Show diff",
+ Vital: true,
},
// Main view controls
{
@@ -473,7 +497,7 @@ func (gui *Gui) generateKeybindings() error {
},
// Diff View Controls
{
- View: commitDiffViewFeature.Name,
+ View: diffViewFeature.Name,
Key: 'c',
Modifier: gocui.ModNone,
Handler: gui.closeCommitDiffView,
@@ -481,7 +505,7 @@ func (gui *Gui) generateKeybindings() error {
Description: "close/cancel",
Vital: true,
}, {
- View: commitDiffViewFeature.Name,
+ View: diffViewFeature.Name,
Key: gocui.KeyArrowUp,
Modifier: gocui.ModNone,
Handler: gui.fastCursorUp,
@@ -489,7 +513,7 @@ func (gui *Gui) generateKeybindings() error {
Description: "Page up",
Vital: true,
}, {
- View: commitDiffViewFeature.Name,
+ View: diffViewFeature.Name,
Key: gocui.KeyArrowDown,
Modifier: gocui.ModNone,
Handler: gui.fastCursorDown,
@@ -497,7 +521,7 @@ func (gui *Gui) generateKeybindings() error {
Description: "Page down",
Vital: true,
}, {
- View: commitDiffViewFeature.Name,
+ View: diffViewFeature.Name,
Key: 'k',
Modifier: gocui.ModNone,
Handler: gui.fastCursorUp,
@@ -505,7 +529,7 @@ func (gui *Gui) generateKeybindings() error {
Description: "Page up",
Vital: false,
}, {
- View: commitDiffViewFeature.Name,
+ View: diffViewFeature.Name,
Key: 'j',
Modifier: gocui.ModNone,
Handler: gui.fastCursorDown,
@@ -630,16 +654,13 @@ func (gui *Gui) updateKeyBindingsView(g *gocui.Gui, viewName string) error {
switch mode := gui.State.Mode.ModeID; mode {
case FetchMode:
v.BgColor = gocui.ColorBlue
- v.FgColor = gocui.ColorWhite
- modeLabel = fetchSymbol + ws + bold.Sprint("FETCH")
+ modeLabel = fetchSymbol + ws + "FETCH"
case PullMode:
v.BgColor = gocui.ColorMagenta
- v.FgColor = gocui.ColorWhite
- modeLabel = pullSymbol + ws + bold.Sprint("PULL")
+ modeLabel = pullSymbol + ws + "PULL"
case MergeMode:
v.BgColor = gocui.ColorCyan
- v.FgColor = gocui.ColorBlack
- modeLabel = mergeSymbol + ws + black.Sprint(bold.Sprint("MERGE"))
+ modeLabel = mergeSymbol + ws + "MERGE"
default:
modeLabel = "No mode selected"
}
diff --git a/pkg/gui/queuehandler.go b/pkg/gui/queuehandler.go
index cbbc372..3be1472 100644
--- a/pkg/gui/queuehandler.go
+++ b/pkg/gui/queuehandler.go
@@ -9,7 +9,6 @@ import (
func (gui *Gui) startQueue(g *gocui.Gui, v *gocui.View) error {
go func(gui_go *Gui, g_go *gocui.Gui) {
for {
- indicateQueueStarted(g_go)
job, finished, err := gui_go.State.Queue.StartNext()
g_go.Update(func(gu *gocui.Gui) error {
gui_go.refreshMain(gu)
diff --git a/pkg/gui/statusview.go b/pkg/gui/statusview.go
index 282d643..d6f0be1 100644
--- a/pkg/gui/statusview.go
+++ b/pkg/gui/statusview.go
@@ -11,7 +11,7 @@ var (
statusHeaderViewFeature = viewFeature{Name: "status-header", Title: " Status Header "}
// statusViewFeature = viewFeature{Name: "status", Title: " Status "}
stageViewFeature = viewFeature{Name: "staged", Title: " Staged "}
- unstageViewFeature = viewFeature{Name: "unstaged", Title: " Unstaged "}
+ unstageViewFeature = viewFeature{Name: "unstaged", Title: " Not Staged "}
stashViewFeature = viewFeature{Name: "stash", Title: " Stash "}
statusViews = []viewFeature{stageViewFeature, unstageViewFeature, stashViewFeature}
diff --git a/pkg/gui/textstyle.go b/pkg/gui/textstyle.go
index 50bc945..33f172d 100644
--- a/pkg/gui/textstyle.go
+++ b/pkg/gui/textstyle.go
@@ -2,6 +2,7 @@ package gui
import (
"regexp"
+ "strings"
"github.com/fatih/color"
"github.com/isacikgoz/gitbatch/pkg/git"
@@ -118,6 +119,30 @@ func adjustTextLength(text string, maxLength int) (adjusted string) {
return text
}
+// colorize the plain diff text collected from system output
+// the style is near to original diff command
+func colorizeDiff(original string) (colorized []string) {
+ colorized = strings.Split(original, "\n")
+ re := regexp.MustCompile(`@@ .+ @@`)
+ for i, line := range colorized {
+ if len(line) > 0 {
+ if line[0] == '-' {
+ colorized[i] = red.Sprint(line)
+ } else if line[0] == '+' {
+ colorized[i] = green.Sprint(line)
+ } else if re.MatchString(line) {
+ s := re.FindString(line)
+ colorized[i] = cyan.Sprint(s) + line[len(s):]
+ } else {
+ continue
+ }
+ } else {
+ continue
+ }
+ }
+ return colorized
+}
+
// the remote link can be too verbose sometimes, so it is good to trim it
func trimRemoteURL(url string) (urltype string, shorturl string) {
// lets trim the unnecessary .git extension of the url