summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2020-08-27 20:50:30 +1000
committerJesse Duffield <jessedduffield@gmail.com>2020-08-27 21:51:07 +1000
commit40bec49de8428be4e771f2ded1e8ffecbd0c4fd5 (patch)
treef97d7d748bb2441d867e5b81c3a9a9323dde0aa6
parentf99d5f74d49109c19f7701005e636a38c9a70fdb (diff)
more efficient refreshing of rebase commits
-rw-r--r--pkg/commands/commit_list_builder.go71
-rw-r--r--pkg/commands/commit_list_builder_test.go9
-rw-r--r--pkg/gui/commits_panel.go25
-rw-r--r--pkg/gui/gui.go1
-rw-r--r--pkg/gui/sub_commits_panel.go2
5 files changed, 74 insertions, 34 deletions
diff --git a/pkg/commands/commit_list_builder.go b/pkg/commands/commit_list_builder.go
index 46c59d38b..bebc78253 100644
--- a/pkg/commands/commit_list_builder.go
+++ b/pkg/commands/commit_list_builder.go
@@ -28,21 +28,19 @@ const SEPARATION_CHAR = "|"
// CommitListBuilder returns a list of Branch objects for the current repo
type CommitListBuilder struct {
- Log *logrus.Entry
- GitCommand *GitCommand
- OSCommand *OSCommand
- Tr *i18n.Localizer
- CherryPickedCommits []*Commit
+ Log *logrus.Entry
+ GitCommand *GitCommand
+ OSCommand *OSCommand
+ Tr *i18n.Localizer
}
// NewCommitListBuilder builds a new commit list builder
-func NewCommitListBuilder(log *logrus.Entry, gitCommand *GitCommand, osCommand *OSCommand, tr *i18n.Localizer, cherryPickedCommits []*Commit) *CommitListBuilder {
+func NewCommitListBuilder(log *logrus.Entry, gitCommand *GitCommand, osCommand *OSCommand, tr *i18n.Localizer) *CommitListBuilder {
return &CommitListBuilder{
- Log: log,
- GitCommand: gitCommand,
- OSCommand: osCommand,
- Tr: tr,
- CherryPickedCommits: cherryPickedCommits,
+ Log: log,
+ GitCommand: gitCommand,
+ OSCommand: osCommand,
+ Tr: tr,
}
}
@@ -94,28 +92,53 @@ type GetCommitsOptions struct {
RefName string // e.g. "HEAD" or "my_branch"
}
+func (c *CommitListBuilder) MergeRebasingCommits(commits []*Commit) ([]*Commit, error) {
+ // chances are we have as many commits as last time so we'll set the capacity to be the old length
+ result := make([]*Commit, 0, len(commits))
+ for i, commit := range commits {
+ if commit.Status != "rebasing" { // removing the existing rebase commits so we can add the refreshed ones
+ result = append(result, commits[i:]...)
+ break
+ }
+ }
+
+ rebaseMode, err := c.GitCommand.RebaseMode()
+ if err != nil {
+ return nil, err
+ }
+
+ if rebaseMode == "" {
+ // not in rebase mode so return original commits
+ return result, nil
+ }
+
+ rebasingCommits, err := c.getRebasingCommits(rebaseMode)
+ if err != nil {
+ return nil, err
+ }
+ if len(rebasingCommits) > 0 {
+ result = append(rebasingCommits, result...)
+ }
+
+ return result, nil
+}
+
// GetCommits obtains the commits of the current branch
func (c *CommitListBuilder) GetCommits(opts GetCommitsOptions) ([]*Commit, error) {
commits := []*Commit{}
var rebasingCommits []*Commit
- rebaseMode := ""
+ rebaseMode, err := c.GitCommand.RebaseMode()
+ if err != nil {
+ return nil, err
+ }
- if opts.IncludeRebaseCommits {
+ if opts.IncludeRebaseCommits && opts.FilterPath == "" {
var err error
- rebaseMode, err = c.GitCommand.RebaseMode()
+ rebasingCommits, err = c.MergeRebasingCommits(commits)
if err != nil {
return nil, err
}
- if rebaseMode != "" && opts.FilterPath == "" {
- // here we want to also prepend the commits that we're in the process of rebasing
- rebasingCommits, err = c.getRebasingCommits(rebaseMode)
- if err != nil {
- return nil, err
- }
- if len(rebasingCommits) > 0 {
- commits = append(commits, rebasingCommits...)
- }
- }
+ commits = append(commits, rebasingCommits...)
}
passedFirstPushedCommit := false
diff --git a/pkg/commands/commit_list_builder_test.go b/pkg/commands/commit_list_builder_test.go
index 590ee6f4a..08114f7a5 100644
--- a/pkg/commands/commit_list_builder_test.go
+++ b/pkg/commands/commit_list_builder_test.go
@@ -13,11 +13,10 @@ func NewDummyCommitListBuilder() *CommitListBuilder {
osCommand := NewDummyOSCommand()
return &CommitListBuilder{
- Log: NewDummyLog(),
- GitCommand: NewDummyGitCommandWithOSCommand(osCommand),
- OSCommand: osCommand,
- Tr: i18n.NewLocalizer(NewDummyLog()),
- CherryPickedCommits: []*Commit{},
+ Log: NewDummyLog(),
+ GitCommand: NewDummyGitCommandWithOSCommand(osCommand),
+ OSCommand: osCommand,
+ Tr: i18n.NewLocalizer(NewDummyLog()),
}
}
diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go
index 200fea7af..950149c6e 100644
--- a/pkg/gui/commits_panel.go
+++ b/pkg/gui/commits_panel.go
@@ -97,7 +97,10 @@ func (gui *Gui) refreshCommits() error {
}
func (gui *Gui) refreshCommitsWithLimit() error {
- builder := commands.NewCommitListBuilder(gui.Log, gui.GitCommand, gui.OSCommand, gui.Tr, gui.State.Modes.CherryPicking.CherryPickedCommits)
+ gui.State.BranchCommitsMutex.Lock()
+ defer gui.State.BranchCommitsMutex.Unlock()
+
+ builder := commands.NewCommitListBuilder(gui.Log, gui.GitCommand, gui.OSCommand, gui.Tr)
commits, err := builder.GetCommits(
commands.GetCommitsOptions{
@@ -115,6 +118,21 @@ func (gui *Gui) refreshCommitsWithLimit() error {
return gui.postRefreshUpdate(gui.Contexts.BranchCommits.Context)
}
+func (gui *Gui) refreshRebaseCommits() error {
+ gui.State.BranchCommitsMutex.Lock()
+ defer gui.State.BranchCommitsMutex.Unlock()
+
+ builder := commands.NewCommitListBuilder(gui.Log, gui.GitCommand, gui.OSCommand, gui.Tr)
+
+ updatedCommits, err := builder.MergeRebasingCommits(gui.State.Commits)
+ if err != nil {
+ return err
+ }
+ gui.State.Commits = updatedCommits
+
+ return gui.postRefreshUpdate(gui.Contexts.BranchCommits.Context)
+}
+
// specific functions
func (gui *Gui) handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
@@ -256,9 +274,8 @@ func (gui *Gui) handleMidRebaseCommand(action string) (bool, error) {
if err := gui.GitCommand.EditRebaseTodo(gui.State.Panels.Commits.SelectedLineIdx, action); err != nil {
return false, gui.surfaceError(err)
}
- // TODO: consider doing this in a way that is less expensive. We don't actually
- // need to reload all the commits, just the TODO commits.
- return true, gui.refreshSidePanels(refreshOptions{scope: []int{COMMITS}})
+
+ return true, gui.refreshRebaseCommits()
}
func (gui *Gui) handleCommitDelete(g *gocui.Gui, v *gocui.View) error {
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index e95ef1e99..858bbef5f 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -297,6 +297,7 @@ type guiState struct {
RefreshingFilesMutex sync.Mutex
RefreshingStatusMutex sync.Mutex
FetchMutex sync.Mutex
+ BranchCommitsMutex sync.Mutex
Searching searchingState
ScreenMode int
SideView *gocui.View
diff --git a/pkg/gui/sub_commits_panel.go b/pkg/gui/sub_commits_panel.go
index 571df1820..06793680f 100644
--- a/pkg/gui/sub_commits_panel.go
+++ b/pkg/gui/sub_commits_panel.go
@@ -77,7 +77,7 @@ func (gui *Gui) handleViewSubCommitFiles() error {
func (gui *Gui) switchToSubCommitsContext(refName string) error {
// need to populate my sub commits
- builder := commands.NewCommitListBuilder(gui.Log, gui.GitCommand, gui.OSCommand, gui.Tr, gui.State.Modes.CherryPicking.CherryPickedCommits)
+ builder := commands.NewCommitListBuilder(gui.Log, gui.GitCommand, gui.OSCommand, gui.Tr)
commits, err := builder.GetCommits(
commands.GetCommitsOptions{