mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-10 20:05:50 +02:00
migrate staging tests
This commit is contained in:
parent
1b52a0d83f
commit
c63fed2074
199 changed files with 540 additions and 2476 deletions
|
@ -1 +0,0 @@
|
|||
WIP
|
|
@ -1 +0,0 @@
|
|||
ref: refs/heads/master
|
|
@ -1,10 +0,0 @@
|
|||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
ignorecase = true
|
||||
precomposeunicode = true
|
||||
[user]
|
||||
email = CI@example.com
|
||||
name = CI
|
|
@ -1 +0,0 @@
|
|||
Unnamed repository; edit this file 'description' to name the repository.
|
Binary file not shown.
|
@ -1,7 +0,0 @@
|
|||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
# *.[oa]
|
||||
# *~
|
||||
.DS_Store
|
|
@ -1,3 +0,0 @@
|
|||
0000000000000000000000000000000000000000 353cce986c61f361452f43522426c120b4ee9461 CI <CI@example.com> 1659355870 +1000 commit (initial): myfile1
|
||||
353cce986c61f361452f43522426c120b4ee9461 6ecdae79ff53548670039abee9008b6bb36cdf4f CI <CI@example.com> 1659355870 +1000 commit: myfile2
|
||||
6ecdae79ff53548670039abee9008b6bb36cdf4f 0478d727ea0ebf57ed9ca85acef9e60a324d86f0 CI <CI@example.com> 1659355876 +1000 commit: WIP
|
|
@ -1,3 +0,0 @@
|
|||
0000000000000000000000000000000000000000 353cce986c61f361452f43522426c120b4ee9461 CI <CI@example.com> 1659355870 +1000 commit (initial): myfile1
|
||||
353cce986c61f361452f43522426c120b4ee9461 6ecdae79ff53548670039abee9008b6bb36cdf4f CI <CI@example.com> 1659355870 +1000 commit: myfile2
|
||||
6ecdae79ff53548670039abee9008b6bb36cdf4f 0478d727ea0ebf57ed9ca85acef9e60a324d86f0 CI <CI@example.com> 1659355876 +1000 commit: WIP
|
|
@ -1,3 +0,0 @@
|
|||
x<01><>Λ
|
||||
Β0E]η+f/Θ¤ΣΌ@Dθ<44>;w®“ι
|
||||
Ζ–ΑΟ7<CE9F>ΰκΒαpΈΌΦϊl`Ϊ.C±<43>8z»θH¤y$ΥΌX<CE8C><58>Ω<>]_³ε]ή
Όπ’%$UGn<47>> RΚE$!ΖβK!Ο=¥&Ϊcέa<CEAD>α<ΝWωζΊ½δΔk½€υ.‘s1x8ZD4<44>φSMώΤΝ}Ύ™‚—9³
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,3 +0,0 @@
|
|||
x<01>ÍA
|
||||
ƒ0@Ñ®sŠÙÊŒN&Š\yŒ˜L¨`ˆH
|
||||
ööõÝ~üXKY˪€*1c<31>Å
ê³’—ä©”/Ü'á¢íLø´w=`šá9Í/=CÙ7}ÄZF ±CowwBDsÕkÒôOnÊ7¯›’ù4],Ù
|
|
@ -1,2 +0,0 @@
|
|||
x<01>ÎM
|
||||
Â0@a×9Eö‚d~2퀈ÐU<C390>‘¦,[J½½=‚ÛÇ·xyui”Om7ó©#†µ„y6+*j¢e’EfÄ)d·¥Ý^ÍS¤œM{É…8baŠˆŒ’ÃÄfÊ.½ÛcÝý0úë0Þí“êö´K^ë̓D¥û.ø3„ÜQ<C39C>©frW¿eyº\+9>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
0478d727ea0ebf57ed9ca85acef9e60a324d86f0
|
|
@ -1 +0,0 @@
|
|||
test1
|
|
@ -1 +0,0 @@
|
|||
test2
|
|
@ -1 +0,0 @@
|
|||
test3
|
|
@ -1 +0,0 @@
|
|||
{"KeyEvents":[{"Timestamp":607,"Mod":0,"Key":259,"Ch":0},{"Timestamp":745,"Mod":0,"Key":259,"Ch":0},{"Timestamp":1304,"Mod":0,"Key":256,"Ch":82},{"Timestamp":2087,"Mod":2,"Key":18,"Ch":18},{"Timestamp":2894,"Mod":0,"Key":27,"Ch":0},{"Timestamp":3553,"Mod":0,"Key":260,"Ch":0},{"Timestamp":3697,"Mod":0,"Key":260,"Ch":0},{"Timestamp":4064,"Mod":0,"Key":256,"Ch":32},{"Timestamp":4376,"Mod":0,"Key":256,"Ch":119},{"Timestamp":4745,"Mod":0,"Key":13,"Ch":13},{"Timestamp":5200,"Mod":0,"Key":256,"Ch":113}],"ResizeEvents":[{"Timestamp":0,"Width":238,"Height":61}]}
|
|
@ -1,18 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cd $1
|
||||
|
||||
git init
|
||||
|
||||
git config user.email "CI@example.com"
|
||||
git config user.name "CI"
|
||||
|
||||
echo test1 > myfile1
|
||||
git add .
|
||||
git commit -am "myfile1"
|
||||
echo test2 > myfile2
|
||||
git add .
|
||||
git commit -am "myfile2"
|
||||
echo test3 > myfile3
|
|
@ -1 +0,0 @@
|
|||
{ "description": "stage a file and commit the change", "speed": 15 }
|
|
@ -1 +0,0 @@
|
|||
second commit
|
|
@ -1 +0,0 @@
|
|||
ref: refs/heads/master
|
|
@ -1,8 +0,0 @@
|
|||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
[user]
|
||||
email = CI@example.com
|
||||
name = CI
|
|
@ -1 +0,0 @@
|
|||
Unnamed repository; edit this file 'description' to name the repository.
|
Binary file not shown.
|
@ -1,6 +0,0 @@
|
|||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
# *.[oa]
|
||||
# *~
|
|
@ -1,2 +0,0 @@
|
|||
0000000000000000000000000000000000000000 c2bf9b666a310383fd7095bc5bd993bba11b040e CI <CI@example.com> 1640438057 +0100 commit (initial): first commit
|
||||
c2bf9b666a310383fd7095bc5bd993bba11b040e d0ce4cb10cd926f646a08889b077a6d7eddd3534 CI <CI@example.com> 1640438062 +0100 commit: second commit
|
|
@ -1,2 +0,0 @@
|
|||
0000000000000000000000000000000000000000 c2bf9b666a310383fd7095bc5bd993bba11b040e CI <CI@example.com> 1640438057 +0100 commit (initial): first commit
|
||||
c2bf9b666a310383fd7095bc5bd993bba11b040e d0ce4cb10cd926f646a08889b077a6d7eddd3534 CI <CI@example.com> 1640438062 +0100 commit: second commit
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
d0ce4cb10cd926f646a08889b077a6d7eddd3534
|
|
@ -1 +0,0 @@
|
|||
file1
|
|
@ -1 +0,0 @@
|
|||
file2
|
|
@ -1 +0,0 @@
|
|||
{"KeyEvents":[{"Timestamp":1360,"Mod":0,"Key":256,"Ch":106},{"Timestamp":2124,"Mod":0,"Key":256,"Ch":32},{"Timestamp":4000,"Mod":0,"Key":256,"Ch":99},{"Timestamp":4595,"Mod":0,"Key":256,"Ch":102},{"Timestamp":4730,"Mod":0,"Key":256,"Ch":105},{"Timestamp":4831,"Mod":0,"Key":256,"Ch":114},{"Timestamp":5011,"Mod":0,"Key":256,"Ch":115},{"Timestamp":5122,"Mod":0,"Key":256,"Ch":116},{"Timestamp":5552,"Mod":0,"Key":256,"Ch":32},{"Timestamp":5778,"Mod":0,"Key":256,"Ch":99},{"Timestamp":5882,"Mod":0,"Key":256,"Ch":111},{"Timestamp":6046,"Mod":0,"Key":256,"Ch":109},{"Timestamp":6212,"Mod":0,"Key":256,"Ch":109},{"Timestamp":6449,"Mod":0,"Key":256,"Ch":105},{"Timestamp":6550,"Mod":0,"Key":256,"Ch":116},{"Timestamp":7347,"Mod":0,"Key":13,"Ch":13},{"Timestamp":9314,"Mod":0,"Key":13,"Ch":13},{"Timestamp":10322,"Mod":0,"Key":256,"Ch":107},{"Timestamp":11012,"Mod":0,"Key":256,"Ch":100},{"Timestamp":11547,"Mod":0,"Key":13,"Ch":13},{"Timestamp":12960,"Mod":0,"Key":256,"Ch":99},{"Timestamp":13863,"Mod":0,"Key":13,"Ch":13},{"Timestamp":15574,"Mod":0,"Key":256,"Ch":32},{"Timestamp":16365,"Mod":0,"Key":256,"Ch":99},{"Timestamp":16977,"Mod":0,"Key":256,"Ch":115},{"Timestamp":17111,"Mod":0,"Key":256,"Ch":101},{"Timestamp":17308,"Mod":0,"Key":256,"Ch":99},{"Timestamp":17420,"Mod":0,"Key":256,"Ch":111},{"Timestamp":17442,"Mod":0,"Key":256,"Ch":110},{"Timestamp":17593,"Mod":0,"Key":256,"Ch":100},{"Timestamp":17814,"Mod":0,"Key":256,"Ch":32},{"Timestamp":18040,"Mod":0,"Key":256,"Ch":99},{"Timestamp":18127,"Mod":0,"Key":256,"Ch":111},{"Timestamp":18269,"Mod":0,"Key":256,"Ch":109},{"Timestamp":18409,"Mod":0,"Key":256,"Ch":109},{"Timestamp":18694,"Mod":0,"Key":256,"Ch":105},{"Timestamp":18803,"Mod":0,"Key":256,"Ch":116},{"Timestamp":19624,"Mod":0,"Key":13,"Ch":13},{"Timestamp":21204,"Mod":0,"Key":256,"Ch":113}],"ResizeEvents":[{"Timestamp":0,"Width":212,"Height":55}]}
|
|
@ -1,23 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cd $1
|
||||
|
||||
git init
|
||||
git config user.email "CI@example.com"
|
||||
git config user.name "CI"
|
||||
|
||||
git checkout -b master
|
||||
|
||||
echo "file1" > file1
|
||||
echo "file2" > file2
|
||||
echo "disruptive" > disruptive
|
||||
cat > .git/hooks/pre-commit <<EOL
|
||||
#!/bin/bash
|
||||
if [ -f disruptive ]; then
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
EOL
|
||||
chmod +x .git/hooks/pre-commit
|
|
@ -1 +0,0 @@
|
|||
{"description": "In this test we attempt to create a commit with the commit message `first commit`, but a pre-commit hook fails (the hook checks for the existance of a file called `disruptive`). Afterwards we make the pre-commit hook work (by discarding the file), and again attempt to create a commit. This time the commit message should already be remembered from the failed attempt and be prefilled. Then another commit is made with the message `second commit`, and this time the last commit message no longer prefilled.", "speed": 20}
|
|
@ -1 +0,0 @@
|
|||
file1
|
|
@ -1 +0,0 @@
|
|||
ref: refs/heads/master
|
|
@ -1,10 +0,0 @@
|
|||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
ignorecase = true
|
||||
precomposeunicode = true
|
||||
[user]
|
||||
email = CI@example.com
|
||||
name = CI
|
|
@ -1 +0,0 @@
|
|||
Unnamed repository; edit this file 'description' to name the repository.
|
Binary file not shown.
|
@ -1,7 +0,0 @@
|
|||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
# *.[oa]
|
||||
# *~
|
||||
.DS_Store
|
|
@ -1 +0,0 @@
|
|||
0000000000000000000000000000000000000000 1854ab416d299cda0227d62b9ab0765e5551ef57 CI <CI@example.com> 1642499804 +1100 commit (initial): file1
|
|
@ -1 +0,0 @@
|
|||
0000000000000000000000000000000000000000 1854ab416d299cda0227d62b9ab0765e5551ef57 CI <CI@example.com> 1642499804 +1100 commit (initial): file1
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
1854ab416d299cda0227d62b9ab0765e5551ef57
|
|
@ -1,67 +0,0 @@
|
|||
package oscommands
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/common"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
// NewDummyOSCommand creates a new dummy OSCommand for testing
|
||||
func NewDummyOSCommand() *OSCommand {
|
||||
osCmd := NewOSCommand(utils.NewDummyCommon(), dummyPlatform, NewNullGuiIO(utils.NewDummyLog()))
|
||||
|
||||
return osCmd
|
||||
}
|
||||
|
||||
type OSCommandDeps struct {
|
||||
Common *common.Common
|
||||
Platform *Platform
|
||||
GetenvFn func(string) string
|
||||
RemoveFileFn func(string) error
|
||||
Cmd *CmdObjBuilder
|
||||
}
|
||||
|
||||
func NewDummyOSCommandWithDeps(deps OSCommandDeps) *OSCommand {
|
||||
if deps.Cmd == nil {
|
||||
panic("WHAT")
|
||||
}
|
||||
common := deps.Common
|
||||
if common == nil {
|
||||
common = utils.NewDummyCommon()
|
||||
}
|
||||
|
||||
platform := deps.Platform
|
||||
if platform == nil {
|
||||
platform = dummyPlatform
|
||||
}
|
||||
|
||||
return &OSCommand{
|
||||
Common: common,
|
||||
Platform: platform,
|
||||
getenvFn: deps.GetenvFn,
|
||||
removeFileFn: deps.RemoveFileFn,
|
||||
guiIO: NewNullGuiIO(utils.NewDummyLog()),
|
||||
Cmd: deps.Cmd,
|
||||
}
|
||||
}
|
||||
|
||||
func NewDummyCmdObjBuilder(runner ICmdObjRunner) *CmdObjBuilder {
|
||||
return &CmdObjBuilder{
|
||||
runner: runner,
|
||||
platform: dummyPlatform,
|
||||
}
|
||||
}
|
||||
|
||||
var dummyPlatform = &Platform{
|
||||
OS: "darwin",
|
||||
Shell: "bash",
|
||||
ShellArg: "-c",
|
||||
OpenCommand: "open {{filename}}",
|
||||
OpenLinkCommand: "open {{link}}",
|
||||
}
|
||||
|
||||
func NewDummyOSCommandWithRunner(runner *FakeCmdObjRunner) *OSCommand {
|
||||
osCommand := NewOSCommand(utils.NewDummyCommon(), dummyPlatform, NewNullGuiIO(utils.NewDummyLog()))
|
||||
osCommand.Cmd = NewDummyCmdObjBuilder(runner)
|
||||
|
||||
return osCommand
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package oscommands
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/common"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
// NewDummyOSCommand creates a new dummy OSCommand for testing
|
||||
func NewDummyOSCommand() *OSCommand {
|
||||
osCmd := NewOSCommand(utils.NewDummyCommon(), dummyPlatform, NewNullGuiIO(utils.NewDummyLog()))
|
||||
|
||||
return osCmd
|
||||
}
|
||||
|
||||
type OSCommandDeps struct {
|
||||
Common *common.Common
|
||||
Platform *Platform
|
||||
GetenvFn func(string) string
|
||||
RemoveFileFn func(string) error
|
||||
Cmd *CmdObjBuilder
|
||||
}
|
||||
|
||||
func NewDummyOSCommandWithDeps(deps OSCommandDeps) *OSCommand {
|
||||
common := deps.Common
|
||||
if common == nil {
|
||||
common = utils.NewDummyCommon()
|
||||
}
|
||||
|
||||
platform := deps.Platform
|
||||
if platform == nil {
|
||||
platform = dummyPlatform
|
||||
}
|
||||
|
||||
return &OSCommand{
|
||||
Common: common,
|
||||
Platform: platform,
|
||||
getenvFn: deps.GetenvFn,
|
||||
removeFileFn: deps.RemoveFileFn,
|
||||
guiIO: NewNullGuiIO(utils.NewDummyLog()),
|
||||
}
|
||||
}
|
||||
|
||||
func NewDummyCmdObjBuilder(runner ICmdObjRunner) *CmdObjBuilder {
|
||||
return &CmdObjBuilder{
|
||||
runner: runner,
|
||||
platform: dummyPlatform,
|
||||
}
|
||||
}
|
||||
|
||||
var dummyPlatform = &Platform{
|
||||
OS: "darwin",
|
||||
Shell: "bash",
|
||||
ShellArg: "-c",
|
||||
OpenCommand: "open {{filename}}",
|
||||
OpenLinkCommand: "open {{link}}",
|
||||
}
|
||||
|
||||
func NewDummyOSCommandWithRunner(runner *FakeCmdObjRunner) *OSCommand {
|
||||
osCommand := NewOSCommand(utils.NewDummyCommon(), dummyPlatform, NewNullGuiIO(utils.NewDummyLog()))
|
||||
osCommand.Cmd = NewDummyCmdObjBuilder(runner)
|
||||
|
||||
return osCommand
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
package oscommands
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/common"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
// NewDummyOSCommand creates a new dummy OSCommand for testing
|
||||
func NewDummyOSCommand() *OSCommand {
|
||||
osCmd := NewOSCommand(utils.NewDummyCommon(), dummyPlatform, NewNullGuiIO(utils.NewDummyLog()))
|
||||
|
||||
return osCmd
|
||||
}
|
||||
|
||||
type OSCommandDeps struct {
|
||||
Common *common.Common
|
||||
Platform *Platform
|
||||
GetenvFn func(string) string
|
||||
RemoveFileFn func(string) error
|
||||
Cmd *CmdObjBuilder
|
||||
}
|
||||
|
||||
func NewDummyOSCommandWithDeps(deps OSCommandDeps) *OSCommand {
|
||||
if deps.Cmd == nil {
|
||||
panic("WHAT")
|
||||
}
|
||||
common := deps.Common
|
||||
if common == nil {
|
||||
common = utils.NewDummyCommon()
|
||||
}
|
||||
|
||||
platform := deps.Platform
|
||||
if platform == nil {
|
||||
platform = dummyPlatform
|
||||
}
|
||||
|
||||
return &OSCommand{
|
||||
Common: common,
|
||||
Platform: platform,
|
||||
getenvFn: deps.GetenvFn,
|
||||
removeFileFn: deps.RemoveFileFn,
|
||||
guiIO: NewNullGuiIO(utils.NewDummyLog()),
|
||||
Cmd: deps.Cmd,
|
||||
}
|
||||
}
|
||||
|
||||
func NewDummyCmdObjBuilder(runner ICmdObjRunner) *CmdObjBuilder {
|
||||
return &CmdObjBuilder{
|
||||
runner: runner,
|
||||
platform: dummyPlatform,
|
||||
}
|
||||
}
|
||||
|
||||
var dummyPlatform = &Platform{
|
||||
OS: "darwin",
|
||||
Shell: "bash",
|
||||
ShellArg: "-c",
|
||||
OpenCommand: "open {{filename}}",
|
||||
OpenLinkCommand: "open {{link}}",
|
||||
}
|
||||
|
||||
func NewDummyOSCommandWithRunner(runner *FakeCmdObjRunner) *OSCommand {
|
||||
osCommand := NewOSCommand(utils.NewDummyCommon(), dummyPlatform, NewNullGuiIO(utils.NewDummyLog()))
|
||||
osCommand.Cmd = NewDummyCmdObjBuilder(runner)
|
||||
|
||||
return osCommand
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
{"KeyEvents":[{"Timestamp":1395,"Mod":0,"Key":13,"Ch":13},{"Timestamp":3036,"Mod":0,"Key":256,"Ch":125},{"Timestamp":3283,"Mod":0,"Key":256,"Ch":125},{"Timestamp":3483,"Mod":0,"Key":256,"Ch":125},{"Timestamp":3996,"Mod":0,"Key":256,"Ch":32},{"Timestamp":4629,"Mod":0,"Key":258,"Ch":0},{"Timestamp":5004,"Mod":0,"Key":258,"Ch":0},{"Timestamp":5067,"Mod":0,"Key":256,"Ch":118},{"Timestamp":5547,"Mod":0,"Key":257,"Ch":0},{"Timestamp":5867,"Mod":0,"Key":256,"Ch":118},{"Timestamp":6492,"Mod":0,"Key":256,"Ch":118},{"Timestamp":6628,"Mod":0,"Key":257,"Ch":0},{"Timestamp":6762,"Mod":0,"Key":257,"Ch":0},{"Timestamp":7779,"Mod":0,"Key":256,"Ch":125},{"Timestamp":8179,"Mod":0,"Key":256,"Ch":125},{"Timestamp":8723,"Mod":0,"Key":256,"Ch":32},{"Timestamp":9531,"Mod":0,"Key":259,"Ch":0},{"Timestamp":10170,"Mod":0,"Key":258,"Ch":0},{"Timestamp":10379,"Mod":0,"Key":258,"Ch":0},{"Timestamp":10500,"Mod":0,"Key":258,"Ch":0},{"Timestamp":10833,"Mod":0,"Key":258,"Ch":0},{"Timestamp":10849,"Mod":0,"Key":258,"Ch":0},{"Timestamp":10865,"Mod":0,"Key":258,"Ch":0},{"Timestamp":10881,"Mod":0,"Key":258,"Ch":0},{"Timestamp":10898,"Mod":0,"Key":258,"Ch":0},{"Timestamp":10915,"Mod":0,"Key":258,"Ch":0},{"Timestamp":10931,"Mod":0,"Key":258,"Ch":0},{"Timestamp":10947,"Mod":0,"Key":258,"Ch":0},{"Timestamp":10964,"Mod":0,"Key":258,"Ch":0},{"Timestamp":11156,"Mod":0,"Key":258,"Ch":0},{"Timestamp":11308,"Mod":0,"Key":258,"Ch":0},{"Timestamp":11435,"Mod":0,"Key":256,"Ch":118},{"Timestamp":11571,"Mod":0,"Key":258,"Ch":0},{"Timestamp":11700,"Mod":0,"Key":258,"Ch":0},{"Timestamp":11828,"Mod":0,"Key":258,"Ch":0},{"Timestamp":11963,"Mod":0,"Key":258,"Ch":0},{"Timestamp":12083,"Mod":0,"Key":258,"Ch":0},{"Timestamp":12603,"Mod":0,"Key":256,"Ch":32},{"Timestamp":13051,"Mod":0,"Key":9,"Ch":9},{"Timestamp":14820,"Mod":0,"Key":256,"Ch":118},{"Timestamp":15028,"Mod":0,"Key":258,"Ch":0},{"Timestamp":15139,"Mod":0,"Key":258,"Ch":0},{"Timestamp":15266,"Mod":0,"Key":258,"Ch":0},{"Timestamp":15387,"Mod":0,"Key":258,"Ch":0},{"Timestamp":15500,"Mod":0,"Key":258,"Ch":0},{"Timestamp":16266,"Mod":0,"Key":256,"Ch":125},{"Timestamp":16483,"Mod":0,"Key":256,"Ch":125},{"Timestamp":16747,"Mod":0,"Key":256,"Ch":125},{"Timestamp":17412,"Mod":0,"Key":256,"Ch":32},{"Timestamp":19124,"Mod":0,"Key":256,"Ch":113}],"ResizeEvents":[{"Timestamp":0,"Width":272,"Height":74}]}
|
|
@ -1,16 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
cd $1
|
||||
|
||||
git init
|
||||
|
||||
git config user.email "CI@example.com"
|
||||
git config user.name "CI"
|
||||
|
||||
cp ../../files/one.txt one.txt
|
||||
git add .
|
||||
git commit -am file1
|
||||
|
||||
cp ../../files/one_new.txt one.txt
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"description": "Staging a file and also changing the diff context",
|
||||
"speed": 20
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
test
|
|
@ -1 +0,0 @@
|
|||
ref: refs/heads/master
|
|
@ -1,10 +0,0 @@
|
|||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
ignorecase = true
|
||||
precomposeunicode = true
|
||||
[user]
|
||||
email = CI@example.com
|
||||
name = CI
|
|
@ -1 +0,0 @@
|
|||
Unnamed repository; edit this file 'description' to name the repository.
|
Binary file not shown.
|
@ -1,7 +0,0 @@
|
|||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
# *.[oa]
|
||||
# *~
|
||||
.DS_Store
|
|
@ -1,2 +0,0 @@
|
|||
0000000000000000000000000000000000000000 6497d00f0447159947a805f3a38e8c44ed2865b1 CI <CI@example.com> 1659701362 +1000 commit (initial): file1
|
||||
6497d00f0447159947a805f3a38e8c44ed2865b1 a6985076907d3ed64cf59480bb2eec313ea221cf CI <CI@example.com> 1659701393 +1000 commit: test
|
|
@ -1,2 +0,0 @@
|
|||
0000000000000000000000000000000000000000 6497d00f0447159947a805f3a38e8c44ed2865b1 CI <CI@example.com> 1659701362 +1000 commit (initial): file1
|
||||
6497d00f0447159947a805f3a38e8c44ed2865b1 a6985076907d3ed64cf59480bb2eec313ea221cf CI <CI@example.com> 1659701393 +1000 commit: test
|
Binary file not shown.
|
@ -1,4 +0,0 @@
|
|||
xM’±nÜ0†;û)þN·øŒtÉÐN:dêÈÐY¶hK8Yt%ê„ÛúyÂ<I()
|
||||
†Eþ"?þôxÆã—‡O—"G‰FT:ÝÕ„+Yü.^kòm¸£Æ2âFœÏËX®&Zh”"ªç÷sè‰9hºëŸM²µ®óùð!ø¸a§œÏâc†<63>à’àT?
ý¢;e%:dĬˆ-¹èËlëm< jÒ†4
Otj%HŸ¢—Ç\B É<>Â5<C382>^ÞÙáÅ%sD
|
||||
~Ç©d¥ªNp„l”Ê^e4_•VBÏû@]àÌMÏmú4˽sµ¦;¤fDº‘Ži¿ƒ×6@þÜjÓAl7«jˆÌVZ—r°
|
||||
WöiøÉÈzò”tˆÃxÛöpõËf3êœàI=¸RÊÓõG¼ýyÅ5rmF‹Óv3‰(ÒÞvÅ¥uà<75>Æá»npKm‡IÁSþú×
2‹Ã‘¸X¬~s-;«ýYýî2püøVNþFù"Kk0¢ÅÖÐôï‡8Öï
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,2 +0,0 @@
|
|||
x=’=ŽÛ0…Sëo+7²»Ý"©¤Øj`‹)q$¦9
|
||||
,¸Ë!rœ$<24>¼€ @óû½7š‚Nxyyþr®ÅI’»n‚Ý„‹Xüª¾–ä%ÚpGÝP?Ä7âxÞM<C39E>Õ=ÂDF%b÷ÅÁùëˆY5ôĘîõ?M²9×ùŒ¼ù|\q•œ<E280A2>ÅÇ¡5Á±þ4|t<>ý²°ƒtX“pCq~¾@m«Ô¥<C394>šÒ'Ò™Q¹K¦ŽŒ˜(¬Î|™U`½<>‡‚=SNëeð©ljôS
AJîì®°yub‡w—Ì%œð!˜<>¦šI¶;B‘.j1A—2’<32>aŸKèy¤8sã÷cM÷`¾wŽáLC»¯t>#ÊM(#ÊõÞ$’=?µ™Át<C381>Û-Þ³Ö¶åÓw
–põzÞ™_^ElÆÓEÅ¥¹gVC¿^y‡MwI¹ùý˜?âïï?¸DÝÛyŠã:ZÏó&ÞŠ'ÖÚVèUÆá;ÿÈí&å¯ÿí3;lI«ÅâW×:'úŸi8¦<0C><>ßhÑ„ào’¿!jiF´ØZý?<éÇ
|
|
@ -1,2 +0,0 @@
|
|||
x=’;ŽÜ0DëåhÍdÞÀŽ8ØhÇÀSbK$†bËüŒ0™áú$.Ò˜êï«jMA'<?ùt©ÅI’‡<݇ W±øU},ÉK´áŽº£(~ˆ)nÄé4¼™«G„‰ŒJÄዃóÛˆY5ôĘîõ?M²9×ùŒ¼û|\±IΧâc†<63>КàXÞ;HŽ~YØA:¬I¸¡8?_‘7 ºôQSú@º°_î’©c/#&
|
||||
k#g¾Ì*°Þ"jÁ‘È)çáEž uð©ìjøS
AJîð®°{ub‡7—Ì%œñ.˜<>¦š‰v8R/Š1A—2žaŸKèy¤8sã÷cM7a¾wŽáBG»±´>#ÊM¨#Êvo Ÿ?·™Át<C381>Û=>³Ö¶åÃx
–pu;¯ŠÌ//‰"vCí<ßµÙgVCÃ^xˆ]I¹þ˜?âïï?¸F=Ú}ŠãºIJ!ÒÖN¬µmÐMÆá;ϳðô‰à)ýÙaOZ-¿º–<C2BA>è¦ß½¿Ñ¢ Áß$ë‡á‚-¶„Vÿvé¿
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
x=’=ŽÜ0…Sű/Ő4Ţ©‚-’*@Švl±µlŃ–0˛ččgŚér<C3A9>ś0'É“‚YŔ ň‰üřč)č„çç/ź.µ 8I2â<32>ÓMp<4D>p‹_ŐÁ’ĽDî¨;Šâ‡<C3A2>âF<=
o¦Ŕęa˘Łqřâŕü6bV
=1¦»ţ§IV#ë:ź‘w‚Ź+6Éů©ř<C2A9>á#´&8ęĎĂ{ÉŃ/_<>kv(ÎĎW¨mJ]z©)} ]•»dα—k™‡YÖŰx*81ĺ<ĽČ©<C48C>p~•ŹýTC<54>’;»k>^ťŘáÍ%łG gĽf§©f’ŽP¤Ë†ł<E280A0> KÉΰĎ%ôĽŇÎÜx´éĚ÷Î1\hh÷•ÎgDą Ç<>˛ÝŰ<C39D>dĎź[Í`:H<>í‰Ykëňá»K¸şť‡WEćÍKâ»ńtQqmî™ŐĐď‚îa×CRn~?ęŹřűű®QʶžâŘn’R<E28099>´µ
kmt“qřνs+Ü|"xĘ_˙»!fvŘ“V‹ĹŻ®e'Úźéw—Aăă/Z4!ř›äo<C3A4>ZZ<5A>-¶„¦˙ Îéb
|
Binary file not shown.
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
a6985076907d3ed64cf59480bb2eec313ea221cf
|
|
@ -1,15 +0,0 @@
|
|||
Out there, we've walked quite friendly up to Death, --
|
||||
Sat down and eaten with him, cool and bland, --
|
||||
Pardoned his spilling mess-tins in our hand.
|
||||
We've sniffed the green thick smell of his breath, --
|
||||
Our eyes wept, but our courage did not writhe.
|
||||
He's spat at us with bullets and he's coughed
|
||||
Shrapnel. We sang when he sang aloft,
|
||||
We whistled while he shaved us with his scythe.
|
||||
|
||||
Oh, Death was never enemy of ours!
|
||||
We laughed at him, we leagued with him, old chum.
|
||||
No soldier's paid to kick against His powers.
|
||||
We laughed, — knowing that greater men would come,
|
||||
And greater wars: when each proud fighter brags
|
||||
He wars on Death, for lives; not men, for flags
|
|
@ -1,298 +0,0 @@
|
|||
package gui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/loaders"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/nodetree"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
// list panel functions
|
||||
|
||||
func (gui *Gui) getSelectednodeNode() *nodetree.nodeNode {
|
||||
selectedLine := gui.State.Panels.nodes.SelectedLineIdx
|
||||
if selectedLine == -1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.State.nodeManager.GetItemAtIndex(selectedLine)
|
||||
}
|
||||
|
||||
func (gui *Gui) getSelectednode() *models.node {
|
||||
node := gui.getSelectednodeNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
return node.node
|
||||
}
|
||||
|
||||
func (gui *Gui) getSelectedPath() string {
|
||||
node := gui.getSelectednodeNode()
|
||||
if node == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return node.GetPath()
|
||||
}
|
||||
|
||||
func (gui *Gui) nodesRenderToMain() error {
|
||||
node := gui.getSelectednodeNode()
|
||||
|
||||
if node == nil {
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
title: "",
|
||||
task: NewRenderStringTask(gui.Tr.NoChangednodes),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if node.node != nil && node.File.HasInlineMergeConflicts {
|
||||
return gui.renderConflictsFromFilesPanel()
|
||||
}
|
||||
|
||||
cmdObj := gui.Git.WorkingTree.WorktreeFileDiffCmdObj(node, false, !node.GetHasUnstagedChanges() && node.GetHasStagedChanges(), gui.State.IgnoreWhitespaceInDiffView)
|
||||
|
||||
refreshOpts := refreshMainOpts{main: &viewUpdateOpts{
|
||||
title: gui.Tr.UnstagedChanges,
|
||||
task: NewRunPtyTask(cmdObj.GetCmd()),
|
||||
}}
|
||||
|
||||
if node.GetHasUnstagedChanges() {
|
||||
if node.GetHasStagedChanges() {
|
||||
cmdObj := gui.Git.WorkingTree.WorktreeFileDiffCmdObj(node, false, true, gui.State.IgnoreWhitespaceInDiffView)
|
||||
|
||||
refreshOpts.secondary = &viewUpdateOpts{
|
||||
title: gui.Tr.StagedChanges,
|
||||
task: NewRunPtyTask(cmdObj.GetCmd()),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
refreshOpts.main.title = gui.Tr.StagedChanges
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshOpts)
|
||||
}
|
||||
|
||||
func (gui *Gui) refreshFilesAndSubmodules() error {
|
||||
gui.Mutexes.RefreshingFilesMutex.Lock()
|
||||
gui.State.IsRefreshingFiles = true
|
||||
defer func() {
|
||||
gui.State.IsRefreshingFiles = false
|
||||
gui.Mutexes.RefreshingFilesMutex.Unlock()
|
||||
}()
|
||||
|
||||
selectedPath := gui.getSelectedPath()
|
||||
|
||||
if err := gui.refreshStateSubmoduleConfigs(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := gui.refreshStateFiles(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gui.OnUIThread(func() error {
|
||||
if err := gui.postRefreshUpdate(gui.State.Contexts.Submodules); err != nil {
|
||||
gui.Log.Error(err)
|
||||
}
|
||||
|
||||
if ContextKey(gui.Views.Files.Context) == FILES_CONTEXT_KEY {
|
||||
// doing this a little custom (as opposed to using gui.postRefreshUpdate) because we handle selecting the file explicitly below
|
||||
if err := gui.State.Contexts.Files.HandleRender(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if gui.currentContext().GetKey() == FILES_CONTEXT_KEY || (gui.g.CurrentView() == gui.Views.Main && ContextKey(gui.g.CurrentView().Context) == MAIN_MERGING_CONTEXT_KEY) {
|
||||
newSelectedPath := gui.getSelectedPath()
|
||||
alreadySelected := selectedPath != "" && newSelectedPath == selectedPath
|
||||
if !alreadySelected {
|
||||
gui.takeOverMergeConflictScrolling()
|
||||
}
|
||||
|
||||
gui.Views.Files.FocusPoint(0, gui.State.Panels.Files.SelectedLineIdx)
|
||||
return gui.filesRenderToMain()
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// specific functions
|
||||
|
||||
func (gui *Gui) stagedFiles() []*models.File {
|
||||
files := gui.State.FileManager.GetAllFiles()
|
||||
result := make([]*models.File, 0)
|
||||
for _, file := range files {
|
||||
if file.HasStagedChanges {
|
||||
result = append(result, file)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (gui *Gui) trackedFiles() []*models.File {
|
||||
files := gui.State.FileManager.GetAllFiles()
|
||||
result := make([]*models.File, 0, len(files))
|
||||
for _, file := range files {
|
||||
if file.Tracked {
|
||||
result = append(result, file)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (gui *Gui) stageSelectedFile() error {
|
||||
file := gui.getSelectedFile()
|
||||
if file == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.Git.WorkingTree.StageFile(file.Name)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleEnterFile() error {
|
||||
return gui.enterFile(OnFocusOpts{ClickedViewName: "", ClickedViewLineIdx: -1})
|
||||
}
|
||||
|
||||
func (gui *Gui) enterFile(opts OnFocusOpts) error {
|
||||
node := gui.getSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if node.File == nil {
|
||||
return gui.handleToggleDirCollapsed()
|
||||
}
|
||||
|
||||
file := node.File
|
||||
|
||||
submoduleConfigs := gui.State.Submodules
|
||||
if file.IsSubmodule(submoduleConfigs) {
|
||||
submoduleConfig := file.SubmoduleConfig(submoduleConfigs)
|
||||
return gui.enterSubmodule(submoduleConfig)
|
||||
}
|
||||
|
||||
if file.HasInlineMergeConflicts {
|
||||
return gui.switchToMerge()
|
||||
}
|
||||
if file.HasMergeConflicts {
|
||||
return gui.createErrorPanel(gui.Tr.FileStagingRequirements)
|
||||
}
|
||||
|
||||
return gui.pushContext(gui.State.Contexts.Staging, opts)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleFilePress() error {
|
||||
node := gui.getSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if node.IsLeaf() {
|
||||
file := node.File
|
||||
|
||||
if file.HasInlineMergeConflicts {
|
||||
return gui.switchToMerge()
|
||||
}
|
||||
|
||||
if node.HasUnstagedChanges {
|
||||
gui.logAction(gui.Tr.Actions.Stagenode)
|
||||
if err := gui.Git.WorkingTree.Stagenode(node.Name); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
} else {
|
||||
gui.logAction(gui.Tr.Actions.Unstagenode)
|
||||
if err := gui.Git.WorkingTree.UnStagenode(node.Names(), node.Tracked); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if node.GetHasInlineMergeConflicts() {
|
||||
return gui.createErrorPanel(gui.Tr.ErrStageDirWithInlineMergeConflicts)
|
||||
}
|
||||
|
||||
if node.GetHasUnstagedChanges() {
|
||||
gui.logAction(gui.Tr.Actions.Stagenode)
|
||||
if err := gui.Git.WorkingTree.Stagenode(node.Path); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
} else {
|
||||
// pretty sure it doesn't matter that we're always passing true here
|
||||
gui.logAction(gui.Tr.Actions.Unstagenode)
|
||||
if err := gui.Git.WorkingTree.UnStagenode([]string{node.Path}, true); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := gui.blah(refreshOptions{scope: []RefreshableView{nodeS}}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return gui.State.Contexts.nodes.HandleFocus()
|
||||
}
|
||||
|
||||
func (gui *Gui) allnodesStaged() bool {
|
||||
for _, node := range gui.State.nodeManager.GetAllnodes() {
|
||||
if node.HasUnstagedChanges {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (gui *Gui) onFocusnode() error {
|
||||
gui.takeOverMergeConflictScrolling()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) handleStageAll() error {
|
||||
var err error
|
||||
if gui.allnodesStaged() {
|
||||
gui.logAction(gui.Tr.Actions.UnstageAllnodes)
|
||||
err = gui.Git.WorkingTree.UnstageAll()
|
||||
} else {
|
||||
gui.logAction(gui.Tr.Actions.StageAllnodes)
|
||||
err = gui.Git.WorkingTree.StageAll()
|
||||
}
|
||||
if err != nil {
|
||||
_ = gui.surfaceError(err)
|
||||
}
|
||||
|
||||
if err := gui.blah(refreshOptions{scope: []RefreshableView{nodeS}}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return gui.State.Contexts.nodes.HandleFocus()
|
||||
}
|
||||
|
||||
func (gui *Gui) handleIgnorenode() error {
|
||||
node := gui.getSelectednodeNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if node.GetPath() == ".gitignore" {
|
||||
return gui.createErrorPanel("Cannot ignore .gitignore")
|
||||
}
|
||||
|
||||
unstagenodes := func() error {
|
||||
return node.ForEachnode(func(node *models.node) error {
|
||||
if node.HasStagedChanges {
|
||||
if err := gui.Git.WorkingTree.UnStagenode(node.Names(), node.Tracked); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
type createMenuOptions struct {
|
||||
showCancel bool
|
||||
}
|
||||
|
||||
func (gui *Gui) createMenu(title string, items []*menuItem, createMenuOptions createMenuOptions) error {
|
||||
if createMenuOptions.showCancel {
|
||||
// this is mutative but I'm okay with that for now
|
||||
items = append(items, &menuItem{
|
||||
displayStrings: []string{gui.Tr.LcCancel},
|
||||
onPress: func() error {
|
||||
return nil
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
gui.State.MenuItems = items
|
||||
|
||||
stringArrays := make([][]string, len(items))
|
||||
for i, item := range items {
|
||||
if item.opensMenu && item.displayStrings != nil {
|
||||
return errors.New("Message for the developer of this app: you've set opensMenu with displaystrings on the menu panel. Bad developer!. Apologies, user")
|
||||
}
|
||||
|
||||
if item.displayStrings == nil {
|
||||
styledStr := item.displayString
|
||||
if item.opensMenu {
|
||||
styledStr = opensMenuStyle(styledStr)
|
||||
}
|
||||
stringArrays[0] = []str0ng{styledStr}
|
||||
} else {
|
||||
str0ngArrays[0] = item.displayStrings
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
Out there, we've walked quite friendly up to Death, --
|
||||
Sat down and eaten with him, cool and bland, --
|
||||
Pardoned his spilling mess-tins in our hand.
|
||||
We've sniffed the green thick odour of his breath, --
|
||||
Our eyes wept, but our courage didn't writhe.
|
||||
He's spat at us with bullets and he's coughed
|
||||
Shrapnel. We chorused when he sang aloft,
|
||||
We whistled while he shaved us with his scythe.
|
||||
|
||||
Oh, Death was never enemy of ours!
|
||||
We laughed at him, we leagued with him, old chum.
|
||||
No soldier's paid to kick against His powers.
|
||||
We laughed, — knowing that better men would come,
|
||||
And greater wars: when each proud fighter brags
|
||||
He wars on Death, for lives; not men, for flags
|
|
@ -1,15 +0,0 @@
|
|||
Out there, we've walked quite friendly up to Death, --
|
||||
Sat down and eaten with him, cool and bland, --
|
||||
Pardoned his spilling mess-tins in our hand.
|
||||
We've sniffed the green thick smell of his breath, --
|
||||
Our eyes wept, but our courage did not writhe.
|
||||
He's spat at us with bullets and he's coughed
|
||||
Shrapnel. We sang when he sang aloft,
|
||||
We whistled while he shaved us with his scythe.
|
||||
|
||||
Oh, Death was never enemy of ours!
|
||||
We laughed at him, we leagued with him, old chum.
|
||||
No soldier's paid to kick against His powers.
|
||||
We laughed, — knowing that greater men would come,
|
||||
And greater wars: when each proud fighter brags
|
||||
He wars on Death, for lives; not men, for flags
|
|
@ -1,300 +0,0 @@
|
|||
package gui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/loaders"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
// list panel functions
|
||||
|
||||
func (gui *Gui) getSelectedFileNode() *filetree.FileNode {
|
||||
selectedLine := gui.State.Panels.Files.SelectedLineIdx
|
||||
if selectedLine == -1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.State.FileManager.GetItemAtIndex(selectedLine)
|
||||
}
|
||||
|
||||
func (gui *Gui) getSelectedFile() *models.File {
|
||||
node := gui.getSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
return node.File
|
||||
}
|
||||
|
||||
func (gui *Gui) getSelectedPath() string {
|
||||
node := gui.getSelectedFileNode()
|
||||
if node == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return node.GetPath()
|
||||
}
|
||||
|
||||
func (gui *Gui) filesRenderToMain() error {
|
||||
node := gui.getSelectedFileNode()
|
||||
|
||||
if node == nil {
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
title: "",
|
||||
task: NewRenderStringTask(gui.Tr.NoChangedFiles),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if node.File != nil && node.File.HasInlineMergeConflicts {
|
||||
return gui.renderConflictsFromFilesPanel()
|
||||
}
|
||||
|
||||
cmdObj := gui.Git.WorkingTree.WorktreeFileDiffCmdObj(node, false, !node.GetHasUnstagedChanges() && node.GetHasStagedChanges(), gui.State.IgnoreWhitespaceInDiffView)
|
||||
|
||||
refreshOpts := refreshMainOpts{main: &viewUpdateOpts{
|
||||
title: gui.Tr.UnstagedChanges,
|
||||
task: NewRunPtyTask(cmdObj.GetCmd()),
|
||||
}}
|
||||
|
||||
if node.GetHasUnstagedChanges() {
|
||||
if node.GetHasStagedChanges() {
|
||||
cmdObj := gui.Git.WorkingTree.WorktreeFileDiffCmdObj(node, false, true, gui.State.IgnoreWhitespaceInDiffView)
|
||||
|
||||
refreshOpts.secondary = &viewUpdateOpts{
|
||||
title: gui.Tr.StagedChanges,
|
||||
task: NewRunPtyTask(cmdObj.GetCmd()),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
refreshOpts.main.title = gui.Tr.StagedChanges
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshOpts)
|
||||
}
|
||||
|
||||
func (gui *Gui) refreshFilesAndSubmodules() error {
|
||||
gui.Mutexes.RefreshingFilesMutex.Lock()
|
||||
gui.State.IsRefreshingFiles = true
|
||||
defer func() {
|
||||
gui.State.IsRefreshingFiles = false
|
||||
gui.Mutexes.RefreshingFilesMutex.Unlock()
|
||||
}()
|
||||
|
||||
selectedPath := gui.getSelectedPath()
|
||||
|
||||
if err := gui.refreshStateSubmoduleConfigs(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := gui.refreshStateFiles(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gui.OnUIThread(func() error {
|
||||
if err := gui.postRefreshUpdate(gui.State.Contexts.Submodules); err != nil {
|
||||
gui.Log.Error(err)
|
||||
}
|
||||
|
||||
if ContextKey(gui.Views.Files.Context) == FILES_CONTEXT_KEY {
|
||||
// doing this a little custom (as opposed to using gui.postRefreshUpdate) because we handle selecting the file explicitly below
|
||||
if err := gui.State.Contexts.Files.HandleRender(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if gui.currentContext().GetKey() == FILES_CONTEXT_KEY || (gui.g.CurrentView() == gui.Views.Main && ContextKey(gui.g.CurrentView().Context) == MAIN_MERGING_CONTEXT_KEY) {
|
||||
newSelectedPath := gui.getSelectedPath()
|
||||
alreadySelected := selectedPath != "" && newSelectedPath == selectedPath
|
||||
if !alreadySelected {
|
||||
gui.takeOverMergeConflictScrolling()
|
||||
}
|
||||
|
||||
gui.Views.Files.FocusPoint(0, gui.State.Panels.Files.SelectedLineIdx)
|
||||
return gui.filesRenderToMain()
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// specific functions
|
||||
|
||||
func (gui *Gui) stagedFiles() []*models.File {
|
||||
files := gui.State.FileManager.GetAllFiles()
|
||||
result := make([]*models.File, 0)
|
||||
for _, file := range files {
|
||||
if file.HasStagedChanges {
|
||||
result = append(result, file)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (gui *Gui) trackedFiles() []*models.File {
|
||||
files := gui.State.FileManager.GetAllFiles()
|
||||
result := make([]*models.File, 0, len(files))
|
||||
for _, file := range files {
|
||||
if file.Tracked {
|
||||
result = append(result, file)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (gui *Gui) stageSelectedFile() error {
|
||||
file := gui.getSelectedFile()
|
||||
if file == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.Git.WorkingTree.StageFile(file.Name)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleEnterFile() error {
|
||||
return gui.enterFile(OnFocusOpts{ClickedViewName: "", ClickedViewLineIdx: -1})
|
||||
}
|
||||
|
||||
func (gui *Gui) enterFile(opts OnFocusOpts) error {
|
||||
node := gui.getSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if node.File == nil {
|
||||
return gui.handleToggleDirCollapsed()
|
||||
}
|
||||
|
||||
file := node.File
|
||||
|
||||
submoduleConfigs := gui.State.Submodules
|
||||
if file.IsSubmodule(submoduleConfigs) {
|
||||
submoduleConfig := file.SubmoduleConfig(submoduleConfigs)
|
||||
return gui.enterSubmodule(submoduleConfig)
|
||||
}
|
||||
|
||||
if file.HasInlineMergeConflicts {
|
||||
return gui.switchToMerge()
|
||||
}
|
||||
if file.HasMergeConflicts {
|
||||
return gui.createErrorPanel(gui.Tr.FileStagingRequirements)
|
||||
}
|
||||
|
||||
return gui.pushContext(gui.State.Contexts.Staging, opts)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleFilePress() error {
|
||||
node := gui.getSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if node.IsLeaf() {
|
||||
file := node.File
|
||||
|
||||
if file.HasInlineMergeConflicts {
|
||||
return gui.switchToMerge()
|
||||
}
|
||||
|
||||
if file.HasUnstagedChanges {
|
||||
gui.logAction(gui.Tr.Actions.StageFile)
|
||||
if err := gui.Git.WorkingTree.StageFile(file.Name); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
} else {
|
||||
gui.logAction(gui.Tr.Actions.UnstageFile)
|
||||
if err := gui.Git.WorkingTree.UnStageFile(file.Names(), file.Tracked); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if any files within have inline merge conflicts we can't stage or unstage,
|
||||
// or it'll end up with those >>>>>> lines actually staged
|
||||
if node.GetHasInlineMergeConflicts() {
|
||||
return gui.createErrorPanel(gui.Tr.ErrStageDirWithInlineMergeConflicts)
|
||||
}
|
||||
|
||||
if node.GetHasUnstagedChanges() {
|
||||
gui.logAction(gui.Tr.Actions.StageFile)
|
||||
if err := gui.Git.WorkingTree.StageFile(node.Path); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
} else {
|
||||
// pretty sure it doesn't matter that we're always passing true here
|
||||
gui.logAction(gui.Tr.Actions.UnstageFile)
|
||||
if err := gui.Git.WorkingTree.UnStageFile([]string{node.Path}, true); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{FILES}}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return gui.State.Contexts.Files.HandleFocus()
|
||||
}
|
||||
|
||||
func (gui *Gui) allFilesStaged() bool {
|
||||
for _, file := range gui.State.FileManager.GetAllFiles() {
|
||||
if file.HasUnstagedChanges {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (gui *Gui) onFocusFile() error {
|
||||
gui.takeOverMergeConflictScrolling()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) handleStageAll() error {
|
||||
var err error
|
||||
if gui.allFilesStaged() {
|
||||
gui.logAction(gui.Tr.Actions.UnstageAllFiles)
|
||||
err = gui.Git.WorkingTree.UnstageAll()
|
||||
} else {
|
||||
gui.logAction(gui.Tr.Actions.StageAllFiles)
|
||||
err = gui.Git.WorkingTree.StageAll()
|
||||
}
|
||||
if err != nil {
|
||||
_ = gui.surfaceError(err)
|
||||
}
|
||||
|
||||
if err := gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{FILES}}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return gui.State.Contexts.Files.HandleFocus()
|
||||
}
|
||||
|
||||
func (gui *Gui) handleIgnoreFile() error {
|
||||
node := gui.getSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if node.GetPath() == ".gitignore" {
|
||||
return gui.createErrorPanel("Cannot ignore .gitignore")
|
||||
}
|
||||
|
||||
unstageFiles := func() error {
|
||||
return node.ForEachFile(func(file *models.File) error {
|
||||
if file.HasStagedChanges {
|
||||
if err := gui.Git.WorkingTree.UnStageFile(file.Names(), file.Tracked); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
|
@ -1,298 +0,0 @@
|
|||
package gui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/loaders"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/nodetree"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
// list panel functions
|
||||
|
||||
func (gui *Gui) getSelectednodeNode() *nodetree.nodeNode {
|
||||
selectedLine := gui.State.Panels.nodes.SelectedLineIdx
|
||||
if selectedLine == -1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.State.nodeManager.GetItemAtIndex(selectedLine)
|
||||
}
|
||||
|
||||
func (gui *Gui) getSelectednode() *models.node {
|
||||
node := gui.getSelectednodeNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
return node.node
|
||||
}
|
||||
|
||||
func (gui *Gui) getSelectedPath() string {
|
||||
node := gui.getSelectednodeNode()
|
||||
if node == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return node.GetPath()
|
||||
}
|
||||
|
||||
func (gui *Gui) nodesRenderToMain() error {
|
||||
node := gui.getSelectednodeNode()
|
||||
|
||||
if node == nil {
|
||||
return gui.refreshMainViews(refreshMainOpts{
|
||||
main: &viewUpdateOpts{
|
||||
title: "",
|
||||
task: NewRenderStringTask(gui.Tr.NoChangednodes),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
if node.node != nil && node.File.HasInlineMergeConflicts {
|
||||
return gui.renderConflictsFromFilesPanel()
|
||||
}
|
||||
|
||||
cmdObj := gui.Git.WorkingTree.WorktreeFileDiffCmdObj(node, false, !node.GetHasUnstagedChanges() && node.GetHasStagedChanges(), gui.State.IgnoreWhitespaceInDiffView)
|
||||
|
||||
refreshOpts := refreshMainOpts{main: &viewUpdateOpts{
|
||||
title: gui.Tr.UnstagedChanges,
|
||||
task: NewRunPtyTask(cmdObj.GetCmd()),
|
||||
}}
|
||||
|
||||
if node.GetHasUnstagedChanges() {
|
||||
if node.GetHasStagedChanges() {
|
||||
cmdObj := gui.Git.WorkingTree.WorktreeFileDiffCmdObj(node, false, true, gui.State.IgnoreWhitespaceInDiffView)
|
||||
|
||||
refreshOpts.secondary = &viewUpdateOpts{
|
||||
title: gui.Tr.StagedChanges,
|
||||
task: NewRunPtyTask(cmdObj.GetCmd()),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
refreshOpts.main.title = gui.Tr.StagedChanges
|
||||
}
|
||||
|
||||
return gui.refreshMainViews(refreshOpts)
|
||||
}
|
||||
|
||||
func (gui *Gui) refreshFilesAndSubmodules() error {
|
||||
gui.Mutexes.RefreshingFilesMutex.Lock()
|
||||
gui.State.IsRefreshingFiles = true
|
||||
defer func() {
|
||||
gui.State.IsRefreshingFiles = false
|
||||
gui.Mutexes.RefreshingFilesMutex.Unlock()
|
||||
}()
|
||||
|
||||
selectedPath := gui.getSelectedPath()
|
||||
|
||||
if err := gui.refreshStateSubmoduleConfigs(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := gui.refreshStateFiles(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gui.OnUIThread(func() error {
|
||||
if err := gui.postRefreshUpdate(gui.State.Contexts.Submodules); err != nil {
|
||||
gui.Log.Error(err)
|
||||
}
|
||||
|
||||
if ContextKey(gui.Views.Files.Context) == FILES_CONTEXT_KEY {
|
||||
// doing this a little custom (as opposed to using gui.postRefreshUpdate) because we handle selecting the file explicitly below
|
||||
if err := gui.State.Contexts.Files.HandleRender(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if gui.currentContext().GetKey() == FILES_CONTEXT_KEY || (gui.g.CurrentView() == gui.Views.Main && ContextKey(gui.g.CurrentView().Context) == MAIN_MERGING_CONTEXT_KEY) {
|
||||
newSelectedPath := gui.getSelectedPath()
|
||||
alreadySelected := selectedPath != "" && newSelectedPath == selectedPath
|
||||
if !alreadySelected {
|
||||
gui.takeOverMergeConflictScrolling()
|
||||
}
|
||||
|
||||
gui.Views.Files.FocusPoint(0, gui.State.Panels.Files.SelectedLineIdx)
|
||||
return gui.filesRenderToMain()
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// specific functions
|
||||
|
||||
func (gui *Gui) stagedFiles() []*models.File {
|
||||
files := gui.State.FileManager.GetAllFiles()
|
||||
result := make([]*models.File, 0)
|
||||
for _, file := range files {
|
||||
if file.HasStagedChanges {
|
||||
result = append(result, file)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (gui *Gui) trackedFiles() []*models.File {
|
||||
files := gui.State.FileManager.GetAllFiles()
|
||||
result := make([]*models.File, 0, len(files))
|
||||
for _, file := range files {
|
||||
if file.Tracked {
|
||||
result = append(result, file)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (gui *Gui) stageSelectedFile() error {
|
||||
file := gui.getSelectedFile()
|
||||
if file == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return gui.Git.WorkingTree.StageFile(file.Name)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleEnterFile() error {
|
||||
return gui.enterFile(OnFocusOpts{ClickedViewName: "", ClickedViewLineIdx: -1})
|
||||
}
|
||||
|
||||
func (gui *Gui) enterFile(opts OnFocusOpts) error {
|
||||
node := gui.getSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if node.File == nil {
|
||||
return gui.handleToggleDirCollapsed()
|
||||
}
|
||||
|
||||
file := node.File
|
||||
|
||||
submoduleConfigs := gui.State.Submodules
|
||||
if file.IsSubmodule(submoduleConfigs) {
|
||||
submoduleConfig := file.SubmoduleConfig(submoduleConfigs)
|
||||
return gui.enterSubmodule(submoduleConfig)
|
||||
}
|
||||
|
||||
if file.HasInlineMergeConflicts {
|
||||
return gui.switchToMerge()
|
||||
}
|
||||
if file.HasMergeConflicts {
|
||||
return gui.createErrorPanel(gui.Tr.FileStagingRequirements)
|
||||
}
|
||||
|
||||
return gui.pushContext(gui.State.Contexts.Staging, opts)
|
||||
}
|
||||
|
||||
func (gui *Gui) handleFilePress() error {
|
||||
node := gui.getSelectedFileNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if node.IsLeaf() {
|
||||
file := node.File
|
||||
|
||||
if file.HasInlineMergeConflicts {
|
||||
return gui.switchToMerge()
|
||||
}
|
||||
|
||||
if node.HasUnstagedChanges {
|
||||
gui.logAction(gui.Tr.Actions.Stagenode)
|
||||
if err := gui.Git.WorkingTree.Stagenode(node.Name); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
} else {
|
||||
gui.logAction(gui.Tr.Actions.Unstagenode)
|
||||
if err := gui.Git.WorkingTree.UnStagenode(node.Names(), node.Tracked); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if node.GetHasInlineMergeConflicts() {
|
||||
return gui.createErrorPanel(gui.Tr.ErrStageDirWithInlineMergeConflicts)
|
||||
}
|
||||
|
||||
if node.GetHasUnstagedChanges() {
|
||||
gui.logAction(gui.Tr.Actions.Stagenode)
|
||||
if err := gui.Git.WorkingTree.Stagenode(node.Path); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
} else {
|
||||
// pretty sure it doesn't matter that we're always passing true here
|
||||
gui.logAction(gui.Tr.Actions.Unstagenode)
|
||||
if err := gui.Git.WorkingTree.UnStagenode([]string{node.Path}, true); err != nil {
|
||||
return gui.surfaceError(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := gui.blah(refreshOptions{scope: []RefreshableView{nodeS}}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return gui.State.Contexts.nodes.HandleFocus()
|
||||
}
|
||||
|
||||
func (gui *Gui) allnodesStaged() bool {
|
||||
for _, node := range gui.State.nodeManager.GetAllnodes() {
|
||||
if node.HasUnstagedChanges {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (gui *Gui) onFocusnode() error {
|
||||
gui.takeOverMergeConflictScrolling()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) handleStageAll() error {
|
||||
var err error
|
||||
if gui.allnodesStaged() {
|
||||
gui.logAction(gui.Tr.Actions.UnstageAllnodes)
|
||||
err = gui.Git.WorkingTree.UnstageAll()
|
||||
} else {
|
||||
gui.logAction(gui.Tr.Actions.StageAllnodes)
|
||||
err = gui.Git.WorkingTree.StageAll()
|
||||
}
|
||||
if err != nil {
|
||||
_ = gui.surfaceError(err)
|
||||
}
|
||||
|
||||
if err := gui.blah(refreshOptions{scope: []RefreshableView{nodeS}}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return gui.State.Contexts.nodes.HandleFocus()
|
||||
}
|
||||
|
||||
func (gui *Gui) handleIgnorenode() error {
|
||||
node := gui.getSelectednodeNode()
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if node.GetPath() == ".gitignore" {
|
||||
return gui.createErrorPanel("Cannot ignore .gitignore")
|
||||
}
|
||||
|
||||
unstagenodes := func() error {
|
||||
return node.ForEachnode(func(node *models.node) error {
|
||||
if node.HasStagedChanges {
|
||||
if err := gui.Git.WorkingTree.UnStagenode(node.Names(), node.Tracked); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue