1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-12-14 11:23:09 +02:00
lazygit/pkg/gui/controllers/helpers/merge_conflicts_helper.go

141 lines
3.5 KiB
Go
Raw Normal View History

package helpers
import (
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
type MergeConflictsHelper struct {
2023-03-23 03:53:18 +02:00
c *HelperCommon
}
func NewMergeConflictsHelper(
c *HelperCommon,
) *MergeConflictsHelper {
return &MergeConflictsHelper{
2023-03-23 03:53:18 +02:00
c: c,
}
}
func (self *MergeConflictsHelper) SetMergeState(path string) (bool, error) {
self.context().GetMutex().Lock()
defer self.context().GetMutex().Unlock()
return self.setMergeStateWithoutLock(path)
}
func (self *MergeConflictsHelper) setMergeStateWithoutLock(path string) (bool, error) {
2023-03-23 03:53:18 +02:00
content, err := self.c.Git().File.Cat(path)
if err != nil {
return false, err
}
if path != self.context().GetState().GetPath() {
self.context().SetUserScrolling(false)
}
self.context().GetState().SetContent(content, path)
return !self.context().GetState().NoConflicts(), nil
}
func (self *MergeConflictsHelper) ResetMergeState() {
self.context().GetMutex().Lock()
defer self.context().GetMutex().Unlock()
self.resetMergeState()
}
func (self *MergeConflictsHelper) resetMergeState() {
self.context().SetUserScrolling(false)
self.context().GetState().Reset()
}
func (self *MergeConflictsHelper) EscapeMerge() error {
self.resetMergeState()
// doing this in separate UI thread so that we're not still holding the lock by the time refresh the file
self.c.OnUIThread(func() error {
// There is a race condition here: refreshing the files scope can trigger the
// confirmation context to be pushed if all conflicts are resolved (prompting
// to continue the merge/rebase. In that case, we don't want to then push the
// files context over it.
// So long as both places call OnUIThread, we're fine.
if self.c.IsCurrentContext(self.c.Contexts().MergeConflicts) {
return self.c.PushContext(self.c.Contexts().Files)
}
return nil
})
return nil
}
func (self *MergeConflictsHelper) SetConflictsAndRender(path string, isFocused bool) (bool, error) {
hasConflicts, err := self.setMergeStateWithoutLock(path)
if err != nil {
return false, err
}
if hasConflicts {
return true, self.context().Render(isFocused)
}
return false, nil
}
func (self *MergeConflictsHelper) SwitchToMerge(path string) error {
if self.context().GetState().GetPath() != path {
hasConflicts, err := self.SetMergeState(path)
if err != nil {
return err
}
if !hasConflicts {
return nil
}
}
2023-03-23 03:53:18 +02:00
return self.c.PushContext(self.c.Contexts().MergeConflicts)
}
func (self *MergeConflictsHelper) context() *context.MergeConflictsContext {
2023-03-23 03:53:18 +02:00
return self.c.Contexts().MergeConflicts
}
func (self *MergeConflictsHelper) Render(isFocused bool) error {
content := self.context().GetContentToRender(isFocused)
var task types.UpdateTask
if self.context().IsUserScrolling() {
task = types.NewRenderStringWithoutScrollTask(content)
} else {
originY := self.context().GetOriginY()
task = types.NewRenderStringWithScrollTask(content, 0, originY)
}
return self.c.RenderToMainViews(types.RefreshMainOpts{
Pair: self.c.MainViewPairs().MergeConflicts,
Main: &types.ViewUpdateOpts{
Task: task,
},
})
}
func (self *MergeConflictsHelper) RefreshMergeState() error {
2023-03-23 03:53:18 +02:00
self.c.Contexts().MergeConflicts.GetMutex().Lock()
defer self.c.Contexts().MergeConflicts.GetMutex().Unlock()
if self.c.CurrentContext().GetKey() != context.MERGE_CONFLICTS_CONTEXT_KEY {
return nil
}
2023-03-23 03:53:18 +02:00
hasConflicts, err := self.SetConflictsAndRender(self.c.Contexts().MergeConflicts.GetState().GetPath(), true)
if err != nil {
return self.c.Error(err)
}
if !hasConflicts {
return self.EscapeMerge()
}
return nil
}