1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-12-04 10:34:55 +02:00

Fix "move patch into new commit" for partial hunk (#2507)

This commit is contained in:
Stefan Haller 2023-03-18 08:17:47 +01:00 committed by GitHub
parent 81ea3107ed
commit 4b4dccfd7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 534 additions and 44 deletions

View File

@ -45,9 +45,7 @@ func (self *PatchCommands) DeletePatchesFromCommit(commits []*models.Commit, com
// apply each patch in reverse // apply each patch in reverse
if err := self.PatchManager.ApplyPatches(true); err != nil { if err := self.PatchManager.ApplyPatches(true); err != nil {
if err := self.rebase.AbortRebase(); err != nil { _ = self.rebase.AbortRebase()
return err
}
return err return err
} }
@ -73,9 +71,8 @@ func (self *PatchCommands) MovePatchToSelectedCommit(commits []*models.Commit, s
// apply each patch forward // apply each patch forward
if err := self.PatchManager.ApplyPatches(false); err != nil { if err := self.PatchManager.ApplyPatches(false); err != nil {
if err := self.rebase.AbortRebase(); err != nil { // Don't abort the rebase here; this might cause conflicts, so give
return err // the user a chance to resolve them
}
return err return err
} }
@ -121,9 +118,7 @@ func (self *PatchCommands) MovePatchToSelectedCommit(commits []*models.Commit, s
// apply each patch in reverse // apply each patch in reverse
if err := self.PatchManager.ApplyPatches(true); err != nil { if err := self.PatchManager.ApplyPatches(true); err != nil {
if err := self.rebase.AbortRebase(); err != nil { _ = self.rebase.AbortRebase()
return err
}
return err return err
} }
@ -132,6 +127,12 @@ func (self *PatchCommands) MovePatchToSelectedCommit(commits []*models.Commit, s
return err return err
} }
patch, err := self.diffHeadAgainstCommit(commits[sourceCommitIdx])
if err != nil {
_ = self.rebase.AbortRebase()
return err
}
if self.rebase.onSuccessfulContinue != nil { if self.rebase.onSuccessfulContinue != nil {
return errors.New("You are midway through another rebase operation. Please abort to start again") return errors.New("You are midway through another rebase operation. Please abort to start again")
} }
@ -139,10 +140,9 @@ func (self *PatchCommands) MovePatchToSelectedCommit(commits []*models.Commit, s
self.rebase.onSuccessfulContinue = func() error { self.rebase.onSuccessfulContinue = func() error {
// now we should be up to the destination, so let's apply forward these patches to that. // now we should be up to the destination, so let's apply forward these patches to that.
// ideally we would ensure we're on the right commit but I'm not sure if that check is necessary // ideally we would ensure we're on the right commit but I'm not sure if that check is necessary
if err := self.PatchManager.ApplyPatches(false); err != nil { if err := self.rebase.workingTree.ApplyPatch(patch, "index", "3way"); err != nil {
if err := self.rebase.AbortRebase(); err != nil { // Don't abort the rebase here; this might cause conflicts, so give
return err // the user a chance to resolve them
}
return err return err
} }
@ -175,9 +175,7 @@ func (self *PatchCommands) MovePatchIntoIndex(commits []*models.Commit, commitId
if err := self.PatchManager.ApplyPatches(true); err != nil { if err := self.PatchManager.ApplyPatches(true); err != nil {
if self.status.WorkingTreeState() == enums.REBASE_MODE_REBASING { if self.status.WorkingTreeState() == enums.REBASE_MODE_REBASING {
if err := self.rebase.AbortRebase(); err != nil { _ = self.rebase.AbortRebase()
return err
}
} }
return err return err
} }
@ -187,17 +185,21 @@ func (self *PatchCommands) MovePatchIntoIndex(commits []*models.Commit, commitId
return err return err
} }
patch, err := self.diffHeadAgainstCommit(commits[commitIdx])
if err != nil {
_ = self.rebase.AbortRebase()
return err
}
if self.rebase.onSuccessfulContinue != nil { if self.rebase.onSuccessfulContinue != nil {
return errors.New("You are midway through another rebase operation. Please abort to start again") return errors.New("You are midway through another rebase operation. Please abort to start again")
} }
self.rebase.onSuccessfulContinue = func() error { self.rebase.onSuccessfulContinue = func() error {
// add patches to index // add patches to index
if err := self.PatchManager.ApplyPatches(false); err != nil { if err := self.rebase.workingTree.ApplyPatch(patch, "index", "3way"); err != nil {
if self.status.WorkingTreeState() == enums.REBASE_MODE_REBASING { if self.status.WorkingTreeState() == enums.REBASE_MODE_REBASING {
if err := self.rebase.AbortRebase(); err != nil { _ = self.rebase.AbortRebase()
return err
}
} }
return err return err
} }
@ -221,9 +223,7 @@ func (self *PatchCommands) PullPatchIntoNewCommit(commits []*models.Commit, comm
} }
if err := self.PatchManager.ApplyPatches(true); err != nil { if err := self.PatchManager.ApplyPatches(true); err != nil {
if err := self.rebase.AbortRebase(); err != nil { _ = self.rebase.AbortRebase()
return err
}
return err return err
} }
@ -232,18 +232,20 @@ func (self *PatchCommands) PullPatchIntoNewCommit(commits []*models.Commit, comm
return err return err
} }
// add patches to index patch, err := self.diffHeadAgainstCommit(commits[commitIdx])
if err := self.PatchManager.ApplyPatches(false); err != nil { if err != nil {
if err := self.rebase.AbortRebase(); err != nil { _ = self.rebase.AbortRebase()
return err return err
} }
if err := self.rebase.workingTree.ApplyPatch(patch, "index", "3way"); err != nil {
_ = self.rebase.AbortRebase()
return err return err
} }
head_message, _ := self.commit.GetHeadCommitMessage() head_message, _ := self.commit.GetHeadCommitMessage()
new_message := fmt.Sprintf("Split from \"%s\"", head_message) new_message := fmt.Sprintf("Split from \"%s\"", head_message)
err := self.commit.CommitCmdObj(new_message).Run() if err := self.commit.CommitCmdObj(new_message).Run(); err != nil {
if err != nil {
return err return err
} }
@ -254,3 +256,12 @@ func (self *PatchCommands) PullPatchIntoNewCommit(commits []*models.Commit, comm
self.PatchManager.Reset() self.PatchManager.Reset()
return self.rebase.ContinueRebase() return self.rebase.ContinueRebase()
} }
// We have just applied a patch in reverse to discard it from a commit; if we
// now try to apply the patch again to move it to a later commit, or to the
// index, then this would conflict "with itself" in case the patch contained
// only some lines of a range of adjacent added lines. To solve this, we
// get the diff of HEAD and the original commit and then apply that.
func (self *PatchCommands) diffHeadAgainstCommit(commit *models.Commit) (string, error) {
return self.cmd.New(fmt.Sprintf("git diff HEAD..%s", commit.Sha)).RunWithOutput()
}

View File

@ -137,7 +137,7 @@ func (self *RebaseCommands) PrepareInteractiveRebaseCommand(baseShaOrRoot string
debug = "TRUE" debug = "TRUE"
} }
cmdStr := fmt.Sprintf("git rebase --interactive --autostash --keep-empty --no-autosquash %s", baseShaOrRoot) cmdStr := fmt.Sprintf("git rebase --interactive --autostash --keep-empty --empty=keep --no-autosquash %s", baseShaOrRoot)
self.Log.WithField("command", cmdStr).Debug("RunCommand") self.Log.WithField("command", cmdStr).Debug("RunCommand")
cmdObj := self.cmd.New(cmdStr) cmdObj := self.cmd.New(cmdStr)

View File

@ -26,7 +26,7 @@ func TestRebaseRebaseBranch(t *testing.T) {
testName: "successful rebase", testName: "successful rebase",
arg: "master", arg: "master",
runner: oscommands.NewFakeRunner(t). runner: oscommands.NewFakeRunner(t).
Expect(`git rebase --interactive --autostash --keep-empty --no-autosquash master`, "", nil), Expect(`git rebase --interactive --autostash --keep-empty --empty=keep --no-autosquash master`, "", nil),
test: func(err error) { test: func(err error) {
assert.NoError(t, err) assert.NoError(t, err)
}, },
@ -35,7 +35,7 @@ func TestRebaseRebaseBranch(t *testing.T) {
testName: "unsuccessful rebase", testName: "unsuccessful rebase",
arg: "master", arg: "master",
runner: oscommands.NewFakeRunner(t). runner: oscommands.NewFakeRunner(t).
Expect(`git rebase --interactive --autostash --keep-empty --no-autosquash master`, "", errors.New("error")), Expect(`git rebase --interactive --autostash --keep-empty --empty=keep --no-autosquash master`, "", errors.New("error")),
test: func(err error) { test: func(err error) {
assert.Error(t, err) assert.Error(t, err)
}, },
@ -125,7 +125,7 @@ func TestRebaseDiscardOldFileChanges(t *testing.T) {
commitIndex: 0, commitIndex: 0,
fileName: "test999.txt", fileName: "test999.txt",
runner: oscommands.NewFakeRunner(t). runner: oscommands.NewFakeRunner(t).
Expect(`git rebase --interactive --autostash --keep-empty --no-autosquash abcdef`, "", nil). Expect(`git rebase --interactive --autostash --keep-empty --empty=keep --no-autosquash abcdef`, "", nil).
Expect(`git cat-file -e HEAD^:"test999.txt"`, "", nil). Expect(`git cat-file -e HEAD^:"test999.txt"`, "", nil).
Expect(`git checkout HEAD^ -- "test999.txt"`, "", nil). Expect(`git checkout HEAD^ -- "test999.txt"`, "", nil).
Expect(`git commit --amend --no-edit --allow-empty`, "", nil). Expect(`git commit --amend --no-edit --allow-empty`, "", nil).

View File

@ -286,3 +286,13 @@ func (p *PatchManager) IsEmpty() bool {
func (p *PatchManager) NewPatchRequired(from string, to string, reverse bool) bool { func (p *PatchManager) NewPatchRequired(from string, to string, reverse bool) bool {
return from != p.From || to != p.To || reverse != p.reverse return from != p.From || to != p.To || reverse != p.reverse
} }
func (p *PatchManager) AllFilesInPatch() []string {
files := make([]string, 0, len(p.fileInfoMap))
for filename := range p.fileInfoMap {
files = append(files, filename)
}
return files
}

View File

@ -94,6 +94,16 @@ func (self *Shell) CreateFile(path string, content string) *Shell {
return self return self
} }
func (self *Shell) DeleteFile(path string) *Shell {
fullPath := filepath.Join(self.dir, path)
err := os.Remove(fullPath)
if err != nil {
self.fail(fmt.Sprintf("error deleting file: %s\n%s", fullPath, err))
}
return self
}
func (self *Shell) CreateDir(path string) *Shell { func (self *Shell) CreateDir(path string) *Shell {
fullPath := filepath.Join(self.dir, path) fullPath := filepath.Join(self.dir, path)
if err := os.MkdirAll(fullPath, 0o755); err != nil { if err := os.MkdirAll(fullPath, 0o755); err != nil {
@ -171,6 +181,13 @@ func (self *Shell) UpdateFileAndAdd(fileName string, fileContents string) *Shell
GitAdd(fileName) GitAdd(fileName)
} }
// convenience method for deleting a file and adding it
func (self *Shell) DeleteFileAndAdd(fileName string) *Shell {
return self.
DeleteFile(fileName).
GitAdd(fileName)
}
// creates commits 01, 02, 03, ..., n with a new file in each // creates commits 01, 02, 03, ..., n with a new file in each
// The reason for padding with zeroes is so that it's easier to do string // The reason for padding with zeroes is so that it's easier to do string
// matches on the commit messages when there are many of them // matches on the commit messages when there are many of them

View File

@ -0,0 +1,88 @@
package patch_building
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MoveToEarlierCommit = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move a patch from a commit to an earlier commit",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.CreateDir("dir")
shell.CreateFileAndAdd("dir/file1", "file1 content")
shell.CreateFileAndAdd("dir/file2", "file2 content")
shell.Commit("first commit")
shell.CreateFileAndAdd("unrelated-file", "")
shell.Commit("destination commit")
shell.UpdateFileAndAdd("dir/file1", "file1 content with old changes")
shell.DeleteFileAndAdd("dir/file2")
shell.CreateFileAndAdd("dir/file3", "file3 content")
shell.Commit("commit to move from")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("commit to move from").IsSelected(),
Contains("destination commit"),
Contains("first commit"),
).
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("dir").IsSelected(),
Contains(" M file1"),
Contains(" D file2"),
Contains(" A file3"),
).
PressPrimaryAction().
PressEscape()
t.Views().Information().Content(Contains("building patch"))
t.Views().Commits().
IsFocused().
SelectNextItem()
t.Common().SelectPatchOption(Contains("move patch to selected commit"))
t.Views().Commits().
IsFocused().
Lines(
Contains("commit to move from"),
Contains("destination commit").IsSelected(),
Contains("first commit"),
).
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("dir").IsSelected(),
Contains(" M file1"),
Contains(" D file2"),
Contains(" A file3"),
Contains("A unrelated-file"),
).
PressEscape()
t.Views().Commits().
IsFocused().
SelectPreviousItem().
PressEnter()
// the original commit has no more files in it
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("(none)"),
)
},
})

View File

@ -0,0 +1,70 @@
package patch_building
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MoveToIndexPartOfAdjacentAddedLines = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move a patch from a commit to the index, with only some lines of a range of adjacent added lines in the patch",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.CreateFileAndAdd("file1", "")
shell.Commit("first commit")
shell.UpdateFileAndAdd("file1", "1st line\n2nd line\n")
shell.Commit("commit to move from")
shell.UpdateFileAndAdd("unrelated-file", "")
shell.Commit("third commit")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("third commit").IsSelected(),
Contains("commit to move from"),
Contains("first commit"),
).
SelectNextItem().
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("file1").IsSelected(),
).
PressEnter()
t.Views().PatchBuilding().
IsFocused().
PressEnter().
PressPrimaryAction()
t.Views().Information().Content(Contains("building patch"))
t.Common().SelectPatchOption(Contains("move patch out into index"))
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("file1").IsSelected(),
).
Tap(func() {
t.Views().Main().
Content(Contains("+2nd line").
DoesNotContain("1st line"))
})
t.Views().Files().
Focus().
ContainsLines(
Contains("M").Contains("file1"),
)
t.Views().Main().
Content(Contains("+1st line\n 2nd line\n"))
},
})

