mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-25 12:24:47 +02:00
better handling of refreshed files
This commit is contained in:
parent
da6fe01eca
commit
1183f68e19
@ -461,87 +461,6 @@ func TestGitCommandCommitAmend(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestGitCommandMergeStatusFiles is a function.
|
|
||||||
func TestGitCommandMergeStatusFiles(t *testing.T) {
|
|
||||||
type scenario struct {
|
|
||||||
testName string
|
|
||||||
oldFiles []*models.File
|
|
||||||
newFiles []*models.File
|
|
||||||
test func([]*models.File)
|
|
||||||
}
|
|
||||||
|
|
||||||
scenarios := []scenario{
|
|
||||||
{
|
|
||||||
"Old file and new file are the same",
|
|
||||||
[]*models.File{},
|
|
||||||
[]*models.File{
|
|
||||||
{
|
|
||||||
Name: "new_file.txt",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
func(files []*models.File) {
|
|
||||||
expected := []*models.File{
|
|
||||||
{
|
|
||||||
Name: "new_file.txt",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Len(t, files, 1)
|
|
||||||
assert.EqualValues(t, expected, files)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"Several files to merge, with some identical",
|
|
||||||
[]*models.File{
|
|
||||||
{
|
|
||||||
Name: "new_file1.txt",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "new_file2.txt",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "new_file3.txt",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[]*models.File{
|
|
||||||
{
|
|
||||||
Name: "new_file4.txt",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "new_file5.txt",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "new_file1.txt",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
func(files []*models.File) {
|
|
||||||
expected := []*models.File{
|
|
||||||
{
|
|
||||||
Name: "new_file1.txt",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "new_file4.txt",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "new_file5.txt",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Len(t, files, 3)
|
|
||||||
assert.EqualValues(t, expected, files)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, s := range scenarios {
|
|
||||||
t.Run(s.testName, func(t *testing.T) {
|
|
||||||
gitCmd := NewDummyGitCommand()
|
|
||||||
|
|
||||||
s.test(gitCmd.MergeStatusFiles(s.oldFiles, s.newFiles, nil))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestGitCommandGetCommitDifferences is a function.
|
// TestGitCommandGetCommitDifferences is a function.
|
||||||
func TestGitCommandGetCommitDifferences(t *testing.T) {
|
func TestGitCommandGetCommitDifferences(t *testing.T) {
|
||||||
type scenario struct {
|
type scenario struct {
|
||||||
|
@ -102,38 +102,3 @@ func (c *GitCommand) GitStatus(opts GitStatusOptions) (string, error) {
|
|||||||
|
|
||||||
return strings.Join(splitLines, "\n"), nil
|
return strings.Join(splitLines, "\n"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MergeStatusFiles merge status files
|
|
||||||
func (c *GitCommand) MergeStatusFiles(oldFiles, newFiles []*models.File, selectedFile *models.File) []*models.File {
|
|
||||||
if len(oldFiles) == 0 {
|
|
||||||
return newFiles
|
|
||||||
}
|
|
||||||
|
|
||||||
appendedIndexes := []int{}
|
|
||||||
|
|
||||||
// retain position of files we already could see
|
|
||||||
result := []*models.File{}
|
|
||||||
for _, oldFile := range oldFiles {
|
|
||||||
for newIndex, newFile := range newFiles {
|
|
||||||
if utils.IncludesInt(appendedIndexes, newIndex) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// if we just staged B and in doing so created 'A -> B' and we are currently have oldFile: A and newFile: 'A -> B', we want to wait until we come across B so the our cursor isn't jumping anywhere
|
|
||||||
waitForMatchingFile := selectedFile != nil && newFile.IsRename() && !selectedFile.IsRename() && newFile.Matches(selectedFile) && !oldFile.Matches(selectedFile)
|
|
||||||
|
|
||||||
if oldFile.Matches(newFile) && !waitForMatchingFile {
|
|
||||||
result = append(result, newFile)
|
|
||||||
appendedIndexes = append(appendedIndexes, newIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// append any new files to the end
|
|
||||||
for index, newFile := range newFiles {
|
|
||||||
if !utils.IncludesInt(appendedIndexes, index) {
|
|
||||||
result = append(result, newFile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
@ -522,26 +522,36 @@ func (gui *Gui) refreshStateFiles() error {
|
|||||||
// keep track of where the cursor is currently and the current file names
|
// keep track of where the cursor is currently and the current file names
|
||||||
// when we refresh, go looking for a matching name
|
// when we refresh, go looking for a matching name
|
||||||
// move the cursor to there.
|
// move the cursor to there.
|
||||||
selectedFile := gui.getSelectedFile()
|
|
||||||
|
selectedNode := gui.getSelectedStatusNode()
|
||||||
|
getPaths := func(node *models.StatusLineNode) []string {
|
||||||
|
if node.File != nil && node.File.IsRename() {
|
||||||
|
return node.File.Names()
|
||||||
|
} else {
|
||||||
|
return []string{node.Path}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selectedPaths := getPaths(selectedNode)
|
||||||
|
|
||||||
prevSelectedLineIdx := gui.State.Panels.Files.SelectedLineIdx
|
prevSelectedLineIdx := gui.State.Panels.Files.SelectedLineIdx
|
||||||
|
|
||||||
// get files to stage
|
|
||||||
// noRenames := gui.State.StatusLineManager.TreeMode
|
|
||||||
files := gui.GitCommand.GetStatusFiles(commands.GetStatusFileOptions{})
|
files := gui.GitCommand.GetStatusFiles(commands.GetStatusFileOptions{})
|
||||||
gui.State.StatusLineManager.SetFiles(
|
gui.State.StatusLineManager.SetFiles(files)
|
||||||
gui.GitCommand.MergeStatusFiles(gui.State.StatusLineManager.GetAllFiles(), files, selectedFile),
|
|
||||||
)
|
|
||||||
|
|
||||||
if err := gui.fileWatcher.addFilesToFileWatcher(files); err != nil {
|
if err := gui.fileWatcher.addFilesToFileWatcher(files); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// let's try to find our file again and move the cursor to that
|
// let's try to find our file again and move the cursor to that
|
||||||
if selectedFile != nil {
|
if selectedNode != nil {
|
||||||
for idx, node := range gui.State.StatusLineManager.GetAllItems() {
|
for idx, node := range gui.State.StatusLineManager.GetAllItems() {
|
||||||
// TODO: check that this works
|
paths := getPaths(node)
|
||||||
selectedFileHasMoved := node.File != nil && node.File.Matches(selectedFile) && idx != prevSelectedLineIdx
|
|
||||||
if selectedFileHasMoved {
|
// If you started off with a rename selected, and now it's broken in two, we want you to jump to the new file, not the old file.
|
||||||
|
// This is because the new should be in the same position as the rename was meaning less cursor jumping
|
||||||
|
foundOldFileInRename := selectedNode.File != nil && selectedNode.File.IsRename() && node.Path == selectedNode.File.PreviousName
|
||||||
|
selectedNodeHasMoved := idx != prevSelectedLineIdx && utils.StringArraysOverlap(paths, selectedPaths) && !foundOldFileInRename
|
||||||
|
if selectedNodeHasMoved {
|
||||||
gui.State.Panels.Files.SelectedLineIdx = idx
|
gui.State.Panels.Files.SelectedLineIdx = idx
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -54,11 +54,13 @@ func GetFlatTreeFromStatusFiles(files []*models.File) *models.StatusLineNode {
|
|||||||
root := &models.StatusLineNode{}
|
root := &models.StatusLineNode{}
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
root.Children = append(root.Children, &models.StatusLineNode{
|
root.Children = append(root.Children, &models.StatusLineNode{
|
||||||
Name: file.Name,
|
Name: file.GetPath(),
|
||||||
Path: file.GetPath(),
|
Path: file.GetPath(),
|
||||||
File: file,
|
File: file,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
root.Sort()
|
||||||
|
|
||||||
return root
|
return root
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user