View File

@ -0,0 +1,89 @@
package patch_building
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MoveToLaterCommit = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move a patch from a commit to a later commit",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.CreateDir("dir")
shell.CreateFileAndAdd("dir/file1", "file1 content")
shell.CreateFileAndAdd("dir/file2", "file2 content")
shell.Commit("first commit")
shell.UpdateFileAndAdd("dir/file1", "file1 content with old changes")
shell.DeleteFileAndAdd("dir/file2")
shell.CreateFileAndAdd("dir/file3", "file3 content")
shell.Commit("commit to move from")
shell.CreateFileAndAdd("unrelated-file", "")
shell.Commit("destination commit")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("destination commit").IsSelected(),
Contains("commit to move from"),
Contains("first commit"),
).
SelectNextItem().
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("dir").IsSelected(),
Contains(" M file1"),
Contains(" D file2"),
Contains(" A file3"),
).
PressPrimaryAction().
PressEscape()
t.Views().Information().Content(Contains("building patch"))
t.Views().Commits().
IsFocused().
SelectPreviousItem()
t.Common().SelectPatchOption(Contains("move patch to selected commit"))
t.Views().Commits().
IsFocused().
Lines(
Contains("destination commit").IsSelected(),
Contains("commit to move from"),
Contains("first commit"),
).
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("dir").IsSelected(),
Contains(" M file1"),
Contains(" D file2"),
Contains(" A file3"),
Contains("A unrelated-file"),
).
PressEscape()
t.Views().Commits().
IsFocused().
SelectNextItem().
PressEnter()
// the original commit has no more files in it
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("(none)"),
)
},
})

View File

@ -0,0 +1,96 @@
package patch_building
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MoveToLaterCommitPartialHunk = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move a patch from a commit to a later commit, with only parts of a hunk in the patch",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.CreateFileAndAdd("file1", "")
shell.Commit("first commit")
shell.UpdateFileAndAdd("file1", "1st line\n2nd line\n")
shell.Commit("commit to move from")
shell.UpdateFileAndAdd("unrelated-file", "")
shell.Commit("destination commit")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("destination commit").IsSelected(),
Contains("commit to move from"),
Contains("first commit"),
).
SelectNextItem().
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("file1").IsSelected(),
).
PressEnter()
t.Views().PatchBuilding().
IsFocused().
PressEnter().
PressPrimaryAction().
PressEscape()
t.Views().Information().Content(Contains("building patch"))
t.Views().CommitFiles().
IsFocused().
PressEscape()
t.Views().Commits().
IsFocused().
SelectPreviousItem()
t.Common().SelectPatchOption(Contains("move patch to selected commit"))
t.Views().Commits().
IsFocused().
Lines(
Contains("destination commit").IsSelected(),
Contains("commit to move from"),
Contains("first commit"),
).
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("file1").IsSelected(),
Contains("unrelated-file"),
).
Tap(func() {
t.Views().Main().
Content(Contains("+1st line\n 2nd line"))
}).
PressEscape()
t.Views().Commits().
IsFocused().
SelectNextItem().
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("file1").IsSelected(),
).
Tap(func() {
t.Views().Main().
Content(Contains("+2nd line").
DoesNotContain("1st line"))
})
},
})

View File

@ -11,13 +11,17 @@ var MoveToNewCommit = NewIntegrationTest(NewIntegrationTestArgs{
Skip: false, Skip: false,
SetupConfig: func(config *config.AppConfig) {}, SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) { SetupRepo: func(shell *Shell) {
shell.CreateFileAndAdd("file1", "file1 content") shell.CreateDir("dir")
shell.CreateFileAndAdd("dir/file1", "file1 content")
shell.CreateFileAndAdd("dir/file2", "file2 content")
shell.Commit("first commit") shell.Commit("first commit")
shell.UpdateFileAndAdd("file1", "file1 content with old changes") shell.UpdateFileAndAdd("dir/file1", "file1 content with old changes")
shell.Commit("second commit") shell.DeleteFileAndAdd("dir/file2")
shell.CreateFileAndAdd("dir/file3", "file3 content")
shell.Commit("commit to move from")
shell.UpdateFileAndAdd("file1", "file1 content with new changes") shell.UpdateFileAndAdd("dir/file1", "file1 content with new changes")
shell.Commit("third commit") shell.Commit("third commit")
}, },
Run: func(t *TestDriver, keys config.KeybindingConfig) { Run: func(t *TestDriver, keys config.KeybindingConfig) {
@ -25,7 +29,7 @@ var MoveToNewCommit = NewIntegrationTest(NewIntegrationTestArgs{
Focus(). Focus().
Lines( Lines(
Contains("third commit").IsSelected(), Contains("third commit").IsSelected(),
Contains("second commit"), Contains("commit to move from"),
Contains("first commit"), Contains("first commit"),
). ).
SelectNextItem(). SelectNextItem().
@ -34,18 +38,35 @@ var MoveToNewCommit = NewIntegrationTest(NewIntegrationTestArgs{
t.Views().CommitFiles(). t.Views().CommitFiles().
IsFocused(). IsFocused().
Lines( Lines(
Contains("file1").IsSelected(), Contains("dir").IsSelected(),
Contains(" M file1"),
Contains(" D file2"),
Contains(" A file3"),
). ).
PressPrimaryAction() PressPrimaryAction().
PressEscape()
t.Views().Information().Content(Contains("building patch")) t.Views().Information().Content(Contains("building patch"))
t.Common().SelectPatchOption(Contains("move patch into new commit")) t.Common().SelectPatchOption(Contains("move patch into new commit"))
t.Views().Commits().
IsFocused().
Lines(
Contains("third commit"),
Contains(`Split from "commit to move from"`).IsSelected(),
Contains("commit to move from"),
Contains("first commit"),
).
PressEnter()
t.Views().CommitFiles(). t.Views().CommitFiles().
IsFocused(). IsFocused().
Lines( Lines(
Contains("file1").IsSelected(), Contains("dir").IsSelected(),
Contains(" M file1"),
Contains(" D file2"),
Contains(" A file3"),
). ).
PressEscape() PressEscape()
@ -53,8 +74,8 @@ var MoveToNewCommit = NewIntegrationTest(NewIntegrationTestArgs{
IsFocused(). IsFocused().
Lines( Lines(
Contains("third commit"), Contains("third commit"),
Contains(`Split from "second commit"`).IsSelected(), Contains(`Split from "commit to move from"`).IsSelected(),
Contains("second commit"), Contains("commit to move from"),
Contains("first commit"), Contains("first commit"),
). ).
SelectNextItem(). SelectNextItem().

View File

@ -0,0 +1,83 @@
package patch_building
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var MoveToNewCommitPartialHunk = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Move a patch from a commit to a new commit, with only parts of a hunk in the patch",
ExtraCmdArgs: "",
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.CreateFileAndAdd("file1", "")
shell.Commit("first commit")
shell.UpdateFileAndAdd("file1", "1st line\n2nd line\n")
shell.Commit("commit to move from")
shell.UpdateFileAndAdd("file1", "1st line\n2nd line\n3rd line\n")
shell.Commit("third commit")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("third commit").IsSelected(),
Contains("commit to move from"),
Contains("first commit"),
).
SelectNextItem().
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("file1").IsSelected(),
).
PressEnter()
t.Views().PatchBuilding().
IsFocused().
PressEnter().
PressPrimaryAction()
t.Views().Information().Content(Contains("building patch"))
t.Common().SelectPatchOption(Contains("move patch into new commit"))
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("file1").IsSelected(),
).
Tap(func() {
t.Views().Main().
Content(Contains("+1st line\n 2nd line"))
}).
PressEscape()
t.Views().Commits().
IsFocused().
Lines(
Contains("third commit"),
Contains(`Split from "commit to move from"`).IsSelected(),
Contains("commit to move from"),
Contains("first commit"),
).
SelectNextItem().
PressEnter()
t.Views().CommitFiles().
IsFocused().
Lines(
Contains("file1").IsSelected(),
).
Tap(func() {
t.Views().Main().
Content(Contains("+2nd line").
DoesNotContain("1st line"))
})
},
})

View File

@ -101,10 +101,15 @@ var tests = []*components.IntegrationTest{
patch_building.ApplyInReverse, patch_building.ApplyInReverse,
patch_building.ApplyInReverseWithConflict, patch_building.ApplyInReverseWithConflict,
patch_building.CopyPatchToClipboard, patch_building.CopyPatchToClipboard,
patch_building.MoveToEarlierCommit,
patch_building.MoveToIndex, patch_building.MoveToIndex,
patch_building.MoveToIndexPartOfAdjacentAddedLines,
patch_building.MoveToIndexPartial, patch_building.MoveToIndexPartial,
patch_building.MoveToIndexWithConflict, patch_building.MoveToIndexWithConflict,
patch_building.MoveToLaterCommit,
patch_building.MoveToLaterCommitPartialHunk,
patch_building.MoveToNewCommit, patch_building.MoveToNewCommit,
patch_building.MoveToNewCommitPartialHunk,
patch_building.RemoveFromCommit, patch_building.RemoveFromCommit,
patch_building.ResetWithEscape, patch_building.ResetWithEscape,
patch_building.SelectAllFiles, patch_building.SelectAllFiles,