Compare commits
480 Commits
v0.40.2
...
update-key
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
150260c8a1 | ||
|
|
49df908dd3 | ||
|
|
fdc54b7455 | ||
|
|
607034a61e | ||
|
|
ee173ff7c9 | ||
|
|
761c77f5a2 | ||
|
|
f9e8428061 | ||
|
|
9d840088ac | ||
|
|
b133318b40 | ||
|
|
24e79a057c | ||
|
|
c66667c8c1 | ||
|
|
e8e7ddea45 | ||
|
|
6322944a5e | ||
|
|
510f9a1ae1 | ||
|
|
9b2a5f636a | ||
|
|
e1aa68a7bd | ||
|
|
cf5d4d4f8e | ||
|
|
bd7fabef1f | ||
|
|
1a38d515d7 | ||
|
|
0f9d9e13d1 | ||
|
|
c07b3fad64 | ||
|
|
9bf3063457 | ||
|
|
7bddf53223 | ||
|
|
0aa6109d4d | ||
|
|
cb1b13e95e | ||
|
|
f9876c9742 | ||
|
|
d28a2ec059 | ||
|
|
f226a277bf | ||
|
|
cce29209be | ||
|
|
efb6524fa0 | ||
|
|
a65f003ccc | ||
|
|
b485363006 | ||
|
|
7fb5266027 | ||
|
|
ae89dde969 | ||
|
|
12500be554 | ||
|
|
05b97c8c8e | ||
|
|
0402674ee7 | ||
|
|
269ef7f250 | ||
|
|
798225d9e1 | ||
|
|
b7d4db2446 | ||
|
|
3d9f1e02e5 | ||
|
|
74d937881e | ||
|
|
e72c759541 | ||
|
|
9cd69e46df | ||
|
|
5511cc170e | ||
|
|
41d5f4dbb5 | ||
|
|
f0de880136 | ||
|
|
44e2542e4a | ||
|
|
a5f3515ad8 | ||
|
|
a67ad44781 | ||
|
|
36134006c5 | ||
|
|
3215839524 | ||
|
|
c2218133bc | ||
|
|
7c3d8921b7 | ||
|
|
221ebdc1fb | ||
|
|
2c9b4770bc | ||
|
|
9867180202 | ||
|
|
8dec35ba67 | ||
|
|
74e07080d0 | ||
|
|
ab3004bcd5 | ||
|
|
1ea0c270df | ||
|
|
51fb82d6bf | ||
|
|
280b4d60f8 | ||
|
|
54bd94ad24 | ||
|
|
8840c1a2b7 | ||
|
|
d08fafb1c4 | ||
|
|
f3eb180f75 | ||
|
|
c0c3aac02e | ||
|
|
24a4302c52 | ||
|
|
e887a2eb3c | ||
|
|
8a94663df1 | ||
|
|
8062f96d6b | ||
|
|
cf59b40a1b | ||
|
|
53acbc8f18 | ||
|
|
36e57d16bd | ||
|
|
080aa78266 | ||
|
|
fc8998e377 | ||
|
|
d4a0ca35c7 | ||
|
|
f79305090b | ||
|
|
f133224683 | ||
|
|
83337d9fa8 | ||
|
|
84e1d15079 | ||
|
|
09a24ee97d | ||
|
|
99a3ccde71 | ||
|
|
8ca8a43968 | ||
|
|
9fa43394fe | ||
|
|
37590a495c | ||
|
|
ee106f9af8 | ||
|
|
23a98937b4 | ||
|
|
a0b63090e0 | ||
|
|
53a8bd2e3f | ||
|
|
e9962b98a7 | ||
|
|
a1ce6029c1 | ||
|
|
8c716184c1 | ||
|
|
5c888a0b47 | ||
|
|
498092a8ec | ||
|
|
caf6a3629d | ||
|
|
1ca96bbe5b | ||
|
|
cb5d0bca1c | ||
|
|
ef3d6f4a32 | ||
|
|
b470442a46 | ||
|
|
bf01c0b00e | ||
|
|
76e39af76f | ||
|
|
5b91cd0cc8 | ||
|
|
6255728e63 | ||
|
|
b657fc4f0b | ||
|
|
d294d51791 | ||
|
|
b35f8776e1 | ||
|
|
8ca78412ac | ||
|
|
33f933ba21 | ||
|
|
d70dd5123d | ||
|
|
15da702140 | ||
|
|
cd50c79ae4 | ||
|
|
3ebba5f32c | ||
|
|
9a423c388d | ||
|
|
daf9b8cfa9 | ||
|
|
b6a9220343 | ||
|
|
aeb017e029 | ||
|
|
a6174271aa | ||
|
|
517e0f8248 | ||
|
|
c1cb95db6f | ||
|
|
966e5f5337 | ||
|
|
f244ec8251 | ||
|
|
2b97f0fb43 | ||
|
|
af5e25cfb5 | ||
|
|
93cae68e94 | ||
|
|
6e6fe6a489 | ||
|
|
2c2436574d | ||
|
|
0cdca9ac2c | ||
|
|
4172be6bc8 | ||
|
|
d97b37a178 | ||
|
|
21334fa889 | ||
|
|
36a29f225b | ||
|
|
1e85c4379f | ||
|
|
470632b97a | ||
|
|
50044dd5e0 | ||
|
|
bc330b8ff3 | ||
|
|
7f36494eb2 | ||
|
|
85c48ba887 | ||
|
|
1e3935cbaf | ||
|
|
3fe491fcb2 | ||
|
|
66b608b2f9 | ||
|
|
4ee01d153b | ||
|
|
79e04fad9a | ||
|
|
6778bc04a3 | ||
|
|
d548f857a4 | ||
|
|
f99c59b6d5 | ||
|
|
0fd4983c66 | ||
|
|
240948b882 | ||
|
|
cf82e69bbe | ||
|
|
653e59a3d5 | ||
|
|
e342860ef1 | ||
|
|
569adae6a2 | ||
|
|
79fe885dcd | ||
|
|
a46f26e148 | ||
|
|
ca4b8b25f0 | ||
|
|
dad2c5fa52 | ||
|
|
8a08abcd35 | ||
|
|
b96befa250 | ||
|
|
8cc820668a | ||
|
|
ccb1ee04a5 | ||
|
|
d00936fb4e | ||
|
|
e84d5acd23 | ||
|
|
a8a4211d2b | ||
|
|
6907816af9 | ||
|
|
38db574de9 | ||
|
|
c7012528fc | ||
|
|
2162e5ff64 | ||
|
|
f40f5710f0 | ||
|
|
97940cae10 | ||
|
|
1555503493 | ||
|
|
1a035db4c8 | ||
|
|
df5b3693d6 | ||
|
|
b123719107 | ||
|
|
6ec109c15a | ||
|
|
dee1ff007d | ||
|
|
02b739743a | ||
|
|
f5361fdcb4 | ||
|
|
b86d5bd688 | ||
|
|
4bfffa69ff | ||
|
|
f9b4bcde38 | ||
|
|
aaecd6cc40 | ||
|
|
7e5f25e415 | ||
|
|
d8059d7f7d | ||
|
|
0f2b79a1d4 | ||
|
|
bb87642aee | ||
|
|
4a5b3eaa52 | ||
|
|
1b4e76797f | ||
|
|
58971182ca | ||
|
|
9427a85805 | ||
|
|
d145e818d0 | ||
|
|
e0fc8fe25b | ||
|
|
bb705d91a4 | ||
|
|
738fa286b2 | ||
|
|
1d1b8cc01f | ||
|
|
c357284e1a | ||
|
|
232596b83d | ||
|
|
1c1d558cc7 | ||
|
|
dffb16ed96 | ||
|
|
df8ce76bd6 | ||
|
|
4d18b62c54 | ||
|
|
8193731a82 | ||
|
|
1a6d062192 | ||
|
|
1ff13cdfc6 | ||
|
|
19e8cafe41 | ||
|
|
cbb5fe6007 | ||
|
|
c4fc30c243 | ||
|
|
117aa1dcc6 | ||
|
|
c550737a4f | ||
|
|
9e37ae3f5d | ||
|
|
c89ef8b84a | ||
|
|
23befdd13a | ||
|
|
58a83b0862 | ||
|
|
d5b4f7bb3e | ||
|
|
3cee4de39c | ||
|
|
f609a04671 | ||
|
|
7ffb6ffb0f | ||
|
|
3691856021 | ||
|
|
b5ca6a3add | ||
|
|
ecaa4846f1 | ||
|
|
787f9966ec | ||
|
|
013cfc77a1 | ||
|
|
16f7b01fec | ||
|
|
421c6565f9 | ||
|
|
d02deeefd8 | ||
|
|
235f5bb221 | ||
|
|
be3b4bd791 | ||
|
|
67d6447e12 | ||
|
|
fd9d7cb7bb | ||
|
|
3d6965ccbb | ||
|
|
707fa37160 | ||
|
|
7075b66bc6 | ||
|
|
9d55d71fdd | ||
|
|
cc9a20c4ab | ||
|
|
c39fafe6ec | ||
|
|
2a11725749 | ||
|
|
deed9eb18e | ||
|
|
50b49ebeb1 | ||
|
|
a74c6eef40 | ||
|
|
a3759c65e4 | ||
|
|
519760077b | ||
|
|
8390622f70 | ||
|
|
a04fbafcfd | ||
|
|
4fe8dee40f | ||
|
|
6fd80565c7 | ||
|
|
5ebd8ac7fe | ||
|
|
3cda1d03d9 | ||
|
|
d4eb02fac0 | ||
|
|
9c72d8a2b0 | ||
|
|
4f3127ccb8 | ||
|
|
877c27722f | ||
|
|
0dda8b58d1 | ||
|
|
e997d1ae5d | ||
|
|
3e2ef84d56 | ||
|
|
b2eccd6fe8 | ||
|
|
cc25a3b8c5 | ||
|
|
e93d945dba | ||
|
|
246e08096f | ||
|
|
860a52a736 | ||
|
|
18d8b29461 | ||
|
|
7af371701d | ||
|
|
5ccc95b76f | ||
|
|
cdb1d76484 | ||
|
|
9e423e949c | ||
|
|
e1ceb6892a | ||
|
|
40b8557608 | ||
|
|
92e107f52d | ||
|
|
2f6a87df98 | ||
|
|
2c29577e3c | ||
|
|
e72559bb27 | ||
|
|
6da1cf87b1 | ||
|
|
508b869773 | ||
|
|
59cc6843e6 | ||
|
|
f108fd2236 | ||
|
|
8081b59a02 | ||
|
|
26d180a50a | ||
|
|
10fe872c71 | ||
|
|
c74448f00d | ||
|
|
41ab7c44a0 | ||
|
|
3589a43682 | ||
|
|
ad70341139 | ||
|
|
ea93df571d | ||
|
|
bc21921001 | ||
|
|
07cbb62510 | ||
|
|
fc868cdda5 | ||
|
|
864a9ada57 | ||
|
|
f3e9d50d94 | ||
|
|
cdad0b998e | ||
|
|
64012d67a9 | ||
|
|
33d9d4dbf1 | ||
|
|
4c5e250ed8 | ||
|
|
1359fa14c1 | ||
|
|
c222a618a8 | ||
|
|
05c32e292e | ||
|
|
fb4f742416 | ||
|
|
276438b601 | ||
|
|
edec116ceb | ||
|
|
1aae1772ce | ||
|
|
a642395e9f | ||
|
|
70bfeddc90 | ||
|
|
e2a966443b | ||
|
|
0b13c3ca87 | ||
|
|
8b6766de79 | ||
|
|
c9371f812f | ||
|
|
e592d81b60 | ||
|
|
f2f50ccf75 | ||
|
|
75aed98c35 | ||
|
|
7f9818cfa2 | ||
|
|
679148449a | ||
|
|
bc00aeb10d | ||
|
|
4d258bd981 | ||
|
|
c465b0f2ff | ||
|
|
25160b671e | ||
|
|
20bfa42792 | ||
|
|
5a740e34c7 | ||
|
|
0aad599a9b | ||
|
|
b6c892a08a | ||
|
|
28d12e4e5d | ||
|
|
5d5e24a48e | ||
|
|
de598e55a6 | ||
|
|
0fd8392067 | ||
|
|
67ac2c5d9b | ||
|
|
7626fd7df3 | ||
|
|
db409fa69f | ||
|
|
5b8a8d356c | ||
|
|
d7e2ca3f10 | ||
|
|
387fbf6ab6 | ||
|
|
917eb88617 | ||
|
|
005827395d | ||
|
|
7f9fa64074 | ||
|
|
ab06a1c85c | ||
|
|
37048911ca | ||
|
|
2b7b6f71ee | ||
|
|
47d422bb8a | ||
|
|
c3ca77d6bf | ||
|
|
a3cd1e93be | ||
|
|
4cf8d81155 | ||
|
|
7774fe0ab3 | ||
|
|
f7db17f7d0 | ||
|
|
1106981827 | ||
|
|
1dac4158e9 | ||
|
|
18c5780485 | ||
|
|
e895052437 | ||
|
|
ade8d78c63 | ||
|
|
2e74b7177e | ||
|
|
6266e19623 | ||
|
|
c67aa49856 | ||
|
|
3a54089859 | ||
|
|
e2c447b8d0 | ||
|
|
843e12286f | ||
|
|
e60936e964 | ||
|
|
b9cfd89b80 | ||
|
|
de4224bbe4 | ||
|
|
ce91de76e4 | ||
|
|
acfce07aa0 | ||
|
|
81216189e4 | ||
|
|
2b26b380b6 | ||
|
|
1ba8d3060b | ||
|
|
f561007fb7 | ||
|
|
a63d5891e2 | ||
|
|
df38e954f4 | ||
|
|
ea532b4729 | ||
|
|
572d1b5920 | ||
|
|
e8fac6ca73 | ||
|
|
4de3fadb00 | ||
|
|
12f24aa8b4 | ||
|
|
911aa7774b | ||
|
|
1fb0e1e151 | ||
|
|
94bf279b5a | ||
|
|
37381b610d | ||
|
|
6d4df57393 | ||
|
|
3df01aaff0 | ||
|
|
4ee4f6f34b | ||
|
|
7953f7fa86 | ||
|
|
7a8df7795c | ||
|
|
aa493d3a9e | ||
|
|
72731f2c16 | ||
|
|
f680b6e82e | ||
|
|
ec22570eac | ||
|
|
198ead7c14 | ||
|
|
297a020abf | ||
|
|
473d989cde | ||
|
|
061bfce835 | ||
|
|
996e30e5d9 | ||
|
|
ecd2a14a15 | ||
|
|
8dfa8dc48c | ||
|
|
f7c183a429 | ||
|
|
473f86fcaa | ||
|
|
28353da61b | ||
|
|
efd49f07fd | ||
|
|
b8e183acc4 | ||
|
|
821c4b05fe | ||
|
|
4272d84fa2 | ||
|
|
e95505453e | ||
|
|
6dc34d19ea | ||
|
|
a670fbb33c | ||
|
|
98e6c119f5 | ||
|
|
c718a73d0a | ||
|
|
d74c817fd8 | ||
|
|
93d19db158 | ||
|
|
d7b611aa05 | ||
|
|
fc6008fdff | ||
|
|
a65d3119c0 | ||
|
|
51ecf4089b | ||
|
|
0c0fe8997b | ||
|
|
f86309dd03 | ||
|
|
c31fcb7134 | ||
|
|
91ec42f3f8 | ||
|
|
8f628296ad | ||
|
|
61bd3e8dd2 | ||
|
|
7263630967 | ||
|
|
16711c6f1a | ||
|
|
b2023f10b6 | ||
|
|
e915488a83 | ||
|
|
b2d629b50a | ||
|
|
125d4fa9dc | ||
|
|
527a1596f3 | ||
|
|
51d9f70f9e | ||
|
|
83727d48b5 | ||
|
|
8efc175340 | ||
|
|
6a6cb25d7e | ||
|
|
fd782ff568 | ||
|
|
dbfb469bad | ||
|
|
888a976fc0 | ||
|
|
2073730186 | ||
|
|
7a4a0c85c4 | ||
|
|
382ecb6bfe | ||
|
|
03694f7502 | ||
|
|
ee308a4994 | ||
|
|
a2b2336173 | ||
|
|
d7b1deb465 | ||
|
|
dd01639f57 | ||
|
|
525932fbf2 | ||
|
|
b1314349d7 | ||
|
|
9671f549a1 | ||
|
|
a1738a77ae | ||
|
|
689deb72bd | ||
|
|
84372cfad9 | ||
|
|
e429415ed4 | ||
|
|
7402be98b6 | ||
|
|
341b9725d4 | ||
|
|
8f164f7bc5 | ||
|
|
79c11a0458 | ||
|
|
4a4afc4639 | ||
|
|
ebdfd8046a | ||
|
|
d99e983236 | ||
|
|
1c6cfafba7 | ||
|
|
83d642b74f | ||
|
|
b1bc437d1b | ||
|
|
26989ce0ee | ||
|
|
e6356ce10c | ||
|
|
b92da0dc54 | ||
|
|
70e668bfcf | ||
|
|
8dd517870d | ||
|
|
f1753f36c8 | ||
|
|
3ea81d4a6f | ||
|
|
0df5cb1286 | ||
|
|
c43830b027 | ||
|
|
08624b8ef7 | ||
|
|
73b68927af | ||
|
|
bf699d3a79 | ||
|
|
f2e8d549ba | ||
|
|
4ffb6c0fea | ||
|
|
54776052a1 | ||
|
|
9c5eedf748 | ||
|
|
ca08956f77 | ||
|
|
aa74239f05 | ||
|
|
9e7018db8a | ||
|
|
cdea5b4873 | ||
|
|
4b0432423d | ||
|
|
2607580a09 | ||
|
|
ebd56bd8d5 | ||
|
|
ed1547e0cb | ||
|
|
82b5c20050 | ||
|
|
f32fe84c9b | ||
|
|
fb05ee369f | ||
|
|
213da4fddd | ||
|
|
e78a09ebab | ||
|
|
1431ffcebf | ||
|
|
1a2a301aa2 |
4
.editorconfig
Normal file
4
.editorconfig
Normal file
@@ -0,0 +1,4 @@
|
||||
root = true
|
||||
|
||||
[*.go]
|
||||
indent_style = tab
|
||||
7
.github/pull_request_template.md
vendored
7
.github/pull_request_template.md
vendored
@@ -2,9 +2,14 @@
|
||||
|
||||
- **Please check if the PR fulfills these requirements**
|
||||
|
||||
* [ ] Cheatsheets are up-to-date (run `go run scripts/cheatsheet/main.go generate`)
|
||||
* [ ] Cheatsheets are up-to-date (run `go generate ./...`)
|
||||
* [ ] Code has been formatted (see [here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#code-formatting))
|
||||
* [ ] Tests have been added/updated (see [here](https://github.com/jesseduffield/lazygit/blob/master/pkg/integration/README.md) for the integration test guide)
|
||||
* [ ] Text is internationalised (see [here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#internationalisation))
|
||||
* [ ] Docs (specifically `docs/Config.md`) have been updated if necessary
|
||||
* [ ] You've read through your own file changes for silly mistakes etc
|
||||
|
||||
<!--
|
||||
Be sure to name your PR with an imperative e.g. 'Add worktrees view'
|
||||
see https://github.com/jesseduffield/lazygit/releases/tag/v0.40.0 for examples
|
||||
-->
|
||||
|
||||
4
.github/workflows/cd.yml
vendored
4
.github/workflows/cd.yml
vendored
@@ -14,11 +14,11 @@ jobs:
|
||||
- name: Unshallow repo
|
||||
run: git fetch --prune --unshallow
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: 1.20.x
|
||||
- name: Run goreleaser
|
||||
uses: goreleaser/goreleaser-action@v1
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: v1.17.2
|
||||
|
||||
116
.github/workflows/ci.yml
vendored
116
.github/workflows/ci.yml
vendored
@@ -30,22 +30,20 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: 1.20.x
|
||||
- name: Cache build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
${{matrix.cache_path}}
|
||||
~/go/pkg/mod
|
||||
key: ${{runner.os}}-go-${{hashFiles('**/go.sum')}}-test
|
||||
restore-keys: |
|
||||
${{runner.os}}-go-
|
||||
- name: Test code
|
||||
# we're passing -short so that we skip the integration tests, which will be run in parallel below
|
||||
run: |
|
||||
go test ./... -short
|
||||
mkdir -p /tmp/code_coverage
|
||||
go test ./... -short -cover -args "-test.gocoverdir=/tmp/code_coverage"
|
||||
- name: Upload code coverage artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: coverage-unit-${{ matrix.os }}-${{ github.run_id }}
|
||||
path: /tmp/code_coverage
|
||||
|
||||
integration-tests:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -89,23 +87,23 @@ jobs:
|
||||
path: ~/git-${{matrix.git-version}}
|
||||
key: ${{runner.os}}-git-${{matrix.git-version}}
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: 1.20.x
|
||||
- name: Cache build
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{runner.os}}-go-${{hashFiles('**/go.sum')}}-test
|
||||
restore-keys: |
|
||||
${{runner.os}}-go-
|
||||
- name: Print git version
|
||||
run: git --version
|
||||
- name: Test code
|
||||
env:
|
||||
# See https://go.dev/blog/integration-test-coverage
|
||||
LAZYGIT_GOCOVERDIR: /tmp/code_coverage
|
||||
run: |
|
||||
mkdir -p /tmp/code_coverage
|
||||
./scripts/run_integration_tests.sh
|
||||
- name: Upload code coverage artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: coverage-integration-${{ matrix.git-version }}-${{ github.run_id }}
|
||||
path: /tmp/code_coverage
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
@@ -115,18 +113,9 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: 1.20.x
|
||||
- name: Cache build
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{runner.os}}-go-${{hashFiles('**/go.sum')}}-build
|
||||
restore-keys: |
|
||||
${{runner.os}}-go-
|
||||
- name: Build linux binary
|
||||
run: |
|
||||
GOOS=linux go build
|
||||
@@ -151,29 +140,21 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: 1.20.x
|
||||
- name: Cache build
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{runner.os}}-go-${{hashFiles('**/go.sum')}}-build
|
||||
restore-keys: |
|
||||
${{runner.os}}-go-
|
||||
- name: Check Cheatsheet
|
||||
run: |
|
||||
go run scripts/cheatsheet/main.go check
|
||||
- name: Check Vendor Directory
|
||||
# ensure our vendor directory matches up with our go modules
|
||||
run: |
|
||||
go mod vendor && git diff --exit-code || (echo "Unexpected change to vendor directory. Run 'go mod vendor' locally and commit the changes" && exit 1)
|
||||
- name: Check Integration Test List
|
||||
# ensure our integration test list is up to date
|
||||
- name: Check go.mod file
|
||||
# ensure our go.mod file is clean
|
||||
run: |
|
||||
go generate pkg/integration/tests/tests.go && git diff --exit-code || (echo "Integration test list not up to date. Run 'go generate pkg/integration/tests/tests.go' locally and commit the changes" && exit 1)
|
||||
go mod tidy && git diff --exit-code || (echo "go.mod file is not clean. Run 'go mod tidy' locally and commit the changes" && exit 1)
|
||||
- name: Check All Auto-Generated Files
|
||||
# ensure all our auto-generated files are up to date
|
||||
run: |
|
||||
go generate ./... && git diff --quiet || (git status -s; echo "Auto-generated files not up to date. Run 'go generate ./...' locally and commit the changes" && exit 1)
|
||||
shell: bash # needed so that we get "-o pipefail"
|
||||
- name: Check Filenames
|
||||
run: scripts/check_filenames.sh
|
||||
@@ -185,20 +166,11 @@ jobs:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: 1.20.x
|
||||
- name: Cache build
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: ${{runner.os}}-go-${{hashFiles('**/go.sum')}}-test
|
||||
restore-keys: |
|
||||
${{runner.os}}-go-
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@v3.1.0
|
||||
uses: golangci/golangci-lint-action@v3.7.0
|
||||
with:
|
||||
version: latest
|
||||
- name: errors
|
||||
@@ -213,3 +185,31 @@ jobs:
|
||||
mode: exactly
|
||||
count: 1
|
||||
labels: "ignore-for-release, feature, enhancement, bug, maintenance, docs, i18n"
|
||||
upload-coverage:
|
||||
# List all jobs that produce coverage files
|
||||
needs: [unit-tests, integration-tests]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Download all coverage artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
path: /tmp/code_coverage
|
||||
|
||||
- name: Combine coverage files
|
||||
run: |
|
||||
# Find all directories in /tmp/code_coverage and create a comma-separated list
|
||||
COVERAGE_DIRS=$(find /tmp/code_coverage -mindepth 1 -maxdepth 1 -type d -printf '/tmp/code_coverage/%f,' | sed 's/,$//')
|
||||
echo "Coverage directories: $COVERAGE_DIRS"
|
||||
# Run the combine command with the generated list
|
||||
go tool covdata textfmt -i=$COVERAGE_DIRS -o coverage.out
|
||||
echo "Combined coverage:"
|
||||
go tool cover -func coverage.out | tail -1 | awk '{print $3}'
|
||||
|
||||
- name: Upload to Codacy
|
||||
run: |
|
||||
CODACY_PROJECT_TOKEN=${{ secrets.CODACY_PROJECT_TOKEN }} \
|
||||
bash <(curl -Ls https://coverage.codacy.com/get.sh) report \
|
||||
--force-coverage-parser go -r coverage.out
|
||||
|
||||
2
.github/workflows/sponsors.yml
vendored
2
.github/workflows/sponsors.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Generate Sponsors 💖
|
||||
uses: JamesIves/github-sponsors-readme-action@v1.0.8
|
||||
uses: JamesIves/github-sponsors-readme-action@v1.2.2
|
||||
with:
|
||||
token: ${{ secrets.SPONSORS_TOKEN }}
|
||||
file: 'README.md'
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -35,10 +35,12 @@ lazygit.exe
|
||||
|
||||
test/git_server/data
|
||||
|
||||
test/results/**
|
||||
test/_results/**
|
||||
|
||||
oryxBuildBinary
|
||||
__debug_bin
|
||||
|
||||
.worktrees
|
||||
demo/output/*
|
||||
|
||||
coverage.out
|
||||
|
||||
@@ -20,7 +20,11 @@ linters:
|
||||
linters-settings:
|
||||
exhaustive:
|
||||
default-signifies-exhaustive: true
|
||||
|
||||
staticcheck:
|
||||
# SA1019 is for checking that we're not using fields marked as deprecated
|
||||
# in a comment. It decides this in a loose way so I'm silencing it. Also because
|
||||
# it's tripping on our own structs.
|
||||
checks: ["all", "-SA1019"]
|
||||
nakedret:
|
||||
# the gods will judge me but I just don't like naked returns at all
|
||||
max-func-lines: 0
|
||||
|
||||
45
.vscode/launch.json
vendored
45
.vscode/launch.json
vendored
@@ -7,11 +7,12 @@
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "main.go",
|
||||
"args": ["--debug", "--use-config-file=${workspaceFolder}/.vscode/debugger_config.yml"],
|
||||
"args": [
|
||||
"--debug",
|
||||
"--use-config-file=${workspaceFolder}/.vscode/debugger_config.yml"
|
||||
],
|
||||
"hideSystemGoroutines": true,
|
||||
"console": "integratedTerminal",
|
||||
"presentation": {
|
||||
"hidden": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Tail Lazygit logs",
|
||||
@@ -19,17 +20,41 @@
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "main.go",
|
||||
"args": ["--logs", "--use-config-file=${workspaceFolder}/.vscode/debugger_config.yml"],
|
||||
"args": [
|
||||
"--logs",
|
||||
"--use-config-file=${workspaceFolder}/.vscode/debugger_config.yml"
|
||||
],
|
||||
"console": "integratedTerminal",
|
||||
"presentation": {
|
||||
"hidden": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Attach to a running Lazygit",
|
||||
"type": "go",
|
||||
"request": "attach",
|
||||
"mode": "local",
|
||||
"processId": "lazygit",
|
||||
"hideSystemGoroutines": true,
|
||||
"console": "integratedTerminal",
|
||||
},
|
||||
{
|
||||
// To use this, first start an integration test with the "cli" runner and
|
||||
// use the -debug option; e.g.
|
||||
// $ make integration-test-cli -- -debug tag/reset.go
|
||||
"name": "Attach to integration test runner",
|
||||
"type": "go",
|
||||
"request": "attach",
|
||||
"mode": "local",
|
||||
"processId": "test_lazygit",
|
||||
"hideSystemGoroutines": true,
|
||||
"console": "integratedTerminal",
|
||||
},
|
||||
],
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Run with logs",
|
||||
"configurations": ["Tail Lazygit logs", "Debug Lazygit"],
|
||||
"configurations": [
|
||||
"Tail Lazygit logs",
|
||||
"Debug Lazygit"
|
||||
],
|
||||
"stopAll": true
|
||||
}
|
||||
]
|
||||
|
||||
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"gopls": {
|
||||
"formatting.gofumpt": true,
|
||||
},
|
||||
}
|
||||
@@ -10,6 +10,15 @@ before making a change.
|
||||
|
||||
[This video](https://www.youtube.com/watch?v=kNavnhzZHtk) walks through the process of adding a small feature to lazygit. If you have no idea where to start, watching that video is a good first step.
|
||||
|
||||
## Codebase guide
|
||||
|
||||
[This doc](./docs/dev/Codebase_Guide.md) explains:
|
||||
* what the different packages in the codebase are for
|
||||
* where important files live
|
||||
* important concepts in the code
|
||||
* how the event loop works
|
||||
* other useful information
|
||||
|
||||
## All code changes happen through Pull Requests
|
||||
|
||||
Pull requests are the best way to propose changes to the codebase. We actively
|
||||
@@ -21,6 +30,8 @@ welcome your pull requests:
|
||||
4. Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
|
||||
5. Issue that pull request!
|
||||
|
||||
Please do not raise pull request from your fork's master branch: make a feature branch instead. Lazygit maintainers will sometimes push changes to your branch when reviewing a PR and we often can't do this if you use your master branch.
|
||||
|
||||
If you've never written Go in your life, then join the club! Lazygit was the maintainer's first Go program, and most contributors have never used Go before. Go is widely considered an easy-to-learn language, so if you're looking for an open source project to gain dev experience, you've come to the right place.
|
||||
|
||||
## Running in a VSCode dev container
|
||||
@@ -97,6 +108,10 @@ To run gofumpt from your terminal go:
|
||||
go install mvdan.cc/gofumpt@latest && gofumpt -l -w .
|
||||
```
|
||||
|
||||
## Programming Font
|
||||
|
||||
Lazygit supports [Nerd Fonts](https://www.nerdfonts.com) to render certain icons. Sometimes we use some of these icons verbatim in string literals in the code (mainly in tests), so you need to set your development environment to use a nerd font to see these.
|
||||
|
||||
## Internationalisation
|
||||
|
||||
Boy that's a hard word to spell. Anyway, lazygit is translated into several languages within the pkg/i18n package. If you need to render text to the user, you should add a new field to the TranslationSet struct in `pkg/i18n/english.go` and add the actual content within the `EnglishTranslationSet()` method in the same file. Then you can access via `gui.Tr.YourNewText` (or `self.c.Tr.YourNewText`, etc). Although it is appreciated if you translate the text into other languages, it's not expected of you (google translate will likely do a bad job anyway!).
|
||||
|
||||
68
Makefile
Normal file
68
Makefile
Normal file
@@ -0,0 +1,68 @@
|
||||
.PHONY: all
|
||||
all: build
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
go build -gcflags='all=-N -l'
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
go install
|
||||
|
||||
.PHONY: run
|
||||
run: build
|
||||
./lazygit
|
||||
|
||||
# Run `make run-debug` in one terminal tab and `make print-log` in another to view the program and its log output side by side
|
||||
.PHONY: run-debug
|
||||
run-debug:
|
||||
go run main.go -debug
|
||||
|
||||
.PHONY: print-log
|
||||
print-log:
|
||||
go run main.go --logs
|
||||
|
||||
.PHONY: unit-test
|
||||
unit-test:
|
||||
go test ./... -short
|
||||
|
||||
.PHONY: test
|
||||
test: unit-test integration-test-all
|
||||
|
||||
# Generate all our auto-generated files (test list, cheatsheets, maybe other things in the future)
|
||||
.PHONY: generate
|
||||
generate:
|
||||
go generate ./...
|
||||
|
||||
.PHONY: format
|
||||
format:
|
||||
gofumpt -l -w .
|
||||
|
||||
# For more details about integration test, see https://github.com/jesseduffield/lazygit/blob/master/pkg/integration/README.md.
|
||||
.PHONY: integration-test-tui
|
||||
integration-test-tui:
|
||||
go run cmd/integration_test/main.go tui $(filter-out $@,$(MAKECMDGOALS))
|
||||
|
||||
.PHONY: integration-test-cli
|
||||
integration-test-cli:
|
||||
go run cmd/integration_test/main.go cli $(filter-out $@,$(MAKECMDGOALS))
|
||||
|
||||
.PHONY: integration-test-all
|
||||
integration-test-all:
|
||||
go test pkg/integration/clients/*.go
|
||||
|
||||
.PHONY: bump-gocui
|
||||
bump-gocui:
|
||||
scripts/bump_gocui.sh
|
||||
|
||||
.PHONY: bump-lazycore
|
||||
bump-lazycore:
|
||||
scripts/bump_lazycore.sh
|
||||
|
||||
.PHONY: record-demo
|
||||
record-demo:
|
||||
demo/record_demo.sh $(filter-out $@,$(MAKECMDGOALS))
|
||||
|
||||
.PHONY: vendor
|
||||
vendor:
|
||||
go mod vendor && go mod tidy
|
||||
@@ -16,7 +16,7 @@ Usage:
|
||||
> go run cmd/integration_test/main.go cli [--slow] [--sandbox] <test1> <test2> ...
|
||||
If you pass no test names, it runs all tests
|
||||
Accepted environment variables:
|
||||
KEY_PRESS_DELAY (e.g. 200): the number of milliseconds to wait between keypresses
|
||||
INPUT_DELAY (e.g. 200): the number of milliseconds to wait between keypresses or mouse clicks
|
||||
|
||||
TUI mode:
|
||||
> go run cmd/integration_test/main.go tui
|
||||
@@ -26,6 +26,29 @@ Usage:
|
||||
> go run cmd/integration_test/main.go help
|
||||
`
|
||||
|
||||
type flagInfo struct {
|
||||
name string // name of the flag; can be used with "-" or "--"
|
||||
flag *bool // a pointer to the variable that should be set to true when this flag is passed
|
||||
}
|
||||
|
||||
// Takes the args that you want to parse (excluding the program name and any
|
||||
// subcommands), and returns the remaining args with the flags removed
|
||||
func parseFlags(args []string, flags []flagInfo) []string {
|
||||
outer:
|
||||
for len(args) > 0 {
|
||||
for _, f := range flags {
|
||||
if args[0] == "-"+f.name || args[0] == "--"+f.name {
|
||||
*f.flag = true
|
||||
args = args[1:]
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
log.Fatal(usage)
|
||||
@@ -35,23 +58,26 @@ func main() {
|
||||
case "help":
|
||||
fmt.Println(usage)
|
||||
case "cli":
|
||||
testNames := os.Args[2:]
|
||||
slow := false
|
||||
sandbox := false
|
||||
// get the next arg if it's --slow
|
||||
if len(os.Args) > 2 {
|
||||
if os.Args[2] == "--slow" || os.Args[2] == "-slow" {
|
||||
testNames = os.Args[3:]
|
||||
slow = true
|
||||
} else if os.Args[2] == "--sandbox" || os.Args[2] == "-sandbox" {
|
||||
testNames = os.Args[3:]
|
||||
sandbox = true
|
||||
}
|
||||
}
|
||||
|
||||
clients.RunCLI(testNames, slow, sandbox)
|
||||
waitForDebugger := false
|
||||
raceDetector := false
|
||||
testNames := parseFlags(os.Args[2:], []flagInfo{
|
||||
{"slow", &slow},
|
||||
{"sandbox", &sandbox},
|
||||
{"debug", &waitForDebugger},
|
||||
{"race", &raceDetector},
|
||||
})
|
||||
clients.RunCLI(testNames, slow, sandbox, waitForDebugger, raceDetector)
|
||||
case "tui":
|
||||
clients.RunTUI()
|
||||
raceDetector := false
|
||||
remainingArgs := parseFlags(os.Args[2:], []flagInfo{
|
||||
{"race", &raceDetector},
|
||||
})
|
||||
if len(remainingArgs) > 0 {
|
||||
log.Fatal("tui only supports the -race argument.")
|
||||
}
|
||||
clients.RunTUI(raceDetector)
|
||||
default:
|
||||
log.Fatal(usage)
|
||||
}
|
||||
|
||||
138
docs/Config.md
138
docs/Config.md
@@ -3,7 +3,7 @@
|
||||
Default path for the config file:
|
||||
|
||||
- Linux: `~/.config/lazygit/config.yml`
|
||||
- MacOS: `~/Library/Application Support/lazygit/config.yml`
|
||||
- MacOS: `~/Library/Application\ Support/lazygit/config.yml`
|
||||
- Windows: `%APPDATA%\lazygit\config.yml`
|
||||
|
||||
For old installations (slightly embarrassing: I didn't realise at the time that you didn't need to supply a vendor name to the path so I just used my name):
|
||||
@@ -16,6 +16,17 @@ If you want to change the config directory:
|
||||
|
||||
- MacOS: `export XDG_CONFIG_HOME="$HOME/.config"`
|
||||
|
||||
JSON schema is available for `config.yml` so that IntelliSense in Visual Studio Code (completion and error checking) is automatically enabled when the [YAML Red Hat][yaml] extension is installed. However, note that automatic schema detection only works if your config file is in one of the standard paths mentioned above. If you override the path to the file, you can still make IntelliSense work by adding
|
||||
|
||||
```yaml
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/lazygit.json
|
||||
```
|
||||
|
||||
to the top of your config file or via [Visual Studio Code settings.json config][settings].
|
||||
|
||||
[yaml]: https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml
|
||||
[settings]: https://github.com/redhat-developer/vscode-yaml#associating-a-schema-to-a-glob-pattern-via-yamlschemas
|
||||
|
||||
## Default
|
||||
|
||||
```yaml
|
||||
@@ -24,10 +35,13 @@ gui:
|
||||
windowSize: 'normal' # one of 'normal' | 'half' | 'full' default is 'normal'
|
||||
scrollHeight: 2 # how many lines you scroll by
|
||||
scrollPastBottom: true # enable scrolling past the bottom
|
||||
scrollOffMargin: 2 # how many lines to keep before/after the cursor when it reaches the top/bottom of the view; see 'Scroll-off Margin' section below
|
||||
scrollOffBehavior: 'margin' # one of 'margin' | 'jump'; see 'Scroll-off Margin' section below
|
||||
sidePanelWidth: 0.3333 # number from 0 to 1
|
||||
expandFocusedSidePanel: false
|
||||
mainPanelSplitMode: 'flexible' # one of 'horizontal' | 'flexible' | 'vertical'
|
||||
language: 'auto' # one of 'auto' | 'en' | 'zh' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru'
|
||||
enlargedSideViewLocation: 'left' # one of 'left' | 'top'
|
||||
language: 'auto' # one of 'auto' | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru'
|
||||
timeFormat: '02 Jan 06' # https://pkg.go.dev/time#Time.Format
|
||||
shortTimeFormat: '3:04PM'
|
||||
theme:
|
||||
@@ -43,8 +57,6 @@ gui:
|
||||
- blue
|
||||
selectedLineBgColor:
|
||||
- blue # set to `default` to have no background colour
|
||||
selectedRangeBgColor:
|
||||
- blue
|
||||
cherryPickedCommitBgColor:
|
||||
- cyan
|
||||
cherryPickedCommitFgColor:
|
||||
@@ -63,14 +75,17 @@ gui:
|
||||
showRandomTip: true
|
||||
showBranchCommitHash: false # show commit hashes alongside branch names
|
||||
showBottomLine: true # for hiding the bottom information line (unless it has important information to tell you)
|
||||
showPanelJumps: true # for showing the jump-to-panel keybindings as panel subtitles
|
||||
showCommandLog: true
|
||||
showIcons: false # deprecated: use nerdFontsVersion instead
|
||||
nerdFontsVersion: "" # nerd fonts version to use ("2" or "3"); empty means don't show nerd font icons
|
||||
showFileIcons: true # for hiding file icons in the file views
|
||||
commandLogSize: 8
|
||||
splitDiff: 'auto' # one of 'auto' | 'always'
|
||||
skipRewordInEditorWarning: false # for skipping the confirmation before launching the reword editor
|
||||
border: 'single' # one of 'single' | 'double' | 'rounded' | 'hidden'
|
||||
border: 'rounded' # one of 'single' | 'double' | 'rounded' | 'hidden'
|
||||
animateExplosion: true # shows an explosion animation when nuking the working tree
|
||||
portraitMode: 'auto' # one of 'auto' | 'never' | 'always'
|
||||
git:
|
||||
paging:
|
||||
colorArg: always
|
||||
@@ -104,7 +119,6 @@ git:
|
||||
overrideGpg: false # prevents lazygit from spawning a separate process when using GPG
|
||||
disableForcePushing: false
|
||||
parseEmoji: false
|
||||
diffContextSize: 3 # how many lines of context are shown around a change in diffs
|
||||
os:
|
||||
copyToClipboardCmd: '' # See 'Custom Command for Copying to Clipboard' section
|
||||
editPreset: '' # see 'Configuring File Editing' section
|
||||
@@ -149,7 +163,7 @@ keybinding:
|
||||
jumpToBlock: ['1', '2', '3', '4', '5'] # goto the Nth block / panel
|
||||
nextMatch: 'n'
|
||||
prevMatch: 'N'
|
||||
optionMenu: null # show help menu
|
||||
optionMenu: <disabled> # show help menu
|
||||
optionMenu-alt1: '?' # show help menu
|
||||
select: '<space>'
|
||||
goInto: '<enter>'
|
||||
@@ -186,20 +200,25 @@ keybinding:
|
||||
toggleWhitespaceInDiffView: '<c-w>'
|
||||
increaseContextInDiffView: '}'
|
||||
decreaseContextInDiffView: '{'
|
||||
toggleRangeSelect: 'v'
|
||||
rangeSelectUp: '<s-up>'
|
||||
rangeSelectDown: '<s-down>'
|
||||
status:
|
||||
checkForUpdate: 'u'
|
||||
recentRepos: '<enter>'
|
||||
files:
|
||||
commitChanges: 'c'
|
||||
commitChangesWithoutHook: 'w' # commit changes without pre-commit hook
|
||||
commit: 'c'
|
||||
commitWithoutHook: 'w' # commit changes without pre-commit hook
|
||||
amendLastCommit: 'A'
|
||||
commitChangesWithEditor: 'C'
|
||||
findBaseCommitForFixup: '<c-f>'
|
||||
confirmDiscard: 'x'
|
||||
ignoreFile: 'i'
|
||||
refreshFiles: 'r'
|
||||
stashAllChanges: 's'
|
||||
stash: 's'
|
||||
viewStashOptions: 'S'
|
||||
toggleStagedAll: 'a' # stage/unstage all
|
||||
viewResetOptions: 'D'
|
||||
reset: 'D'
|
||||
fetch: 'f'
|
||||
toggleTreeView: '`'
|
||||
openMergeTool: 'M'
|
||||
@@ -211,31 +230,31 @@ keybinding:
|
||||
forceCheckoutBranch: 'F'
|
||||
rebaseBranch: 'r'
|
||||
renameBranch: 'R'
|
||||
mergeIntoCurrentBranch: 'M'
|
||||
merge: 'M'
|
||||
viewGitFlowOptions: 'i'
|
||||
fastForward: 'f' # fast-forward this branch from its upstream
|
||||
createTag: 'T'
|
||||
newTag: 'T'
|
||||
pushTag: 'P'
|
||||
setUpstream: 'u' # set as upstream of checked-out branch
|
||||
fetchRemote: 'f'
|
||||
fetch: 'f'
|
||||
commits:
|
||||
squashDown: 's'
|
||||
renameCommit: 'r'
|
||||
renameCommitWithEditor: 'R'
|
||||
squash: 's'
|
||||
reword: 'r'
|
||||
rewordWithEditor: 'R'
|
||||
viewResetOptions: 'g'
|
||||
markCommitAsFixup: 'f'
|
||||
fixup: 'f'
|
||||
createFixupCommit: 'F' # create fixup commit for this commit
|
||||
squashAboveCommits: 'S'
|
||||
applyFixupCommits: 'S'
|
||||
moveDownCommit: '<c-j>' # move commit down one
|
||||
moveUpCommit: '<c-k>' # move commit up one
|
||||
amendToCommit: 'A'
|
||||
pickCommit: 'p' # pick commit (when mid-rebase)
|
||||
revertCommit: 't'
|
||||
cherryPickCopy: 'c'
|
||||
cherryPickCopyRange: 'C'
|
||||
pasteCommits: 'v'
|
||||
amend: 'A'
|
||||
amendCommitAttribute: 'a'
|
||||
pick: 'p' # pick commit (when mid-rebase)
|
||||
revert: 't'
|
||||
cherryPickCopy: 'C'
|
||||
pasteCommits: 'V'
|
||||
tagCommit: 'T'
|
||||
checkoutCommit: '<space>'
|
||||
checkout: '<space>'
|
||||
resetCherryPick: '<c-R>'
|
||||
copyCommitMessageToClipboard: '<c-y>'
|
||||
openLogMenu: '<c-l>'
|
||||
@@ -244,10 +263,8 @@ keybinding:
|
||||
popStash: 'g'
|
||||
renameStash: 'r'
|
||||
commitFiles:
|
||||
checkoutCommitFile: 'c'
|
||||
checkout: 'c'
|
||||
main:
|
||||
toggleDragSelect: 'v'
|
||||
toggleDragSelect-alt: 'V'
|
||||
toggleSelectHunk: 'a'
|
||||
pickBothHunks: 'b'
|
||||
submodules:
|
||||
@@ -279,7 +296,7 @@ os:
|
||||
open: 'open {{filename}}'
|
||||
```
|
||||
|
||||
### Custom Command for Copying to Clipboard
|
||||
## Custom Command for Copying to Clipboard
|
||||
```yaml
|
||||
os:
|
||||
copyToClipboardCmd: ''
|
||||
@@ -293,29 +310,22 @@ os:
|
||||
```
|
||||
|
||||
|
||||
### Configuring File Editing
|
||||
## Configuring File Editing
|
||||
|
||||
There are two commands for opening files, `o` for "open" and `e` for "edit". `o`
|
||||
acts as if the file was double-clicked in the Finder/Explorer, so it also works
|
||||
for non-text files, whereas `e` opens the file in an editor. `e` can also jump
|
||||
to the right line in the file if you invoke it from the staging panel, for
|
||||
example.
|
||||
There are two commands for opening files, `o` for "open" and `e` for "edit". `o` acts as if the file was double-clicked in the Finder/Explorer, so it also works for non-text files, whereas `e` opens the file in an editor. `e` can also jump to the right line in the file if you invoke it from the staging panel, for example.
|
||||
|
||||
To tell lazygit which editor to use for the `e` command, the easiest way to do
|
||||
that is to provide an editPreset config, e.g.
|
||||
To tell lazygit which editor to use for the `e` command, the easiest way to do that is to provide an editPreset config, e.g.
|
||||
|
||||
```yaml
|
||||
os:
|
||||
editPreset: 'vscode'
|
||||
```
|
||||
|
||||
Supported presets are `vim`, `nvim`, `emacs`, `nano`, `vscode`, `sublime`, `bbedit`,
|
||||
`kakoune`, `helix`, and `xcode`. In many cases lazygit will be able to guess the right preset
|
||||
from your $(git config core.editor), or an environment variable such as $VISUAL or $EDITOR.
|
||||
Supported presets are `vim`, `nvim`, `nvim-remote`, `lvim`, `emacs`, `nano`, `micro`, `vscode`, `sublime`, `bbedit`, `kakoune`, `helix`, and `xcode`. In many cases lazygit will be able to guess the right preset from your $(git config core.editor), or an environment variable such as $VISUAL or $EDITOR.
|
||||
|
||||
If for some reason you are not happy with the default commands from a preset, or
|
||||
there simply is no preset for your editor, you can customize the commands by
|
||||
setting the `edit`, `editAtLine`, and `editAtLineAndWait` options, e.g.:
|
||||
`nvim-remote` is an experimental preset for when you have invoked lazygit from within a neovim process, allowing lazygit to open the file from within the parent process rather than spawning a new one.
|
||||
|
||||
If for some reason you are not happy with the default commands from a preset, or there simply is no preset for your editor, you can customize the commands by setting the `edit`, `editAtLine`, and `editAtLineAndWait` options, e.g.:
|
||||
|
||||
```yaml
|
||||
os:
|
||||
@@ -326,13 +336,11 @@ os:
|
||||
openDirInEditor: 'myeditor {{dir}}'
|
||||
```
|
||||
|
||||
The `editInTerminal` option is used to decide whether lazygit needs to suspend
|
||||
itself to the background before calling the editor.
|
||||
The `editInTerminal` option is used to decide whether lazygit needs to suspend itself to the background before calling the editor. It should really be named `suspend` because for some cases like when lazygit is opened from within a neovim session and you're using the `nvim-remote` preset, you're technically still in a terminal. Nonetheless we're sticking with the name `editInTerminal` for backwards compatibility.
|
||||
|
||||
Contributions of new editor presets are welcome; see the `getPreset` function in
|
||||
[`editor_presets.go`](https://github.com/jesseduffield/lazygit/blob/master/pkg/config/editor_presets.go).
|
||||
Contributions of new editor presets are welcome; see the `getPreset` function in [`editor_presets.go`](https://github.com/jesseduffield/lazygit/blob/master/pkg/config/editor_presets.go).
|
||||
|
||||
### Overriding default config file location
|
||||
## Overriding default config file location
|
||||
|
||||
To override the default config directory, use `CONFIG_DIR="$HOME/.config/lazygit"`. This directory contains the config file in addition to some other files lazygit uses to keep track of state across sessions.
|
||||
|
||||
@@ -346,6 +354,14 @@ or
|
||||
LG_CONFIG_FILE="$HOME/.base_lg_conf,$HOME/.light_theme_lg_conf" lazygit
|
||||
```
|
||||
|
||||
## Scroll-off Margin
|
||||
|
||||
When the selected line gets close to the bottom of the window and you hit down-arrow, there's a feature called "scroll-off margin" that lets the view scroll a little earlier so that you can see a bit of what's coming in the direction that you are moving. This is controlled by the `gui.scrollOffMargin` setting (default: 2), so it keeps 2 lines below the selection visible as you scroll down. It can be set to 0 to scroll only when the selection reaches the bottom of the window.
|
||||
|
||||
That's the behavior when `gui.scrollOffBehavior` is set to "margin" (the default). If you set `gui.scrollOffBehavior` to "jump", then upon reaching the last line of a view and hitting down-arrow the view will scroll by half a page so that the selection ends up in the middle of the view. This may feel a little jarring because the cursor jumps around when continuously moving down, but it has the advantage that the view doesn't scroll as often.
|
||||
|
||||
This setting applies both to all list views (e.g. commits and branches etc), and to the staging view.
|
||||
|
||||
## Color Attributes
|
||||
|
||||
For color attributes you can choose an array of attributes (with max one color attribute)
|
||||
@@ -373,15 +389,13 @@ The available attributes are:
|
||||
|
||||
## Highlighting the selected line
|
||||
|
||||
If you don't like the default behaviour of highlighting the selected line with a blue background, you can use the `selectedLineBgColor` and `selectedRangeBgColor` keys to customise the behaviour. If you just want to embolden the selected line (this was the original default), you can do the following:
|
||||
If you don't like the default behaviour of highlighting the selected line with a blue background, you can use the `selectedLineBgColor` key to customise the behaviour. If you just want to embolden the selected line (this was the original default), you can do the following:
|
||||
|
||||
```yaml
|
||||
gui:
|
||||
theme:
|
||||
selectedLineBgColor:
|
||||
- default
|
||||
selectedRangeBgColor:
|
||||
- default
|
||||
```
|
||||
|
||||
You can also use the reverse attribute like so:
|
||||
@@ -391,8 +405,6 @@ gui:
|
||||
theme:
|
||||
selectedLineBgColor:
|
||||
- reverse
|
||||
selectedRangeBgColor:
|
||||
- reverse
|
||||
```
|
||||
|
||||
## Custom Author Color
|
||||
@@ -442,19 +454,18 @@ gui:
|
||||
nerdFontsVersion: "3"
|
||||
```
|
||||
|
||||
Supported versions are "2" and "3". The deprecated config `showIcons` sets the
|
||||
version to "2" for backwards compatibility.
|
||||
Supported versions are "2" and "3". The deprecated config `showIcons` sets the version to "2" for backwards compatibility.
|
||||
|
||||
## Keybindings
|
||||
|
||||
For all possible keybinding options, check [Custom_Keybindings.md](https://github.com/jesseduffield/lazygit/blob/master/docs/keybindings/Custom_Keybindings.md)
|
||||
|
||||
You can disable certain key bindings by specifying `null`.
|
||||
You can disable certain key bindings by specifying `<disabled>`.
|
||||
|
||||
```yaml
|
||||
keybinding:
|
||||
universal:
|
||||
edit: null # disable 'edit file'
|
||||
edit: <disabled> # disable 'edit file'
|
||||
```
|
||||
|
||||
### Example Keybindings For Colemak Users
|
||||
@@ -491,9 +502,7 @@ keybinding:
|
||||
|
||||
## Custom pull request URLs
|
||||
|
||||
Some git provider setups (e.g. on-premises GitLab) can have distinct URLs for git-related calls and
|
||||
the web interface/API itself. To work with those, Lazygit needs to know where it needs to create
|
||||
the pull request. You can do so on your `config.yml` file using the following syntax:
|
||||
Some git provider setups (e.g. on-premises GitLab) can have distinct URLs for git-related calls and the web interface/API itself. To work with those, Lazygit needs to know where it needs to create the pull request. You can do so on your `config.yml` file using the following syntax:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -508,8 +517,7 @@ Where:
|
||||
|
||||
## Predefined commit message prefix
|
||||
|
||||
In situations where certain naming pattern is used for branches and commits, pattern can be used to populate
|
||||
commit message with prefix that is parsed from the branch name.
|
||||
In situations where certain naming pattern is used for branches and commits, pattern can be used to populate commit message with prefix that is parsed from the branch name.
|
||||
|
||||
Example:
|
||||
|
||||
@@ -539,9 +547,7 @@ Result:
|
||||
|
||||
## Launching not in a repository behaviour
|
||||
|
||||
By default, when launching lazygit from a directory that is not a repository,
|
||||
you will be prompted to choose if you would like to initialize a repo. You can
|
||||
override this behaviour in the config with one of the following:
|
||||
By default, when launching lazygit from a directory that is not a repository, you will be prompted to choose if you would like to initialize a repo. You can override this behaviour in the config with one of the following:
|
||||
|
||||
```yaml
|
||||
# for default prompting behaviour
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Custom Pagers
|
||||
|
||||
Lazygit supports custom pagers, [configured](/docs/Config.md) in the config.yml file (which can be opened by pressing `o` in the Status panel).
|
||||
Lazygit supports custom pagers, [configured](/docs/Config.md) in the config.yml file (which can be opened by pressing `e` in the Status panel).
|
||||
|
||||
Support does not extend to Windows users, because we're making use of a package which doesn't have Windows support.
|
||||
|
||||
@@ -62,3 +62,25 @@ git:
|
||||
```
|
||||
|
||||
If you set `useConfig: true`, lazygit will use whatever pager is specified in `$GIT_PAGER`, `$PAGER`, or your *git config*. If the pager ends with something like ` | less` we will strip that part out, because less doesn't play nice with our rendering approach. If the custom pager uses less under the hood, that will also break rendering (hence the `--paging=never` flag for the `delta` pager).
|
||||
|
||||
## Using external diff commands
|
||||
|
||||
Some diff tools can't work as a simple pager like the ones above do, because they need access to the entire diff, so just post-processing git's diff is not enough for them. The most notable example is probably [difftastic](https://difftastic.wilfred.me.uk).
|
||||
|
||||
These can be used in lazygit by using the `externalDiffCommand` config; in the case of difftastic, that could be
|
||||
|
||||
```yaml
|
||||
git:
|
||||
paging:
|
||||
externalDiffCommand: difft --color=always
|
||||
```
|
||||
|
||||
The `colorArg`, `pager`, and `useConfig` options are not used in this case.
|
||||
|
||||
You can add whatever extra arguments you prefer for your difftool; for instance
|
||||
|
||||
```yaml
|
||||
git:
|
||||
paging:
|
||||
externalDiffCommand: difft --color=always --display=inline --syntax-highlight=off
|
||||
```
|
||||
|
||||
64
docs/Fixup_Commits.md
Normal file
64
docs/Fixup_Commits.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# Fixup Commits
|
||||
|
||||
## Background
|
||||
|
||||
There's this common scenario that you have a PR in review, the reviewer is
|
||||
requesting some changes, and you make those changes and would normally simply
|
||||
squash them into the original commit that they came from. If you do that,
|
||||
however, there's no way for the reviewer to see what you changed. You could just
|
||||
make a separate commit with those changes at the end of the branch, but this is
|
||||
not ideal because it results in a git history that is not very clean.
|
||||
|
||||
To help with this, git has a concept of fixup commits: you do make a separate
|
||||
commit, but the subject of this commit is the string "fixup! " followed by the
|
||||
original commit subject. This both tells the reviewer what's going on (you are
|
||||
making a change that you later will squash into the designated commit), and it
|
||||
provides an easy way to actually perform this squash operation when you are
|
||||
ready to do that (before merging).
|
||||
|
||||
## Creating fixup commits
|
||||
|
||||
You could of course create fixup commits manually by typing in the commit
|
||||
message with the prefix yourself. But lazygit has an easier way to do that:
|
||||
in the Commits view, select the commit that you want to create a fixup for, and
|
||||
press shift-F (for "Create fixup commit for this commit"). This automatically
|
||||
creates a commit with the appropriate subject line.
|
||||
|
||||
Don't confuse this with the lowercase "f" command ("Fixup commit"); that one
|
||||
squashes the selected commit into its parent, this is not what we want here.
|
||||
|
||||
## Squashing fixup commits
|
||||
|
||||
When you're ready to merge the branch and want to squash all these fixup commits
|
||||
that you created, that's very easy to do: select the first commit of your branch
|
||||
and hit shift-S (for "Squash all 'fixup!' commits above selected commit
|
||||
(autosquash)"). Boom, done.
|
||||
|
||||
## Finding the commit to create a fixup for
|
||||
|
||||
When you are making changes to code that you changed earlier in a long branch,
|
||||
it can be tedious to find the commit to squash it into. Lazygit has a command to
|
||||
help you with this, too: in the Files view, press ctrl-f to select the right
|
||||
base commit in the Commits view automatically. From there, you can either press
|
||||
shift-F to create a fixup commit for it, or shift-A to amend your changes into
|
||||
the commit if you haven't published your branch yet.
|
||||
|
||||
This command works in many cases, and when it does it almost feels like magic,
|
||||
but it's important to understand its limitations because it doesn't always work.
|
||||
The way it works is that it looks at the deleted lines of your current
|
||||
modifications, blames them to find out which commit those lines come from, and
|
||||
if they all come from the same commit, it selects it. So here are cases where it
|
||||
doesn't work:
|
||||
|
||||
- Your current diff has only added lines, but no deleted lines. In this case
|
||||
there's no way for lazygit to know which commit you want to add them to.
|
||||
- The deleted lines belong to multiple different commits. In this case you can
|
||||
help lazygit by staging a set of files or hunks that all belong to the same
|
||||
commit; if some changes are staged, the ctrl-f command works only on those.
|
||||
- The found commit is already on master; in this case, lazygit refuses to select
|
||||
it, because it doesn't make sense to create fixups for it, let alone amend to
|
||||
it.
|
||||
|
||||
To sum it up: the command works great if you are changing code again that you
|
||||
changed or added earlier in the same branch. This is a common enough case to
|
||||
make the command useful.
|
||||
@@ -3,8 +3,9 @@
|
||||
* [Configuration](./Config.md).
|
||||
* [Custom Commands](./Custom_Command_Keybindings.md)
|
||||
* [Custom Pagers](./Custom_Pagers.md)
|
||||
* [Dev docs](./dev)
|
||||
* [Keybindings](./keybindings)
|
||||
* [Undo/Redo](./Undoing.md)
|
||||
* [Range Select](./Range_Select.md)
|
||||
* [Searching/Filtering](./Searching.md)
|
||||
* [Stacked Branches](./Stacked_Branches.md)
|
||||
* [Dev docs](./dev)
|
||||
|
||||
14
docs/Range_Select.md
Normal file
14
docs/Range_Select.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Range Select
|
||||
|
||||
Some actions can be performed on a range of contiguous items. For example:
|
||||
* staging multiple files at once
|
||||
* squashing multiple commits at once
|
||||
* copying (for cherry-pick) multiple commits at once
|
||||
|
||||
There are two ways to select a range of items:
|
||||
1. Sticky range select: Press 'v' to toggle range select, then expand the selection using the up/down arrow key. To reset the selection, press 'v' again.
|
||||
2. Non-sticky range select: Press shift+up or shift+down to expand the selection. To reset the selection, press up/down without shift.
|
||||
|
||||
The sticky option will be more familiar to vim users, and the second option will feel more natural to users who aren't used to doing things in a modal way.
|
||||
|
||||
In order to perform an action on a range of items, simply press the normal key for that action. If the action only works on individual items, it will raise an error. This is a new feature and the plan is to incrementally support range select for more and more actions. If there is an action you would like to support range select which currently does not, please raise an issue in the repo.
|
||||
@@ -7,7 +7,7 @@ refactorings, one for backend changes, and one for frontend changes. Those
|
||||
branches would then all be stacked onto each other.
|
||||
|
||||
Git has support for rebasing such a stack as a whole; you can enable it by
|
||||
setting the git config `rebase.updateRfs` to true. If you then rebase the
|
||||
setting the git config `rebase.updateRefs` to true. If you then rebase the
|
||||
topmost branch of the stack, the other ones in the stack will follow. This
|
||||
includes interactive rebases, so for example amending a commit in the first
|
||||
branch of the stack will "just work" in the sense that it keeps the other
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Undo/Redo in lazygit
|
||||
|
||||

|
||||
You can undo the last action by pressing 'z' and redo with `ctrl+z`. Here we drop a couple of commits and then undo the actions.
|
||||
Undo uses the reflog which is specific to commits and branches so we can't undo changes to the working tree or stash.
|
||||
|
||||
## Keybindings:
|
||||
'z' to undo, 'ctrl+z' to redo
|
||||

|
||||
|
||||
## How it works
|
||||
|
||||
|
||||
94
docs/dev/Codebase_Guide.md
Normal file
94
docs/dev/Codebase_Guide.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Lazygit Codebase Guide
|
||||
|
||||
## Packages
|
||||
|
||||
* `pkg/app`: Contains startup code, inititalises a bunch of stuff like logging, the user config, etc, before starting the gui. Catches and handles some errors that the gui raises.
|
||||
* `pkg/app/daemon`: Contains code relating to the lazygit daemon. This could be better named: it's is not a daemon in the sense that it's a long-running background process; rather it's a short-lived background process that we pass to git for certain tasks, like GIT_EDITOR for when we want to set the TODO file for an interactive rebase.
|
||||
* `pkg/cheatsheet`: Generates the keybinding cheatsheets in `docs/keybindings`.
|
||||
* `pkg/commands/git_commands`: All communication to the git binary happens here. So for example there's a `Checkout` method which calls `git checkout`.
|
||||
* `pkg/commands/oscommands`: Contains code for talking to the OS, and for invoking commands in general
|
||||
* `pkg/commands/git_config`: Reading of the git config all happens here.
|
||||
* `pkg/commands/hosting_service`: Contains code that is specific to git hosting services (aka forges).
|
||||
* `pkg/commands/models`: Contains model structs that represent commits, branches, files, etc.
|
||||
* `pkg/commands/patch`: Contains code for parsing and working with git patches
|
||||
* `pkg/common`: Contains the `Common` struct which holds common dependencies like the logger, i18n, and the user config. Most structs in the code will have a field named `c` which holds a common struct (or a derivative of the common struct).
|
||||
* `pkg/config`: Contains code relating to the Lazygit user config. Specifically `pkg/config/user_config/go` defines the user config struct and its default values.
|
||||
* `pkg/constants`: Contains some constant strings (e.g. links to docs)
|
||||
* `pkg/env`: Contains code relating to setting/getting environment variables
|
||||
* `pkg/i18n`: Contains internationalised strings
|
||||
* `pkg/integration`: Contains end-to-end tests
|
||||
* `pkg/jsonschema`: Contains generator for user config JSON schema.
|
||||
* `pkg/logs`: Contains code for instantiating the logger and for tailing the logs via `lazygit --logs`
|
||||
* `pkg/tasks`: Contains code for running asynchronous tasks: mostly related to efficiently rendering command output to the main window.
|
||||
* `pkg/theme`: Contains code related to colour themes.
|
||||
* `pkg/updates`: Contains code related to Lazygit updates (checking for update, download and installing the update)
|
||||
* `pkg/utils`: Contains lots of low-level helper functions
|
||||
* `pkg/gui`: Contains code related to the gui. We've still got a God Struct in the form of our Gui struct, but over time code has been moved out into contexts, controllers, and helpers, and we intend to continue moving more code out over time.
|
||||
* `pkg/gui/context`: Contains code relating to contexts. There is a context for each view e.g. a branches context, a tags context, etc. Contexts manage state related to the view and receive keypresses.
|
||||
* `pkg/gui/controllers`: Contains code relating to controllers. Controllers define a list of keybindings and their associated handlers. One controller can be assigned to multiple contexts, and one context can contain multiple controllers.
|
||||
* `pkg/gui/controllers/helpers`: Contains code that is shared between multiple controllers.
|
||||
* `pkg/gui/filetree`: Contains code relating to the representation of filetrees.
|
||||
* `pkg/gui/keybindings`: Contains code for mapping between keybindings and their labels
|
||||
* `pkg/gui/mergeconflicts`: Contains code relating to the handling of merge conflicts
|
||||
* `pkg/gui/modes`: Contains code relating to the state of different modes e.g. cherry picking mode, rebase mode.
|
||||
* `pkg/gui/patch_exploring`: Contains code relating to the state of patch-oriented views like the staging view.
|
||||
* `pkg/gui/popup`: Contains code that lets you easily raise popups
|
||||
* `pkg/gui/presentation`: Contains presentation code i.e. code concerned with rendering content inside views
|
||||
* `pkg/gui/services/custom_commands`: Contains code related to user-defined custom commands.
|
||||
* `pkg/gui/status`: Contains code for invoking loaders and toasts
|
||||
* `pkg/gui/style`: Contains code for specifying text styles (colour, bold, etc)
|
||||
* `pkg/gui/types`: Contains various gui-specific types and interfaces. Lots of code lives here to avoid circular dependencies
|
||||
* `vendor/github.com/jesseduffield/gocui`: Gocui is the underlying library used for handling the gui event loop, handling keypresses, and rendering the UI. It defines the View struct which our own context structs build upon.
|
||||
|
||||
## Important files
|
||||
|
||||
* `pkg/config/user_config.go`: defines the user config and default values
|
||||
* `pkg/gui/keybindings.go`: defines keybindings which have not yet been moved into a controller (originally all keybindings were defined here)
|
||||
* `pkg/gui/controllers.go`: links up controllers with contexts
|
||||
* `pkg/gui/controllers/helpers/helpers.go`: defines all the different helper structs
|
||||
* `pkg/commands/git.go`: defines all the different git command structs
|
||||
* `pkg/gui/gui.go`: defines the top-level gui state and gui initialisation/run code
|
||||
* `pkg/gui/layout.go`: defines what happens on each render
|
||||
* `pkg/gui/controllers/helpers/window_arrangement_helper.go`: defines the layout of the UI and the size/position of each window
|
||||
* `pkg/gui/context/context.go`: defines the different contexts
|
||||
* `pkg/gui/context/setup.go`: defines initialisation code for all contexts
|
||||
* `pkg/gui/context.go`: manages the lifecycle of contexts, the context stack, and focus changes.
|
||||
* `pkg/gui/types/views.go`: defines views
|
||||
* `pkg/gui/views.go`: defines the ordering of views (front to back) and their initialisation code
|
||||
* `pkg/gui/gui_common.go`: defines gui-specific methods that all controllers and helpers have access to
|
||||
* `pkg/i18n/english.go`: defines the set of i18n strings and their English values
|
||||
* `pkg/gui/controllers/helpers/refresh_helper.go`: manages refreshing of models. The refresh helper is typically invoked at the end of an action to re-load affected models from git (e.g. re-load branches after doing a git pull)
|
||||
* `pkg/gui/controllers/quit_actions.go`: contains code that runs when you hit 'escape' on a view (assuming the view doesn't define its own escape handler)
|
||||
* `vendor/github.com/jesseduffield/gocui/gui.go`: defines the gocui gui struct
|
||||
* `vendor/github.com/jesseduffield/gocui/view.go`: defines the gocui view struct
|
||||
|
||||
## Concepts
|
||||
|
||||
* **View**: Views are defined in the gocui package, and they maintain an internal buffer of content which is rendered each time the screen is drawn.
|
||||
* **Context**: A context is tied to a view and contains some additional state and logic specific to that view e.g. the branches context has code relating specifically to branches, and writes the list of branches to the branches view. Views and contexts share some responsibilities for historical reasons.
|
||||
* **Controller**: A controller defined keybindings with associated handlers. One controller can be assigned to multiple contexts and one context can have multiple controllers. For example the list controller handles keybindings relating to navigating a list, and is assigned to all list contexts (e.g. the branches context).
|
||||
* **Helper**: A helper defines shared code used by controllers, or used by some other parts of the application. Often a controller will have a method that ends up needing to be used by another controller, so in that case we move the method out into a helper so that both controllers can use it. We need to do this because controllers cannot refer to other controllers' methods.
|
||||
|
||||
In terms of dependencies, controllers sit at the highest level, so they can refer to helpers, contexts, and views (although it's preferable for view-specific code to live in contexts). Helpers can refer to contexts and views, and contexts can only refer to views. Views can't refer to contexts, controllers, or helpers.
|
||||
|
||||
* **Window**: A window is a section of the screen which will render a view. Windows are named after the default view that appears there, so for example there is a 'stash' window that is so named because by default the stash view appears there. But if you press enter on a stash entry, the stash entry's files will be shown in a different view, but in the same window.
|
||||
* **Panel**: The term 'panel' is still used in a few places to refer to either a view or a window, and it's a term that is now deprecated in favour of 'view' and 'window'.
|
||||
* **Tab**: Each tab in a window (e.g. Files, Worktrees, Submodules) actually has a corresponding view which we bring to the front upon changing tabs.
|
||||
* **Model**: Representation of a git object e.g. commits, branches, files.
|
||||
* **ViewModel**: Used by a context to maintain state related to the view.
|
||||
* **Keybinding**: A keybinding associates a _key_ with an _action_. For example if you press the 'down' arrow, the action performed will be your cursor moving down a list by one.
|
||||
* **Action**: An action is the thing that happens when you press a key. Often an action will invoke a git command, but not always: for example, navigation actions don't involve git.
|
||||
* **Common structs**: Most structs have a field named `c` which contains a 'common' struct: a struct containing a bag of dependencies that most structs of the same layer require. For example if you want to access a helper from a controller you can do so with `self.c.Helpers.MyHelper`.
|
||||
|
||||
## Event loop and threads
|
||||
|
||||
The event loop is managed in the `MainLoop` function of `vendor/github.com/jesseduffield/gocui/gui.go`. Any time there is an event like a key press or a window resize, the event will be processed and then the screen will be redrawn. This involves calling the `layout` function defined in `pkg/gui/layout.go`, which lays out the windows and invokes some on-render hooks.
|
||||
|
||||
Often, as part of handling a keypress, we'll want to run some code asynchronously so that it doesn't block the UI thread. For this we'll typically run `self.c.OnWorker(myFunc)`. If the worker wants to then do something on the UI thread again it can call `self.c.OnUIThread(myOtherFunc)`.
|
||||
|
||||
## Legacy code structure
|
||||
|
||||
Before we had controllers and contexts, all the code lived directly in the gui package under a gui God Struct. This was fairly bloated and so we split things out to have a better separation of concerns. Nonetheless, it's a big effort to migrate all the code so we still have some logic in the gui struct that ought to live somewhere else. Likewise, we have some keybindings defined in `pkg/gui/keybindings.go` that ought to live on a controller (all keybindings used to be defined in that one file).
|
||||
|
||||
The new structure has its own problems: we don't have a clear guide on whether code should live in a controller or helper. The current approach is to put code in a controller until it's needed by another controller, and to then extract it out into a helper. We may be better off just putting code in helpers to start with and leaving controllers super-thin, with the responsibility of just pairing keys with corresponding helper functions. But it's not clear to me if that would be better than the current approach.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# Dev Documentation Overview
|
||||
|
||||
* [Busy/Idle tracking](./Busy.md).
|
||||
* [Codebase Guide](./Codebase_Guide.md)
|
||||
* [Busy/Idle Tracking](./Busy.md)
|
||||
* [Integration Tests](../../pkg/integration/README.md)
|
||||
* [Demo Recordings](./Demo_Recordings.md)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go run scripts/cheatsheet/main.go generate` from the project root._
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go generate ./...` from the project root._
|
||||
|
||||
# Lazygit Keybindings
|
||||
|
||||
@@ -6,348 +6,358 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|
||||
|
||||
## Global keybindings
|
||||
|
||||
<pre>
|
||||
<kbd><c-r></kbd>: Switch to a recent repo
|
||||
<kbd><pgup></kbd>: Scroll up main panel (fn+up/shift+k)
|
||||
<kbd><pgdown></kbd>: Scroll down main panel (fn+down/shift+j)
|
||||
<kbd>@</kbd>: Open command log menu
|
||||
<kbd>}</kbd>: Increase the size of the context shown around changes in the diff view
|
||||
<kbd>{</kbd>: Decrease the size of the context shown around changes in the diff view
|
||||
<kbd>:</kbd>: Execute custom command
|
||||
<kbd><c-p></kbd>: View custom patch options
|
||||
<kbd>m</kbd>: View merge/rebase options
|
||||
<kbd>R</kbd>: Refresh
|
||||
<kbd>+</kbd>: Next screen mode (normal/half/fullscreen)
|
||||
<kbd>_</kbd>: Prev screen mode
|
||||
<kbd>?</kbd>: Open menu
|
||||
<kbd><c-s></kbd>: View filter-by-path options
|
||||
<kbd>W</kbd>: Open diff menu
|
||||
<kbd><c-e></kbd>: Open diff menu
|
||||
<kbd><c-w></kbd>: Toggle whether or not whitespace changes are shown in the diff view
|
||||
<kbd>z</kbd>: Undo
|
||||
<kbd><c-z></kbd>: Redo
|
||||
<kbd>P</kbd>: Push
|
||||
<kbd>p</kbd>: Pull
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-r> `` | Switch to a recent repo | |
|
||||
| `` <pgup> (fn+up/shift+k) `` | Scroll up main window | |
|
||||
| `` <pgdown> (fn+down/shift+j) `` | Scroll down main window | |
|
||||
| `` @ `` | View command log options | View options for the command log e.g. show/hide the command log and focus the command log. |
|
||||
| `` P `` | Push | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` p `` | Pull | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` } `` | Increase diff context size | Increase the amount of the context shown around changes in the diff view. |
|
||||
| `` { `` | Decrease diff context size | Decrease the amount of the context shown around changes in the diff view. |
|
||||
| `` : `` | Execute custom command | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
|
||||
| `` <c-p> `` | View custom patch options | |
|
||||
| `` m `` | View merge/rebase options | View options to abort/continue/skip the current merge/rebase. |
|
||||
| `` R `` | Refresh | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. |
|
||||
| `` + `` | Next screen mode (normal/half/fullscreen) | |
|
||||
| `` _ `` | Prev screen mode | |
|
||||
| `` ? `` | Open keybindings menu | |
|
||||
| `` <c-s> `` | View filter-by-path options | View options for filtering the commit log by a file path, so that only commits relating to that path are shown. |
|
||||
| `` W `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` <c-e> `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` q `` | Quit | |
|
||||
| `` <esc> `` | Cancel | |
|
||||
| `` <c-w> `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view. |
|
||||
| `` z `` | Undo | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
|
||||
| `` <c-z> `` | Redo | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
|
||||
|
||||
## List panel navigation
|
||||
|
||||
<pre>
|
||||
<kbd>,</kbd>: Previous page
|
||||
<kbd>.</kbd>: Next page
|
||||
<kbd><</kbd>: Scroll to top
|
||||
<kbd>></kbd>: Scroll to bottom
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
<kbd>H</kbd>: Scroll left
|
||||
<kbd>L</kbd>: Scroll right
|
||||
<kbd>]</kbd>: Next tab
|
||||
<kbd>[</kbd>: Previous tab
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` , `` | Previous page | |
|
||||
| `` . `` | Next page | |
|
||||
| `` < `` | Scroll to top | |
|
||||
| `` > `` | Scroll to bottom | |
|
||||
| `` v `` | Toggle range select | |
|
||||
| `` <s-down> `` | Range select down | |
|
||||
| `` <s-up> `` | Range select up | |
|
||||
| `` / `` | Search the current view by text | |
|
||||
| `` H `` | Scroll left | |
|
||||
| `` L `` | Scroll right | |
|
||||
| `` ] `` | Next tab | |
|
||||
| `` [ `` | Previous tab | |
|
||||
|
||||
## Commit files
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy the committed file name to the clipboard
|
||||
<kbd>c</kbd>: Checkout file
|
||||
<kbd>d</kbd>: Discard this commit's changes to this file
|
||||
<kbd>o</kbd>: Open file
|
||||
<kbd>e</kbd>: Edit file
|
||||
<kbd><space></kbd>: Toggle file included in patch
|
||||
<kbd>a</kbd>: Toggle all files included in patch
|
||||
<kbd><enter></kbd>: Enter file to add selected lines to the patch (or toggle directory collapsed)
|
||||
<kbd>`</kbd>: Toggle file tree view
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy path to clipboard | |
|
||||
| `` c `` | Checkout | Checkout file. This replaces the file in your working tree with the version from the selected commit. |
|
||||
| `` d `` | Remove | Discard this commit's changes to this file. This runs an interactive rebase in the background, so you may get a merge conflict if a later commit also changes this file. |
|
||||
| `` o `` | Open file | Open file in default application. |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <space> `` | Toggle file included in patch | Toggle whether the file is included in the custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` a `` | Toggle all files | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` <enter> `` | Enter file / Toggle directory collapsed | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
|
||||
| `` ` `` | Toggle file tree view | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Commit summary
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: Confirm
|
||||
<kbd><esc></kbd>: Close
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | Confirm | |
|
||||
| `` <esc> `` | Close | |
|
||||
|
||||
## Commits
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy commit SHA to clipboard
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (copied) commits selection
|
||||
<kbd>b</kbd>: View bisect options
|
||||
<kbd>s</kbd>: Squash down
|
||||
<kbd>f</kbd>: Fixup commit
|
||||
<kbd>r</kbd>: Reword commit
|
||||
<kbd>R</kbd>: Reword commit with editor
|
||||
<kbd>d</kbd>: Delete commit
|
||||
<kbd>e</kbd>: Edit commit
|
||||
<kbd>p</kbd>: Pick commit (when mid-rebase)
|
||||
<kbd>F</kbd>: Create fixup commit for this commit
|
||||
<kbd>S</kbd>: Squash all 'fixup!' commits above selected commit (autosquash)
|
||||
<kbd><c-j></kbd>: Move commit down one
|
||||
<kbd><c-k></kbd>: Move commit up one
|
||||
<kbd>v</kbd>: Paste commits (cherry-pick)
|
||||
<kbd>B</kbd>: Mark commit as base commit for rebase
|
||||
<kbd>A</kbd>: Amend commit with staged changes
|
||||
<kbd>a</kbd>: Set/Reset commit author
|
||||
<kbd>t</kbd>: Revert commit
|
||||
<kbd>T</kbd>: Tag commit
|
||||
<kbd><c-l></kbd>: Open log menu
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: Checkout commit
|
||||
<kbd>y</kbd>: Copy commit attribute
|
||||
<kbd>o</kbd>: Open commit in browser
|
||||
<kbd>n</kbd>: Create new branch off of commit
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>c</kbd>: Copy commit (cherry-pick)
|
||||
<kbd>C</kbd>: Copy commit range (cherry-pick)
|
||||
<kbd><enter></kbd>: View selected item's files
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy commit SHA to clipboard | |
|
||||
| `` <c-r> `` | Reset copied (cherry-picked) commits selection | |
|
||||
| `` b `` | View bisect options | |
|
||||
| `` s `` | Squash | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. |
|
||||
| `` f `` | Fixup | Meld the selected commit into the commit below it. Similar to fixup, but the selected commit's message will be discarded. |
|
||||
| `` r `` | Reword | Reword the selected commit's message. |
|
||||
| `` R `` | Reword with editor | |
|
||||
| `` d `` | Drop | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. |
|
||||
| `` e `` | Edit (start interactive rebase) | Edit the selected commit. Use this to start an interactive rebase from the selected commit. When already mid-rebase, this will mark the selected commit for editing, which means that upon continuing the rebase, the rebase will pause at the selected commit to allow you to make changes. |
|
||||
| `` i `` | Start interactive rebase | Start an interactive rebase for the commits on your branch. This will include all commits from the HEAD commit down to the first merge commit or main branch commit.
|
||||
If you would instead like to start an interactive rebase from the selected commit, press `e`. |
|
||||
| `` p `` | Pick | Mark the selected commit to be picked (when mid-rebase). This means that the commit will be retained upon continuing the rebase. |
|
||||
| `` F `` | Create fixup commit | Create 'fixup!' commit for the selected commit. Later on, you can press `S` on this same commit to apply all above fixup commits. |
|
||||
| `` S `` | Apply fixup commits | Squash all 'fixup!' commits, either above the selected commit, or all in current branch (autosquash). |
|
||||
| `` <c-j> `` | Move commit down one | |
|
||||
| `` <c-k> `` | Move commit up one | |
|
||||
| `` V `` | Paste (cherry-pick) | |
|
||||
| `` B `` | Mark as base commit for rebase | Select a base commit for the next rebase. When you rebase onto a branch, only commits above the base commit will be brought across. This uses the `git rebase --onto` command. |
|
||||
| `` A `` | Amend | Amend commit with staged changes. If the selected commit is the HEAD commit, this will perform `git commit --amend`. Otherwise the commit will be amended via a rebase. |
|
||||
| `` a `` | Amend commit attribute | Set/Reset commit author or set co-author. |
|
||||
| `` t `` | Revert | Create a revert commit for the selected commit, which applies the selected commit's changes in reverse. |
|
||||
| `` T `` | Tag commit | Create a new tag pointing at the selected commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` <c-l> `` | View log options | View options for commit log e.g. changing sort order, hiding the git graph, showing the whole git graph. |
|
||||
| `` <space> `` | Checkout | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | Open commit in browser | |
|
||||
| `` n `` | Create new branch off of commit | |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | Copy (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | View files | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Confirmation panel
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: Confirm
|
||||
<kbd><esc></kbd>: Close/Cancel
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | Confirm | |
|
||||
| `` <esc> `` | Close/Cancel | |
|
||||
|
||||
## Files
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy the file name to the clipboard
|
||||
<kbd>d</kbd>: View 'discard changes' options
|
||||
<kbd><space></kbd>: Toggle staged
|
||||
<kbd><c-b></kbd>: Filter files by status
|
||||
<kbd>c</kbd>: Commit changes
|
||||
<kbd>w</kbd>: Commit changes without pre-commit hook
|
||||
<kbd>A</kbd>: Amend last commit
|
||||
<kbd>C</kbd>: Commit changes using git editor
|
||||
<kbd>e</kbd>: Edit file
|
||||
<kbd>o</kbd>: Open file
|
||||
<kbd>i</kbd>: Ignore or exclude file
|
||||
<kbd>r</kbd>: Refresh files
|
||||
<kbd>s</kbd>: Stash all changes
|
||||
<kbd>S</kbd>: View stash options
|
||||
<kbd>a</kbd>: Stage/unstage all
|
||||
<kbd><enter></kbd>: Stage individual hunks/lines for file, or collapse/expand for directory
|
||||
<kbd>g</kbd>: View upstream reset options
|
||||
<kbd>D</kbd>: View reset options
|
||||
<kbd>`</kbd>: Toggle file tree view
|
||||
<kbd>M</kbd>: Open external merge tool (git mergetool)
|
||||
<kbd>f</kbd>: Fetch
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy path to clipboard | |
|
||||
| `` <space> `` | Stage | Toggle staged for selected file. |
|
||||
| `` <c-b> `` | Filter files by status | |
|
||||
| `` y `` | Copy to clipboard | |
|
||||
| `` c `` | Commit | Commit staged changes. |
|
||||
| `` w `` | Commit changes without pre-commit hook | |
|
||||
| `` A `` | Amend last commit | |
|
||||
| `` C `` | Commit changes using git editor | |
|
||||
| `` <c-f> `` | Find base commit for fixup | Find the commit that your current changes are building upon, for the sake of amending/fixing up the commit. This spares you from having to look through your branch's commits one-by-one to see which commit should be amended/fixed up. See docs: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` o `` | Open file | Open file in default application. |
|
||||
| `` i `` | Ignore or exclude file | |
|
||||
| `` r `` | Refresh files | |
|
||||
| `` s `` | Stash | Stash all changes. For other variations of stashing, use the view stash options keybinding. |
|
||||
| `` S `` | View stash options | View stash options (e.g. stash all, stash staged, stash unstaged). |
|
||||
| `` a `` | Stage all | Toggle staged/unstaged for all files in working tree. |
|
||||
| `` <enter> `` | Stage lines / Collapse directory | If the selected item is a file, focus the staging view so you can stage individual hunks/lines. If the selected item is a directory, collapse/expand it. |
|
||||
| `` d `` | Discard | View options for discarding changes to the selected file. |
|
||||
| `` g `` | View upstream reset options | |
|
||||
| `` D `` | Reset | View reset options for working tree (e.g. nuking the working tree). |
|
||||
| `` ` `` | Toggle file tree view | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` M `` | Open external merge tool | Run `git mergetool`. |
|
||||
| `` f `` | Fetch | Fetch changes from remote. |
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Local branches
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy branch name to clipboard
|
||||
<kbd>i</kbd>: Show git-flow options
|
||||
<kbd><space></kbd>: Checkout
|
||||
<kbd>n</kbd>: New branch
|
||||
<kbd>o</kbd>: Create pull request
|
||||
<kbd>O</kbd>: Create pull request options
|
||||
<kbd><c-y></kbd>: Copy pull request URL to clipboard
|
||||
<kbd>c</kbd>: Checkout by name
|
||||
<kbd>F</kbd>: Force checkout
|
||||
<kbd>d</kbd>: Delete branch
|
||||
<kbd>r</kbd>: Rebase checked-out branch onto this branch
|
||||
<kbd>M</kbd>: Merge into currently checked out branch
|
||||
<kbd>f</kbd>: Fast-forward this branch from its upstream
|
||||
<kbd>T</kbd>: Create tag
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>R</kbd>: Rename branch
|
||||
<kbd>u</kbd>: Set/Unset upstream
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: View commits
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy branch name to clipboard | |
|
||||
| `` i `` | Show git-flow options | |
|
||||
| `` <space> `` | Checkout | Checkout selected item. |
|
||||
| `` n `` | New branch | |
|
||||
| `` o `` | Create pull request | |
|
||||
| `` O `` | View create pull request options | |
|
||||
| `` <c-y> `` | Copy pull request URL to clipboard | |
|
||||
| `` c `` | Checkout by name | Checkout by name. In the input box you can enter '-' to switch to the last branch. |
|
||||
| `` F `` | Force checkout | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||
| `` r `` | Rebase | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` M `` | Merge | Merge selected branch into currently checked out branch. |
|
||||
| `` f `` | Fast-forward | Fast-forward selected branch from its upstream. |
|
||||
| `` T `` | New tag | |
|
||||
| `` s `` | Sort order | |
|
||||
| `` g `` | Reset | |
|
||||
| `` R `` | Rename branch | |
|
||||
| `` u `` | View upstream options | View options relating to the branch's upstream e.g. setting/unsetting the upstream and resetting to the upstream. |
|
||||
| `` <enter> `` | View commits | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Main panel (merging)
|
||||
|
||||
<pre>
|
||||
<kbd>e</kbd>: Edit file
|
||||
<kbd>o</kbd>: Open file
|
||||
<kbd><left></kbd>: Select previous conflict
|
||||
<kbd><right></kbd>: Select next conflict
|
||||
<kbd><up></kbd>: Select previous hunk
|
||||
<kbd><down></kbd>: Select next hunk
|
||||
<kbd>z</kbd>: Undo
|
||||
<kbd>M</kbd>: Open external merge tool (git mergetool)
|
||||
<kbd><space></kbd>: Pick hunk
|
||||
<kbd>b</kbd>: Pick all hunks
|
||||
<kbd><esc></kbd>: Return to files panel
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Pick hunk | |
|
||||
| `` b `` | Pick all hunks | |
|
||||
| `` <up> `` | Previous hunk | |
|
||||
| `` <down> `` | Next hunk | |
|
||||
| `` <left> `` | Previous conflict | |
|
||||
| `` <right> `` | Next conflict | |
|
||||
| `` z `` | Undo | Undo last merge conflict resolution. |
|
||||
| `` e `` | Edit file | Open file in external editor. |
|
||||
| `` o `` | Open file | Open file in default application. |
|
||||
| `` M `` | Open external merge tool | Run `git mergetool`. |
|
||||
| `` <esc> `` | Return to files panel | |
|
||||
|
||||
## Main panel (normal)
|
||||
|
||||
<pre>
|
||||
<kbd>mouse wheel down</kbd>: Scroll down (fn+up)
|
||||
<kbd>mouse wheel up</kbd>: Scroll up (fn+down)
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` mouse wheel down (fn+up) `` | Scroll down | |
|
||||
| `` mouse wheel up (fn+down) `` | Scroll up | |
|
||||
|
||||
## Main panel (patch building)
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: Select previous hunk
|
||||
<kbd><right></kbd>: Select next hunk
|
||||
<kbd>v</kbd>: Toggle drag select
|
||||
<kbd>V</kbd>: Toggle drag select
|
||||
<kbd>a</kbd>: Toggle select hunk
|
||||
<kbd><c-o></kbd>: Copy the selected text to the clipboard
|
||||
<kbd>o</kbd>: Open file
|
||||
<kbd>e</kbd>: Edit file
|
||||
<kbd><space></kbd>: Add/Remove line(s) to patch
|
||||
<kbd><esc></kbd>: Exit custom patch builder
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | Go to previous hunk | |
|
||||
| `` <right> `` | Go to next hunk | |
|
||||
| `` v `` | Toggle range select | |
|
||||
| `` a `` | Select hunk | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | Copy selected text to clipboard | |
|
||||
| `` o `` | Open file | Open file in default application. |
|
||||
| `` e `` | Edit file | Open file in external editor. |
|
||||
| `` <space> `` | Toggle lines in patch | |
|
||||
| `` <esc> `` | Exit custom patch builder | |
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Main panel (staging)
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: Select previous hunk
|
||||
<kbd><right></kbd>: Select next hunk
|
||||
<kbd>v</kbd>: Toggle drag select
|
||||
<kbd>V</kbd>: Toggle drag select
|
||||
<kbd>a</kbd>: Toggle select hunk
|
||||
<kbd><c-o></kbd>: Copy the selected text to the clipboard
|
||||
<kbd>o</kbd>: Open file
|
||||
<kbd>e</kbd>: Edit file
|
||||
<kbd><esc></kbd>: Return to files panel
|
||||
<kbd><tab></kbd>: Switch to other panel (staged/unstaged changes)
|
||||
<kbd><space></kbd>: Toggle line staged / unstaged
|
||||
<kbd>d</kbd>: Discard change (git reset)
|
||||
<kbd>E</kbd>: Edit hunk
|
||||
<kbd>c</kbd>: Commit changes
|
||||
<kbd>w</kbd>: Commit changes without pre-commit hook
|
||||
<kbd>C</kbd>: Commit changes using git editor
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | Go to previous hunk | |
|
||||
| `` <right> `` | Go to next hunk | |
|
||||
| `` v `` | Toggle range select | |
|
||||
| `` a `` | Select hunk | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | Copy selected text to clipboard | |
|
||||
| `` <space> `` | Stage | Toggle selection staged / unstaged. |
|
||||
| `` d `` | Discard | When unstaged change is selected, discard the change using `git reset`. When staged change is selected, unstage the change. |
|
||||
| `` o `` | Open file | Open file in default application. |
|
||||
| `` e `` | Edit file | Open file in external editor. |
|
||||
| `` <esc> `` | Return to files panel | |
|
||||
| `` <tab> `` | Switch view | Switch to other view (staged/unstaged changes). |
|
||||
| `` E `` | Edit hunk | Edit selected hunk in external editor. |
|
||||
| `` c `` | Commit | Commit staged changes. |
|
||||
| `` w `` | Commit changes without pre-commit hook | |
|
||||
| `` C `` | Commit changes using git editor | |
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Menu
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: Execute
|
||||
<kbd><esc></kbd>: Close
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | Execute | |
|
||||
| `` <esc> `` | Close | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Reflog
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy commit SHA to clipboard
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: Checkout commit
|
||||
<kbd>y</kbd>: Copy commit attribute
|
||||
<kbd>o</kbd>: Open commit in browser
|
||||
<kbd>n</kbd>: Create new branch off of commit
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>c</kbd>: Copy commit (cherry-pick)
|
||||
<kbd>C</kbd>: Copy commit range (cherry-pick)
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (copied) commits selection
|
||||
<kbd><enter></kbd>: View commits
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy commit SHA to clipboard | |
|
||||
| `` <space> `` | Checkout | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | Open commit in browser | |
|
||||
| `` n `` | Create new branch off of commit | |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | Copy (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | Reset copied (cherry-picked) commits selection | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | View commits | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Remote branches
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy branch name to clipboard
|
||||
<kbd><space></kbd>: Checkout
|
||||
<kbd>n</kbd>: New branch
|
||||
<kbd>M</kbd>: Merge into currently checked out branch
|
||||
<kbd>r</kbd>: Rebase checked-out branch onto this branch
|
||||
<kbd>d</kbd>: Delete branch
|
||||
<kbd>u</kbd>: Set as upstream of checked-out branch
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: View commits
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy branch name to clipboard | |
|
||||
| `` <space> `` | Checkout | Checkout a new local branch based on the selected remote branch. The new branch will track the remote branch. |
|
||||
| `` n `` | New branch | |
|
||||
| `` M `` | Merge | Merge selected branch into currently checked out branch. |
|
||||
| `` r `` | Rebase | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||
| `` u `` | Set as upstream | Set the selected remote branch as the upstream of the checked-out branch. |
|
||||
| `` s `` | Sort order | |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | View commits | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Remotes
|
||||
|
||||
<pre>
|
||||
<kbd>f</kbd>: Fetch remote
|
||||
<kbd>n</kbd>: Add new remote
|
||||
<kbd>d</kbd>: Remove remote
|
||||
<kbd>e</kbd>: Edit remote
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | View branches | |
|
||||
| `` n `` | New remote | |
|
||||
| `` d `` | Remove | Remove the selected remote. Any local branches tracking a remote branch from the remote will be unaffected. |
|
||||
| `` e `` | Edit | Edit the selected remote's name or URL. |
|
||||
| `` f `` | Fetch | Fetch updates from the remote repository. This retrieves new commits and branches without merging them into your local branches. |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Stash
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: Apply
|
||||
<kbd>g</kbd>: Pop
|
||||
<kbd>d</kbd>: Drop
|
||||
<kbd>n</kbd>: New branch
|
||||
<kbd>r</kbd>: Rename stash
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: View selected item's files
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Apply | Apply the stash entry to your working directory. |
|
||||
| `` g `` | Pop | Apply the stash entry to your working directory and remove the stash entry. |
|
||||
| `` d `` | Drop | Remove the stash entry from the stash list. |
|
||||
| `` n `` | New branch | Create a new branch from the selected stash entry. This works by git checking out the commit that the stash entry was created from, creating a new branch from that commit, then applying the stash entry to the new branch as an additional commit. |
|
||||
| `` r `` | Rename stash | |
|
||||
| `` <enter> `` | View files | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Status
|
||||
|
||||
<pre>
|
||||
<kbd>o</kbd>: Open config file
|
||||
<kbd>e</kbd>: Edit config file
|
||||
<kbd>u</kbd>: Check for update
|
||||
<kbd><enter></kbd>: Switch to a recent repo
|
||||
<kbd>a</kbd>: Show all branch logs
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` o `` | Open config file | Open file in default application. |
|
||||
| `` e `` | Edit config file | Open file in external editor. |
|
||||
| `` u `` | Check for update | |
|
||||
| `` <enter> `` | Switch to a recent repo | |
|
||||
| `` a `` | Show all branch logs | |
|
||||
|
||||
## Sub-commits
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy commit SHA to clipboard
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: Checkout commit
|
||||
<kbd>y</kbd>: Copy commit attribute
|
||||
<kbd>o</kbd>: Open commit in browser
|
||||
<kbd>n</kbd>: Create new branch off of commit
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>c</kbd>: Copy commit (cherry-pick)
|
||||
<kbd>C</kbd>: Copy commit range (cherry-pick)
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (copied) commits selection
|
||||
<kbd><enter></kbd>: View selected item's files
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy commit SHA to clipboard | |
|
||||
| `` <space> `` | Checkout | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | Open commit in browser | |
|
||||
| `` n `` | Create new branch off of commit | |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | Copy (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | Reset copied (cherry-picked) commits selection | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | View files | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Submodules
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy submodule name to clipboard
|
||||
<kbd><enter></kbd>: Enter submodule
|
||||
<kbd><space></kbd>: Enter submodule
|
||||
<kbd>d</kbd>: Remove submodule
|
||||
<kbd>u</kbd>: Update submodule
|
||||
<kbd>n</kbd>: Add new submodule
|
||||
<kbd>e</kbd>: Update submodule URL
|
||||
<kbd>i</kbd>: Initialize submodule
|
||||
<kbd>b</kbd>: View bulk submodule options
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy submodule name to clipboard | |
|
||||
| `` <enter> `` | Enter | Enter submodule. After entering the submodule, you can press `<esc>` to escape back to the parent repo. |
|
||||
| `` d `` | Remove | Remove the selected submodule and its corresponding directory. |
|
||||
| `` u `` | Update | Update selected submodule. |
|
||||
| `` n `` | New submodule | |
|
||||
| `` e `` | Update submodule URL | |
|
||||
| `` i `` | Initialize | Initialize the selected submodule to prepare for fetching. You probably want to follow this up by invoking the 'update' action to fetch the submodule. |
|
||||
| `` b `` | View bulk submodule options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Tags
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: Checkout
|
||||
<kbd>d</kbd>: Delete tag
|
||||
<kbd>P</kbd>: Push tag
|
||||
<kbd>n</kbd>: Create tag
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: View commits
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Checkout | Checkout the selected tag tag as a detached HEAD. |
|
||||
| `` n `` | New tag | Create new tag from current commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` d `` | Delete | View delete options for local/remote tag. |
|
||||
| `` P `` | Push tag | Push the selected tag to a remote. You'll be prompted to select a remote. |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | View commits | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Worktrees
|
||||
|
||||
<pre>
|
||||
<kbd>n</kbd>: Create worktree
|
||||
<kbd><space></kbd>: Switch to worktree
|
||||
<kbd><enter></kbd>: Switch to worktree
|
||||
<kbd>o</kbd>: Open in editor
|
||||
<kbd>d</kbd>: Remove worktree
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` n `` | New worktree | |
|
||||
| `` <space> `` | Switch | Switch to the selected worktree. |
|
||||
| `` o `` | Open in editor | |
|
||||
| `` d `` | Remove | Remove the selected worktree. This will both delete the worktree's directory, as well as metadata about the worktree in the .git directory. |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go run scripts/cheatsheet/main.go generate` from the project root._
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go generate ./...` from the project root._
|
||||
|
||||
# Lazygit キーバインド
|
||||
|
||||
@@ -6,348 +6,358 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|
||||
|
||||
## グローバルキーバインド
|
||||
|
||||
<pre>
|
||||
<kbd><c-r></kbd>: 最近使用したリポジトリに切り替え
|
||||
<kbd><pgup></kbd>: メインパネルを上にスクロール (fn+up/shift+k)
|
||||
<kbd><pgdown></kbd>: メインパネルを下にスクロール (fn+down/shift+j)
|
||||
<kbd>@</kbd>: コマンドログメニューを開く
|
||||
<kbd>}</kbd>: Increase the size of the context shown around changes in the diff view
|
||||
<kbd>{</kbd>: Decrease the size of the context shown around changes in the diff view
|
||||
<kbd>:</kbd>: カスタムコマンドを実行
|
||||
<kbd><c-p></kbd>: View custom patch options
|
||||
<kbd>m</kbd>: View merge/rebase options
|
||||
<kbd>R</kbd>: リフレッシュ
|
||||
<kbd>+</kbd>: 次のスクリーンモード (normal/half/fullscreen)
|
||||
<kbd>_</kbd>: 前のスクリーンモード
|
||||
<kbd>?</kbd>: メニューを開く
|
||||
<kbd><c-s></kbd>: View filter-by-path options
|
||||
<kbd>W</kbd>: 差分メニューを開く
|
||||
<kbd><c-e></kbd>: 差分メニューを開く
|
||||
<kbd><c-w></kbd>: 空白文字の差分の表示有無を切り替え
|
||||
<kbd>z</kbd>: アンドゥ (via reflog) (experimental)
|
||||
<kbd><c-z></kbd>: リドゥ (via reflog) (experimental)
|
||||
<kbd>P</kbd>: Push
|
||||
<kbd>p</kbd>: Pull
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-r> `` | 最近使用したリポジトリに切り替え | |
|
||||
| `` <pgup> (fn+up/shift+k) `` | メインパネルを上にスクロール | |
|
||||
| `` <pgdown> (fn+down/shift+j) `` | メインパネルを下にスクロール | |
|
||||
| `` @ `` | コマンドログメニューを開く | View options for the command log e.g. show/hide the command log and focus the command log. |
|
||||
| `` P `` | Push | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` p `` | Pull | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` } `` | Increase diff context size | Increase the amount of the context shown around changes in the diff view. |
|
||||
| `` { `` | Decrease diff context size | Decrease the amount of the context shown around changes in the diff view. |
|
||||
| `` : `` | カスタムコマンドを実行 | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
|
||||
| `` <c-p> `` | View custom patch options | |
|
||||
| `` m `` | View merge/rebase options | View options to abort/continue/skip the current merge/rebase. |
|
||||
| `` R `` | リフレッシュ | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. |
|
||||
| `` + `` | 次のスクリーンモード (normal/half/fullscreen) | |
|
||||
| `` _ `` | 前のスクリーンモード | |
|
||||
| `` ? `` | メニューを開く | |
|
||||
| `` <c-s> `` | View filter-by-path options | View options for filtering the commit log by a file path, so that only commits relating to that path are shown. |
|
||||
| `` W `` | 差分メニューを開く | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` <c-e> `` | 差分メニューを開く | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` q `` | 終了 | |
|
||||
| `` <esc> `` | キャンセル | |
|
||||
| `` <c-w> `` | 空白文字の差分の表示有無を切り替え | Toggle whether or not whitespace changes are shown in the diff view. |
|
||||
| `` z `` | アンドゥ (via reflog) (experimental) | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
|
||||
| `` <c-z> `` | リドゥ (via reflog) (experimental) | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
|
||||
|
||||
## 一覧パネルの操作
|
||||
|
||||
<pre>
|
||||
<kbd>,</kbd>: 前のページ
|
||||
<kbd>.</kbd>: 次のページ
|
||||
<kbd><</kbd>: 最上部までスクロール
|
||||
<kbd>></kbd>: 最下部までスクロール
|
||||
<kbd>/</kbd>: 検索を開始
|
||||
<kbd>H</kbd>: 左スクロール
|
||||
<kbd>L</kbd>: 右スクロール
|
||||
<kbd>]</kbd>: 次のタブ
|
||||
<kbd>[</kbd>: 前のタブ
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` , `` | 前のページ | |
|
||||
| `` . `` | 次のページ | |
|
||||
| `` < `` | 最上部までスクロール | |
|
||||
| `` > `` | 最下部までスクロール | |
|
||||
| `` v `` | 範囲選択を切り替え | |
|
||||
| `` <s-down> `` | Range select down | |
|
||||
| `` <s-up> `` | Range select up | |
|
||||
| `` / `` | 検索を開始 | |
|
||||
| `` H `` | 左スクロール | |
|
||||
| `` L `` | 右スクロール | |
|
||||
| `` ] `` | 次のタブ | |
|
||||
| `` [ `` | 前のタブ | |
|
||||
|
||||
## Stash
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: 適用
|
||||
<kbd>g</kbd>: Pop
|
||||
<kbd>d</kbd>: Drop
|
||||
<kbd>n</kbd>: 新しいブランチを作成
|
||||
<kbd>r</kbd>: Stashを変更
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: View selected item's files
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | 適用 | Apply the stash entry to your working directory. |
|
||||
| `` g `` | Pop | Apply the stash entry to your working directory and remove the stash entry. |
|
||||
| `` d `` | Drop | Remove the stash entry from the stash list. |
|
||||
| `` n `` | 新しいブランチを作成 | Create a new branch from the selected stash entry. This works by git checking out the commit that the stash entry was created from, creating a new branch from that commit, then applying the stash entry to the new branch as an additional commit. |
|
||||
| `` r `` | Stashを変更 | |
|
||||
| `` <enter> `` | View files | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Sub-commits
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: コミットのSHAをクリップボードにコピー
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: コミットをチェックアウト
|
||||
<kbd>y</kbd>: コミットの情報をコピー
|
||||
<kbd>o</kbd>: ブラウザでコミットを開く
|
||||
<kbd>n</kbd>: コミットにブランチを作成
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>c</kbd>: コミットをコピー (cherry-pick)
|
||||
<kbd>C</kbd>: コミットを範囲コピー (cherry-pick)
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (copied) commits selection
|
||||
<kbd><enter></kbd>: View selected item's files
|
||||
<kbd>/</kbd>: 検索を開始
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | コミットのSHAをクリップボードにコピー | |
|
||||
| `` <space> `` | チェックアウト | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | コミットの情報をコピー | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | ブラウザでコミットを開く | |
|
||||
| `` n `` | コミットにブランチを作成 | |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | コミットをコピー (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | Reset copied (cherry-picked) commits selection | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | View files | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | 検索を開始 | |
|
||||
|
||||
## Worktrees
|
||||
|
||||
<pre>
|
||||
<kbd>n</kbd>: Create worktree
|
||||
<kbd><space></kbd>: Switch to worktree
|
||||
<kbd><enter></kbd>: Switch to worktree
|
||||
<kbd>o</kbd>: Open in editor
|
||||
<kbd>d</kbd>: Remove worktree
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` n `` | New worktree | |
|
||||
| `` <space> `` | Switch | Switch to the selected worktree. |
|
||||
| `` o `` | Open in editor | |
|
||||
| `` d `` | Remove | Remove the selected worktree. This will both delete the worktree's directory, as well as metadata about the worktree in the .git directory. |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## コミット
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: コミットのSHAをクリップボードにコピー
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (copied) commits selection
|
||||
<kbd>b</kbd>: View bisect options
|
||||
<kbd>s</kbd>: Squash down
|
||||
<kbd>f</kbd>: Fixup commit
|
||||
<kbd>r</kbd>: コミットメッセージを変更
|
||||
<kbd>R</kbd>: エディタでコミットメッセージを編集
|
||||
<kbd>d</kbd>: コミットを削除
|
||||
<kbd>e</kbd>: コミットを編集
|
||||
<kbd>p</kbd>: Pick commit (when mid-rebase)
|
||||
<kbd>F</kbd>: このコミットに対するfixupコミットを作成
|
||||
<kbd>S</kbd>: Squash all 'fixup!' commits above selected commit (autosquash)
|
||||
<kbd><c-j></kbd>: コミットを1つ下に移動
|
||||
<kbd><c-k></kbd>: コミットを1つ上に移動
|
||||
<kbd>v</kbd>: コミットを貼り付け (cherry-pick)
|
||||
<kbd>B</kbd>: Mark commit as base commit for rebase
|
||||
<kbd>A</kbd>: ステージされた変更でamendコミット
|
||||
<kbd>a</kbd>: Set/Reset commit author
|
||||
<kbd>t</kbd>: コミットをrevert
|
||||
<kbd>T</kbd>: タグを作成
|
||||
<kbd><c-l></kbd>: ログメニューを開く
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: コミットをチェックアウト
|
||||
<kbd>y</kbd>: コミットの情報をコピー
|
||||
<kbd>o</kbd>: ブラウザでコミットを開く
|
||||
<kbd>n</kbd>: コミットにブランチを作成
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>c</kbd>: コミットをコピー (cherry-pick)
|
||||
<kbd>C</kbd>: コミットを範囲コピー (cherry-pick)
|
||||
<kbd><enter></kbd>: View selected item's files
|
||||
<kbd>/</kbd>: 検索を開始
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | コミットのSHAをクリップボードにコピー | |
|
||||
| `` <c-r> `` | Reset copied (cherry-picked) commits selection | |
|
||||
| `` b `` | View bisect options | |
|
||||
| `` s `` | Squash | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. |
|
||||
| `` f `` | Fixup | Meld the selected commit into the commit below it. Similar to fixup, but the selected commit's message will be discarded. |
|
||||
| `` r `` | コミットメッセージを変更 | Reword the selected commit's message. |
|
||||
| `` R `` | エディタでコミットメッセージを編集 | |
|
||||
| `` d `` | コミットを削除 | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. |
|
||||
| `` e `` | Edit (start interactive rebase) | コミットを編集 |
|
||||
| `` i `` | Start interactive rebase | Start an interactive rebase for the commits on your branch. This will include all commits from the HEAD commit down to the first merge commit or main branch commit.
|
||||
If you would instead like to start an interactive rebase from the selected commit, press `e`. |
|
||||
| `` p `` | Pick | Mark the selected commit to be picked (when mid-rebase). This means that the commit will be retained upon continuing the rebase. |
|
||||
| `` F `` | Create fixup commit | このコミットに対するfixupコミットを作成 |
|
||||
| `` S `` | Apply fixup commits | Squash all 'fixup!' commits, either above the selected commit, or all in current branch (autosquash). |
|
||||
| `` <c-j> `` | コミットを1つ下に移動 | |
|
||||
| `` <c-k> `` | コミットを1つ上に移動 | |
|
||||
| `` V `` | コミットを貼り付け (cherry-pick) | |
|
||||
| `` B `` | Mark as base commit for rebase | Select a base commit for the next rebase. When you rebase onto a branch, only commits above the base commit will be brought across. This uses the `git rebase --onto` command. |
|
||||
| `` A `` | Amend | ステージされた変更でamendコミット |
|
||||
| `` a `` | Amend commit attribute | Set/Reset commit author or set co-author. |
|
||||
| `` t `` | Revert | Create a revert commit for the selected commit, which applies the selected commit's changes in reverse. |
|
||||
| `` T `` | タグを作成 | Create a new tag pointing at the selected commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` <c-l> `` | ログメニューを開く | View options for commit log e.g. changing sort order, hiding the git graph, showing the whole git graph. |
|
||||
| `` <space> `` | チェックアウト | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | コミットの情報をコピー | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | ブラウザでコミットを開く | |
|
||||
| `` n `` | コミットにブランチを作成 | |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | コミットをコピー (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | View files | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | 検索を開始 | |
|
||||
|
||||
## コミットファイル
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: コミットされたファイル名をクリップボードにコピー
|
||||
<kbd>c</kbd>: Checkout file
|
||||
<kbd>d</kbd>: Discard this commit's changes to this file
|
||||
<kbd>o</kbd>: ファイルを開く
|
||||
<kbd>e</kbd>: ファイルを編集
|
||||
<kbd><space></kbd>: Toggle file included in patch
|
||||
<kbd>a</kbd>: Toggle all files included in patch
|
||||
<kbd><enter></kbd>: Enter file to add selected lines to the patch (or toggle directory collapsed)
|
||||
<kbd>`</kbd>: ファイルツリーの表示を切り替え
|
||||
<kbd>/</kbd>: 検索を開始
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | ファイル名をクリップボードにコピー | |
|
||||
| `` c `` | チェックアウト | Checkout file. This replaces the file in your working tree with the version from the selected commit. |
|
||||
| `` d `` | Remove | Discard this commit's changes to this file. This runs an interactive rebase in the background, so you may get a merge conflict if a later commit also changes this file. |
|
||||
| `` o `` | ファイルを開く | Open file in default application. |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <space> `` | Toggle file included in patch | Toggle whether the file is included in the custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` a `` | Toggle all files | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` <enter> `` | Enter file / Toggle directory collapsed | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
|
||||
| `` ` `` | ファイルツリーの表示を切り替え | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` / `` | 検索を開始 | |
|
||||
|
||||
## コミットメッセージ
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: 確認
|
||||
<kbd><esc></kbd>: 閉じる
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | 確認 | |
|
||||
| `` <esc> `` | 閉じる | |
|
||||
|
||||
## サブモジュール
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: サブモジュール名をクリップボードにコピー
|
||||
<kbd><enter></kbd>: サブモジュールを開く
|
||||
<kbd><space></kbd>: サブモジュールを開く
|
||||
<kbd>d</kbd>: サブモジュールを削除
|
||||
<kbd>u</kbd>: サブモジュールを更新
|
||||
<kbd>n</kbd>: サブモジュールを新規追加
|
||||
<kbd>e</kbd>: サブモジュールのURLを更新
|
||||
<kbd>i</kbd>: サブモジュールを初期化
|
||||
<kbd>b</kbd>: View bulk submodule options
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | サブモジュール名をクリップボードにコピー | |
|
||||
| `` <enter> `` | Enter | サブモジュールを開く |
|
||||
| `` d `` | Remove | Remove the selected submodule and its corresponding directory. |
|
||||
| `` u `` | Update | サブモジュールを更新 |
|
||||
| `` n `` | サブモジュールを新規追加 | |
|
||||
| `` e `` | サブモジュールのURLを更新 | |
|
||||
| `` i `` | Initialize | サブモジュールを初期化 |
|
||||
| `` b `` | View bulk submodule options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## ステータス
|
||||
|
||||
<pre>
|
||||
<kbd>o</kbd>: 設定ファイルを開く
|
||||
<kbd>e</kbd>: 設定ファイルを編集
|
||||
<kbd>u</kbd>: 更新を確認
|
||||
<kbd><enter></kbd>: 最近使用したリポジトリに切り替え
|
||||
<kbd>a</kbd>: すべてのブランチログを表示
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` o `` | 設定ファイルを開く | Open file in default application. |
|
||||
| `` e `` | 設定ファイルを編集 | Open file in external editor. |
|
||||
| `` u `` | 更新を確認 | |
|
||||
| `` <enter> `` | 最近使用したリポジトリに切り替え | |
|
||||
| `` a `` | すべてのブランチログを表示 | |
|
||||
|
||||
## タグ
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: チェックアウト
|
||||
<kbd>d</kbd>: タグを削除
|
||||
<kbd>P</kbd>: タグをpush
|
||||
<kbd>n</kbd>: タグを作成
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: コミットを閲覧
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | チェックアウト | Checkout the selected tag tag as a detached HEAD. |
|
||||
| `` n `` | タグを作成 | Create new tag from current commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` d `` | Delete | View delete options for local/remote tag. |
|
||||
| `` P `` | タグをpush | Push the selected tag to a remote. You'll be prompted to select a remote. |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | コミットを閲覧 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## ファイル
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: ファイル名をクリップボードにコピー
|
||||
<kbd>d</kbd>: View 'discard changes' options
|
||||
<kbd><space></kbd>: ステージ/アンステージ
|
||||
<kbd><c-b></kbd>: ファイルをフィルタ (ステージ/アンステージ)
|
||||
<kbd>c</kbd>: 変更をコミット
|
||||
<kbd>w</kbd>: pre-commitフックを実行せずに変更をコミット
|
||||
<kbd>A</kbd>: 最新のコミットにamend
|
||||
<kbd>C</kbd>: gitエディタを使用して変更をコミット
|
||||
<kbd>e</kbd>: ファイルを編集
|
||||
<kbd>o</kbd>: ファイルを開く
|
||||
<kbd>i</kbd>: ファイルをignore
|
||||
<kbd>r</kbd>: ファイルをリフレッシュ
|
||||
<kbd>s</kbd>: 変更をstash
|
||||
<kbd>S</kbd>: View stash options
|
||||
<kbd>a</kbd>: すべての変更をステージ/アンステージ
|
||||
<kbd><enter></kbd>: Stage individual hunks/lines for file, or collapse/expand for directory
|
||||
<kbd>g</kbd>: View upstream reset options
|
||||
<kbd>D</kbd>: View reset options
|
||||
<kbd>`</kbd>: ファイルツリーの表示を切り替え
|
||||
<kbd>M</kbd>: Git mergetoolを開く
|
||||
<kbd>f</kbd>: Fetch
|
||||
<kbd>/</kbd>: 検索を開始
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | ファイル名をクリップボードにコピー | |
|
||||
| `` <space> `` | ステージ/アンステージ | Toggle staged for selected file. |
|
||||
| `` <c-b> `` | ファイルをフィルタ (ステージ/アンステージ) | |
|
||||
| `` y `` | Copy to clipboard | |
|
||||
| `` c `` | 変更をコミット | Commit staged changes. |
|
||||
| `` w `` | pre-commitフックを実行せずに変更をコミット | |
|
||||
| `` A `` | 最新のコミットにamend | |
|
||||
| `` C `` | gitエディタを使用して変更をコミット | |
|
||||
| `` <c-f> `` | Find base commit for fixup | Find the commit that your current changes are building upon, for the sake of amending/fixing up the commit. This spares you from having to look through your branch's commits one-by-one to see which commit should be amended/fixed up. See docs: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` o `` | ファイルを開く | Open file in default application. |
|
||||
| `` i `` | ファイルをignore | |
|
||||
| `` r `` | ファイルをリフレッシュ | |
|
||||
| `` s `` | Stash | Stash all changes. For other variations of stashing, use the view stash options keybinding. |
|
||||
| `` S `` | View stash options | View stash options (e.g. stash all, stash staged, stash unstaged). |
|
||||
| `` a `` | すべての変更をステージ/アンステージ | Toggle staged/unstaged for all files in working tree. |
|
||||
| `` <enter> `` | Stage lines / Collapse directory | If the selected item is a file, focus the staging view so you can stage individual hunks/lines. If the selected item is a directory, collapse/expand it. |
|
||||
| `` d `` | Discard | View options for discarding changes to the selected file. |
|
||||
| `` g `` | View upstream reset options | |
|
||||
| `` D `` | Reset | View reset options for working tree (e.g. nuking the working tree). |
|
||||
| `` ` `` | ファイルツリーの表示を切り替え | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` M `` | Git mergetoolを開く | Run `git mergetool`. |
|
||||
| `` f `` | Fetch | Fetch changes from remote. |
|
||||
| `` / `` | 検索を開始 | |
|
||||
|
||||
## ブランチ
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: ブランチ名をクリップボードにコピー
|
||||
<kbd>i</kbd>: Show git-flow options
|
||||
<kbd><space></kbd>: チェックアウト
|
||||
<kbd>n</kbd>: 新しいブランチを作成
|
||||
<kbd>o</kbd>: Pull Requestを作成
|
||||
<kbd>O</kbd>: Create pull request options
|
||||
<kbd><c-y></kbd>: Pull RequestのURLをクリップボードにコピー
|
||||
<kbd>c</kbd>: Checkout by name
|
||||
<kbd>F</kbd>: Force checkout
|
||||
<kbd>d</kbd>: ブランチを削除
|
||||
<kbd>r</kbd>: Rebase checked-out branch onto this branch
|
||||
<kbd>M</kbd>: 現在のブランチにマージ
|
||||
<kbd>f</kbd>: Fast-forward this branch from its upstream
|
||||
<kbd>T</kbd>: タグを作成
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>R</kbd>: ブランチ名を変更
|
||||
<kbd>u</kbd>: Set/Unset upstream
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: コミットを閲覧
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | ブランチ名をクリップボードにコピー | |
|
||||
| `` i `` | Show git-flow options | |
|
||||
| `` <space> `` | チェックアウト | Checkout selected item. |
|
||||
| `` n `` | 新しいブランチを作成 | |
|
||||
| `` o `` | Pull Requestを作成 | |
|
||||
| `` O `` | View create pull request options | |
|
||||
| `` <c-y> `` | Pull RequestのURLをクリップボードにコピー | |
|
||||
| `` c `` | Checkout by name | Checkout by name. In the input box you can enter '-' to switch to the last branch. |
|
||||
| `` F `` | Force checkout | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||
| `` r `` | Rebase | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` M `` | 現在のブランチにマージ | Merge selected branch into currently checked out branch. |
|
||||
| `` f `` | Fast-forward | Fast-forward selected branch from its upstream. |
|
||||
| `` T `` | タグを作成 | |
|
||||
| `` s `` | 並び替え | |
|
||||
| `` g `` | Reset | |
|
||||
| `` R `` | ブランチ名を変更 | |
|
||||
| `` u `` | View upstream options | View options relating to the branch's upstream e.g. setting/unsetting the upstream and resetting to the upstream. |
|
||||
| `` <enter> `` | コミットを閲覧 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## メインパネル (Merging)
|
||||
|
||||
<pre>
|
||||
<kbd>e</kbd>: ファイルを編集
|
||||
<kbd>o</kbd>: ファイルを開く
|
||||
<kbd><left></kbd>: 前のコンフリクトを選択
|
||||
<kbd><right></kbd>: 次のコンフリクトを選択
|
||||
<kbd><up></kbd>: 前のhunkを選択
|
||||
<kbd><down></kbd>: 次のhunkを選択
|
||||
<kbd>z</kbd>: アンドゥ
|
||||
<kbd>M</kbd>: Git mergetoolを開く
|
||||
<kbd><space></kbd>: Pick hunk
|
||||
<kbd>b</kbd>: Pick all hunks
|
||||
<kbd><esc></kbd>: ファイル一覧に戻る
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Pick hunk | |
|
||||
| `` b `` | Pick all hunks | |
|
||||
| `` <up> `` | 前のhunkを選択 | |
|
||||
| `` <down> `` | 次のhunkを選択 | |
|
||||
| `` <left> `` | 前のコンフリクトを選択 | |
|
||||
| `` <right> `` | 次のコンフリクトを選択 | |
|
||||
| `` z `` | アンドゥ | Undo last merge conflict resolution. |
|
||||
| `` e `` | ファイルを編集 | Open file in external editor. |
|
||||
| `` o `` | ファイルを開く | Open file in default application. |
|
||||
| `` M `` | Git mergetoolを開く | Run `git mergetool`. |
|
||||
| `` <esc> `` | ファイル一覧に戻る | |
|
||||
|
||||
## メインパネル (Normal)
|
||||
|
||||
<pre>
|
||||
<kbd>mouse wheel down</kbd>: 下にスクロール (fn+up)
|
||||
<kbd>mouse wheel up</kbd>: 上にスクロール (fn+down)
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` mouse wheel down (fn+up) `` | 下にスクロール | |
|
||||
| `` mouse wheel up (fn+down) `` | 上にスクロール | |
|
||||
|
||||
## メインパネル (Patch Building)
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: 前のhunkを選択
|
||||
<kbd><right></kbd>: 次のhunkを選択
|
||||
<kbd>v</kbd>: 範囲選択を切り替え
|
||||
<kbd>V</kbd>: 範囲選択を切り替え
|
||||
<kbd>a</kbd>: Hunk選択を切り替え
|
||||
<kbd><c-o></kbd>: 選択されたテキストをクリップボードにコピー
|
||||
<kbd>o</kbd>: ファイルを開く
|
||||
<kbd>e</kbd>: ファイルを編集
|
||||
<kbd><space></kbd>: 行をパッチに追加/削除
|
||||
<kbd><esc></kbd>: Exit custom patch builder
|
||||
<kbd>/</kbd>: 検索を開始
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | 前のhunkを選択 | |
|
||||
| `` <right> `` | 次のhunkを選択 | |
|
||||
| `` v `` | 範囲選択を切り替え | |
|
||||
| `` a `` | Hunk選択を切り替え | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | 選択されたテキストをクリップボードにコピー | |
|
||||
| `` o `` | ファイルを開く | Open file in default application. |
|
||||
| `` e `` | ファイルを編集 | Open file in external editor. |
|
||||
| `` <space> `` | 行をパッチに追加/削除 | |
|
||||
| `` <esc> `` | Exit custom patch builder | |
|
||||
| `` / `` | 検索を開始 | |
|
||||
|
||||
## メインパネル (Staging)
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: 前のhunkを選択
|
||||
<kbd><right></kbd>: 次のhunkを選択
|
||||
<kbd>v</kbd>: 範囲選択を切り替え
|
||||
<kbd>V</kbd>: 範囲選択を切り替え
|
||||
<kbd>a</kbd>: Hunk選択を切り替え
|
||||
<kbd><c-o></kbd>: 選択されたテキストをクリップボードにコピー
|
||||
<kbd>o</kbd>: ファイルを開く
|
||||
<kbd>e</kbd>: ファイルを編集
|
||||
<kbd><esc></kbd>: ファイル一覧に戻る
|
||||
<kbd><tab></kbd>: パネルを切り替え
|
||||
<kbd><space></kbd>: 選択行をステージ/アンステージ
|
||||
<kbd>d</kbd>: 変更を削除 (git reset)
|
||||
<kbd>E</kbd>: Edit hunk
|
||||
<kbd>c</kbd>: 変更をコミット
|
||||
<kbd>w</kbd>: pre-commitフックを実行せずに変更をコミット
|
||||
<kbd>C</kbd>: gitエディタを使用して変更をコミット
|
||||
<kbd>/</kbd>: 検索を開始
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | 前のhunkを選択 | |
|
||||
| `` <right> `` | 次のhunkを選択 | |
|
||||
| `` v `` | 範囲選択を切り替え | |
|
||||
| `` a `` | Hunk選択を切り替え | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | 選択されたテキストをクリップボードにコピー | |
|
||||
| `` <space> `` | ステージ/アンステージ | 選択行をステージ/アンステージ |
|
||||
| `` d `` | 変更を削除 (git reset) | When unstaged change is selected, discard the change using `git reset`. When staged change is selected, unstage the change. |
|
||||
| `` o `` | ファイルを開く | Open file in default application. |
|
||||
| `` e `` | ファイルを編集 | Open file in external editor. |
|
||||
| `` <esc> `` | ファイル一覧に戻る | |
|
||||
| `` <tab> `` | パネルを切り替え | Switch to other view (staged/unstaged changes). |
|
||||
| `` E `` | Edit hunk | Edit selected hunk in external editor. |
|
||||
| `` c `` | 変更をコミット | Commit staged changes. |
|
||||
| `` w `` | pre-commitフックを実行せずに変更をコミット | |
|
||||
| `` C `` | gitエディタを使用して変更をコミット | |
|
||||
| `` / `` | 検索を開始 | |
|
||||
|
||||
## メニュー
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: 実行
|
||||
<kbd><esc></kbd>: 閉じる
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | 実行 | |
|
||||
| `` <esc> `` | 閉じる | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## リモート
|
||||
|
||||
<pre>
|
||||
<kbd>f</kbd>: リモートをfetch
|
||||
<kbd>n</kbd>: リモートを新規追加
|
||||
<kbd>d</kbd>: リモートを削除
|
||||
<kbd>e</kbd>: リモートを編集
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | View branches | |
|
||||
| `` n `` | リモートを新規追加 | |
|
||||
| `` d `` | Remove | Remove the selected remote. Any local branches tracking a remote branch from the remote will be unaffected. |
|
||||
| `` e `` | Edit | リモートを編集 |
|
||||
| `` f `` | Fetch | リモートをfetch |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## リモートブランチ
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: ブランチ名をクリップボードにコピー
|
||||
<kbd><space></kbd>: チェックアウト
|
||||
<kbd>n</kbd>: 新しいブランチを作成
|
||||
<kbd>M</kbd>: 現在のブランチにマージ
|
||||
<kbd>r</kbd>: Rebase checked-out branch onto this branch
|
||||
<kbd>d</kbd>: ブランチを削除
|
||||
<kbd>u</kbd>: Set as upstream of checked-out branch
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: コミットを閲覧
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | ブランチ名をクリップボードにコピー | |
|
||||
| `` <space> `` | チェックアウト | Checkout a new local branch based on the selected remote branch. The new branch will track the remote branch. |
|
||||
| `` n `` | 新しいブランチを作成 | |
|
||||
| `` M `` | 現在のブランチにマージ | Merge selected branch into currently checked out branch. |
|
||||
| `` r `` | Rebase | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||
| `` u `` | Set as upstream | Set the selected remote branch as the upstream of the checked-out branch. |
|
||||
| `` s `` | 並び替え | |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | コミットを閲覧 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 参照ログ
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: コミットのSHAをクリップボードにコピー
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: コミットをチェックアウト
|
||||
<kbd>y</kbd>: コミットの情報をコピー
|
||||
<kbd>o</kbd>: ブラウザでコミットを開く
|
||||
<kbd>n</kbd>: コミットにブランチを作成
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>c</kbd>: コミットをコピー (cherry-pick)
|
||||
<kbd>C</kbd>: コミットを範囲コピー (cherry-pick)
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (copied) commits selection
|
||||
<kbd><enter></kbd>: コミットを閲覧
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | コミットのSHAをクリップボードにコピー | |
|
||||
| `` <space> `` | チェックアウト | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | コミットの情報をコピー | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | ブラウザでコミットを開く | |
|
||||
| `` n `` | コミットにブランチを作成 | |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | コミットをコピー (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | Reset copied (cherry-picked) commits selection | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | コミットを閲覧 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 確認パネル
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: 確認
|
||||
<kbd><esc></kbd>: 閉じる/キャンセル
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | 確認 | |
|
||||
| `` <esc> `` | 閉じる/キャンセル | |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go run scripts/cheatsheet/main.go generate` from the project root._
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go generate ./...` from the project root._
|
||||
|
||||
# Lazygit 키 바인딩
|
||||
|
||||
@@ -6,348 +6,358 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|
||||
|
||||
## 글로벌 키 바인딩
|
||||
|
||||
<pre>
|
||||
<kbd><c-r></kbd>: 최근에 사용한 저장소로 전환
|
||||
<kbd><pgup></kbd>: 메인 패널을 위로 스크롤 (fn+up/shift+k)
|
||||
<kbd><pgdown></kbd>: 메인 패널을 아래로로 스크롤 (fn+down/shift+j)
|
||||
<kbd>@</kbd>: 명령어 로그 메뉴 열기
|
||||
<kbd>}</kbd>: Diff 보기의 변경 사항 주위에 표시되는 컨텍스트의 크기를 늘리기
|
||||
<kbd>{</kbd>: Diff 보기의 변경 사항 주위에 표시되는 컨텍스트 크기 줄이기
|
||||
<kbd>:</kbd>: Execute custom command
|
||||
<kbd><c-p></kbd>: 커스텀 Patch 옵션 보기
|
||||
<kbd>m</kbd>: View merge/rebase options
|
||||
<kbd>R</kbd>: 새로고침
|
||||
<kbd>+</kbd>: 다음 스크린 모드 (normal/half/fullscreen)
|
||||
<kbd>_</kbd>: 이전 스크린 모드
|
||||
<kbd>?</kbd>: 매뉴 열기
|
||||
<kbd><c-s></kbd>: View filter-by-path options
|
||||
<kbd>W</kbd>: Diff 메뉴 열기
|
||||
<kbd><c-e></kbd>: Diff 메뉴 열기
|
||||
<kbd><c-w></kbd>: 공백문자를 Diff 뷰에서 표시 여부 전환
|
||||
<kbd>z</kbd>: 되돌리기 (reflog) (실험적)
|
||||
<kbd><c-z></kbd>: 다시 실행 (reflog) (실험적)
|
||||
<kbd>P</kbd>: 푸시
|
||||
<kbd>p</kbd>: 업데이트
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-r> `` | 최근에 사용한 저장소로 전환 | |
|
||||
| `` <pgup> (fn+up/shift+k) `` | 메인 패널을 위로 스크롤 | |
|
||||
| `` <pgdown> (fn+down/shift+j) `` | 메인 패널을 아래로로 스크롤 | |
|
||||
| `` @ `` | 명령어 로그 메뉴 열기 | View options for the command log e.g. show/hide the command log and focus the command log. |
|
||||
| `` P `` | 푸시 | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` p `` | 업데이트 | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` } `` | Diff 보기의 변경 사항 주위에 표시되는 컨텍스트의 크기를 늘리기 | Increase the amount of the context shown around changes in the diff view. |
|
||||
| `` { `` | Diff 보기의 변경 사항 주위에 표시되는 컨텍스트 크기 줄이기 | Decrease the amount of the context shown around changes in the diff view. |
|
||||
| `` : `` | Execute custom command | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
|
||||
| `` <c-p> `` | 커스텀 Patch 옵션 보기 | |
|
||||
| `` m `` | View merge/rebase options | View options to abort/continue/skip the current merge/rebase. |
|
||||
| `` R `` | 새로고침 | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. |
|
||||
| `` + `` | 다음 스크린 모드 (normal/half/fullscreen) | |
|
||||
| `` _ `` | 이전 스크린 모드 | |
|
||||
| `` ? `` | 매뉴 열기 | |
|
||||
| `` <c-s> `` | View filter-by-path options | View options for filtering the commit log by a file path, so that only commits relating to that path are shown. |
|
||||
| `` W `` | Diff 메뉴 열기 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` <c-e> `` | Diff 메뉴 열기 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` q `` | 종료 | |
|
||||
| `` <esc> `` | 취소 | |
|
||||
| `` <c-w> `` | 공백문자를 Diff 뷰에서 표시 여부 전환 | Toggle whether or not whitespace changes are shown in the diff view. |
|
||||
| `` z `` | 되돌리기 (reflog) (실험적) | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
|
||||
| `` <c-z> `` | 다시 실행 (reflog) (실험적) | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
|
||||
|
||||
## List panel navigation
|
||||
|
||||
<pre>
|
||||
<kbd>,</kbd>: 이전 페이지
|
||||
<kbd>.</kbd>: 다음 페이지
|
||||
<kbd><</kbd>: 맨 위로 스크롤
|
||||
<kbd>></kbd>: 맨 아래로 스크롤
|
||||
<kbd>/</kbd>: 검색 시작
|
||||
<kbd>H</kbd>: 우 스크롤
|
||||
<kbd>L</kbd>: 좌 스크롤
|
||||
<kbd>]</kbd>: 이전 탭
|
||||
<kbd>[</kbd>: 다음 탭
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` , `` | 이전 페이지 | |
|
||||
| `` . `` | 다음 페이지 | |
|
||||
| `` < `` | 맨 위로 스크롤 | |
|
||||
| `` > `` | 맨 아래로 스크롤 | |
|
||||
| `` v `` | 드래그 선택 전환 | |
|
||||
| `` <s-down> `` | Range select down | |
|
||||
| `` <s-up> `` | Range select up | |
|
||||
| `` / `` | 검색 시작 | |
|
||||
| `` H `` | 우 스크롤 | |
|
||||
| `` L `` | 좌 스크롤 | |
|
||||
| `` ] `` | 이전 탭 | |
|
||||
| `` [ `` | 다음 탭 | |
|
||||
|
||||
## Reflog
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 커밋 SHA를 클립보드에 복사
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: 커밋을 체크아웃
|
||||
<kbd>y</kbd>: 커밋 attribute 복사
|
||||
<kbd>o</kbd>: 브라우저에서 커밋 열기
|
||||
<kbd>n</kbd>: 커밋에서 새 브랜치를 만듭니다.
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>c</kbd>: 커밋을 복사 (cherry-pick)
|
||||
<kbd>C</kbd>: 커밋을 범위로 복사 (cherry-pick)
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (copied) commits selection
|
||||
<kbd><enter></kbd>: 커밋 보기
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 커밋 SHA를 클립보드에 복사 | |
|
||||
| `` <space> `` | 체크아웃 | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | 커밋 attribute 복사 | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | 브라우저에서 커밋 열기 | |
|
||||
| `` n `` | 커밋에서 새 브랜치를 만듭니다. | |
|
||||
| `` g `` | View reset options | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | 커밋을 복사 (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | Reset cherry-picked (copied) commits selection | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | 커밋 보기 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Stash
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: 적용
|
||||
<kbd>g</kbd>: Pop
|
||||
<kbd>d</kbd>: Drop
|
||||
<kbd>n</kbd>: 새 브랜치 생성
|
||||
<kbd>r</kbd>: Rename stash
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: View selected item's files
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | 적용 | Apply the stash entry to your working directory. |
|
||||
| `` g `` | Pop | Apply the stash entry to your working directory and remove the stash entry. |
|
||||
| `` d `` | Drop | Remove the stash entry from the stash list. |
|
||||
| `` n `` | 새 브랜치 생성 | Create a new branch from the selected stash entry. This works by git checking out the commit that the stash entry was created from, creating a new branch from that commit, then applying the stash entry to the new branch as an additional commit. |
|
||||
| `` r `` | Rename stash | |
|
||||
| `` <enter> `` | View selected item's files | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Sub-commits
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 커밋 SHA를 클립보드에 복사
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: 커밋을 체크아웃
|
||||
<kbd>y</kbd>: 커밋 attribute 복사
|
||||
<kbd>o</kbd>: 브라우저에서 커밋 열기
|
||||
<kbd>n</kbd>: 커밋에서 새 브랜치를 만듭니다.
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>c</kbd>: 커밋을 복사 (cherry-pick)
|
||||
<kbd>C</kbd>: 커밋을 범위로 복사 (cherry-pick)
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (copied) commits selection
|
||||
<kbd><enter></kbd>: View selected item's files
|
||||
<kbd>/</kbd>: 검색 시작
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 커밋 SHA를 클립보드에 복사 | |
|
||||
| `` <space> `` | 체크아웃 | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | 커밋 attribute 복사 | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | 브라우저에서 커밋 열기 | |
|
||||
| `` n `` | 커밋에서 새 브랜치를 만듭니다. | |
|
||||
| `` g `` | View reset options | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | 커밋을 복사 (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | Reset cherry-picked (copied) commits selection | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | View selected item's files | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | 검색 시작 | |
|
||||
|
||||
## Worktrees
|
||||
|
||||
<pre>
|
||||
<kbd>n</kbd>: Create worktree
|
||||
<kbd><space></kbd>: Switch to worktree
|
||||
<kbd><enter></kbd>: Switch to worktree
|
||||
<kbd>o</kbd>: Open in editor
|
||||
<kbd>d</kbd>: Remove worktree
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` n `` | New worktree | |
|
||||
| `` <space> `` | Switch | Switch to the selected worktree. |
|
||||
| `` o `` | Open in editor | |
|
||||
| `` d `` | Remove | Remove the selected worktree. This will both delete the worktree's directory, as well as metadata about the worktree in the .git directory. |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 메뉴
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: 실행
|
||||
<kbd><esc></kbd>: 닫기
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | 실행 | |
|
||||
| `` <esc> `` | 닫기 | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 메인 패널 (Merging)
|
||||
|
||||
<pre>
|
||||
<kbd>e</kbd>: 파일 편집
|
||||
<kbd>o</kbd>: 파일 닫기
|
||||
<kbd><left></kbd>: 이전 충돌을 선택
|
||||
<kbd><right></kbd>: 다음 충돌을 선택
|
||||
<kbd><up></kbd>: 이전 hunk를 선택
|
||||
<kbd><down></kbd>: 다음 hunk를 선택
|
||||
<kbd>z</kbd>: 되돌리기
|
||||
<kbd>M</kbd>: Git mergetool를 열기
|
||||
<kbd><space></kbd>: Pick hunk
|
||||
<kbd>b</kbd>: Pick all hunks
|
||||
<kbd><esc></kbd>: 파일 목록으로 돌아가기
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Pick hunk | |
|
||||
| `` b `` | Pick all hunks | |
|
||||
| `` <up> `` | 이전 hunk를 선택 | |
|
||||
| `` <down> `` | 다음 hunk를 선택 | |
|
||||
| `` <left> `` | 이전 충돌을 선택 | |
|
||||
| `` <right> `` | 다음 충돌을 선택 | |
|
||||
| `` z `` | 되돌리기 | Undo last merge conflict resolution. |
|
||||
| `` e `` | 파일 편집 | Open file in external editor. |
|
||||
| `` o `` | 파일 닫기 | Open file in default application. |
|
||||
| `` M `` | Git mergetool를 열기 | Run `git mergetool`. |
|
||||
| `` <esc> `` | 파일 목록으로 돌아가기 | |
|
||||
|
||||
## 메인 패널 (Normal)
|
||||
|
||||
<pre>
|
||||
<kbd>mouse wheel down</kbd>: 아래로 스크롤 (fn+up)
|
||||
<kbd>mouse wheel up</kbd>: 위로 스크롤 (fn+down)
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` mouse wheel down (fn+up) `` | 아래로 스크롤 | |
|
||||
| `` mouse wheel up (fn+down) `` | 위로 스크롤 | |
|
||||
|
||||
## 메인 패널 (Patch Building)
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: 이전 hunk를 선택
|
||||
<kbd><right></kbd>: 다음 hunk를 선택
|
||||
<kbd>v</kbd>: 드래그 선택 전환
|
||||
<kbd>V</kbd>: 드래그 선택 전환
|
||||
<kbd>a</kbd>: Toggle select hunk
|
||||
<kbd><c-o></kbd>: 선택한 텍스트를 클립보드에 복사
|
||||
<kbd>o</kbd>: 파일 닫기
|
||||
<kbd>e</kbd>: 파일 편집
|
||||
<kbd><space></kbd>: Line(s)을 패치에 추가/삭제
|
||||
<kbd><esc></kbd>: Exit custom patch builder
|
||||
<kbd>/</kbd>: 검색 시작
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | 이전 hunk를 선택 | |
|
||||
| `` <right> `` | 다음 hunk를 선택 | |
|
||||
| `` v `` | 드래그 선택 전환 | |
|
||||
| `` a `` | Toggle select hunk | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | 선택한 텍스트를 클립보드에 복사 | |
|
||||
| `` o `` | 파일 닫기 | Open file in default application. |
|
||||
| `` e `` | 파일 편집 | Open file in external editor. |
|
||||
| `` <space> `` | Line(s)을 패치에 추가/삭제 | |
|
||||
| `` <esc> `` | Exit custom patch builder | |
|
||||
| `` / `` | 검색 시작 | |
|
||||
|
||||
## 메인 패널 (Staging)
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: 이전 hunk를 선택
|
||||
<kbd><right></kbd>: 다음 hunk를 선택
|
||||
<kbd>v</kbd>: 드래그 선택 전환
|
||||
<kbd>V</kbd>: 드래그 선택 전환
|
||||
<kbd>a</kbd>: Toggle select hunk
|
||||
<kbd><c-o></kbd>: 선택한 텍스트를 클립보드에 복사
|
||||
<kbd>o</kbd>: 파일 닫기
|
||||
<kbd>e</kbd>: 파일 편집
|
||||
<kbd><esc></kbd>: 파일 목록으로 돌아가기
|
||||
<kbd><tab></kbd>: 패널 전환
|
||||
<kbd><space></kbd>: 선택한 행을 staged / unstaged
|
||||
<kbd>d</kbd>: 변경을 삭제 (git reset)
|
||||
<kbd>E</kbd>: Edit hunk
|
||||
<kbd>c</kbd>: 커밋 변경내용
|
||||
<kbd>w</kbd>: Commit changes without pre-commit hook
|
||||
<kbd>C</kbd>: Git 편집기를 사용하여 변경 내용을 커밋합니다.
|
||||
<kbd>/</kbd>: 검색 시작
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | 이전 hunk를 선택 | |
|
||||
| `` <right> `` | 다음 hunk를 선택 | |
|
||||
| `` v `` | 드래그 선택 전환 | |
|
||||
| `` a `` | Toggle select hunk | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | 선택한 텍스트를 클립보드에 복사 | |
|
||||
| `` <space> `` | Staged 전환 | 선택한 행을 staged / unstaged |
|
||||
| `` d `` | 변경을 삭제 (git reset) | When unstaged change is selected, discard the change using `git reset`. When staged change is selected, unstage the change. |
|
||||
| `` o `` | 파일 닫기 | Open file in default application. |
|
||||
| `` e `` | 파일 편집 | Open file in external editor. |
|
||||
| `` <esc> `` | 파일 목록으로 돌아가기 | |
|
||||
| `` <tab> `` | 패널 전환 | Switch to other view (staged/unstaged changes). |
|
||||
| `` E `` | Edit hunk | Edit selected hunk in external editor. |
|
||||
| `` c `` | 커밋 변경내용 | Commit staged changes. |
|
||||
| `` w `` | Commit changes without pre-commit hook | |
|
||||
| `` C `` | Git 편집기를 사용하여 변경 내용을 커밋합니다. | |
|
||||
| `` / `` | 검색 시작 | |
|
||||
|
||||
## 브랜치
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 브랜치명을 클립보드에 복사
|
||||
<kbd>i</kbd>: Git-flow 옵션 보기
|
||||
<kbd><space></kbd>: 체크아웃
|
||||
<kbd>n</kbd>: 새 브랜치 생성
|
||||
<kbd>o</kbd>: 풀 리퀘스트 생성
|
||||
<kbd>O</kbd>: 풀 리퀘스트 생성 옵션
|
||||
<kbd><c-y></kbd>: 풀 리퀘스트 URL을 클립보드에 복사
|
||||
<kbd>c</kbd>: 이름으로 체크아웃
|
||||
<kbd>F</kbd>: 강제 체크아웃
|
||||
<kbd>d</kbd>: 브랜치 삭제
|
||||
<kbd>r</kbd>: 체크아웃된 브랜치를 이 브랜치에 리베이스
|
||||
<kbd>M</kbd>: 현재 브랜치에 병합
|
||||
<kbd>f</kbd>: Fast-forward this branch from its upstream
|
||||
<kbd>T</kbd>: 태그를 생성
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>R</kbd>: 브랜치 이름 변경
|
||||
<kbd>u</kbd>: Set/Unset upstream
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: 커밋 보기
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 브랜치명을 클립보드에 복사 | |
|
||||
| `` i `` | Git-flow 옵션 보기 | |
|
||||
| `` <space> `` | 체크아웃 | Checkout selected item. |
|
||||
| `` n `` | 새 브랜치 생성 | |
|
||||
| `` o `` | 풀 리퀘스트 생성 | |
|
||||
| `` O `` | 풀 리퀘스트 생성 옵션 | |
|
||||
| `` <c-y> `` | 풀 리퀘스트 URL을 클립보드에 복사 | |
|
||||
| `` c `` | 이름으로 체크아웃 | Checkout by name. In the input box you can enter '-' to switch to the last branch. |
|
||||
| `` F `` | 강제 체크아웃 | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||
| `` r `` | 체크아웃된 브랜치를 이 브랜치에 리베이스 | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` M `` | 현재 브랜치에 병합 | Merge selected branch into currently checked out branch. |
|
||||
| `` f `` | Fast-forward this branch from its upstream | Fast-forward selected branch from its upstream. |
|
||||
| `` T `` | 태그를 생성 | |
|
||||
| `` s `` | Sort order | |
|
||||
| `` g `` | View reset options | |
|
||||
| `` R `` | 브랜치 이름 변경 | |
|
||||
| `` u `` | View upstream options | View options relating to the branch's upstream e.g. setting/unsetting the upstream and resetting to the upstream. |
|
||||
| `` <enter> `` | 커밋 보기 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 상태
|
||||
|
||||
<pre>
|
||||
<kbd>o</kbd>: 설정 파일 열기
|
||||
<kbd>e</kbd>: 설정 파일 수정
|
||||
<kbd>u</kbd>: 업데이트 확인
|
||||
<kbd><enter></kbd>: 최근에 사용한 저장소로 전환
|
||||
<kbd>a</kbd>: 모든 브랜치 로그 표시
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` o `` | 설정 파일 열기 | Open file in default application. |
|
||||
| `` e `` | 설정 파일 수정 | Open file in external editor. |
|
||||
| `` u `` | 업데이트 확인 | |
|
||||
| `` <enter> `` | 최근에 사용한 저장소로 전환 | |
|
||||
| `` a `` | 모든 브랜치 로그 표시 | |
|
||||
|
||||
## 서브모듈
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 서브모듈 이름을 클립보드에 복사
|
||||
<kbd><enter></kbd>: 서브모듈 열기
|
||||
<kbd><space></kbd>: 서브모듈 열기
|
||||
<kbd>d</kbd>: 서브모듈 삭제
|
||||
<kbd>u</kbd>: 서브모듈 업데이트
|
||||
<kbd>n</kbd>: 새로운 서브모듈 추가
|
||||
<kbd>e</kbd>: 서브모듈의 URL을 수정
|
||||
<kbd>i</kbd>: 서브모듈 초기화
|
||||
<kbd>b</kbd>: View bulk submodule options
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 서브모듈 이름을 클립보드에 복사 | |
|
||||
| `` <enter> `` | Enter | 서브모듈 열기 |
|
||||
| `` d `` | Remove | Remove the selected submodule and its corresponding directory. |
|
||||
| `` u `` | Update | 서브모듈 업데이트 |
|
||||
| `` n `` | 새로운 서브모듈 추가 | |
|
||||
| `` e `` | 서브모듈의 URL을 수정 | |
|
||||
| `` i `` | Initialize | 서브모듈 초기화 |
|
||||
| `` b `` | View bulk submodule options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 원격
|
||||
|
||||
<pre>
|
||||
<kbd>f</kbd>: 원격을 업데이트
|
||||
<kbd>n</kbd>: 새로운 Remote 추가
|
||||
<kbd>d</kbd>: Remote를 삭제
|
||||
<kbd>e</kbd>: Remote를 수정
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | View branches | |
|
||||
| `` n `` | 새로운 Remote 추가 | |
|
||||
| `` d `` | Remove | Remove the selected remote. Any local branches tracking a remote branch from the remote will be unaffected. |
|
||||
| `` e `` | Edit | Remote를 수정 |
|
||||
| `` f `` | Fetch | 원격을 업데이트 |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 원격 브랜치
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 브랜치명을 클립보드에 복사
|
||||
<kbd><space></kbd>: 체크아웃
|
||||
<kbd>n</kbd>: 새 브랜치 생성
|
||||
<kbd>M</kbd>: 현재 브랜치에 병합
|
||||
<kbd>r</kbd>: 체크아웃된 브랜치를 이 브랜치에 리베이스
|
||||
<kbd>d</kbd>: 브랜치 삭제
|
||||
<kbd>u</kbd>: Set as upstream of checked-out branch
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: 커밋 보기
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 브랜치명을 클립보드에 복사 | |
|
||||
| `` <space> `` | 체크아웃 | Checkout a new local branch based on the selected remote branch. The new branch will track the remote branch. |
|
||||
| `` n `` | 새 브랜치 생성 | |
|
||||
| `` M `` | 현재 브랜치에 병합 | Merge selected branch into currently checked out branch. |
|
||||
| `` r `` | 체크아웃된 브랜치를 이 브랜치에 리베이스 | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||
| `` u `` | Set as upstream | Set the selected remote branch as the upstream of the checked-out branch. |
|
||||
| `` s `` | Sort order | |
|
||||
| `` g `` | View reset options | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | 커밋 보기 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 커밋
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 커밋 SHA를 클립보드에 복사
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (copied) commits selection
|
||||
<kbd>b</kbd>: Bisect 옵션 보기
|
||||
<kbd>s</kbd>: Squash down
|
||||
<kbd>f</kbd>: Fixup commit
|
||||
<kbd>r</kbd>: 커밋메시지 변경
|
||||
<kbd>R</kbd>: 에디터에서 커밋메시지 수정
|
||||
<kbd>d</kbd>: 커밋 삭제
|
||||
<kbd>e</kbd>: 커밋을 편집
|
||||
<kbd>p</kbd>: Pick commit (when mid-rebase)
|
||||
<kbd>F</kbd>: Create fixup commit for this commit
|
||||
<kbd>S</kbd>: Squash all 'fixup!' commits above selected commit (autosquash)
|
||||
<kbd><c-j></kbd>: 커밋을 1개 아래로 이동
|
||||
<kbd><c-k></kbd>: 커밋을 1개 위로 이동
|
||||
<kbd>v</kbd>: 커밋을 붙여넣기 (cherry-pick)
|
||||
<kbd>B</kbd>: Mark commit as base commit for rebase
|
||||
<kbd>A</kbd>: Amend commit with staged changes
|
||||
<kbd>a</kbd>: Set/Reset commit author
|
||||
<kbd>t</kbd>: 커밋 되돌리기
|
||||
<kbd>T</kbd>: Tag commit
|
||||
<kbd><c-l></kbd>: 로그 메뉴 열기
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: 커밋을 체크아웃
|
||||
<kbd>y</kbd>: 커밋 attribute 복사
|
||||
<kbd>o</kbd>: 브라우저에서 커밋 열기
|
||||
<kbd>n</kbd>: 커밋에서 새 브랜치를 만듭니다.
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>c</kbd>: 커밋을 복사 (cherry-pick)
|
||||
<kbd>C</kbd>: 커밋을 범위로 복사 (cherry-pick)
|
||||
<kbd><enter></kbd>: View selected item's files
|
||||
<kbd>/</kbd>: 검색 시작
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 커밋 SHA를 클립보드에 복사 | |
|
||||
| `` <c-r> `` | Reset cherry-picked (copied) commits selection | |
|
||||
| `` b `` | Bisect 옵션 보기 | |
|
||||
| `` s `` | Squash | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. |
|
||||
| `` f `` | Fixup | Meld the selected commit into the commit below it. Similar to fixup, but the selected commit's message will be discarded. |
|
||||
| `` r `` | 커밋메시지 변경 | Reword the selected commit's message. |
|
||||
| `` R `` | 에디터에서 커밋메시지 수정 | |
|
||||
| `` d `` | 커밋 삭제 | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. |
|
||||
| `` e `` | Edit (start interactive rebase) | 커밋을 편집 |
|
||||
| `` i `` | Start interactive rebase | Start an interactive rebase for the commits on your branch. This will include all commits from the HEAD commit down to the first merge commit or main branch commit.
|
||||
If you would instead like to start an interactive rebase from the selected commit, press `e`. |
|
||||
| `` p `` | Pick | Pick commit (when mid-rebase) |
|
||||
| `` F `` | Create fixup commit | Create fixup commit for this commit |
|
||||
| `` S `` | Apply fixup commits | Squash all 'fixup!' commits above selected commit (autosquash) |
|
||||
| `` <c-j> `` | 커밋을 1개 아래로 이동 | |
|
||||
| `` <c-k> `` | 커밋을 1개 위로 이동 | |
|
||||
| `` V `` | 커밋을 붙여넣기 (cherry-pick) | |
|
||||
| `` B `` | Mark as base commit for rebase | Select a base commit for the next rebase. When you rebase onto a branch, only commits above the base commit will be brought across. This uses the `git rebase --onto` command. |
|
||||
| `` A `` | Amend | Amend commit with staged changes |
|
||||
| `` a `` | Amend commit attribute | Set/Reset commit author or set co-author. |
|
||||
| `` t `` | Revert | Create a revert commit for the selected commit, which applies the selected commit's changes in reverse. |
|
||||
| `` T `` | Tag commit | Create a new tag pointing at the selected commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` <c-l> `` | 로그 메뉴 열기 | View options for commit log e.g. changing sort order, hiding the git graph, showing the whole git graph. |
|
||||
| `` <space> `` | 체크아웃 | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | 커밋 attribute 복사 | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | 브라우저에서 커밋 열기 | |
|
||||
| `` n `` | 커밋에서 새 브랜치를 만듭니다. | |
|
||||
| `` g `` | View reset options | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | 커밋을 복사 (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | View selected item's files | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | 검색 시작 | |
|
||||
|
||||
## 커밋 파일
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 커밋한 파일명을 클립보드에 복사
|
||||
<kbd>c</kbd>: Checkout file
|
||||
<kbd>d</kbd>: Discard this commit's changes to this file
|
||||
<kbd>o</kbd>: 파일 닫기
|
||||
<kbd>e</kbd>: 파일 편집
|
||||
<kbd><space></kbd>: Toggle file included in patch
|
||||
<kbd>a</kbd>: Toggle all files included in patch
|
||||
<kbd><enter></kbd>: Enter file to add selected lines to the patch (or toggle directory collapsed)
|
||||
<kbd>`</kbd>: 파일 트리뷰로 전환
|
||||
<kbd>/</kbd>: 검색 시작
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 파일명을 클립보드에 복사 | |
|
||||
| `` c `` | 체크아웃 | Checkout file |
|
||||
| `` d `` | Remove | Discard this commit's changes to this file |
|
||||
| `` o `` | 파일 닫기 | Open file in default application. |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <space> `` | Toggle file included in patch | Toggle whether the file is included in the custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` a `` | Toggle all files included in patch | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` <enter> `` | Enter file to add selected lines to the patch (or toggle directory collapsed) | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
|
||||
| `` ` `` | 파일 트리뷰로 전환 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` / `` | 검색 시작 | |
|
||||
|
||||
## 커밋메시지
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: 확인
|
||||
<kbd><esc></kbd>: 닫기
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | 확인 | |
|
||||
| `` <esc> `` | 닫기 | |
|
||||
|
||||
## 태그
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: 체크아웃
|
||||
<kbd>d</kbd>: 태그 삭제
|
||||
<kbd>P</kbd>: 태그를 push
|
||||
<kbd>n</kbd>: 태그를 생성
|
||||
<kbd>g</kbd>: View reset options
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: 커밋 보기
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | 체크아웃 | Checkout the selected tag tag as a detached HEAD. |
|
||||
| `` n `` | 태그를 생성 | Create new tag from current commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` d `` | Delete | View delete options for local/remote tag. |
|
||||
| `` P `` | 태그를 push | Push the selected tag to a remote. You'll be prompted to select a remote. |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | 커밋 보기 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 파일
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 파일명을 클립보드에 복사
|
||||
<kbd>d</kbd>: View 'discard changes' options
|
||||
<kbd><space></kbd>: Staged 전환
|
||||
<kbd><c-b></kbd>: 파일을 필터하기 (Staged/unstaged)
|
||||
<kbd>c</kbd>: 커밋 변경내용
|
||||
<kbd>w</kbd>: Commit changes without pre-commit hook
|
||||
<kbd>A</kbd>: 마지맛 커밋 수정
|
||||
<kbd>C</kbd>: Git 편집기를 사용하여 변경 내용을 커밋합니다.
|
||||
<kbd>e</kbd>: 파일 편집
|
||||
<kbd>o</kbd>: 파일 닫기
|
||||
<kbd>i</kbd>: Ignore file
|
||||
<kbd>r</kbd>: 파일 새로고침
|
||||
<kbd>s</kbd>: 변경사항을 Stash
|
||||
<kbd>S</kbd>: Stash 옵션 보기
|
||||
<kbd>a</kbd>: 모든 변경을 Staged/unstaged으로 전환
|
||||
<kbd><enter></kbd>: Stage individual hunks/lines for file, or collapse/expand for directory
|
||||
<kbd>g</kbd>: View upstream reset options
|
||||
<kbd>D</kbd>: View reset options
|
||||
<kbd>`</kbd>: 파일 트리뷰로 전환
|
||||
<kbd>M</kbd>: Git mergetool를 열기
|
||||
<kbd>f</kbd>: Fetch
|
||||
<kbd>/</kbd>: 검색 시작
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 파일명을 클립보드에 복사 | |
|
||||
| `` <space> `` | Staged 전환 | Toggle staged for selected file. |
|
||||
| `` <c-b> `` | 파일을 필터하기 (Staged/unstaged) | |
|
||||
| `` y `` | Copy to clipboard | |
|
||||
| `` c `` | 커밋 변경내용 | Commit staged changes. |
|
||||
| `` w `` | Commit changes without pre-commit hook | |
|
||||
| `` A `` | 마지맛 커밋 수정 | |
|
||||
| `` C `` | Git 편집기를 사용하여 변경 내용을 커밋합니다. | |
|
||||
| `` <c-f> `` | Find base commit for fixup | Find the commit that your current changes are building upon, for the sake of amending/fixing up the commit. This spares you from having to look through your branch's commits one-by-one to see which commit should be amended/fixed up. See docs: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` o `` | 파일 닫기 | Open file in default application. |
|
||||
| `` i `` | Ignore file | |
|
||||
| `` r `` | 파일 새로고침 | |
|
||||
| `` s `` | Stash | Stash all changes. For other variations of stashing, use the view stash options keybinding. |
|
||||
| `` S `` | Stash 옵션 보기 | View stash options (e.g. stash all, stash staged, stash unstaged). |
|
||||
| `` a `` | 모든 변경을 Staged/unstaged으로 전환 | Toggle staged/unstaged for all files in working tree. |
|
||||
| `` <enter> `` | Stage individual hunks/lines for file, or collapse/expand for directory | If the selected item is a file, focus the staging view so you can stage individual hunks/lines. If the selected item is a directory, collapse/expand it. |
|
||||
| `` d `` | View 'discard changes' options | View options for discarding changes to the selected file. |
|
||||
| `` g `` | View upstream reset options | |
|
||||
| `` D `` | Reset | View reset options for working tree (e.g. nuking the working tree). |
|
||||
| `` ` `` | 파일 트리뷰로 전환 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` M `` | Git mergetool를 열기 | Run `git mergetool`. |
|
||||
| `` f `` | Fetch | Fetch changes from remote. |
|
||||
| `` / `` | 검색 시작 | |
|
||||
|
||||
## 확인 패널
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: 확인
|
||||
<kbd><esc></kbd>: 닫기/취소
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | 확인 | |
|
||||
| `` <esc> `` | 닫기/취소 | |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go run scripts/cheatsheet/main.go generate` from the project root._
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go generate ./...` from the project root._
|
||||
|
||||
# Lazygit Sneltoetsen
|
||||
|
||||
@@ -6,348 +6,358 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|
||||
|
||||
## Globale sneltoetsen
|
||||
|
||||
<pre>
|
||||
<kbd><c-r></kbd>: Wissel naar een recente repo
|
||||
<kbd><pgup></kbd>: Scroll naar beneden vanaf hoofdpaneel (fn+up/shift+k)
|
||||
<kbd><pgdown></kbd>: Scroll naar beneden vanaf hoofdpaneel (fn+down/shift+j)
|
||||
<kbd>@</kbd>: Open command log menu
|
||||
<kbd>}</kbd>: Increase the size of the context shown around changes in the diff view
|
||||
<kbd>{</kbd>: Decrease the size of the context shown around changes in the diff view
|
||||
<kbd>:</kbd>: Voer aangepaste commando uit
|
||||
<kbd><c-p></kbd>: Bekijk aangepaste patch opties
|
||||
<kbd>m</kbd>: Bekijk merge/rebase opties
|
||||
<kbd>R</kbd>: Verversen
|
||||
<kbd>+</kbd>: Volgende scherm modus (normaal/half/groot)
|
||||
<kbd>_</kbd>: Vorige scherm modus
|
||||
<kbd>?</kbd>: Open menu
|
||||
<kbd><c-s></kbd>: Bekijk scoping opties
|
||||
<kbd>W</kbd>: Open diff menu
|
||||
<kbd><c-e></kbd>: Open diff menu
|
||||
<kbd><c-w></kbd>: Toggle whether or not whitespace changes are shown in the diff view
|
||||
<kbd>z</kbd>: Ongedaan maken (via reflog) (experimenteel)
|
||||
<kbd><c-z></kbd>: Redo (via reflog) (experimenteel)
|
||||
<kbd>P</kbd>: Push
|
||||
<kbd>p</kbd>: Pull
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-r> `` | Wissel naar een recente repo | |
|
||||
| `` <pgup> (fn+up/shift+k) `` | Scroll naar beneden vanaf hoofdpaneel | |
|
||||
| `` <pgdown> (fn+down/shift+j) `` | Scroll naar beneden vanaf hoofdpaneel | |
|
||||
| `` @ `` | View command log options | View options for the command log e.g. show/hide the command log and focus the command log. |
|
||||
| `` P `` | Push | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` p `` | Pull | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` } `` | Increase diff context size | Increase the amount of the context shown around changes in the diff view. |
|
||||
| `` { `` | Decrease diff context size | Decrease the amount of the context shown around changes in the diff view. |
|
||||
| `` : `` | Voer aangepaste commando uit | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
|
||||
| `` <c-p> `` | Bekijk aangepaste patch opties | |
|
||||
| `` m `` | Bekijk merge/rebase opties | View options to abort/continue/skip the current merge/rebase. |
|
||||
| `` R `` | Verversen | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. |
|
||||
| `` + `` | Volgende scherm modus (normaal/half/groot) | |
|
||||
| `` _ `` | Vorige scherm modus | |
|
||||
| `` ? `` | Open menu | |
|
||||
| `` <c-s> `` | Bekijk scoping opties | View options for filtering the commit log by a file path, so that only commits relating to that path are shown. |
|
||||
| `` W `` | Open diff menu | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` <c-e> `` | Open diff menu | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` q `` | Quit | |
|
||||
| `` <esc> `` | Annuleren | |
|
||||
| `` <c-w> `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view. |
|
||||
| `` z `` | Ongedaan maken (via reflog) (experimenteel) | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
|
||||
| `` <c-z> `` | Redo (via reflog) (experimenteel) | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
|
||||
|
||||
## Lijstpaneel navigatie
|
||||
|
||||
<pre>
|
||||
<kbd>,</kbd>: Vorige pagina
|
||||
<kbd>.</kbd>: Volgende pagina
|
||||
<kbd><</kbd>: Scroll naar boven
|
||||
<kbd>></kbd>: Scroll naar beneden
|
||||
<kbd>/</kbd>: Start met zoeken
|
||||
<kbd>H</kbd>: Scroll left
|
||||
<kbd>L</kbd>: Scroll right
|
||||
<kbd>]</kbd>: Volgende tabblad
|
||||
<kbd>[</kbd>: Vorige tabblad
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` , `` | Vorige pagina | |
|
||||
| `` . `` | Volgende pagina | |
|
||||
| `` < `` | Scroll naar boven | |
|
||||
| `` > `` | Scroll naar beneden | |
|
||||
| `` v `` | Toggle drag selecteer | |
|
||||
| `` <s-down> `` | Range select down | |
|
||||
| `` <s-up> `` | Range select up | |
|
||||
| `` / `` | Start met zoeken | |
|
||||
| `` H `` | Scroll left | |
|
||||
| `` L `` | Scroll right | |
|
||||
| `` ] `` | Volgende tabblad | |
|
||||
| `` [ `` | Vorige tabblad | |
|
||||
|
||||
## Bestanden
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Kopieer de bestandsnaam naar het klembord
|
||||
<kbd>d</kbd>: Bekijk 'veranderingen ongedaan maken' opties
|
||||
<kbd><space></kbd>: Toggle staged
|
||||
<kbd><c-b></kbd>: Filter files by status
|
||||
<kbd>c</kbd>: Commit veranderingen
|
||||
<kbd>w</kbd>: Commit veranderingen zonder pre-commit hook
|
||||
<kbd>A</kbd>: Wijzig laatste commit
|
||||
<kbd>C</kbd>: Commit veranderingen met de git editor
|
||||
<kbd>e</kbd>: Verander bestand
|
||||
<kbd>o</kbd>: Open bestand
|
||||
<kbd>i</kbd>: Ignore or exclude file
|
||||
<kbd>r</kbd>: Refresh bestanden
|
||||
<kbd>s</kbd>: Stash-bestanden
|
||||
<kbd>S</kbd>: Bekijk stash opties
|
||||
<kbd>a</kbd>: Toggle staged alle
|
||||
<kbd><enter></kbd>: Stage individuele hunks/lijnen
|
||||
<kbd>g</kbd>: Bekijk upstream reset opties
|
||||
<kbd>D</kbd>: Bekijk reset opties
|
||||
<kbd>`</kbd>: Toggle bestandsboom weergave
|
||||
<kbd>M</kbd>: Open external merge tool (git mergetool)
|
||||
<kbd>f</kbd>: Fetch
|
||||
<kbd>/</kbd>: Start met zoeken
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Kopieer de bestandsnaam naar het klembord | |
|
||||
| `` <space> `` | Toggle staged | Toggle staged for selected file. |
|
||||
| `` <c-b> `` | Filter files by status | |
|
||||
| `` y `` | Copy to clipboard | |
|
||||
| `` c `` | Commit veranderingen | Commit staged changes. |
|
||||
| `` w `` | Commit veranderingen zonder pre-commit hook | |
|
||||
| `` A `` | Wijzig laatste commit | |
|
||||
| `` C `` | Commit veranderingen met de git editor | |
|
||||
| `` <c-f> `` | Find base commit for fixup | Find the commit that your current changes are building upon, for the sake of amending/fixing up the commit. This spares you from having to look through your branch's commits one-by-one to see which commit should be amended/fixed up. See docs: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` o `` | Open bestand | Open file in default application. |
|
||||
| `` i `` | Ignore or exclude file | |
|
||||
| `` r `` | Refresh bestanden | |
|
||||
| `` s `` | Stash | Stash all changes. For other variations of stashing, use the view stash options keybinding. |
|
||||
| `` S `` | Bekijk stash opties | View stash options (e.g. stash all, stash staged, stash unstaged). |
|
||||
| `` a `` | Toggle staged alle | Toggle staged/unstaged for all files in working tree. |
|
||||
| `` <enter> `` | Stage individuele hunks/lijnen | If the selected item is a file, focus the staging view so you can stage individual hunks/lines. If the selected item is a directory, collapse/expand it. |
|
||||
| `` d `` | Bekijk 'veranderingen ongedaan maken' opties | View options for discarding changes to the selected file. |
|
||||
| `` g `` | Bekijk upstream reset opties | |
|
||||
| `` D `` | Reset | View reset options for working tree (e.g. nuking the working tree). |
|
||||
| `` ` `` | Toggle bestandsboom weergave | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` M `` | Open external merge tool | Run `git mergetool`. |
|
||||
| `` f `` | Fetch | Fetch changes from remote. |
|
||||
| `` / `` | Start met zoeken | |
|
||||
|
||||
## Bevestigingspaneel
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: Bevestig
|
||||
<kbd><esc></kbd>: Sluiten
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | Bevestig | |
|
||||
| `` <esc> `` | Sluiten | |
|
||||
|
||||
## Branches
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Kopieer branch name naar klembord
|
||||
<kbd>i</kbd>: Laat git-flow opties zien
|
||||
<kbd><space></kbd>: Uitchecken
|
||||
<kbd>n</kbd>: Nieuwe branch
|
||||
<kbd>o</kbd>: Maak een pull-request
|
||||
<kbd>O</kbd>: Bekijk opties voor pull-aanvraag
|
||||
<kbd><c-y></kbd>: Kopieer de URL van het pull-verzoek naar het klembord
|
||||
<kbd>c</kbd>: Uitchecken bij naam
|
||||
<kbd>F</kbd>: Forceer checkout
|
||||
<kbd>d</kbd>: Verwijder branch
|
||||
<kbd>r</kbd>: Rebase branch
|
||||
<kbd>M</kbd>: Merge in met huidige checked out branch
|
||||
<kbd>f</kbd>: Fast-forward deze branch vanaf zijn upstream
|
||||
<kbd>T</kbd>: Creëer tag
|
||||
<kbd>g</kbd>: Bekijk reset opties
|
||||
<kbd>R</kbd>: Hernoem branch
|
||||
<kbd>u</kbd>: Set/Unset upstream
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: Bekijk commits
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Kopieer branch name naar klembord | |
|
||||
| `` i `` | Laat git-flow opties zien | |
|
||||
| `` <space> `` | Uitchecken | Checkout selected item. |
|
||||
| `` n `` | Nieuwe branch | |
|
||||
| `` o `` | Maak een pull-request | |
|
||||
| `` O `` | Bekijk opties voor pull-aanvraag | |
|
||||
| `` <c-y> `` | Kopieer de URL van het pull-verzoek naar het klembord | |
|
||||
| `` c `` | Uitchecken bij naam | Checkout by name. In the input box you can enter '-' to switch to the last branch. |
|
||||
| `` F `` | Forceer checkout | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||
| `` r `` | Rebase branch | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` M `` | Merge in met huidige checked out branch | Merge selected branch into currently checked out branch. |
|
||||
| `` f `` | Fast-forward deze branch vanaf zijn upstream | Fast-forward selected branch from its upstream. |
|
||||
| `` T `` | Creëer tag | |
|
||||
| `` s `` | Sort order | |
|
||||
| `` g `` | Bekijk reset opties | |
|
||||
| `` R `` | Hernoem branch | |
|
||||
| `` u `` | View upstream options | View options relating to the branch's upstream e.g. setting/unsetting the upstream and resetting to the upstream. |
|
||||
| `` <enter> `` | Bekijk commits | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Commit bericht
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: Bevestig
|
||||
<kbd><esc></kbd>: Sluiten
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | Bevestig | |
|
||||
| `` <esc> `` | Sluiten | |
|
||||
|
||||
## Commit bestanden
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Kopieer de vastgelegde bestandsnaam naar het klembord
|
||||
<kbd>c</kbd>: Bestand uitchecken
|
||||
<kbd>d</kbd>: Uitsluit deze commit zijn veranderingen aan dit bestand
|
||||
<kbd>o</kbd>: Open bestand
|
||||
<kbd>e</kbd>: Verander bestand
|
||||
<kbd><space></kbd>: Toggle bestand inbegrepen in patch
|
||||
<kbd>a</kbd>: Toggle all files included in patch
|
||||
<kbd><enter></kbd>: Enter bestand om geselecteerde regels toe te voegen aan de patch
|
||||
<kbd>`</kbd>: Toggle bestandsboom weergave
|
||||
<kbd>/</kbd>: Start met zoeken
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Kopieer de bestandsnaam naar het klembord | |
|
||||
| `` c `` | Uitchecken | Bestand uitchecken |
|
||||
| `` d `` | Remove | Uitsluit deze commit zijn veranderingen aan dit bestand |
|
||||
| `` o `` | Open bestand | Open file in default application. |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <space> `` | Toggle bestand inbegrepen in patch | Toggle whether the file is included in the custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` a `` | Toggle all files | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` <enter> `` | Enter bestand om geselecteerde regels toe te voegen aan de patch | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
|
||||
| `` ` `` | Toggle bestandsboom weergave | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` / `` | Start met zoeken | |
|
||||
|
||||
## Commits
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Kopieer commit SHA naar klembord
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (gekopieerde) commits selectie
|
||||
<kbd>b</kbd>: View bisect options
|
||||
<kbd>s</kbd>: Squash beneden
|
||||
<kbd>f</kbd>: Fixup commit
|
||||
<kbd>r</kbd>: Hernoem commit
|
||||
<kbd>R</kbd>: Hernoem commit met editor
|
||||
<kbd>d</kbd>: Verwijder commit
|
||||
<kbd>e</kbd>: Wijzig commit
|
||||
<kbd>p</kbd>: Kies commit (wanneer midden in rebase)
|
||||
<kbd>F</kbd>: Creëer fixup commit
|
||||
<kbd>S</kbd>: Squash bovenstaande commits
|
||||
<kbd><c-j></kbd>: Verplaats commit 1 naar beneden
|
||||
<kbd><c-k></kbd>: Verplaats commit 1 naar boven
|
||||
<kbd>v</kbd>: Plak commits (cherry-pick)
|
||||
<kbd>B</kbd>: Mark commit as base commit for rebase
|
||||
<kbd>A</kbd>: Wijzig commit met staged veranderingen
|
||||
<kbd>a</kbd>: Set/Reset commit author
|
||||
<kbd>t</kbd>: Commit ongedaan maken
|
||||
<kbd>T</kbd>: Tag commit
|
||||
<kbd><c-l></kbd>: Open log menu
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: Checkout commit
|
||||
<kbd>y</kbd>: Copy commit attribute
|
||||
<kbd>o</kbd>: Open commit in browser
|
||||
<kbd>n</kbd>: Creëer nieuwe branch van commit
|
||||
<kbd>g</kbd>: Bekijk reset opties
|
||||
<kbd>c</kbd>: Kopieer commit (cherry-pick)
|
||||
<kbd>C</kbd>: Kopieer commit reeks (cherry-pick)
|
||||
<kbd><enter></kbd>: Bekijk gecommite bestanden
|
||||
<kbd>/</kbd>: Start met zoeken
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Kopieer commit SHA naar klembord | |
|
||||
| `` <c-r> `` | Reset cherry-picked (gekopieerde) commits selectie | |
|
||||
| `` b `` | View bisect options | |
|
||||
| `` s `` | Squash | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. |
|
||||
| `` f `` | Fixup | Meld the selected commit into the commit below it. Similar to fixup, but the selected commit's message will be discarded. |
|
||||
| `` r `` | Hernoem commit | Reword the selected commit's message. |
|
||||
| `` R `` | Hernoem commit met editor | |
|
||||
| `` d `` | Verwijder commit | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. |
|
||||
| `` e `` | Edit (start interactive rebase) | Wijzig commit |
|
||||
| `` i `` | Start interactive rebase | Start an interactive rebase for the commits on your branch. This will include all commits from the HEAD commit down to the first merge commit or main branch commit.
|
||||
If you would instead like to start an interactive rebase from the selected commit, press `e`. |
|
||||
| `` p `` | Pick | Kies commit (wanneer midden in rebase) |
|
||||
| `` F `` | Create fixup commit | Creëer fixup commit |
|
||||
| `` S `` | Apply fixup commits | Squash bovenstaande commits |
|
||||
| `` <c-j> `` | Verplaats commit 1 naar beneden | |
|
||||
| `` <c-k> `` | Verplaats commit 1 naar boven | |
|
||||
| `` V `` | Plak commits (cherry-pick) | |
|
||||
| `` B `` | Mark as base commit for rebase | Select a base commit for the next rebase. When you rebase onto a branch, only commits above the base commit will be brought across. This uses the `git rebase --onto` command. |
|
||||
| `` A `` | Amend | Wijzig commit met staged veranderingen |
|
||||
| `` a `` | Amend commit attribute | Set/Reset commit author or set co-author. |
|
||||
| `` t `` | Revert | Create a revert commit for the selected commit, which applies the selected commit's changes in reverse. |
|
||||
| `` T `` | Tag commit | Create a new tag pointing at the selected commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` <c-l> `` | View log options | View options for commit log e.g. changing sort order, hiding the git graph, showing the whole git graph. |
|
||||
| `` <space> `` | Uitchecken | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | Open commit in browser | |
|
||||
| `` n `` | Creëer nieuwe branch van commit | |
|
||||
| `` g `` | Bekijk reset opties | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | Kopieer commit (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | Bekijk gecommite bestanden | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Start met zoeken | |
|
||||
|
||||
## Menu
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: Uitvoeren
|
||||
<kbd><esc></kbd>: Sluiten
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | Uitvoeren | |
|
||||
| `` <esc> `` | Sluiten | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Mergen
|
||||
|
||||
<pre>
|
||||
<kbd>e</kbd>: Verander bestand
|
||||
<kbd>o</kbd>: Open bestand
|
||||
<kbd><left></kbd>: Selecteer voorgaand conflict
|
||||
<kbd><right></kbd>: Selecteer volgende conflict
|
||||
<kbd><up></kbd>: Selecteer bovenste hunk
|
||||
<kbd><down></kbd>: Selecteer onderste hunk
|
||||
<kbd>z</kbd>: Ongedaan maken
|
||||
<kbd>M</kbd>: Open external merge tool (git mergetool)
|
||||
<kbd><space></kbd>: Kies stuk
|
||||
<kbd>b</kbd>: Kies beide stukken
|
||||
<kbd><esc></kbd>: Ga terug naar het bestanden paneel
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Kies stuk | |
|
||||
| `` b `` | Kies beide stukken | |
|
||||
| `` <up> `` | Selecteer bovenste hunk | |
|
||||
| `` <down> `` | Selecteer onderste hunk | |
|
||||
| `` <left> `` | Selecteer voorgaand conflict | |
|
||||
| `` <right> `` | Selecteer volgende conflict | |
|
||||
| `` z `` | Ongedaan maken | Undo last merge conflict resolution. |
|
||||
| `` e `` | Verander bestand | Open file in external editor. |
|
||||
| `` o `` | Open bestand | Open file in default application. |
|
||||
| `` M `` | Open external merge tool | Run `git mergetool`. |
|
||||
| `` <esc> `` | Ga terug naar het bestanden paneel | |
|
||||
|
||||
## Normaal
|
||||
|
||||
<pre>
|
||||
<kbd>mouse wheel down</kbd>: Scroll omlaag (fn+up)
|
||||
<kbd>mouse wheel up</kbd>: Scroll omhoog (fn+down)
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` mouse wheel down (fn+up) `` | Scroll omlaag | |
|
||||
| `` mouse wheel up (fn+down) `` | Scroll omhoog | |
|
||||
|
||||
## Patch bouwen
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: Selecteer de vorige hunk
|
||||
<kbd><right></kbd>: Selecteer de volgende hunk
|
||||
<kbd>v</kbd>: Toggle drag selecteer
|
||||
<kbd>V</kbd>: Toggle drag selecteer
|
||||
<kbd>a</kbd>: Toggle selecteer hunk
|
||||
<kbd><c-o></kbd>: Copy the selected text to the clipboard
|
||||
<kbd>o</kbd>: Open bestand
|
||||
<kbd>e</kbd>: Verander bestand
|
||||
<kbd><space></kbd>: Voeg toe/verwijder lijn(en) in patch
|
||||
<kbd><esc></kbd>: Sluit lijn-bij-lijn modus
|
||||
<kbd>/</kbd>: Start met zoeken
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | Selecteer de vorige hunk | |
|
||||
| `` <right> `` | Selecteer de volgende hunk | |
|
||||
| `` v `` | Toggle drag selecteer | |
|
||||
| `` a `` | Toggle selecteer hunk | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | Copy selected text to clipboard | |
|
||||
| `` o `` | Open bestand | Open file in default application. |
|
||||
| `` e `` | Verander bestand | Open file in external editor. |
|
||||
| `` <space> `` | Voeg toe/verwijder lijn(en) in patch | |
|
||||
| `` <esc> `` | Sluit lijn-bij-lijn modus | |
|
||||
| `` / `` | Start met zoeken | |
|
||||
|
||||
## Reflog
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Kopieer commit SHA naar klembord
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: Checkout commit
|
||||
<kbd>y</kbd>: Copy commit attribute
|
||||
<kbd>o</kbd>: Open commit in browser
|
||||
<kbd>n</kbd>: Creëer nieuwe branch van commit
|
||||
<kbd>g</kbd>: Bekijk reset opties
|
||||
<kbd>c</kbd>: Kopieer commit (cherry-pick)
|
||||
<kbd>C</kbd>: Kopieer commit reeks (cherry-pick)
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (gekopieerde) commits selectie
|
||||
<kbd><enter></kbd>: Bekijk commits
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Kopieer commit SHA naar klembord | |
|
||||
| `` <space> `` | Uitchecken | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | Open commit in browser | |
|
||||
| `` n `` | Creëer nieuwe branch van commit | |
|
||||
| `` g `` | Bekijk reset opties | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | Kopieer commit (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | Reset cherry-picked (gekopieerde) commits selectie | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | Bekijk commits | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Remote branches
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Kopieer branch name naar klembord
|
||||
<kbd><space></kbd>: Uitchecken
|
||||
<kbd>n</kbd>: Nieuwe branch
|
||||
<kbd>M</kbd>: Merge in met huidige checked out branch
|
||||
<kbd>r</kbd>: Rebase branch
|
||||
<kbd>d</kbd>: Verwijder branch
|
||||
<kbd>u</kbd>: Stel in als upstream van uitgecheckte branch
|
||||
<kbd>g</kbd>: Bekijk reset opties
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: Bekijk commits
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Kopieer branch name naar klembord | |
|
||||
| `` <space> `` | Uitchecken | Checkout a new local branch based on the selected remote branch. The new branch will track the remote branch. |
|
||||
| `` n `` | Nieuwe branch | |
|
||||
| `` M `` | Merge in met huidige checked out branch | Merge selected branch into currently checked out branch. |
|
||||
| `` r `` | Rebase branch | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||
| `` u `` | Set as upstream | Stel in als upstream van uitgecheckte branch |
|
||||
| `` s `` | Sort order | |
|
||||
| `` g `` | Bekijk reset opties | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | Bekijk commits | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Remotes
|
||||
|
||||
<pre>
|
||||
<kbd>f</kbd>: Fetch remote
|
||||
<kbd>n</kbd>: Voeg een nieuwe remote toe
|
||||
<kbd>d</kbd>: Verwijder remote
|
||||
<kbd>e</kbd>: Wijzig remote
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | View branches | |
|
||||
| `` n `` | Voeg een nieuwe remote toe | |
|
||||
| `` d `` | Remove | Remove the selected remote. Any local branches tracking a remote branch from the remote will be unaffected. |
|
||||
| `` e `` | Edit | Wijzig remote |
|
||||
| `` f `` | Fetch | Fetch remote |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Staging
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: Selecteer de vorige hunk
|
||||
<kbd><right></kbd>: Selecteer de volgende hunk
|
||||
<kbd>v</kbd>: Toggle drag selecteer
|
||||
<kbd>V</kbd>: Toggle drag selecteer
|
||||
<kbd>a</kbd>: Toggle selecteer hunk
|
||||
<kbd><c-o></kbd>: Copy the selected text to the clipboard
|
||||
<kbd>o</kbd>: Open bestand
|
||||
<kbd>e</kbd>: Verander bestand
|
||||
<kbd><esc></kbd>: Ga terug naar het bestanden paneel
|
||||
<kbd><tab></kbd>: Ga naar een ander paneel
|
||||
<kbd><space></kbd>: Toggle lijnen staged / unstaged
|
||||
<kbd>d</kbd>: Verwijdert change (git reset)
|
||||
<kbd>E</kbd>: Edit hunk
|
||||
<kbd>c</kbd>: Commit veranderingen
|
||||
<kbd>w</kbd>: Commit veranderingen zonder pre-commit hook
|
||||
<kbd>C</kbd>: Commit veranderingen met de git editor
|
||||
<kbd>/</kbd>: Start met zoeken
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | Selecteer de vorige hunk | |
|
||||
| `` <right> `` | Selecteer de volgende hunk | |
|
||||
| `` v `` | Toggle drag selecteer | |
|
||||
| `` a `` | Toggle selecteer hunk | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | Copy selected text to clipboard | |
|
||||
| `` <space> `` | Toggle staged | Toggle lijnen staged / unstaged |
|
||||
| `` d `` | Verwijdert change (git reset) | When unstaged change is selected, discard the change using `git reset`. When staged change is selected, unstage the change. |
|
||||
| `` o `` | Open bestand | Open file in default application. |
|
||||
| `` e `` | Verander bestand | Open file in external editor. |
|
||||
| `` <esc> `` | Ga terug naar het bestanden paneel | |
|
||||
| `` <tab> `` | Ga naar een ander paneel | Switch to other view (staged/unstaged changes). |
|
||||
| `` E `` | Edit hunk | Edit selected hunk in external editor. |
|
||||
| `` c `` | Commit veranderingen | Commit staged changes. |
|
||||
| `` w `` | Commit veranderingen zonder pre-commit hook | |
|
||||
| `` C `` | Commit veranderingen met de git editor | |
|
||||
| `` / `` | Start met zoeken | |
|
||||
|
||||
## Stash
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: Toepassen
|
||||
<kbd>g</kbd>: Pop
|
||||
<kbd>d</kbd>: Laten vallen
|
||||
<kbd>n</kbd>: Nieuwe branch
|
||||
<kbd>r</kbd>: Rename stash
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: Bekijk gecommite bestanden
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Toepassen | Apply the stash entry to your working directory. |
|
||||
| `` g `` | Pop | Apply the stash entry to your working directory and remove the stash entry. |
|
||||
| `` d `` | Laten vallen | Remove the stash entry from the stash list. |
|
||||
| `` n `` | Nieuwe branch | Create a new branch from the selected stash entry. This works by git checking out the commit that the stash entry was created from, creating a new branch from that commit, then applying the stash entry to the new branch as an additional commit. |
|
||||
| `` r `` | Rename stash | |
|
||||
| `` <enter> `` | Bekijk gecommite bestanden | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Status
|
||||
|
||||
<pre>
|
||||
<kbd>o</kbd>: Open config bestand
|
||||
<kbd>e</kbd>: Verander config bestand
|
||||
<kbd>u</kbd>: Check voor updates
|
||||
<kbd><enter></kbd>: Wissel naar een recente repo
|
||||
<kbd>a</kbd>: Alle logs van de branch laten zien
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` o `` | Open config bestand | Open file in default application. |
|
||||
| `` e `` | Verander config bestand | Open file in external editor. |
|
||||
| `` u `` | Check voor updates | |
|
||||
| `` <enter> `` | Wissel naar een recente repo | |
|
||||
| `` a `` | Alle logs van de branch laten zien | |
|
||||
|
||||
## Sub-commits
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Kopieer commit SHA naar klembord
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: Checkout commit
|
||||
<kbd>y</kbd>: Copy commit attribute
|
||||
<kbd>o</kbd>: Open commit in browser
|
||||
<kbd>n</kbd>: Creëer nieuwe branch van commit
|
||||
<kbd>g</kbd>: Bekijk reset opties
|
||||
<kbd>c</kbd>: Kopieer commit (cherry-pick)
|
||||
<kbd>C</kbd>: Kopieer commit reeks (cherry-pick)
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (gekopieerde) commits selectie
|
||||
<kbd><enter></kbd>: Bekijk gecommite bestanden
|
||||
<kbd>/</kbd>: Start met zoeken
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Kopieer commit SHA naar klembord | |
|
||||
| `` <space> `` | Uitchecken | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | Open commit in browser | |
|
||||
| `` n `` | Creëer nieuwe branch van commit | |
|
||||
| `` g `` | Bekijk reset opties | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | Kopieer commit (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | Reset cherry-picked (gekopieerde) commits selectie | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | Bekijk gecommite bestanden | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Start met zoeken | |
|
||||
|
||||
## Submodules
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Kopieer submodule naam naar klembord
|
||||
<kbd><enter></kbd>: Enter submodule
|
||||
<kbd><space></kbd>: Enter submodule
|
||||
<kbd>d</kbd>: Remove submodule
|
||||
<kbd>u</kbd>: Update submodule
|
||||
<kbd>n</kbd>: Voeg nieuwe submodule toe
|
||||
<kbd>e</kbd>: Update submodule URL
|
||||
<kbd>i</kbd>: Initialiseer submodule
|
||||
<kbd>b</kbd>: Bekijk bulk submodule opties
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Kopieer submodule naam naar klembord | |
|
||||
| `` <enter> `` | Enter | Enter submodule |
|
||||
| `` d `` | Remove | Remove the selected submodule and its corresponding directory. |
|
||||
| `` u `` | Update | Update selected submodule. |
|
||||
| `` n `` | Voeg nieuwe submodule toe | |
|
||||
| `` e `` | Update submodule URL | |
|
||||
| `` i `` | Initialize | Initialiseer submodule |
|
||||
| `` b `` | Bekijk bulk submodule opties | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Tags
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: Uitchecken
|
||||
<kbd>d</kbd>: Verwijder tag
|
||||
<kbd>P</kbd>: Push tag
|
||||
<kbd>n</kbd>: Creëer tag
|
||||
<kbd>g</kbd>: Bekijk reset opties
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: Bekijk commits
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Uitchecken | Checkout the selected tag tag as a detached HEAD. |
|
||||
| `` n `` | Creëer tag | Create new tag from current commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` d `` | Delete | View delete options for local/remote tag. |
|
||||
| `` P `` | Push tag | Push the selected tag to a remote. You'll be prompted to select a remote. |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | Bekijk commits | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Worktrees
|
||||
|
||||
<pre>
|
||||
<kbd>n</kbd>: Create worktree
|
||||
<kbd><space></kbd>: Switch to worktree
|
||||
<kbd><enter></kbd>: Switch to worktree
|
||||
<kbd>o</kbd>: Open in editor
|
||||
<kbd>d</kbd>: Remove worktree
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` n `` | New worktree | |
|
||||
| `` <space> `` | Switch | Switch to the selected worktree. |
|
||||
| `` o `` | Open in editor | |
|
||||
| `` d `` | Remove | Remove the selected worktree. This will both delete the worktree's directory, as well as metadata about the worktree in the .git directory. |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go run scripts/cheatsheet/main.go generate` from the project root._
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go generate ./...` from the project root._
|
||||
|
||||
# Lazygit Keybindings
|
||||
|
||||
@@ -6,348 +6,358 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|
||||
|
||||
## Globalne
|
||||
|
||||
<pre>
|
||||
<kbd><c-r></kbd>: Switch to a recent repo
|
||||
<kbd><pgup></kbd>: Scroll up main panel (fn+up/shift+k)
|
||||
<kbd><pgdown></kbd>: Scroll down main panel (fn+down/shift+j)
|
||||
<kbd>@</kbd>: Open command log menu
|
||||
<kbd>}</kbd>: Increase the size of the context shown around changes in the diff view
|
||||
<kbd>{</kbd>: Decrease the size of the context shown around changes in the diff view
|
||||
<kbd>:</kbd>: Wykonaj własną komendę
|
||||
<kbd><c-p></kbd>: View custom patch options
|
||||
<kbd>m</kbd>: Widok scalenia/opcje zmiany bazy
|
||||
<kbd>R</kbd>: Odśwież
|
||||
<kbd>+</kbd>: Next screen mode (normal/half/fullscreen)
|
||||
<kbd>_</kbd>: Prev screen mode
|
||||
<kbd>?</kbd>: Open menu
|
||||
<kbd><c-s></kbd>: View filter-by-path options
|
||||
<kbd>W</kbd>: Open diff menu
|
||||
<kbd><c-e></kbd>: Open diff menu
|
||||
<kbd><c-w></kbd>: Toggle whether or not whitespace changes are shown in the diff view
|
||||
<kbd>z</kbd>: Undo
|
||||
<kbd><c-z></kbd>: Redo
|
||||
<kbd>P</kbd>: Push
|
||||
<kbd>p</kbd>: Pull
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-r> `` | Switch to a recent repo | |
|
||||
| `` <pgup> (fn+up/shift+k) `` | Scroll up main window | |
|
||||
| `` <pgdown> (fn+down/shift+j) `` | Scroll down main window | |
|
||||
| `` @ `` | View command log options | View options for the command log e.g. show/hide the command log and focus the command log. |
|
||||
| `` P `` | Push | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` p `` | Pull | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` } `` | Increase diff context size | Increase the amount of the context shown around changes in the diff view. |
|
||||
| `` { `` | Decrease diff context size | Decrease the amount of the context shown around changes in the diff view. |
|
||||
| `` : `` | Wykonaj własną komendę | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
|
||||
| `` <c-p> `` | View custom patch options | |
|
||||
| `` m `` | Widok scalenia/opcje zmiany bazy | View options to abort/continue/skip the current merge/rebase. |
|
||||
| `` R `` | Odśwież | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. |
|
||||
| `` + `` | Next screen mode (normal/half/fullscreen) | |
|
||||
| `` _ `` | Prev screen mode | |
|
||||
| `` ? `` | Open keybindings menu | |
|
||||
| `` <c-s> `` | View filter-by-path options | View options for filtering the commit log by a file path, so that only commits relating to that path are shown. |
|
||||
| `` W `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` <c-e> `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` q `` | Quit | |
|
||||
| `` <esc> `` | Anuluj | |
|
||||
| `` <c-w> `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view. |
|
||||
| `` z `` | Undo | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
|
||||
| `` <c-z> `` | Redo | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
|
||||
|
||||
## List panel navigation
|
||||
|
||||
<pre>
|
||||
<kbd>,</kbd>: Previous page
|
||||
<kbd>.</kbd>: Next page
|
||||
<kbd><</kbd>: Scroll to top
|
||||
<kbd>></kbd>: Scroll to bottom
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
<kbd>H</kbd>: Scroll left
|
||||
<kbd>L</kbd>: Scroll right
|
||||
<kbd>]</kbd>: Next tab
|
||||
<kbd>[</kbd>: Previous tab
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` , `` | Previous page | |
|
||||
| `` . `` | Next page | |
|
||||
| `` < `` | Scroll to top | |
|
||||
| `` > `` | Scroll to bottom | |
|
||||
| `` v `` | Toggle range select | |
|
||||
| `` <s-down> `` | Range select down | |
|
||||
| `` <s-up> `` | Range select up | |
|
||||
| `` / `` | Search the current view by text | |
|
||||
| `` H `` | Scroll left | |
|
||||
| `` L `` | Scroll right | |
|
||||
| `` ] `` | Next tab | |
|
||||
| `` [ `` | Previous tab | |
|
||||
|
||||
## Commit summary
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: Potwierdź
|
||||
<kbd><esc></kbd>: Zamknij
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | Potwierdź | |
|
||||
| `` <esc> `` | Zamknij | |
|
||||
|
||||
## Commity
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy commit SHA to clipboard
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (copied) commits selection
|
||||
<kbd>b</kbd>: View bisect options
|
||||
<kbd>s</kbd>: Ściśnij
|
||||
<kbd>f</kbd>: Napraw commit
|
||||
<kbd>r</kbd>: Zmień nazwę commita
|
||||
<kbd>R</kbd>: Zmień nazwę commita w edytorze
|
||||
<kbd>d</kbd>: Usuń commit
|
||||
<kbd>e</kbd>: Edytuj commit
|
||||
<kbd>p</kbd>: Wybierz commit (podczas zmiany bazy)
|
||||
<kbd>F</kbd>: Utwórz commit naprawczy dla tego commita
|
||||
<kbd>S</kbd>: Spłaszcz wszystkie commity naprawcze powyżej zaznaczonych commitów (autosquash)
|
||||
<kbd><c-j></kbd>: Przenieś commit 1 w dół
|
||||
<kbd><c-k></kbd>: Przenieś commit 1 w górę
|
||||
<kbd>v</kbd>: Wklej commity (przebieranie)
|
||||
<kbd>B</kbd>: Mark commit as base commit for rebase
|
||||
<kbd>A</kbd>: Popraw commit zmianami z poczekalni
|
||||
<kbd>a</kbd>: Set/Reset commit author
|
||||
<kbd>t</kbd>: Odwróć commit
|
||||
<kbd>T</kbd>: Tag commit
|
||||
<kbd><c-l></kbd>: Open log menu
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: Checkout commit
|
||||
<kbd>y</kbd>: Copy commit attribute
|
||||
<kbd>o</kbd>: Open commit in browser
|
||||
<kbd>n</kbd>: Create new branch off of commit
|
||||
<kbd>g</kbd>: Wyświetl opcje resetu
|
||||
<kbd>c</kbd>: Kopiuj commit (przebieranie)
|
||||
<kbd>C</kbd>: Kopiuj zakres commitów (przebieranie)
|
||||
<kbd><enter></kbd>: Przeglądaj pliki commita
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy commit SHA to clipboard | |
|
||||
| `` <c-r> `` | Reset copied (cherry-picked) commits selection | |
|
||||
| `` b `` | View bisect options | |
|
||||
| `` s `` | Spłaszcz | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. |
|
||||
| `` f `` | Napraw | Meld the selected commit into the commit below it. Similar to fixup, but the selected commit's message will be discarded. |
|
||||
| `` r `` | Zmień nazwę commita | Reword the selected commit's message. |
|
||||
| `` R `` | Zmień nazwę commita w edytorze | |
|
||||
| `` d `` | Usuń commit | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. |
|
||||
| `` e `` | Edit (start interactive rebase) | Edytuj commit |
|
||||
| `` i `` | Start interactive rebase | Start an interactive rebase for the commits on your branch. This will include all commits from the HEAD commit down to the first merge commit or main branch commit.
|
||||
If you would instead like to start an interactive rebase from the selected commit, press `e`. |
|
||||
| `` p `` | Pick | Wybierz commit (podczas zmiany bazy) |
|
||||
| `` F `` | Create fixup commit | Utwórz commit naprawczy dla tego commita |
|
||||
| `` S `` | Apply fixup commits | Spłaszcz wszystkie commity naprawcze powyżej zaznaczonych commitów (autosquash) |
|
||||
| `` <c-j> `` | Przenieś commit 1 w dół | |
|
||||
| `` <c-k> `` | Przenieś commit 1 w górę | |
|
||||
| `` V `` | Wklej commity (przebieranie) | |
|
||||
| `` B `` | Mark as base commit for rebase | Select a base commit for the next rebase. When you rebase onto a branch, only commits above the base commit will be brought across. This uses the `git rebase --onto` command. |
|
||||
| `` A `` | Amend | Popraw commit zmianami z poczekalni |
|
||||
| `` a `` | Amend commit attribute | Set/Reset commit author or set co-author. |
|
||||
| `` t `` | Revert | Create a revert commit for the selected commit, which applies the selected commit's changes in reverse. |
|
||||
| `` T `` | Tag commit | Create a new tag pointing at the selected commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` <c-l> `` | View log options | View options for commit log e.g. changing sort order, hiding the git graph, showing the whole git graph. |
|
||||
| `` <space> `` | Przełącz | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | Open commit in browser | |
|
||||
| `` n `` | Create new branch off of commit | |
|
||||
| `` g `` | Wyświetl opcje resetu | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | Kopiuj commit (przebieranie) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | Przeglądaj pliki commita | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Confirmation panel
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: Potwierdź
|
||||
<kbd><esc></kbd>: Zamknij
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | Potwierdź | |
|
||||
| `` <esc> `` | Zamknij | |
|
||||
|
||||
## Local branches
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy branch name to clipboard
|
||||
<kbd>i</kbd>: Show git-flow options
|
||||
<kbd><space></kbd>: Przełącz
|
||||
<kbd>n</kbd>: Nowa gałąź
|
||||
<kbd>o</kbd>: Utwórz żądanie pobrania
|
||||
<kbd>O</kbd>: Utwórz opcje żądania ściągnięcia
|
||||
<kbd><c-y></kbd>: Skopiuj adres URL żądania pobrania do schowka
|
||||
<kbd>c</kbd>: Przełącz używając nazwy
|
||||
<kbd>F</kbd>: Wymuś przełączenie
|
||||
<kbd>d</kbd>: Usuń gałąź
|
||||
<kbd>r</kbd>: Zmiana bazy gałęzi
|
||||
<kbd>M</kbd>: Scal do obecnej gałęzi
|
||||
<kbd>f</kbd>: Fast-forward this branch from its upstream
|
||||
<kbd>T</kbd>: Create tag
|
||||
<kbd>g</kbd>: Wyświetl opcje resetu
|
||||
<kbd>R</kbd>: Rename branch
|
||||
<kbd>u</kbd>: Set/Unset upstream
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: View commits
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy branch name to clipboard | |
|
||||
| `` i `` | Show git-flow options | |
|
||||
| `` <space> `` | Przełącz | Checkout selected item. |
|
||||
| `` n `` | Nowa gałąź | |
|
||||
| `` o `` | Utwórz żądanie pobrania | |
|
||||
| `` O `` | Utwórz opcje żądania ściągnięcia | |
|
||||
| `` <c-y> `` | Skopiuj adres URL żądania pobrania do schowka | |
|
||||
| `` c `` | Przełącz używając nazwy | Checkout by name. In the input box you can enter '-' to switch to the last branch. |
|
||||
| `` F `` | Wymuś przełączenie | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||
| `` r `` | Zmiana bazy gałęzi | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` M `` | Scal do obecnej gałęzi | Merge selected branch into currently checked out branch. |
|
||||
| `` f `` | Fast-forward | Fast-forward selected branch from its upstream. |
|
||||
| `` T `` | New tag | |
|
||||
| `` s `` | Sort order | |
|
||||
| `` g `` | Wyświetl opcje resetu | |
|
||||
| `` R `` | Rename branch | |
|
||||
| `` u `` | View upstream options | View options relating to the branch's upstream e.g. setting/unsetting the upstream and resetting to the upstream. |
|
||||
| `` <enter> `` | View commits | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Main panel (patch building)
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: Poprzedni kawałek
|
||||
<kbd><right></kbd>: Następny kawałek
|
||||
<kbd>v</kbd>: Toggle drag select
|
||||
<kbd>V</kbd>: Toggle drag select
|
||||
<kbd>a</kbd>: Toggle select hunk
|
||||
<kbd><c-o></kbd>: Copy the selected text to the clipboard
|
||||
<kbd>o</kbd>: Otwórz plik
|
||||
<kbd>e</kbd>: Edytuj plik
|
||||
<kbd><space></kbd>: Add/Remove line(s) to patch
|
||||
<kbd><esc></kbd>: Wyście z trybu "linia po linii"
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | Poprzedni kawałek | |
|
||||
| `` <right> `` | Następny kawałek | |
|
||||
| `` v `` | Toggle range select | |
|
||||
| `` a `` | Select hunk | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | Copy selected text to clipboard | |
|
||||
| `` o `` | Otwórz plik | Open file in default application. |
|
||||
| `` e `` | Edytuj plik | Open file in external editor. |
|
||||
| `` <space> `` | Toggle lines in patch | |
|
||||
| `` <esc> `` | Wyście z trybu "linia po linii" | |
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Menu
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: Wykonaj
|
||||
<kbd><esc></kbd>: Zamknij
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | Wykonaj | |
|
||||
| `` <esc> `` | Zamknij | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Pliki
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy the file name to the clipboard
|
||||
<kbd>d</kbd>: Pokaż opcje porzucania zmian
|
||||
<kbd><space></kbd>: Przełącz stan poczekalni
|
||||
<kbd><c-b></kbd>: Filter files by status
|
||||
<kbd>c</kbd>: Zatwierdź zmiany
|
||||
<kbd>w</kbd>: Zatwierdź zmiany bez skryptu pre-commit
|
||||
<kbd>A</kbd>: Zmień ostatni commit
|
||||
<kbd>C</kbd>: Zatwierdź zmiany używając edytora
|
||||
<kbd>e</kbd>: Edytuj plik
|
||||
<kbd>o</kbd>: Otwórz plik
|
||||
<kbd>i</kbd>: Ignore or exclude file
|
||||
<kbd>r</kbd>: Odśwież pliki
|
||||
<kbd>s</kbd>: Przechowaj zmiany
|
||||
<kbd>S</kbd>: Wyświetl opcje schowka
|
||||
<kbd>a</kbd>: Przełącz stan poczekalni wszystkich
|
||||
<kbd><enter></kbd>: Zatwierdź pojedyncze linie
|
||||
<kbd>g</kbd>: View upstream reset options
|
||||
<kbd>D</kbd>: Wyświetl opcje resetu
|
||||
<kbd>`</kbd>: Toggle file tree view
|
||||
<kbd>M</kbd>: Open external merge tool (git mergetool)
|
||||
<kbd>f</kbd>: Pobierz
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy path to clipboard | |
|
||||
| `` <space> `` | Przełącz stan poczekalni | Toggle staged for selected file. |
|
||||
| `` <c-b> `` | Filter files by status | |
|
||||
| `` y `` | Copy to clipboard | |
|
||||
| `` c `` | Zatwierdź zmiany | Commit staged changes. |
|
||||
| `` w `` | Zatwierdź zmiany bez skryptu pre-commit | |
|
||||
| `` A `` | Zmień ostatni commit | |
|
||||
| `` C `` | Zatwierdź zmiany używając edytora | |
|
||||
| `` <c-f> `` | Find base commit for fixup | Find the commit that your current changes are building upon, for the sake of amending/fixing up the commit. This spares you from having to look through your branch's commits one-by-one to see which commit should be amended/fixed up. See docs: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` o `` | Otwórz plik | Open file in default application. |
|
||||
| `` i `` | Ignore or exclude file | |
|
||||
| `` r `` | Odśwież pliki | |
|
||||
| `` s `` | Stash | Stash all changes. For other variations of stashing, use the view stash options keybinding. |
|
||||
| `` S `` | Wyświetl opcje schowka | View stash options (e.g. stash all, stash staged, stash unstaged). |
|
||||
| `` a `` | Przełącz stan poczekalni wszystkich | Toggle staged/unstaged for all files in working tree. |
|
||||
| `` <enter> `` | Zatwierdź pojedyncze linie | If the selected item is a file, focus the staging view so you can stage individual hunks/lines. If the selected item is a directory, collapse/expand it. |
|
||||
| `` d `` | Pokaż opcje porzucania zmian | View options for discarding changes to the selected file. |
|
||||
| `` g `` | View upstream reset options | |
|
||||
| `` D `` | Reset | View reset options for working tree (e.g. nuking the working tree). |
|
||||
| `` ` `` | Toggle file tree view | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` M `` | Open external merge tool | Run `git mergetool`. |
|
||||
| `` f `` | Pobierz | Fetch changes from remote. |
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Pliki commita
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy the committed file name to the clipboard
|
||||
<kbd>c</kbd>: Plik wybierania
|
||||
<kbd>d</kbd>: Porzuć zmiany commita dla tego pliku
|
||||
<kbd>o</kbd>: Otwórz plik
|
||||
<kbd>e</kbd>: Edytuj plik
|
||||
<kbd><space></kbd>: Toggle file included in patch
|
||||
<kbd>a</kbd>: Toggle all files included in patch
|
||||
<kbd><enter></kbd>: Enter file to add selected lines to the patch (or toggle directory collapsed)
|
||||
<kbd>`</kbd>: Toggle file tree view
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy path to clipboard | |
|
||||
| `` c `` | Przełącz | Plik wybierania |
|
||||
| `` d `` | Remove | Porzuć zmiany commita dla tego pliku |
|
||||
| `` o `` | Otwórz plik | Open file in default application. |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <space> `` | Toggle file included in patch | Toggle whether the file is included in the custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` a `` | Toggle all files | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` <enter> `` | Enter file / Toggle directory collapsed | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
|
||||
| `` ` `` | Toggle file tree view | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Poczekalnia
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: Poprzedni kawałek
|
||||
<kbd><right></kbd>: Następny kawałek
|
||||
<kbd>v</kbd>: Toggle drag select
|
||||
<kbd>V</kbd>: Toggle drag select
|
||||
<kbd>a</kbd>: Toggle select hunk
|
||||
<kbd><c-o></kbd>: Copy the selected text to the clipboard
|
||||
<kbd>o</kbd>: Otwórz plik
|
||||
<kbd>e</kbd>: Edytuj plik
|
||||
<kbd><esc></kbd>: Wróć do panelu plików
|
||||
<kbd><tab></kbd>: Switch to other panel (staged/unstaged changes)
|
||||
<kbd><space></kbd>: Toggle line staged / unstaged
|
||||
<kbd>d</kbd>: Discard change (git reset)
|
||||
<kbd>E</kbd>: Edit hunk
|
||||
<kbd>c</kbd>: Zatwierdź zmiany
|
||||
<kbd>w</kbd>: Zatwierdź zmiany bez skryptu pre-commit
|
||||
<kbd>C</kbd>: Zatwierdź zmiany używając edytora
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | Poprzedni kawałek | |
|
||||
| `` <right> `` | Następny kawałek | |
|
||||
| `` v `` | Toggle range select | |
|
||||
| `` a `` | Select hunk | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | Copy selected text to clipboard | |
|
||||
| `` <space> `` | Przełącz stan poczekalni | Toggle selection staged / unstaged. |
|
||||
| `` d `` | Discard | When unstaged change is selected, discard the change using `git reset`. When staged change is selected, unstage the change. |
|
||||
| `` o `` | Otwórz plik | Open file in default application. |
|
||||
| `` e `` | Edytuj plik | Open file in external editor. |
|
||||
| `` <esc> `` | Wróć do panelu plików | |
|
||||
| `` <tab> `` | Switch view | Switch to other view (staged/unstaged changes). |
|
||||
| `` E `` | Edit hunk | Edit selected hunk in external editor. |
|
||||
| `` c `` | Zatwierdź zmiany | Commit staged changes. |
|
||||
| `` w `` | Zatwierdź zmiany bez skryptu pre-commit | |
|
||||
| `` C `` | Zatwierdź zmiany używając edytora | |
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Reflog
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy commit SHA to clipboard
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: Checkout commit
|
||||
<kbd>y</kbd>: Copy commit attribute
|
||||
<kbd>o</kbd>: Open commit in browser
|
||||
<kbd>n</kbd>: Create new branch off of commit
|
||||
<kbd>g</kbd>: Wyświetl opcje resetu
|
||||
<kbd>c</kbd>: Kopiuj commit (przebieranie)
|
||||
<kbd>C</kbd>: Kopiuj zakres commitów (przebieranie)
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (copied) commits selection
|
||||
<kbd><enter></kbd>: View commits
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy commit SHA to clipboard | |
|
||||
| `` <space> `` | Przełącz | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | Open commit in browser | |
|
||||
| `` n `` | Create new branch off of commit | |
|
||||
| `` g `` | Wyświetl opcje resetu | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | Kopiuj commit (przebieranie) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | Reset copied (cherry-picked) commits selection | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | View commits | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Remote branches
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy branch name to clipboard
|
||||
<kbd><space></kbd>: Przełącz
|
||||
<kbd>n</kbd>: Nowa gałąź
|
||||
<kbd>M</kbd>: Scal do obecnej gałęzi
|
||||
<kbd>r</kbd>: Zmiana bazy gałęzi
|
||||
<kbd>d</kbd>: Usuń gałąź
|
||||
<kbd>u</kbd>: Set as upstream of checked-out branch
|
||||
<kbd>g</kbd>: Wyświetl opcje resetu
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: View commits
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy branch name to clipboard | |
|
||||
| `` <space> `` | Przełącz | Checkout a new local branch based on the selected remote branch. The new branch will track the remote branch. |
|
||||
| `` n `` | Nowa gałąź | |
|
||||
| `` M `` | Scal do obecnej gałęzi | Merge selected branch into currently checked out branch. |
|
||||
| `` r `` | Zmiana bazy gałęzi | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||
| `` u `` | Set as upstream | Set the selected remote branch as the upstream of the checked-out branch. |
|
||||
| `` s `` | Sort order | |
|
||||
| `` g `` | Wyświetl opcje resetu | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | View commits | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Remotes
|
||||
|
||||
<pre>
|
||||
<kbd>f</kbd>: Fetch remote
|
||||
<kbd>n</kbd>: Add new remote
|
||||
<kbd>d</kbd>: Remove remote
|
||||
<kbd>e</kbd>: Edit remote
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | View branches | |
|
||||
| `` n `` | New remote | |
|
||||
| `` d `` | Remove | Remove the selected remote. Any local branches tracking a remote branch from the remote will be unaffected. |
|
||||
| `` e `` | Edit | Edit the selected remote's name or URL. |
|
||||
| `` f `` | Pobierz | Fetch updates from the remote repository. This retrieves new commits and branches without merging them into your local branches. |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Scalanie
|
||||
|
||||
<pre>
|
||||
<kbd>e</kbd>: Edytuj plik
|
||||
<kbd>o</kbd>: Otwórz plik
|
||||
<kbd><left></kbd>: Poprzedni konflikt
|
||||
<kbd><right></kbd>: Następny konflikt
|
||||
<kbd><up></kbd>: Wybierz poprzedni kawałek
|
||||
<kbd><down></kbd>: Wybierz następny kawałek
|
||||
<kbd>z</kbd>: Cofnij
|
||||
<kbd>M</kbd>: Open external merge tool (git mergetool)
|
||||
<kbd><space></kbd>: Wybierz kawałek
|
||||
<kbd>b</kbd>: Wybierz oba kawałki
|
||||
<kbd><esc></kbd>: Wróć do panelu plików
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Wybierz kawałek | |
|
||||
| `` b `` | Wybierz oba kawałki | |
|
||||
| `` <up> `` | Wybierz poprzedni kawałek | |
|
||||
| `` <down> `` | Wybierz następny kawałek | |
|
||||
| `` <left> `` | Poprzedni konflikt | |
|
||||
| `` <right> `` | Następny konflikt | |
|
||||
| `` z `` | Cofnij | Undo last merge conflict resolution. |
|
||||
| `` e `` | Edytuj plik | Open file in external editor. |
|
||||
| `` o `` | Otwórz plik | Open file in default application. |
|
||||
| `` M `` | Open external merge tool | Run `git mergetool`. |
|
||||
| `` <esc> `` | Wróć do panelu plików | |
|
||||
|
||||
## Schowek
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: Zastosuj
|
||||
<kbd>g</kbd>: Wyciągnij
|
||||
<kbd>d</kbd>: Porzuć
|
||||
<kbd>n</kbd>: Nowa gałąź
|
||||
<kbd>r</kbd>: Rename stash
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: Przeglądaj pliki commita
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Zastosuj | Apply the stash entry to your working directory. |
|
||||
| `` g `` | Wyciągnij | Apply the stash entry to your working directory and remove the stash entry. |
|
||||
| `` d `` | Porzuć | Remove the stash entry from the stash list. |
|
||||
| `` n `` | Nowa gałąź | Create a new branch from the selected stash entry. This works by git checking out the commit that the stash entry was created from, creating a new branch from that commit, then applying the stash entry to the new branch as an additional commit. |
|
||||
| `` r `` | Rename stash | |
|
||||
| `` <enter> `` | Przeglądaj pliki commita | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Status
|
||||
|
||||
<pre>
|
||||
<kbd>o</kbd>: Otwórz konfigurację
|
||||
<kbd>e</kbd>: Edytuj konfigurację
|
||||
<kbd>u</kbd>: Sprawdź aktualizacje
|
||||
<kbd><enter></kbd>: Switch to a recent repo
|
||||
<kbd>a</kbd>: Pokaż wszystkie logi gałęzi
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` o `` | Otwórz konfigurację | Open file in default application. |
|
||||
| `` e `` | Edytuj konfigurację | Open file in external editor. |
|
||||
| `` u `` | Sprawdź aktualizacje | |
|
||||
| `` <enter> `` | Switch to a recent repo | |
|
||||
| `` a `` | Pokaż wszystkie logi gałęzi | |
|
||||
|
||||
## Sub-commits
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy commit SHA to clipboard
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: Checkout commit
|
||||
<kbd>y</kbd>: Copy commit attribute
|
||||
<kbd>o</kbd>: Open commit in browser
|
||||
<kbd>n</kbd>: Create new branch off of commit
|
||||
<kbd>g</kbd>: Wyświetl opcje resetu
|
||||
<kbd>c</kbd>: Kopiuj commit (przebieranie)
|
||||
<kbd>C</kbd>: Kopiuj zakres commitów (przebieranie)
|
||||
<kbd><c-r></kbd>: Reset cherry-picked (copied) commits selection
|
||||
<kbd><enter></kbd>: Przeglądaj pliki commita
|
||||
<kbd>/</kbd>: Search the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy commit SHA to clipboard | |
|
||||
| `` <space> `` | Przełącz | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | Open commit in browser | |
|
||||
| `` n `` | Create new branch off of commit | |
|
||||
| `` g `` | Wyświetl opcje resetu | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | Kopiuj commit (przebieranie) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | Reset copied (cherry-picked) commits selection | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | Przeglądaj pliki commita | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Search the current view by text | |
|
||||
|
||||
## Submodules
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Copy submodule name to clipboard
|
||||
<kbd><enter></kbd>: Enter submodule
|
||||
<kbd><space></kbd>: Enter submodule
|
||||
<kbd>d</kbd>: Remove submodule
|
||||
<kbd>u</kbd>: Update submodule
|
||||
<kbd>n</kbd>: Add new submodule
|
||||
<kbd>e</kbd>: Update submodule URL
|
||||
<kbd>i</kbd>: Initialize submodule
|
||||
<kbd>b</kbd>: View bulk submodule options
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Copy submodule name to clipboard | |
|
||||
| `` <enter> `` | Enter | Enter submodule. After entering the submodule, you can press `<esc>` to escape back to the parent repo. |
|
||||
| `` d `` | Remove | Remove the selected submodule and its corresponding directory. |
|
||||
| `` u `` | Update | Update selected submodule. |
|
||||
| `` n `` | New submodule | |
|
||||
| `` e `` | Update submodule URL | |
|
||||
| `` i `` | Initialize | Initialize the selected submodule to prepare for fetching. You probably want to follow this up by invoking the 'update' action to fetch the submodule. |
|
||||
| `` b `` | View bulk submodule options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Tags
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: Przełącz
|
||||
<kbd>d</kbd>: Delete tag
|
||||
<kbd>P</kbd>: Push tag
|
||||
<kbd>n</kbd>: Create tag
|
||||
<kbd>g</kbd>: Wyświetl opcje resetu
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: View commits
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Przełącz | Checkout the selected tag tag as a detached HEAD. |
|
||||
| `` n `` | New tag | Create new tag from current commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` d `` | Delete | View delete options for local/remote tag. |
|
||||
| `` P `` | Push tag | Push the selected tag to a remote. You'll be prompted to select a remote. |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | View commits | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Worktrees
|
||||
|
||||
<pre>
|
||||
<kbd>n</kbd>: Create worktree
|
||||
<kbd><space></kbd>: Switch to worktree
|
||||
<kbd><enter></kbd>: Switch to worktree
|
||||
<kbd>o</kbd>: Open in editor
|
||||
<kbd>d</kbd>: Remove worktree
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` n `` | New worktree | |
|
||||
| `` <space> `` | Switch | Switch to the selected worktree. |
|
||||
| `` o `` | Open in editor | |
|
||||
| `` d `` | Remove | Remove the selected worktree. This will both delete the worktree's directory, as well as metadata about the worktree in the .git directory. |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Zwykłe
|
||||
|
||||
<pre>
|
||||
<kbd>mouse wheel down</kbd>: Przewiń w dół (fn+up)
|
||||
<kbd>mouse wheel up</kbd>: Przewiń w górę (fn+down)
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` mouse wheel down (fn+up) `` | Przewiń w dół | |
|
||||
| `` mouse wheel up (fn+down) `` | Przewiń w górę | |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go run scripts/cheatsheet/main.go generate` from the project root._
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go generate ./...` from the project root._
|
||||
|
||||
# Lazygit Связки клавиш
|
||||
|
||||
@@ -6,348 +6,358 @@ _Связки клавиш_
|
||||
|
||||
## Глобальные сочетания клавиш
|
||||
|
||||
<pre>
|
||||
<kbd><c-r></kbd>: Переключиться на последний репозиторий
|
||||
<kbd><pgup></kbd>: Прокрутить вверх главную панель (fn+up/shift+k)
|
||||
<kbd><pgdown></kbd>: Прокрутить вниз главную панель (fn+down/shift+j)
|
||||
<kbd>@</kbd>: Открыть меню журнала команд
|
||||
<kbd>}</kbd>: Увеличить размер контекста, отображаемого вокруг изменений в просмотрщике сравнении
|
||||
<kbd>{</kbd>: Уменьшите размер контекста, отображаемого вокруг изменений в просмотрщике сравнении
|
||||
<kbd>:</kbd>: Выполнить пользовательскую команду
|
||||
<kbd><c-p></kbd>: Просмотреть пользовательские параметры патча
|
||||
<kbd>m</kbd>: Просмотреть параметры слияния/перебазирования
|
||||
<kbd>R</kbd>: Обновить
|
||||
<kbd>+</kbd>: Следующий режим экрана (нормальный/полуэкранный/полноэкранный)
|
||||
<kbd>_</kbd>: Предыдущий режим экрана
|
||||
<kbd>?</kbd>: Открыть меню
|
||||
<kbd><c-s></kbd>: Просмотреть параметры фильтрации по пути
|
||||
<kbd>W</kbd>: Открыть меню сравнении
|
||||
<kbd><c-e></kbd>: Открыть меню сравнении
|
||||
<kbd><c-w></kbd>: Переключить отображение изменении пробелов в просмотрщике сравнении
|
||||
<kbd>z</kbd>: Отменить (через reflog) (экспериментальный)
|
||||
<kbd><c-z></kbd>: Повторить (через reflog) (экспериментальный)
|
||||
<kbd>P</kbd>: Отправить изменения
|
||||
<kbd>p</kbd>: Получить и слить изменения
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-r> `` | Переключиться на последний репозиторий | |
|
||||
| `` <pgup> (fn+up/shift+k) `` | Прокрутить вверх главную панель | |
|
||||
| `` <pgdown> (fn+down/shift+j) `` | Прокрутить вниз главную панель | |
|
||||
| `` @ `` | Открыть меню журнала команд | View options for the command log e.g. show/hide the command log and focus the command log. |
|
||||
| `` P `` | Отправить изменения | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` p `` | Получить и слить изменения | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` } `` | Увеличить размер контекста, отображаемого вокруг изменений в просмотрщике сравнении | Increase the amount of the context shown around changes in the diff view. |
|
||||
| `` { `` | Уменьшите размер контекста, отображаемого вокруг изменений в просмотрщике сравнении | Decrease the amount of the context shown around changes in the diff view. |
|
||||
| `` : `` | Выполнить пользовательскую команду | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
|
||||
| `` <c-p> `` | Просмотреть пользовательские параметры патча | |
|
||||
| `` m `` | Просмотреть параметры слияния/перебазирования | View options to abort/continue/skip the current merge/rebase. |
|
||||
| `` R `` | Обновить | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. |
|
||||
| `` + `` | Следующий режим экрана (нормальный/полуэкранный/полноэкранный) | |
|
||||
| `` _ `` | Предыдущий режим экрана | |
|
||||
| `` ? `` | Открыть меню | |
|
||||
| `` <c-s> `` | Просмотреть параметры фильтрации по пути | View options for filtering the commit log by a file path, so that only commits relating to that path are shown. |
|
||||
| `` W `` | Открыть меню сравнении | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` <c-e> `` | Открыть меню сравнении | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` q `` | Выйти | |
|
||||
| `` <esc> `` | Отменить | |
|
||||
| `` <c-w> `` | Переключить отображение изменении пробелов в просмотрщике сравнении | Toggle whether or not whitespace changes are shown in the diff view. |
|
||||
| `` z `` | Отменить (через reflog) (экспериментальный) | Журнал ссылок (reflog) будет использоваться для определения того, какую команду git запустить, чтобы отменить последнюю команду git. Сюда не входят изменения в рабочем дереве; учитываются только коммиты. |
|
||||
| `` <c-z> `` | Повторить (через reflog) (экспериментальный) | Журнал ссылок (reflog) будет использоваться для определения того, какую команду git нужно запустить, чтобы повторить последнюю команду git. Сюда не входят изменения в рабочем дереве; учитываются только коммиты. |
|
||||
|
||||
## Навигация по панели списка
|
||||
|
||||
<pre>
|
||||
<kbd>,</kbd>: Предыдущая страница
|
||||
<kbd>.</kbd>: Следующая страница
|
||||
<kbd><</kbd>: Пролистать наверх
|
||||
<kbd>></kbd>: Прокрутить вниз
|
||||
<kbd>/</kbd>: Найти
|
||||
<kbd>H</kbd>: Прокрутить влево
|
||||
<kbd>L</kbd>: Прокрутить вправо
|
||||
<kbd>]</kbd>: Следующая вкладка
|
||||
<kbd>[</kbd>: Предыдущая вкладка
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` , `` | Предыдущая страница | |
|
||||
| `` . `` | Следующая страница | |
|
||||
| `` < `` | Пролистать наверх | |
|
||||
| `` > `` | Прокрутить вниз | |
|
||||
| `` v `` | Переключить выборку перетаскивания | |
|
||||
| `` <s-down> `` | Range select down | |
|
||||
| `` <s-up> `` | Range select up | |
|
||||
| `` / `` | Найти | |
|
||||
| `` H `` | Прокрутить влево | |
|
||||
| `` L `` | Прокрутить вправо | |
|
||||
| `` ] `` | Следующая вкладка | |
|
||||
| `` [ `` | Предыдущая вкладка | |
|
||||
|
||||
## Worktrees
|
||||
|
||||
<pre>
|
||||
<kbd>n</kbd>: Create worktree
|
||||
<kbd><space></kbd>: Switch to worktree
|
||||
<kbd><enter></kbd>: Switch to worktree
|
||||
<kbd>o</kbd>: Open in editor
|
||||
<kbd>d</kbd>: Remove worktree
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` n `` | New worktree | |
|
||||
| `` <space> `` | Switch | Switch to the selected worktree. |
|
||||
| `` o `` | Open in editor | |
|
||||
| `` d `` | Remove | Remove the selected worktree. This will both delete the worktree's directory, as well as metadata about the worktree in the .git directory. |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Главная панель (Индексирование)
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: Выбрать предыдущую часть
|
||||
<kbd><right></kbd>: Выбрать следующую часть
|
||||
<kbd>v</kbd>: Переключить выборку перетаскивания
|
||||
<kbd>V</kbd>: Переключить выборку перетаскивания
|
||||
<kbd>a</kbd>: Переключить выборку частей
|
||||
<kbd><c-o></kbd>: Скопировать выделенный текст в буфер обмена
|
||||
<kbd>o</kbd>: Открыть файл
|
||||
<kbd>e</kbd>: Редактировать файл
|
||||
<kbd><esc></kbd>: Вернуться к панели файлов
|
||||
<kbd><tab></kbd>: Переключиться на другую панель (проиндексированные/непроиндексированные изменения)
|
||||
<kbd><space></kbd>: Переключить строку в проиндексированные / непроиндексированные
|
||||
<kbd>d</kbd>: Отменить изменение (git reset)
|
||||
<kbd>E</kbd>: Изменить эту часть
|
||||
<kbd>c</kbd>: Сохранить изменения
|
||||
<kbd>w</kbd>: Закоммитить изменения без предварительного хука коммита
|
||||
<kbd>C</kbd>: Сохранить изменения с помощью редактора git
|
||||
<kbd>/</kbd>: Найти
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | Выбрать предыдущую часть | |
|
||||
| `` <right> `` | Выбрать следующую часть | |
|
||||
| `` v `` | Переключить выборку перетаскивания | |
|
||||
| `` a `` | Переключить выборку частей | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | Скопировать выделенный текст в буфер обмена | |
|
||||
| `` <space> `` | Переключить индекс | Переключить строку в проиндексированные / непроиндексированные |
|
||||
| `` d `` | Отменить изменение (git reset) | When unstaged change is selected, discard the change using `git reset`. When staged change is selected, unstage the change. |
|
||||
| `` o `` | Открыть файл | Open file in default application. |
|
||||
| `` e `` | Редактировать файл | Open file in external editor. |
|
||||
| `` <esc> `` | Вернуться к панели файлов | |
|
||||
| `` <tab> `` | Переключиться на другую панель (проиндексированные/непроиндексированные изменения) | Switch to other view (staged/unstaged changes). |
|
||||
| `` E `` | Изменить эту часть | Edit selected hunk in external editor. |
|
||||
| `` c `` | Сохранить изменения | Commit staged changes. |
|
||||
| `` w `` | Закоммитить изменения без предварительного хука коммита | |
|
||||
| `` C `` | Сохранить изменения с помощью редактора git | |
|
||||
| `` / `` | Найти | |
|
||||
|
||||
## Главная панель (Обычный)
|
||||
|
||||
<pre>
|
||||
<kbd>mouse wheel down</kbd>: Прокрутить вниз (fn+up)
|
||||
<kbd>mouse wheel up</kbd>: Прокрутить вверх (fn+down)
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` mouse wheel down (fn+up) `` | Прокрутить вниз | |
|
||||
| `` mouse wheel up (fn+down) `` | Прокрутить вверх | |
|
||||
|
||||
## Главная панель (Слияние)
|
||||
|
||||
<pre>
|
||||
<kbd>e</kbd>: Редактировать файл
|
||||
<kbd>o</kbd>: Открыть файл
|
||||
<kbd><left></kbd>: Выбрать предыдущий конфликт
|
||||
<kbd><right></kbd>: Выбрать следующий конфликт
|
||||
<kbd><up></kbd>: Выбрать предыдущую часть
|
||||
<kbd><down></kbd>: Выбрать следующую часть
|
||||
<kbd>z</kbd>: Отменить
|
||||
<kbd>M</kbd>: Открыть внешний инструмент слияния (git mergetool)
|
||||
<kbd><space></kbd>: Выбрать эту часть
|
||||
<kbd>b</kbd>: Выбрать все части
|
||||
<kbd><esc></kbd>: Вернуться к панели файлов
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Выбрать эту часть | |
|
||||
| `` b `` | Выбрать все части | |
|
||||
| `` <up> `` | Выбрать предыдущую часть | |
|
||||
| `` <down> `` | Выбрать следующую часть | |
|
||||
| `` <left> `` | Выбрать предыдущий конфликт | |
|
||||
| `` <right> `` | Выбрать следующий конфликт | |
|
||||
| `` z `` | Отменить | Undo last merge conflict resolution. |
|
||||
| `` e `` | Редактировать файл | Open file in external editor. |
|
||||
| `` o `` | Открыть файл | Open file in default application. |
|
||||
| `` M `` | Открыть внешний инструмент слияния (git mergetool) | Run `git mergetool`. |
|
||||
| `` <esc> `` | Вернуться к панели файлов | |
|
||||
|
||||
## Главная панель (сборка патчей)
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: Выбрать предыдущую часть
|
||||
<kbd><right></kbd>: Выбрать следующую часть
|
||||
<kbd>v</kbd>: Переключить выборку перетаскивания
|
||||
<kbd>V</kbd>: Переключить выборку перетаскивания
|
||||
<kbd>a</kbd>: Переключить выборку частей
|
||||
<kbd><c-o></kbd>: Скопировать выделенный текст в буфер обмена
|
||||
<kbd>o</kbd>: Открыть файл
|
||||
<kbd>e</kbd>: Редактировать файл
|
||||
<kbd><space></kbd>: Добавить/удалить строку(и) для патча
|
||||
<kbd><esc></kbd>: Выйти из сборщика пользовательских патчей
|
||||
<kbd>/</kbd>: Найти
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | Выбрать предыдущую часть | |
|
||||
| `` <right> `` | Выбрать следующую часть | |
|
||||
| `` v `` | Переключить выборку перетаскивания | |
|
||||
| `` a `` | Переключить выборку частей | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | Скопировать выделенный текст в буфер обмена | |
|
||||
| `` o `` | Открыть файл | Open file in default application. |
|
||||
| `` e `` | Редактировать файл | Open file in external editor. |
|
||||
| `` <space> `` | Добавить/удалить строку(и) для патча | |
|
||||
| `` <esc> `` | Выйти из сборщика пользовательских патчей | |
|
||||
| `` / `` | Найти | |
|
||||
|
||||
## Журнал ссылок (Reflog)
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Скопировать SHA коммита в буфер обмена
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: Переключить коммит
|
||||
<kbd>y</kbd>: Скопировать атрибут коммита
|
||||
<kbd>o</kbd>: Открыть коммит в браузере
|
||||
<kbd>n</kbd>: Создать новую ветку с этого коммита
|
||||
<kbd>g</kbd>: Просмотреть параметры сброса
|
||||
<kbd>c</kbd>: Скопировать отобранные коммит (cherry-pick)
|
||||
<kbd>C</kbd>: Скопировать несколько отобранных коммитов (cherry-pick)
|
||||
<kbd><c-r></kbd>: Сбросить отобранную (скопированную | cherry-picked) выборку коммитов
|
||||
<kbd><enter></kbd>: Просмотреть коммиты
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Скопировать SHA коммита в буфер обмена | |
|
||||
| `` <space> `` | Переключить | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Скопировать атрибут коммита | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | Открыть коммит в браузере | |
|
||||
| `` n `` | Создать новую ветку с этого коммита | |
|
||||
| `` g `` | Просмотреть параметры сброса | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | Скопировать отобранные коммит (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | Сбросить отобранную (скопированную | cherry-picked) выборку коммитов | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | Просмотреть коммиты | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Коммиты
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Скопировать SHA коммита в буфер обмена
|
||||
<kbd><c-r></kbd>: Сбросить отобранную (скопированную | cherry-picked) выборку коммитов
|
||||
<kbd>b</kbd>: Просмотреть параметры бинарного поиска
|
||||
<kbd>s</kbd>: Объединить несколько коммитов в один нижний
|
||||
<kbd>f</kbd>: Объединить несколько коммитов в один отбросив сообщение коммита
|
||||
<kbd>r</kbd>: Перефразировать коммит
|
||||
<kbd>R</kbd>: Переписать коммит с помощью редактора
|
||||
<kbd>d</kbd>: Удалить коммит
|
||||
<kbd>e</kbd>: Изменить коммит
|
||||
<kbd>p</kbd>: Выбрать коммит (в середине перебазирования)
|
||||
<kbd>F</kbd>: Создать fixup коммит для этого коммита
|
||||
<kbd>S</kbd>: Объединить все 'fixup!' коммиты выше в выбранный коммит (автосохранение)
|
||||
<kbd><c-j></kbd>: Переместить коммит вниз на один
|
||||
<kbd><c-k></kbd>: Переместить коммит вверх на один
|
||||
<kbd>v</kbd>: Вставить отобранные коммиты (cherry-pick)
|
||||
<kbd>B</kbd>: Mark commit as base commit for rebase
|
||||
<kbd>A</kbd>: Править последний коммит с проиндексированными изменениями
|
||||
<kbd>a</kbd>: Установить/убрать автора коммита
|
||||
<kbd>t</kbd>: Отменить коммит
|
||||
<kbd>T</kbd>: Пометить коммит тегом
|
||||
<kbd><c-l></kbd>: Открыть меню журнала
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: Переключить коммит
|
||||
<kbd>y</kbd>: Скопировать атрибут коммита
|
||||
<kbd>o</kbd>: Открыть коммит в браузере
|
||||
<kbd>n</kbd>: Создать новую ветку с этого коммита
|
||||
<kbd>g</kbd>: Просмотреть параметры сброса
|
||||
<kbd>c</kbd>: Скопировать отобранные коммит (cherry-pick)
|
||||
<kbd>C</kbd>: Скопировать несколько отобранных коммитов (cherry-pick)
|
||||
<kbd><enter></kbd>: Просмотреть файлы выбранного элемента
|
||||
<kbd>/</kbd>: Найти
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Скопировать SHA коммита в буфер обмена | |
|
||||
| `` <c-r> `` | Сбросить отобранную (скопированную | cherry-picked) выборку коммитов | |
|
||||
| `` b `` | Просмотреть параметры бинарного поиска | |
|
||||
| `` s `` | Объединить коммиты (Squash) | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. |
|
||||
| `` f `` | Объединить несколько коммитов в один отбросив сообщение коммита (Fixup) | Meld the selected commit into the commit below it. Similar to fixup, but the selected commit's message will be discarded. |
|
||||
| `` r `` | Перефразировать коммит | Reword the selected commit's message. |
|
||||
| `` R `` | Переписать коммит с помощью редактора | |
|
||||
| `` d `` | Удалить коммит | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. |
|
||||
| `` e `` | Edit (start interactive rebase) | Изменить коммит |
|
||||
| `` i `` | Start interactive rebase | Start an interactive rebase for the commits on your branch. This will include all commits from the HEAD commit down to the first merge commit or main branch commit.
|
||||
If you would instead like to start an interactive rebase from the selected commit, press `e`. |
|
||||
| `` p `` | Pick | Выбрать коммит (в середине перебазирования) |
|
||||
| `` F `` | Create fixup commit | Создать fixup коммит для этого коммита |
|
||||
| `` S `` | Apply fixup commits | Объединить все 'fixup!' коммиты выше в выбранный коммит (автосохранение) |
|
||||
| `` <c-j> `` | Переместить коммит вниз на один | |
|
||||
| `` <c-k> `` | Переместить коммит вверх на один | |
|
||||
| `` V `` | Вставить отобранные коммиты (cherry-pick) | |
|
||||
| `` B `` | Mark as base commit for rebase | Select a base commit for the next rebase. When you rebase onto a branch, only commits above the base commit will be brought across. This uses the `git rebase --onto` command. |
|
||||
| `` A `` | Amend | Править последний коммит с проиндексированными изменениями |
|
||||
| `` a `` | Установить/убрать автора коммита | Set/Reset commit author or set co-author. |
|
||||
| `` t `` | Revert | Create a revert commit for the selected commit, which applies the selected commit's changes in reverse. |
|
||||
| `` T `` | Пометить коммит тегом | Create a new tag pointing at the selected commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` <c-l> `` | Открыть меню журнала | View options for commit log e.g. changing sort order, hiding the git graph, showing the whole git graph. |
|
||||
| `` <space> `` | Переключить | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Скопировать атрибут коммита | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | Открыть коммит в браузере | |
|
||||
| `` n `` | Создать новую ветку с этого коммита | |
|
||||
| `` g `` | Просмотреть параметры сброса | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | Скопировать отобранные коммит (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | Просмотреть файлы выбранного элемента | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Найти | |
|
||||
|
||||
## Локальные Ветки
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Скопировать название ветки в буфер обмена
|
||||
<kbd>i</kbd>: Показать параметры git-flow
|
||||
<kbd><space></kbd>: Переключить
|
||||
<kbd>n</kbd>: Новая ветка
|
||||
<kbd>o</kbd>: Создать запрос на принятие изменений
|
||||
<kbd>O</kbd>: Создать параметры запроса принятие изменений
|
||||
<kbd><c-y></kbd>: Скопировать URL запроса на принятие изменений в буфер обмена
|
||||
<kbd>c</kbd>: Переключить по названию
|
||||
<kbd>F</kbd>: Принудительное переключение
|
||||
<kbd>d</kbd>: Удалить ветку
|
||||
<kbd>r</kbd>: Перебазировать переключённую ветку на эту ветку
|
||||
<kbd>M</kbd>: Слияние с текущей переключённой веткой
|
||||
<kbd>f</kbd>: Перемотать эту ветку вперёд из её upstream-ветки
|
||||
<kbd>T</kbd>: Создать тег
|
||||
<kbd>g</kbd>: Просмотреть параметры сброса
|
||||
<kbd>R</kbd>: Переименовать ветку
|
||||
<kbd>u</kbd>: Установить/убрать upstream-ветку
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: Просмотреть коммиты
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Скопировать название ветки в буфер обмена | |
|
||||
| `` i `` | Показать параметры git-flow | |
|
||||
| `` <space> `` | Переключить | Checkout selected item. |
|
||||
| `` n `` | Новая ветка | |
|
||||
| `` o `` | Создать запрос на принятие изменений | |
|
||||
| `` O `` | Создать параметры запроса принятие изменений | |
|
||||
| `` <c-y> `` | Скопировать URL запроса на принятие изменений в буфер обмена | |
|
||||
| `` c `` | Переключить по названию | Checkout by name. In the input box you can enter '-' to switch to the last branch. |
|
||||
| `` F `` | Принудительное переключение | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||
| `` r `` | Перебазировать переключённую ветку на эту ветку | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` M `` | Слияние с текущей переключённой веткой | Merge selected branch into currently checked out branch. |
|
||||
| `` f `` | Перемотать эту ветку вперёд из её upstream-ветки | Fast-forward selected branch from its upstream. |
|
||||
| `` T `` | Создать тег | |
|
||||
| `` s `` | Порядок сортировки | |
|
||||
| `` g `` | Просмотреть параметры сброса | |
|
||||
| `` R `` | Переименовать ветку | |
|
||||
| `` u `` | View upstream options | View options relating to the branch's upstream e.g. setting/unsetting the upstream and resetting to the upstream. |
|
||||
| `` <enter> `` | Просмотреть коммиты | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Меню
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: Выполнить
|
||||
<kbd><esc></kbd>: Закрыть
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | Выполнить | |
|
||||
| `` <esc> `` | Закрыть | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Панель Подтверждения
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: Подтвердить
|
||||
<kbd><esc></kbd>: Закрыть/отменить
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | Подтвердить | |
|
||||
| `` <esc> `` | Закрыть/отменить | |
|
||||
|
||||
## Подкоммиты
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Скопировать SHA коммита в буфер обмена
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: Переключить коммит
|
||||
<kbd>y</kbd>: Скопировать атрибут коммита
|
||||
<kbd>o</kbd>: Открыть коммит в браузере
|
||||
<kbd>n</kbd>: Создать новую ветку с этого коммита
|
||||
<kbd>g</kbd>: Просмотреть параметры сброса
|
||||
<kbd>c</kbd>: Скопировать отобранные коммит (cherry-pick)
|
||||
<kbd>C</kbd>: Скопировать несколько отобранных коммитов (cherry-pick)
|
||||
<kbd><c-r></kbd>: Сбросить отобранную (скопированную | cherry-picked) выборку коммитов
|
||||
<kbd><enter></kbd>: Просмотреть файлы выбранного элемента
|
||||
<kbd>/</kbd>: Найти
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Скопировать SHA коммита в буфер обмена | |
|
||||
| `` <space> `` | Переключить | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Скопировать атрибут коммита | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | Открыть коммит в браузере | |
|
||||
| `` n `` | Создать новую ветку с этого коммита | |
|
||||
| `` g `` | Просмотреть параметры сброса | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | Скопировать отобранные коммит (cherry-pick) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | Сбросить отобранную (скопированную | cherry-picked) выборку коммитов | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | Просмотреть файлы выбранного элемента | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Найти | |
|
||||
|
||||
## Подмодули
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Скопировать название подмодуля в буфер обмена
|
||||
<kbd><enter></kbd>: Ввести подмодуль
|
||||
<kbd><space></kbd>: Ввести подмодуль
|
||||
<kbd>d</kbd>: Удалить подмодуль
|
||||
<kbd>u</kbd>: Обновить подмодуль
|
||||
<kbd>n</kbd>: Добавить новый подмодуль
|
||||
<kbd>e</kbd>: Обновить URL подмодуля
|
||||
<kbd>i</kbd>: Инициализировать подмодуль
|
||||
<kbd>b</kbd>: Просмотреть параметры массового подмодуля
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Скопировать название подмодуля в буфер обмена | |
|
||||
| `` <enter> `` | Enter | Ввести подмодуль |
|
||||
| `` d `` | Remove | Remove the selected submodule and its corresponding directory. |
|
||||
| `` u `` | Update | Обновить подмодуль |
|
||||
| `` n `` | Добавить новый подмодуль | |
|
||||
| `` e `` | Обновить URL подмодуля | |
|
||||
| `` i `` | Initialize | Инициализировать подмодуль |
|
||||
| `` b `` | Просмотреть параметры массового подмодуля | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Сводка коммита
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: Подтвердить
|
||||
<kbd><esc></kbd>: Закрыть
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | Подтвердить | |
|
||||
| `` <esc> `` | Закрыть | |
|
||||
|
||||
## Сохранить Изменения Файлов
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Скопировать закомиченное имя файла в буфер обмена
|
||||
<kbd>c</kbd>: Переключить файл
|
||||
<kbd>d</kbd>: Отменить изменения коммита в этом файле
|
||||
<kbd>o</kbd>: Открыть файл
|
||||
<kbd>e</kbd>: Редактировать файл
|
||||
<kbd><space></kbd>: Переключить файлы включённые в патч
|
||||
<kbd>a</kbd>: Переключить все файлы, включённые в патч
|
||||
<kbd><enter></kbd>: Введите файл, чтобы добавить выбранные строки в патч (или свернуть каталог переключения)
|
||||
<kbd>`</kbd>: Переключить вид дерева файлов
|
||||
<kbd>/</kbd>: Найти
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Скопировать название файла в буфер обмена | |
|
||||
| `` c `` | Переключить | Переключить файл |
|
||||
| `` d `` | Remove | Отменить изменения коммита в этом файле |
|
||||
| `` o `` | Открыть файл | Open file in default application. |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <space> `` | Переключить файлы включённые в патч | Toggle whether the file is included in the custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` a `` | Переключить все файлы, включённые в патч | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` <enter> `` | Введите файл, чтобы добавить выбранные строки в патч (или свернуть каталог переключения) | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
|
||||
| `` ` `` | Переключить вид дерева файлов | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` / `` | Найти | |
|
||||
|
||||
## Статус
|
||||
|
||||
<pre>
|
||||
<kbd>o</kbd>: Открыть файл конфигурации
|
||||
<kbd>e</kbd>: Редактировать файл конфигурации
|
||||
<kbd>u</kbd>: Проверить обновления
|
||||
<kbd><enter></kbd>: Переключиться на последний репозиторий
|
||||
<kbd>a</kbd>: Показать все логи ветки
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` o `` | Открыть файл конфигурации | Open file in default application. |
|
||||
| `` e `` | Редактировать файл конфигурации | Open file in external editor. |
|
||||
| `` u `` | Проверить обновления | |
|
||||
| `` <enter> `` | Переключиться на последний репозиторий | |
|
||||
| `` a `` | Показать все логи ветки | |
|
||||
|
||||
## Теги
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: Переключить
|
||||
<kbd>d</kbd>: Удалить тег
|
||||
<kbd>P</kbd>: Отправить тег
|
||||
<kbd>n</kbd>: Создать тег
|
||||
<kbd>g</kbd>: Просмотреть параметры сброса
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: Просмотреть коммиты
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Переключить | Checkout the selected tag tag as a detached HEAD. |
|
||||
| `` n `` | Создать тег | Create new tag from current commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` d `` | Delete | View delete options for local/remote tag. |
|
||||
| `` P `` | Отправить тег | Push the selected tag to a remote. You'll be prompted to select a remote. |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | Просмотреть коммиты | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Удалённые ветки
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Скопировать название ветки в буфер обмена
|
||||
<kbd><space></kbd>: Переключить
|
||||
<kbd>n</kbd>: Новая ветка
|
||||
<kbd>M</kbd>: Слияние с текущей переключённой веткой
|
||||
<kbd>r</kbd>: Перебазировать переключённую ветку на эту ветку
|
||||
<kbd>d</kbd>: Удалить ветку
|
||||
<kbd>u</kbd>: Установить как upstream-ветку переключённую ветку
|
||||
<kbd>g</kbd>: Просмотреть параметры сброса
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: Просмотреть коммиты
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Скопировать название ветки в буфер обмена | |
|
||||
| `` <space> `` | Переключить | Checkout a new local branch based on the selected remote branch. The new branch will track the remote branch. |
|
||||
| `` n `` | Новая ветка | |
|
||||
| `` M `` | Слияние с текущей переключённой веткой | Merge selected branch into currently checked out branch. |
|
||||
| `` r `` | Перебазировать переключённую ветку на эту ветку | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||
| `` u `` | Set as upstream | Установить как upstream-ветку переключённую ветку |
|
||||
| `` s `` | Порядок сортировки | |
|
||||
| `` g `` | Просмотреть параметры сброса | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | Просмотреть коммиты | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Удалённые репозитории
|
||||
|
||||
<pre>
|
||||
<kbd>f</kbd>: Получение изменения из удалённого репозитория
|
||||
<kbd>n</kbd>: Добавить новую удалённую ветку
|
||||
<kbd>d</kbd>: Удалить удалённую ветку
|
||||
<kbd>e</kbd>: Редактировать удалённый репозитории
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | View branches | |
|
||||
| `` n `` | Добавить новую удалённую ветку | |
|
||||
| `` d `` | Remove | Remove the selected remote. Any local branches tracking a remote branch from the remote will be unaffected. |
|
||||
| `` e `` | Edit | Редактировать удалённый репозитории |
|
||||
| `` f `` | Получить изменения | Получение изменения из удалённого репозитория |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Файлы
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: Скопировать название файла в буфер обмена
|
||||
<kbd>d</kbd>: Просмотреть параметры «отмены изменении»
|
||||
<kbd><space></kbd>: Переключить индекс
|
||||
<kbd><c-b></kbd>: Фильтровать файлы (проиндексированные/непроиндексированные)
|
||||
<kbd>c</kbd>: Сохранить изменения
|
||||
<kbd>w</kbd>: Закоммитить изменения без предварительного хука коммита
|
||||
<kbd>A</kbd>: Правка последнего коммита
|
||||
<kbd>C</kbd>: Сохранить изменения с помощью редактора git
|
||||
<kbd>e</kbd>: Редактировать файл
|
||||
<kbd>o</kbd>: Открыть файл
|
||||
<kbd>i</kbd>: Игнорировать или исключить файл
|
||||
<kbd>r</kbd>: Обновить файлы
|
||||
<kbd>s</kbd>: Припрятать все изменения
|
||||
<kbd>S</kbd>: Просмотреть параметры хранилища
|
||||
<kbd>a</kbd>: Все проиндексированные/непроиндексированные
|
||||
<kbd><enter></kbd>: Проиндексировать отдельные части/строки для файла или свернуть/развернуть для каталога
|
||||
<kbd>g</kbd>: Просмотреть параметры сброса upstream-ветки
|
||||
<kbd>D</kbd>: Просмотреть параметры сброса
|
||||
<kbd>`</kbd>: Переключить вид дерева файлов
|
||||
<kbd>M</kbd>: Открыть внешний инструмент слияния (git mergetool)
|
||||
<kbd>f</kbd>: Получить изменения
|
||||
<kbd>/</kbd>: Найти
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | Скопировать название файла в буфер обмена | |
|
||||
| `` <space> `` | Переключить индекс | Toggle staged for selected file. |
|
||||
| `` <c-b> `` | Фильтровать файлы (проиндексированные/непроиндексированные) | |
|
||||
| `` y `` | Copy to clipboard | |
|
||||
| `` c `` | Сохранить изменения | Commit staged changes. |
|
||||
| `` w `` | Закоммитить изменения без предварительного хука коммита | |
|
||||
| `` A `` | Правка последнего коммита | |
|
||||
| `` C `` | Сохранить изменения с помощью редактора git | |
|
||||
| `` <c-f> `` | Find base commit for fixup | Find the commit that your current changes are building upon, for the sake of amending/fixing up the commit. This spares you from having to look through your branch's commits one-by-one to see which commit should be amended/fixed up. See docs: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` o `` | Открыть файл | Open file in default application. |
|
||||
| `` i `` | Игнорировать или исключить файл | |
|
||||
| `` r `` | Обновить файлы | |
|
||||
| `` s `` | Stash | Stash all changes. For other variations of stashing, use the view stash options keybinding. |
|
||||
| `` S `` | Просмотреть параметры хранилища | View stash options (e.g. stash all, stash staged, stash unstaged). |
|
||||
| `` a `` | Все проиндексированные/непроиндексированные | Toggle staged/unstaged for all files in working tree. |
|
||||
| `` <enter> `` | Проиндексировать отдельные части/строки для файла или свернуть/развернуть для каталога | If the selected item is a file, focus the staging view so you can stage individual hunks/lines. If the selected item is a directory, collapse/expand it. |
|
||||
| `` d `` | Просмотреть параметры «отмены изменении» | View options for discarding changes to the selected file. |
|
||||
| `` g `` | Просмотреть параметры сброса upstream-ветки | |
|
||||
| `` D `` | Reset | View reset options for working tree (e.g. nuking the working tree). |
|
||||
| `` ` `` | Переключить вид дерева файлов | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` M `` | Открыть внешний инструмент слияния (git mergetool) | Run `git mergetool`. |
|
||||
| `` f `` | Получить изменения | Fetch changes from remote. |
|
||||
| `` / `` | Найти | |
|
||||
|
||||
## Хранилище
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: Применить припрятанные изменения
|
||||
<kbd>g</kbd>: Применить припрятанные изменения и тут же удалить их из хранилища
|
||||
<kbd>d</kbd>: Удалить припрятанные изменения из хранилища
|
||||
<kbd>n</kbd>: Новая ветка
|
||||
<kbd>r</kbd>: Переименовать хранилище
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: Просмотреть файлы выбранного элемента
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | Применить припрятанные изменения | Apply the stash entry to your working directory. |
|
||||
| `` g `` | Применить припрятанные изменения и тут же удалить их из хранилища | Apply the stash entry to your working directory and remove the stash entry. |
|
||||
| `` d `` | Удалить припрятанные изменения из хранилища | Remove the stash entry from the stash list. |
|
||||
| `` n `` | Новая ветка | Create a new branch from the selected stash entry. This works by git checking out the commit that the stash entry was created from, creating a new branch from that commit, then applying the stash entry to the new branch as an additional commit. |
|
||||
| `` r `` | Переименовать хранилище | |
|
||||
| `` <enter> `` | Просмотреть файлы выбранного элемента | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go run scripts/cheatsheet/main.go generate` from the project root._
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go generate ./...` from the project root._
|
||||
|
||||
# Lazygit 按键绑定
|
||||
|
||||
@@ -6,348 +6,358 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|
||||
|
||||
## 全局键绑定
|
||||
|
||||
<pre>
|
||||
<kbd><c-r></kbd>: 切换到最近的仓库
|
||||
<kbd><pgup></kbd>: 向上滚动主面板 (fn+up/shift+k)
|
||||
<kbd><pgdown></kbd>: 向下滚动主面板 (fn+down/shift+j)
|
||||
<kbd>@</kbd>: 打开命令日志菜单
|
||||
<kbd>}</kbd>: 扩大差异视图中显示的上下文范围
|
||||
<kbd>{</kbd>: 缩小差异视图中显示的上下文范围
|
||||
<kbd>:</kbd>: 执行自定义命令
|
||||
<kbd><c-p></kbd>: 查看自定义补丁选项
|
||||
<kbd>m</kbd>: 查看 合并/变基 选项
|
||||
<kbd>R</kbd>: 刷新
|
||||
<kbd>+</kbd>: 下一屏模式(正常/半屏/全屏)
|
||||
<kbd>_</kbd>: 上一屏模式
|
||||
<kbd>?</kbd>: 打开菜单
|
||||
<kbd><c-s></kbd>: 查看按路径过滤选项
|
||||
<kbd>W</kbd>: 打开 diff 菜单
|
||||
<kbd><c-e></kbd>: 打开 diff 菜单
|
||||
<kbd><c-w></kbd>: 切换是否在差异视图中显示空白字符差异
|
||||
<kbd>z</kbd>: (通过 reflog)撤销「实验功能」
|
||||
<kbd><c-z></kbd>: (通过 reflog)重做「实验功能」
|
||||
<kbd>P</kbd>: 推送
|
||||
<kbd>p</kbd>: 拉取
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-r> `` | 切换到最近的仓库 | |
|
||||
| `` <pgup> (fn+up/shift+k) `` | 向上滚动主面板 | |
|
||||
| `` <pgdown> (fn+down/shift+j) `` | 向下滚动主面板 | |
|
||||
| `` @ `` | 打开命令日志菜单 | View options for the command log e.g. show/hide the command log and focus the command log. |
|
||||
| `` P `` | 推送 | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` p `` | 拉取 | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` } `` | 扩大差异视图中显示的上下文范围 | Increase the amount of the context shown around changes in the diff view. |
|
||||
| `` { `` | 缩小差异视图中显示的上下文范围 | Decrease the amount of the context shown around changes in the diff view. |
|
||||
| `` : `` | 执行自定义命令 | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
|
||||
| `` <c-p> `` | 查看自定义补丁选项 | |
|
||||
| `` m `` | 查看 合并/变基 选项 | View options to abort/continue/skip the current merge/rebase. |
|
||||
| `` R `` | 刷新 | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. |
|
||||
| `` + `` | 下一屏模式(正常/半屏/全屏) | |
|
||||
| `` _ `` | 上一屏模式 | |
|
||||
| `` ? `` | 打开菜单 | |
|
||||
| `` <c-s> `` | 查看按路径过滤选项 | View options for filtering the commit log by a file path, so that only commits relating to that path are shown. |
|
||||
| `` W `` | 打开 diff 菜单 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` <c-e> `` | 打开 diff 菜单 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` q `` | 退出 | |
|
||||
| `` <esc> `` | 取消 | |
|
||||
| `` <c-w> `` | 切换是否在差异视图中显示空白字符差异 | Toggle whether or not whitespace changes are shown in the diff view. |
|
||||
| `` z `` | (通过 reflog)撤销「实验功能」 | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
|
||||
| `` <c-z> `` | (通过 reflog)重做「实验功能」 | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
|
||||
|
||||
## 列表面板导航
|
||||
|
||||
<pre>
|
||||
<kbd>,</kbd>: 上一页
|
||||
<kbd>.</kbd>: 下一页
|
||||
<kbd><</kbd>: 滚动到顶部
|
||||
<kbd>></kbd>: 滚动到底部
|
||||
<kbd>/</kbd>: 开始搜索
|
||||
<kbd>H</kbd>: 向左滚动
|
||||
<kbd>L</kbd>: 向右滚动
|
||||
<kbd>]</kbd>: 下一个标签
|
||||
<kbd>[</kbd>: 上一个标签
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` , `` | 上一页 | |
|
||||
| `` . `` | 下一页 | |
|
||||
| `` < `` | 滚动到顶部 | |
|
||||
| `` > `` | 滚动到底部 | |
|
||||
| `` v `` | 切换拖动选择 | |
|
||||
| `` <s-down> `` | Range select down | |
|
||||
| `` <s-up> `` | Range select up | |
|
||||
| `` / `` | 开始搜索 | |
|
||||
| `` H `` | 向左滚动 | |
|
||||
| `` L `` | 向右滚动 | |
|
||||
| `` ] `` | 下一个标签 | |
|
||||
| `` [ `` | 上一个标签 | |
|
||||
|
||||
## Reflog 页面
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 将提交的 SHA 复制到剪贴板
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: 检出提交
|
||||
<kbd>y</kbd>: Copy commit attribute
|
||||
<kbd>o</kbd>: 在浏览器中打开提交
|
||||
<kbd>n</kbd>: 从提交创建新分支
|
||||
<kbd>g</kbd>: 查看重置选项
|
||||
<kbd>c</kbd>: 复制提交(拣选)
|
||||
<kbd>C</kbd>: 复制提交范围(拣选)
|
||||
<kbd><c-r></kbd>: 重置已拣选(复制)的提交
|
||||
<kbd><enter></kbd>: 查看提交
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 将提交的 SHA 复制到剪贴板 | |
|
||||
| `` <space> `` | 检出 | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | 在浏览器中打开提交 | |
|
||||
| `` n `` | 从提交创建新分支 | |
|
||||
| `` g `` | 查看重置选项 | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | 复制提交(拣选) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | 重置已拣选(复制)的提交 | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | 查看提交 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Worktrees
|
||||
|
||||
<pre>
|
||||
<kbd>n</kbd>: Create worktree
|
||||
<kbd><space></kbd>: Switch to worktree
|
||||
<kbd><enter></kbd>: Switch to worktree
|
||||
<kbd>o</kbd>: Open in editor
|
||||
<kbd>d</kbd>: Remove worktree
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` n `` | New worktree | |
|
||||
| `` <space> `` | Switch | Switch to the selected worktree. |
|
||||
| `` o `` | Open in editor | |
|
||||
| `` d `` | Remove | Remove the selected worktree. This will both delete the worktree's directory, as well as metadata about the worktree in the .git directory. |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 分支页面
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 将分支名称复制到剪贴板
|
||||
<kbd>i</kbd>: 显示 git-flow 选项
|
||||
<kbd><space></kbd>: 检出
|
||||
<kbd>n</kbd>: 新分支
|
||||
<kbd>o</kbd>: 创建抓取请求
|
||||
<kbd>O</kbd>: 创建抓取请求选项
|
||||
<kbd><c-y></kbd>: 将抓取请求 URL 复制到剪贴板
|
||||
<kbd>c</kbd>: 按名称检出
|
||||
<kbd>F</kbd>: 强制检出
|
||||
<kbd>d</kbd>: 删除分支
|
||||
<kbd>r</kbd>: 将已检出的分支变基到该分支
|
||||
<kbd>M</kbd>: 合并到当前检出的分支
|
||||
<kbd>f</kbd>: 从上游快进此分支
|
||||
<kbd>T</kbd>: 创建标签
|
||||
<kbd>g</kbd>: 查看重置选项
|
||||
<kbd>R</kbd>: 重命名分支
|
||||
<kbd>u</kbd>: Set/Unset upstream
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: 查看提交
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 将分支名称复制到剪贴板 | |
|
||||
| `` i `` | 显示 git-flow 选项 | |
|
||||
| `` <space> `` | 检出 | Checkout selected item. |
|
||||
| `` n `` | 新分支 | |
|
||||
| `` o `` | 创建抓取请求 | |
|
||||
| `` O `` | 创建抓取请求选项 | |
|
||||
| `` <c-y> `` | 将抓取请求 URL 复制到剪贴板 | |
|
||||
| `` c `` | 按名称检出 | Checkout by name. In the input box you can enter '-' to switch to the last branch. |
|
||||
| `` F `` | 强制检出 | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||
| `` r `` | 将已检出的分支变基到该分支 | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` M `` | 合并到当前检出的分支 | Merge selected branch into currently checked out branch. |
|
||||
| `` f `` | 从上游快进此分支 | Fast-forward selected branch from its upstream. |
|
||||
| `` T `` | 创建标签 | |
|
||||
| `` s `` | Sort order | |
|
||||
| `` g `` | 查看重置选项 | |
|
||||
| `` R `` | 重命名分支 | |
|
||||
| `` u `` | View upstream options | View options relating to the branch's upstream e.g. setting/unsetting the upstream and resetting to the upstream. |
|
||||
| `` <enter> `` | 查看提交 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 子提交
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 将提交的 SHA 复制到剪贴板
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: 检出提交
|
||||
<kbd>y</kbd>: Copy commit attribute
|
||||
<kbd>o</kbd>: 在浏览器中打开提交
|
||||
<kbd>n</kbd>: 从提交创建新分支
|
||||
<kbd>g</kbd>: 查看重置选项
|
||||
<kbd>c</kbd>: 复制提交(拣选)
|
||||
<kbd>C</kbd>: 复制提交范围(拣选)
|
||||
<kbd><c-r></kbd>: 重置已拣选(复制)的提交
|
||||
<kbd><enter></kbd>: 查看提交的文件
|
||||
<kbd>/</kbd>: 开始搜索
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 将提交的 SHA 复制到剪贴板 | |
|
||||
| `` <space> `` | 检出 | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | 在浏览器中打开提交 | |
|
||||
| `` n `` | 从提交创建新分支 | |
|
||||
| `` g `` | 查看重置选项 | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | 复制提交(拣选) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | 重置已拣选(复制)的提交 | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | 查看提交的文件 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | 开始搜索 | |
|
||||
|
||||
## 子模块
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 将子模块名称复制到剪贴板
|
||||
<kbd><enter></kbd>: 输入子模块
|
||||
<kbd><space></kbd>: 输入子模块
|
||||
<kbd>d</kbd>: 删除子模块
|
||||
<kbd>u</kbd>: 更新子模块
|
||||
<kbd>n</kbd>: 添加新的子模块
|
||||
<kbd>e</kbd>: 更新子模块 URL
|
||||
<kbd>i</kbd>: 初始化子模块
|
||||
<kbd>b</kbd>: 查看批量子模块选项
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 将子模块名称复制到剪贴板 | |
|
||||
| `` <enter> `` | Enter | 输入子模块 |
|
||||
| `` d `` | Remove | Remove the selected submodule and its corresponding directory. |
|
||||
| `` u `` | Update | 更新子模块 |
|
||||
| `` n `` | 添加新的子模块 | |
|
||||
| `` e `` | 更新子模块 URL | |
|
||||
| `` i `` | Initialize | 初始化子模块 |
|
||||
| `` b `` | 查看批量子模块选项 | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 提交
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 将提交的 SHA 复制到剪贴板
|
||||
<kbd><c-r></kbd>: 重置已拣选(复制)的提交
|
||||
<kbd>b</kbd>: 查看二分查找选项
|
||||
<kbd>s</kbd>: 向下压缩
|
||||
<kbd>f</kbd>: 修正提交(fixup)
|
||||
<kbd>r</kbd>: 改写提交
|
||||
<kbd>R</kbd>: 使用编辑器重命名提交
|
||||
<kbd>d</kbd>: 删除提交
|
||||
<kbd>e</kbd>: 编辑提交
|
||||
<kbd>p</kbd>: 选择提交(变基过程中)
|
||||
<kbd>F</kbd>: 创建修正提交
|
||||
<kbd>S</kbd>: 压缩在所选提交之上的所有“fixup!”提交(自动压缩)
|
||||
<kbd><c-j></kbd>: 下移提交
|
||||
<kbd><c-k></kbd>: 上移提交
|
||||
<kbd>v</kbd>: 粘贴提交(拣选)
|
||||
<kbd>B</kbd>: Mark commit as base commit for rebase
|
||||
<kbd>A</kbd>: 用已暂存的更改来修补提交
|
||||
<kbd>a</kbd>: Set/Reset commit author
|
||||
<kbd>t</kbd>: 还原提交
|
||||
<kbd>T</kbd>: 标签提交
|
||||
<kbd><c-l></kbd>: 打开日志菜单
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: 检出提交
|
||||
<kbd>y</kbd>: Copy commit attribute
|
||||
<kbd>o</kbd>: 在浏览器中打开提交
|
||||
<kbd>n</kbd>: 从提交创建新分支
|
||||
<kbd>g</kbd>: 查看重置选项
|
||||
<kbd>c</kbd>: 复制提交(拣选)
|
||||
<kbd>C</kbd>: 复制提交范围(拣选)
|
||||
<kbd><enter></kbd>: 查看提交的文件
|
||||
<kbd>/</kbd>: 开始搜索
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 将提交的 SHA 复制到剪贴板 | |
|
||||
| `` <c-r> `` | 重置已拣选(复制)的提交 | |
|
||||
| `` b `` | 查看二分查找选项 | |
|
||||
| `` s `` | 压缩 | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. |
|
||||
| `` f `` | 修正(fixup) | Meld the selected commit into the commit below it. Similar to fixup, but the selected commit's message will be discarded. |
|
||||
| `` r `` | 改写提交 | Reword the selected commit's message. |
|
||||
| `` R `` | 使用编辑器重命名提交 | |
|
||||
| `` d `` | 删除提交 | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. |
|
||||
| `` e `` | Edit (start interactive rebase) | 编辑提交 |
|
||||
| `` i `` | Start interactive rebase | Start an interactive rebase for the commits on your branch. This will include all commits from the HEAD commit down to the first merge commit or main branch commit.
|
||||
If you would instead like to start an interactive rebase from the selected commit, press `e`. |
|
||||
| `` p `` | Pick | 选择提交(变基过程中) |
|
||||
| `` F `` | Create fixup commit | 创建修正提交 |
|
||||
| `` S `` | Apply fixup commits | 压缩在所选提交之上的所有“fixup!”提交(自动压缩) |
|
||||
| `` <c-j> `` | 下移提交 | |
|
||||
| `` <c-k> `` | 上移提交 | |
|
||||
| `` V `` | 粘贴提交(拣选) | |
|
||||
| `` B `` | Mark as base commit for rebase | Select a base commit for the next rebase. When you rebase onto a branch, only commits above the base commit will be brought across. This uses the `git rebase --onto` command. |
|
||||
| `` A `` | Amend | 用已暂存的更改来修补提交 |
|
||||
| `` a `` | Amend commit attribute | Set/Reset commit author or set co-author. |
|
||||
| `` t `` | Revert | Create a revert commit for the selected commit, which applies the selected commit's changes in reverse. |
|
||||
| `` T `` | 标签提交 | Create a new tag pointing at the selected commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` <c-l> `` | 打开日志菜单 | View options for commit log e.g. changing sort order, hiding the git graph, showing the whole git graph. |
|
||||
| `` <space> `` | 检出 | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | Copy commit attribute to clipboard | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | 在浏览器中打开提交 | |
|
||||
| `` n `` | 从提交创建新分支 | |
|
||||
| `` g `` | 查看重置选项 | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | 复制提交(拣选) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | 查看提交的文件 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | 开始搜索 | |
|
||||
|
||||
## 提交文件
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 将提交的文件名复制到剪贴板
|
||||
<kbd>c</kbd>: 检出文件
|
||||
<kbd>d</kbd>: 放弃对此文件的提交更改
|
||||
<kbd>o</kbd>: 打开文件
|
||||
<kbd>e</kbd>: 编辑文件
|
||||
<kbd><space></kbd>: 补丁中包含的切换文件
|
||||
<kbd>a</kbd>: Toggle all files included in patch
|
||||
<kbd><enter></kbd>: 输入文件以将所选行添加到补丁中(或切换目录折叠)
|
||||
<kbd>`</kbd>: 切换文件树视图
|
||||
<kbd>/</kbd>: 开始搜索
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 将文件名复制到剪贴板 | |
|
||||
| `` c `` | 检出 | 检出文件 |
|
||||
| `` d `` | Remove | 放弃对此文件的提交更改 |
|
||||
| `` o `` | 打开文件 | Open file in default application. |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <space> `` | 补丁中包含的切换文件 | Toggle whether the file is included in the custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` a `` | Toggle all files | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` <enter> `` | 输入文件以将所选行添加到补丁中(或切换目录折叠) | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
|
||||
| `` ` `` | 切换文件树视图 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` / `` | 开始搜索 | |
|
||||
|
||||
## 提交讯息
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: 确认
|
||||
<kbd><esc></kbd>: 关闭
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | 确认 | |
|
||||
| `` <esc> `` | 关闭 | |
|
||||
|
||||
## 文件
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 将文件名复制到剪贴板
|
||||
<kbd>d</kbd>: 查看'放弃更改'选项
|
||||
<kbd><space></kbd>: 切换暂存状态
|
||||
<kbd><c-b></kbd>: Filter files by status
|
||||
<kbd>c</kbd>: 提交更改
|
||||
<kbd>w</kbd>: 提交更改而无需预先提交钩子
|
||||
<kbd>A</kbd>: 修补最后一次提交
|
||||
<kbd>C</kbd>: 提交更改(使用编辑器编辑提交信息)
|
||||
<kbd>e</kbd>: 编辑文件
|
||||
<kbd>o</kbd>: 打开文件
|
||||
<kbd>i</kbd>: 忽略文件
|
||||
<kbd>r</kbd>: 刷新文件
|
||||
<kbd>s</kbd>: 将所有更改加入贮藏
|
||||
<kbd>S</kbd>: 查看贮藏选项
|
||||
<kbd>a</kbd>: 切换所有文件的暂存状态
|
||||
<kbd><enter></kbd>: 暂存单个 块/行 用于文件, 或 折叠/展开 目录
|
||||
<kbd>g</kbd>: 查看上游重置选项
|
||||
<kbd>D</kbd>: 查看重置选项
|
||||
<kbd>`</kbd>: 切换文件树视图
|
||||
<kbd>M</kbd>: 打开外部合并工具 (git mergetool)
|
||||
<kbd>f</kbd>: 抓取
|
||||
<kbd>/</kbd>: 开始搜索
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 将文件名复制到剪贴板 | |
|
||||
| `` <space> `` | 切换暂存状态 | Toggle staged for selected file. |
|
||||
| `` <c-b> `` | Filter files by status | |
|
||||
| `` y `` | Copy to clipboard | |
|
||||
| `` c `` | 提交更改 | Commit staged changes. |
|
||||
| `` w `` | 提交更改而无需预先提交钩子 | |
|
||||
| `` A `` | 修补最后一次提交 | |
|
||||
| `` C `` | 提交更改(使用编辑器编辑提交信息) | |
|
||||
| `` <c-f> `` | Find base commit for fixup | Find the commit that your current changes are building upon, for the sake of amending/fixing up the commit. This spares you from having to look through your branch's commits one-by-one to see which commit should be amended/fixed up. See docs: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` o `` | 打开文件 | Open file in default application. |
|
||||
| `` i `` | 忽略文件 | |
|
||||
| `` r `` | 刷新文件 | |
|
||||
| `` s `` | Stash | Stash all changes. For other variations of stashing, use the view stash options keybinding. |
|
||||
| `` S `` | 查看贮藏选项 | View stash options (e.g. stash all, stash staged, stash unstaged). |
|
||||
| `` a `` | 切换所有文件的暂存状态 | Toggle staged/unstaged for all files in working tree. |
|
||||
| `` <enter> `` | 暂存单个 块/行 用于文件, 或 折叠/展开 目录 | If the selected item is a file, focus the staging view so you can stage individual hunks/lines. If the selected item is a directory, collapse/expand it. |
|
||||
| `` d `` | 查看'放弃更改'选项 | View options for discarding changes to the selected file. |
|
||||
| `` g `` | 查看上游重置选项 | |
|
||||
| `` D `` | Reset | View reset options for working tree (e.g. nuking the working tree). |
|
||||
| `` ` `` | 切换文件树视图 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` M `` | 打开外部合并工具 (git mergetool) | Run `git mergetool`. |
|
||||
| `` f `` | 抓取 | Fetch changes from remote. |
|
||||
| `` / `` | 开始搜索 | |
|
||||
|
||||
## 构建补丁中
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: 选择上一个区块
|
||||
<kbd><right></kbd>: 选择下一个区块
|
||||
<kbd>v</kbd>: 切换拖动选择
|
||||
<kbd>V</kbd>: 切换拖动选择
|
||||
<kbd>a</kbd>: 切换选择区块
|
||||
<kbd><c-o></kbd>: 将选中文本复制到剪贴板
|
||||
<kbd>o</kbd>: 打开文件
|
||||
<kbd>e</kbd>: 编辑文件
|
||||
<kbd><space></kbd>: 添加/移除 行到补丁
|
||||
<kbd><esc></kbd>: 退出逐行模式
|
||||
<kbd>/</kbd>: 开始搜索
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | 选择上一个区块 | |
|
||||
| `` <right> `` | 选择下一个区块 | |
|
||||
| `` v `` | 切换拖动选择 | |
|
||||
| `` a `` | 切换选择区块 | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | 将选中文本复制到剪贴板 | |
|
||||
| `` o `` | 打开文件 | Open file in default application. |
|
||||
| `` e `` | 编辑文件 | Open file in external editor. |
|
||||
| `` <space> `` | 添加/移除 行到补丁 | |
|
||||
| `` <esc> `` | 退出逐行模式 | |
|
||||
| `` / `` | 开始搜索 | |
|
||||
|
||||
## 标签页面
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: 检出
|
||||
<kbd>d</kbd>: 删除标签
|
||||
<kbd>P</kbd>: 推送标签
|
||||
<kbd>n</kbd>: 创建标签
|
||||
<kbd>g</kbd>: 查看重置选项
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: 查看提交
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | 检出 | Checkout the selected tag tag as a detached HEAD. |
|
||||
| `` n `` | 创建标签 | Create new tag from current commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` d `` | Delete | View delete options for local/remote tag. |
|
||||
| `` P `` | 推送标签 | Push the selected tag to a remote. You'll be prompted to select a remote. |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | 查看提交 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 正在合并
|
||||
|
||||
<pre>
|
||||
<kbd>e</kbd>: 编辑文件
|
||||
<kbd>o</kbd>: 打开文件
|
||||
<kbd><left></kbd>: 选择上一个冲突
|
||||
<kbd><right></kbd>: 选择下一个冲突
|
||||
<kbd><up></kbd>: 选择顶部块
|
||||
<kbd><down></kbd>: 选择底部块
|
||||
<kbd>z</kbd>: 撤销
|
||||
<kbd>M</kbd>: 打开外部合并工具 (git mergetool)
|
||||
<kbd><space></kbd>: 选中区块
|
||||
<kbd>b</kbd>: 选中所有区块
|
||||
<kbd><esc></kbd>: 返回文件面板
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | 选中区块 | |
|
||||
| `` b `` | 选中所有区块 | |
|
||||
| `` <up> `` | 选择顶部块 | |
|
||||
| `` <down> `` | 选择底部块 | |
|
||||
| `` <left> `` | 选择上一个冲突 | |
|
||||
| `` <right> `` | 选择下一个冲突 | |
|
||||
| `` z `` | 撤销 | Undo last merge conflict resolution. |
|
||||
| `` e `` | 编辑文件 | Open file in external editor. |
|
||||
| `` o `` | 打开文件 | Open file in default application. |
|
||||
| `` M `` | 打开外部合并工具 (git mergetool) | Run `git mergetool`. |
|
||||
| `` <esc> `` | 返回文件面板 | |
|
||||
|
||||
## 正在暂存
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: 选择上一个区块
|
||||
<kbd><right></kbd>: 选择下一个区块
|
||||
<kbd>v</kbd>: 切换拖动选择
|
||||
<kbd>V</kbd>: 切换拖动选择
|
||||
<kbd>a</kbd>: 切换选择区块
|
||||
<kbd><c-o></kbd>: 将选中文本复制到剪贴板
|
||||
<kbd>o</kbd>: 打开文件
|
||||
<kbd>e</kbd>: 编辑文件
|
||||
<kbd><esc></kbd>: 返回文件面板
|
||||
<kbd><tab></kbd>: 切换到其他面板
|
||||
<kbd><space></kbd>: 切换行暂存状态
|
||||
<kbd>d</kbd>: 取消变更 (git reset)
|
||||
<kbd>E</kbd>: Edit hunk
|
||||
<kbd>c</kbd>: 提交更改
|
||||
<kbd>w</kbd>: 提交更改而无需预先提交钩子
|
||||
<kbd>C</kbd>: 提交更改(使用编辑器编辑提交信息)
|
||||
<kbd>/</kbd>: 开始搜索
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | 选择上一个区块 | |
|
||||
| `` <right> `` | 选择下一个区块 | |
|
||||
| `` v `` | 切换拖动选择 | |
|
||||
| `` a `` | 切换选择区块 | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | 将选中文本复制到剪贴板 | |
|
||||
| `` <space> `` | 切换暂存状态 | 切换行暂存状态 |
|
||||
| `` d `` | 取消变更 (git reset) | When unstaged change is selected, discard the change using `git reset`. When staged change is selected, unstage the change. |
|
||||
| `` o `` | 打开文件 | Open file in default application. |
|
||||
| `` e `` | 编辑文件 | Open file in external editor. |
|
||||
| `` <esc> `` | 返回文件面板 | |
|
||||
| `` <tab> `` | 切换到其他面板 | Switch to other view (staged/unstaged changes). |
|
||||
| `` E `` | Edit hunk | Edit selected hunk in external editor. |
|
||||
| `` c `` | 提交更改 | Commit staged changes. |
|
||||
| `` w `` | 提交更改而无需预先提交钩子 | |
|
||||
| `` C `` | 提交更改(使用编辑器编辑提交信息) | |
|
||||
| `` / `` | 开始搜索 | |
|
||||
|
||||
## 正常
|
||||
|
||||
<pre>
|
||||
<kbd>mouse wheel down</kbd>: 向下滚动 (fn+up)
|
||||
<kbd>mouse wheel up</kbd>: 向上滚动 (fn+down)
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` mouse wheel down (fn+up) `` | 向下滚动 | |
|
||||
| `` mouse wheel up (fn+down) `` | 向上滚动 | |
|
||||
|
||||
## 状态
|
||||
|
||||
<pre>
|
||||
<kbd>o</kbd>: 打开配置文件
|
||||
<kbd>e</kbd>: 编辑配置文件
|
||||
<kbd>u</kbd>: 检查更新
|
||||
<kbd><enter></kbd>: 切换到最近的仓库
|
||||
<kbd>a</kbd>: 显示所有分支的日志
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` o `` | 打开配置文件 | Open file in default application. |
|
||||
| `` e `` | 编辑配置文件 | Open file in external editor. |
|
||||
| `` u `` | 检查更新 | |
|
||||
| `` <enter> `` | 切换到最近的仓库 | |
|
||||
| `` a `` | 显示所有分支的日志 | |
|
||||
|
||||
## 确认面板
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: 确认
|
||||
<kbd><esc></kbd>: 关闭
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | 确认 | |
|
||||
| `` <esc> `` | 关闭 | |
|
||||
|
||||
## 菜单
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: 执行
|
||||
<kbd><esc></kbd>: 关闭
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | 执行 | |
|
||||
| `` <esc> `` | 关闭 | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 贮藏
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: 应用
|
||||
<kbd>g</kbd>: 应用并删除
|
||||
<kbd>d</kbd>: 删除
|
||||
<kbd>n</kbd>: 新分支
|
||||
<kbd>r</kbd>: Rename stash
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: 查看提交的文件
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | 应用 | Apply the stash entry to your working directory. |
|
||||
| `` g `` | 应用并删除 | Apply the stash entry to your working directory and remove the stash entry. |
|
||||
| `` d `` | 删除 | Remove the stash entry from the stash list. |
|
||||
| `` n `` | 新分支 | Create a new branch from the selected stash entry. This works by git checking out the commit that the stash entry was created from, creating a new branch from that commit, then applying the stash entry to the new branch as an additional commit. |
|
||||
| `` r `` | Rename stash | |
|
||||
| `` <enter> `` | 查看提交的文件 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 远程分支
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 将分支名称复制到剪贴板
|
||||
<kbd><space></kbd>: 检出
|
||||
<kbd>n</kbd>: 新分支
|
||||
<kbd>M</kbd>: 合并到当前检出的分支
|
||||
<kbd>r</kbd>: 将已检出的分支变基到该分支
|
||||
<kbd>d</kbd>: 删除分支
|
||||
<kbd>u</kbd>: 设置为检出分支的上游
|
||||
<kbd>g</kbd>: 查看重置选项
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: 查看提交
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 将分支名称复制到剪贴板 | |
|
||||
| `` <space> `` | 检出 | Checkout a new local branch based on the selected remote branch. The new branch will track the remote branch. |
|
||||
| `` n `` | 新分支 | |
|
||||
| `` M `` | 合并到当前检出的分支 | Merge selected branch into currently checked out branch. |
|
||||
| `` r `` | 将已检出的分支变基到该分支 | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||
| `` u `` | Set as upstream | 设置为检出分支的上游 |
|
||||
| `` s `` | Sort order | |
|
||||
| `` g `` | 查看重置选项 | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | 查看提交 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 远程页面
|
||||
|
||||
<pre>
|
||||
<kbd>f</kbd>: 抓取远程仓库
|
||||
<kbd>n</kbd>: 添加新的远程仓库
|
||||
<kbd>d</kbd>: 删除远程
|
||||
<kbd>e</kbd>: 编辑远程仓库
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | View branches | |
|
||||
| `` n `` | 添加新的远程仓库 | |
|
||||
| `` d `` | Remove | Remove the selected remote. Any local branches tracking a remote branch from the remote will be unaffected. |
|
||||
| `` e `` | Edit | 编辑远程仓库 |
|
||||
| `` f `` | 抓取 | 抓取远程仓库 |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go run scripts/cheatsheet/main.go generate` from the project root._
|
||||
_This file is auto-generated. To update, make the changes in the pkg/i18n directory and then run `go generate ./...` from the project root._
|
||||
|
||||
# Lazygit 鍵盤快捷鍵
|
||||
|
||||
@@ -6,348 +6,358 @@ _說明:`<c-b>` 表示 Ctrl+B、`<a-b>` 表示 Alt+B,`B`表示 Shift+B_
|
||||
|
||||
## 全局快捷鍵
|
||||
|
||||
<pre>
|
||||
<kbd><c-r></kbd>: 切換到最近使用的版本庫
|
||||
<kbd><pgup></kbd>: 向上捲動主面板 (fn+up/shift+k)
|
||||
<kbd><pgdown></kbd>: 向下捲動主面板 (fn+down/shift+j)
|
||||
<kbd>@</kbd>: 開啟命令記錄選單
|
||||
<kbd>}</kbd>: 增加差異檢視中顯示變更周圍上下文的大小
|
||||
<kbd>{</kbd>: 減小差異檢視中顯示變更周圍上下文的大小
|
||||
<kbd>:</kbd>: 執行自訂命令
|
||||
<kbd><c-p></kbd>: 檢視自訂補丁選項
|
||||
<kbd>m</kbd>: 查看合併/變基選項
|
||||
<kbd>R</kbd>: 重新整理
|
||||
<kbd>+</kbd>: 下一個螢幕模式(常規/半螢幕/全螢幕)
|
||||
<kbd>_</kbd>: 上一個螢幕模式
|
||||
<kbd>?</kbd>: 開啟選單
|
||||
<kbd><c-s></kbd>: 檢視篩選路徑選項
|
||||
<kbd>W</kbd>: 開啟差異比較選單
|
||||
<kbd><c-e></kbd>: 開啟差異比較選單
|
||||
<kbd><c-w></kbd>: 切換是否在差異檢視中顯示空格變更
|
||||
<kbd>z</kbd>: 復原
|
||||
<kbd><c-z></kbd>: 取消復原
|
||||
<kbd>P</kbd>: 推送
|
||||
<kbd>p</kbd>: 拉取
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-r> `` | 切換到最近使用的版本庫 | |
|
||||
| `` <pgup> (fn+up/shift+k) `` | 向上捲動主面板 | |
|
||||
| `` <pgdown> (fn+down/shift+j) `` | 向下捲動主面板 | |
|
||||
| `` @ `` | 開啟命令記錄選單 | View options for the command log e.g. show/hide the command log and focus the command log. |
|
||||
| `` P `` | 推送 | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` p `` | 拉取 | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
|
||||
| `` } `` | 增加差異檢視中顯示變更周圍上下文的大小 | Increase the amount of the context shown around changes in the diff view. |
|
||||
| `` { `` | 減小差異檢視中顯示變更周圍上下文的大小 | Decrease the amount of the context shown around changes in the diff view. |
|
||||
| `` : `` | 執行自訂命令 | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
|
||||
| `` <c-p> `` | 檢視自訂補丁選項 | |
|
||||
| `` m `` | 查看合併/變基選項 | View options to abort/continue/skip the current merge/rebase. |
|
||||
| `` R `` | 重新整理 | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. |
|
||||
| `` + `` | 下一個螢幕模式(常規/半螢幕/全螢幕) | |
|
||||
| `` _ `` | 上一個螢幕模式 | |
|
||||
| `` ? `` | 開啟選單 | |
|
||||
| `` <c-s> `` | 檢視篩選路徑選項 | View options for filtering the commit log by a file path, so that only commits relating to that path are shown. |
|
||||
| `` W `` | 開啟差異比較選單 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` <c-e> `` | 開啟差異比較選單 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. |
|
||||
| `` q `` | 結束 | |
|
||||
| `` <esc> `` | 取消 | |
|
||||
| `` <c-w> `` | 切換是否在差異檢視中顯示空格變更 | Toggle whether or not whitespace changes are shown in the diff view. |
|
||||
| `` z `` | 復原 | 將使用 reflog 確定要運行哪個 git 命令以復原上一個 git 命令。這不包括工作區的更改;只考慮提交。 |
|
||||
| `` <c-z> `` | 取消復原 | 將使用 reflog 確定要運行哪個 git 命令以重作上一個 git 命令。這不包括工作區的更改;只考慮提交。 |
|
||||
|
||||
## 列表面板導航
|
||||
|
||||
<pre>
|
||||
<kbd>,</kbd>: 上一頁
|
||||
<kbd>.</kbd>: 下一頁
|
||||
<kbd><</kbd>: 捲動到頂部
|
||||
<kbd>></kbd>: 捲動到底部
|
||||
<kbd>/</kbd>: 開始搜尋
|
||||
<kbd>H</kbd>: 向左捲動
|
||||
<kbd>L</kbd>: 向右捲動
|
||||
<kbd>]</kbd>: 下一個索引標籤
|
||||
<kbd>[</kbd>: 上一個索引標籤
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` , `` | 上一頁 | |
|
||||
| `` . `` | 下一頁 | |
|
||||
| `` < `` | 捲動到頂部 | |
|
||||
| `` > `` | 捲動到底部 | |
|
||||
| `` v `` | 切換拖曳選擇 | |
|
||||
| `` <s-down> `` | Range select down | |
|
||||
| `` <s-up> `` | Range select up | |
|
||||
| `` / `` | 開始搜尋 | |
|
||||
| `` H `` | 向左捲動 | |
|
||||
| `` L `` | 向右捲動 | |
|
||||
| `` ] `` | 下一個索引標籤 | |
|
||||
| `` [ `` | 上一個索引標籤 | |
|
||||
|
||||
## Reflog
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 複製提交 SHA 到剪貼簿
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: 檢出提交
|
||||
<kbd>y</kbd>: 複製提交屬性
|
||||
<kbd>o</kbd>: 在瀏覽器中開啟提交
|
||||
<kbd>n</kbd>: 從提交建立新分支
|
||||
<kbd>g</kbd>: 檢視重設選項
|
||||
<kbd>c</kbd>: 複製提交 (揀選)
|
||||
<kbd>C</kbd>: 複製提交範圍 (揀選)
|
||||
<kbd><c-r></kbd>: 重設選定的揀選 (複製) 提交
|
||||
<kbd><enter></kbd>: 檢視提交
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 複製提交 SHA 到剪貼簿 | |
|
||||
| `` <space> `` | 檢出 | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | 複製提交屬性 | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | 在瀏覽器中開啟提交 | |
|
||||
| `` n `` | 從提交建立新分支 | |
|
||||
| `` g `` | 檢視重設選項 | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | 複製提交 (揀選) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | 重設選定的揀選 (複製) 提交 | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | 檢視提交 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## Worktrees
|
||||
|
||||
<pre>
|
||||
<kbd>n</kbd>: Create worktree
|
||||
<kbd><space></kbd>: Switch to worktree
|
||||
<kbd><enter></kbd>: Switch to worktree
|
||||
<kbd>o</kbd>: Open in editor
|
||||
<kbd>d</kbd>: Remove worktree
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` n `` | New worktree | |
|
||||
| `` <space> `` | Switch | Switch to the selected worktree. |
|
||||
| `` o `` | Open in editor | |
|
||||
| `` d `` | Remove | Remove the selected worktree. This will both delete the worktree's directory, as well as metadata about the worktree in the .git directory. |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 主視窗 (一般)
|
||||
|
||||
<pre>
|
||||
<kbd>mouse wheel down</kbd>: 向下捲動 (fn+up)
|
||||
<kbd>mouse wheel up</kbd>: 向上捲動 (fn+down)
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` mouse wheel down (fn+up) `` | 向下捲動 | |
|
||||
| `` mouse wheel up (fn+down) `` | 向上捲動 | |
|
||||
|
||||
## 主視窗 (合併中)
|
||||
|
||||
<pre>
|
||||
<kbd>e</kbd>: 編輯檔案
|
||||
<kbd>o</kbd>: 開啟檔案
|
||||
<kbd><left></kbd>: 選擇上一個衝突
|
||||
<kbd><right></kbd>: 選擇下一個衝突
|
||||
<kbd><up></kbd>: 選擇上一段
|
||||
<kbd><down></kbd>: 選擇下一段
|
||||
<kbd>z</kbd>: 復原
|
||||
<kbd>M</kbd>: 開啟外部合併工具 (git mergetool)
|
||||
<kbd><space></kbd>: 挑選程式碼片段
|
||||
<kbd>b</kbd>: 挑選所有程式碼片段
|
||||
<kbd><esc></kbd>: 返回檔案面板
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | 挑選程式碼片段 | |
|
||||
| `` b `` | 挑選所有程式碼片段 | |
|
||||
| `` <up> `` | 選擇上一段 | |
|
||||
| `` <down> `` | 選擇下一段 | |
|
||||
| `` <left> `` | 選擇上一個衝突 | |
|
||||
| `` <right> `` | 選擇下一個衝突 | |
|
||||
| `` z `` | 復原 | Undo last merge conflict resolution. |
|
||||
| `` e `` | 編輯檔案 | Open file in external editor. |
|
||||
| `` o `` | 開啟檔案 | Open file in default application. |
|
||||
| `` M `` | 開啟外部合併工具 (git mergetool) | Run `git mergetool`. |
|
||||
| `` <esc> `` | 返回檔案面板 | |
|
||||
|
||||
## 主視窗 (預存中)
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: 選擇上一段
|
||||
<kbd><right></kbd>: 選擇下一段
|
||||
<kbd>v</kbd>: 切換拖曳選擇
|
||||
<kbd>V</kbd>: 切換拖曳選擇
|
||||
<kbd>a</kbd>: 切換選擇程式碼塊
|
||||
<kbd><c-o></kbd>: 複製所選文本至剪貼簿
|
||||
<kbd>o</kbd>: 開啟檔案
|
||||
<kbd>e</kbd>: 編輯檔案
|
||||
<kbd><esc></kbd>: 返回檔案面板
|
||||
<kbd><tab></kbd>: 切換至另一個面板 (已預存/未預存更改)
|
||||
<kbd><space></kbd>: 切換現有行的狀態 (已預存/未預存)
|
||||
<kbd>d</kbd>: 刪除變更 (git reset)
|
||||
<kbd>E</kbd>: 編輯程式碼塊
|
||||
<kbd>c</kbd>: 提交變更
|
||||
<kbd>w</kbd>: 沒有預提交 hook 就提交更改
|
||||
<kbd>C</kbd>: 使用 git 編輯器提交變更
|
||||
<kbd>/</kbd>: 開始搜尋
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | 選擇上一段 | |
|
||||
| `` <right> `` | 選擇下一段 | |
|
||||
| `` v `` | 切換拖曳選擇 | |
|
||||
| `` a `` | 切換選擇程式碼塊 | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | 複製所選文本至剪貼簿 | |
|
||||
| `` <space> `` | 切換預存 | 切換現有行的狀態 (已預存/未預存) |
|
||||
| `` d `` | 刪除變更 (git reset) | When unstaged change is selected, discard the change using `git reset`. When staged change is selected, unstage the change. |
|
||||
| `` o `` | 開啟檔案 | Open file in default application. |
|
||||
| `` e `` | 編輯檔案 | Open file in external editor. |
|
||||
| `` <esc> `` | 返回檔案面板 | |
|
||||
| `` <tab> `` | 切換至另一個面板 (已預存/未預存更改) | Switch to other view (staged/unstaged changes). |
|
||||
| `` E `` | 編輯程式碼塊 | Edit selected hunk in external editor. |
|
||||
| `` c `` | 提交變更 | Commit staged changes. |
|
||||
| `` w `` | 沒有預提交 hook 就提交更改 | |
|
||||
| `` C `` | 使用 git 編輯器提交變更 | |
|
||||
| `` / `` | 開始搜尋 | |
|
||||
|
||||
## 主面板 (補丁生成)
|
||||
|
||||
<pre>
|
||||
<kbd><left></kbd>: 選擇上一段
|
||||
<kbd><right></kbd>: 選擇下一段
|
||||
<kbd>v</kbd>: 切換拖曳選擇
|
||||
<kbd>V</kbd>: 切換拖曳選擇
|
||||
<kbd>a</kbd>: 切換選擇程式碼塊
|
||||
<kbd><c-o></kbd>: 複製所選文本至剪貼簿
|
||||
<kbd>o</kbd>: 開啟檔案
|
||||
<kbd>e</kbd>: 編輯檔案
|
||||
<kbd><space></kbd>: 向 (或從) 補丁中添加/刪除行
|
||||
<kbd><esc></kbd>: 退出自訂補丁建立器
|
||||
<kbd>/</kbd>: 開始搜尋
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <left> `` | 選擇上一段 | |
|
||||
| `` <right> `` | 選擇下一段 | |
|
||||
| `` v `` | 切換拖曳選擇 | |
|
||||
| `` a `` | 切換選擇程式碼塊 | Toggle hunk selection mode. |
|
||||
| `` <c-o> `` | 複製所選文本至剪貼簿 | |
|
||||
| `` o `` | 開啟檔案 | Open file in default application. |
|
||||
| `` e `` | 編輯檔案 | Open file in external editor. |
|
||||
| `` <space> `` | 向 (或從) 補丁中添加/刪除行 | |
|
||||
| `` <esc> `` | 退出自訂補丁建立器 | |
|
||||
| `` / `` | 開始搜尋 | |
|
||||
|
||||
## 功能表
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: 執行
|
||||
<kbd><esc></kbd>: 關閉
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | 執行 | |
|
||||
| `` <esc> `` | 關閉 | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 子提交
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 複製提交 SHA 到剪貼簿
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: 檢出提交
|
||||
<kbd>y</kbd>: 複製提交屬性
|
||||
<kbd>o</kbd>: 在瀏覽器中開啟提交
|
||||
<kbd>n</kbd>: 從提交建立新分支
|
||||
<kbd>g</kbd>: 檢視重設選項
|
||||
<kbd>c</kbd>: 複製提交 (揀選)
|
||||
<kbd>C</kbd>: 複製提交範圍 (揀選)
|
||||
<kbd><c-r></kbd>: 重設選定的揀選 (複製) 提交
|
||||
<kbd><enter></kbd>: 檢視所選項目的檔案
|
||||
<kbd>/</kbd>: 開始搜尋
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 複製提交 SHA 到剪貼簿 | |
|
||||
| `` <space> `` | 檢出 | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | 複製提交屬性 | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | 在瀏覽器中開啟提交 | |
|
||||
| `` n `` | 從提交建立新分支 | |
|
||||
| `` g `` | 檢視重設選項 | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | 複製提交 (揀選) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-r> `` | 重設選定的揀選 (複製) 提交 | |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | 檢視所選項目的檔案 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | 開始搜尋 | |
|
||||
|
||||
## 子模組
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 複製子模組名稱到剪貼簿
|
||||
<kbd><enter></kbd>: 進入子模組
|
||||
<kbd><space></kbd>: 進入子模組
|
||||
<kbd>d</kbd>: 移除子模組
|
||||
<kbd>u</kbd>: 更新子模組
|
||||
<kbd>n</kbd>: 新增子模組
|
||||
<kbd>e</kbd>: 更新子模組 URL
|
||||
<kbd>i</kbd>: 初始化子模組
|
||||
<kbd>b</kbd>: 查看批量子模組選項
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 複製子模組名稱到剪貼簿 | |
|
||||
| `` <enter> `` | Enter | 進入子模組 |
|
||||
| `` d `` | Remove | Remove the selected submodule and its corresponding directory. |
|
||||
| `` u `` | Update | 更新子模組 |
|
||||
| `` n `` | 新增子模組 | |
|
||||
| `` e `` | 更新子模組 URL | |
|
||||
| `` i `` | Initialize | 初始化子模組 |
|
||||
| `` b `` | 查看批量子模組選項 | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 提交
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 複製提交 SHA 到剪貼簿
|
||||
<kbd><c-r></kbd>: 重設選定的揀選 (複製) 提交
|
||||
<kbd>b</kbd>: 查看二分選項
|
||||
<kbd>s</kbd>: 向下壓縮
|
||||
<kbd>f</kbd>: 修復提交 (Fixup)
|
||||
<kbd>r</kbd>: 改寫提交
|
||||
<kbd>R</kbd>: 使用編輯器改寫提交
|
||||
<kbd>d</kbd>: 刪除提交
|
||||
<kbd>e</kbd>: 編輯提交
|
||||
<kbd>p</kbd>: 挑選提交 (於變基過程中)
|
||||
<kbd>F</kbd>: 為此提交建立修復提交
|
||||
<kbd>S</kbd>: 壓縮上方所有的“fixup!”提交 (自動壓縮)
|
||||
<kbd><c-j></kbd>: 向下移動提交
|
||||
<kbd><c-k></kbd>: 向上移動提交
|
||||
<kbd>v</kbd>: 貼上提交 (揀選)
|
||||
<kbd>B</kbd>: Mark commit as base commit for rebase
|
||||
<kbd>A</kbd>: 使用已預存的更改修正提交
|
||||
<kbd>a</kbd>: 設置/重設提交作者
|
||||
<kbd>t</kbd>: 還原提交
|
||||
<kbd>T</kbd>: 打標籤到提交
|
||||
<kbd><c-l></kbd>: 開啟記錄選單
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><space></kbd>: 檢出提交
|
||||
<kbd>y</kbd>: 複製提交屬性
|
||||
<kbd>o</kbd>: 在瀏覽器中開啟提交
|
||||
<kbd>n</kbd>: 從提交建立新分支
|
||||
<kbd>g</kbd>: 檢視重設選項
|
||||
<kbd>c</kbd>: 複製提交 (揀選)
|
||||
<kbd>C</kbd>: 複製提交範圍 (揀選)
|
||||
<kbd><enter></kbd>: 檢視所選項目的檔案
|
||||
<kbd>/</kbd>: 開始搜尋
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 複製提交 SHA 到剪貼簿 | |
|
||||
| `` <c-r> `` | 重設選定的揀選 (複製) 提交 | |
|
||||
| `` b `` | 查看二分選項 | |
|
||||
| `` s `` | 壓縮 (Squash) | Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it. |
|
||||
| `` f `` | 修復 (Fixup) | Meld the selected commit into the commit below it. Similar to fixup, but the selected commit's message will be discarded. |
|
||||
| `` r `` | 改寫提交 | Reword the selected commit's message. |
|
||||
| `` R `` | 使用編輯器改寫提交 | |
|
||||
| `` d `` | 刪除提交 | Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts. |
|
||||
| `` e `` | Edit (start interactive rebase) | 編輯提交 |
|
||||
| `` i `` | Start interactive rebase | Start an interactive rebase for the commits on your branch. This will include all commits from the HEAD commit down to the first merge commit or main branch commit.
|
||||
If you would instead like to start an interactive rebase from the selected commit, press `e`. |
|
||||
| `` p `` | Pick | 挑選提交 (於變基過程中) |
|
||||
| `` F `` | Create fixup commit | 為此提交建立修復提交 |
|
||||
| `` S `` | Apply fixup commits | 壓縮上方所有的“fixup!”提交 (自動壓縮) |
|
||||
| `` <c-j> `` | 向下移動提交 | |
|
||||
| `` <c-k> `` | 向上移動提交 | |
|
||||
| `` V `` | 貼上提交 (揀選) | |
|
||||
| `` B `` | Mark as base commit for rebase | Select a base commit for the next rebase. When you rebase onto a branch, only commits above the base commit will be brought across. This uses the `git rebase --onto` command. |
|
||||
| `` A `` | Amend | 使用已預存的更改修正提交 |
|
||||
| `` a `` | 設置/重設提交作者 | Set/Reset commit author or set co-author. |
|
||||
| `` t `` | Revert | Create a revert commit for the selected commit, which applies the selected commit's changes in reverse. |
|
||||
| `` T `` | 打標籤到提交 | Create a new tag pointing at the selected commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` <c-l> `` | 開啟記錄選單 | View options for commit log e.g. changing sort order, hiding the git graph, showing the whole git graph. |
|
||||
| `` <space> `` | 檢出 | Checkout the selected commit as a detached HEAD. |
|
||||
| `` y `` | 複製提交屬性 | Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author). |
|
||||
| `` o `` | 在瀏覽器中開啟提交 | |
|
||||
| `` n `` | 從提交建立新分支 | |
|
||||
| `` g `` | 檢視重設選項 | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` C `` | 複製提交 (揀選) | Mark commit as copied. Then, within the local commits view, you can press `V` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `<esc>` to cancel the selection. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <enter> `` | 檢視所選項目的檔案 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | 開始搜尋 | |
|
||||
|
||||
## 提交摘要
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: 確認
|
||||
<kbd><esc></kbd>: 關閉
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | 確認 | |
|
||||
| `` <esc> `` | 關閉 | |
|
||||
|
||||
## 提交檔案
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 複製提交的檔案名稱到剪貼簿
|
||||
<kbd>c</kbd>: 檢出檔案
|
||||
<kbd>d</kbd>: 捨棄此提交對此檔案的更改
|
||||
<kbd>o</kbd>: 開啟檔案
|
||||
<kbd>e</kbd>: 編輯檔案
|
||||
<kbd><space></kbd>: 切換檔案是否包含在補丁中
|
||||
<kbd>a</kbd>: 切換所有檔案是否包含在補丁中
|
||||
<kbd><enter></kbd>: 輸入檔案以將選定的行添加至補丁(或切換目錄折疊)
|
||||
<kbd>`</kbd>: 切換檔案樹狀視圖
|
||||
<kbd>/</kbd>: 開始搜尋
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 複製檔案名稱到剪貼簿 | |
|
||||
| `` c `` | 檢出 | 檢出檔案 |
|
||||
| `` d `` | Remove | 捨棄此提交對此檔案的更改 |
|
||||
| `` o `` | 開啟檔案 | Open file in default application. |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` <space> `` | 切換檔案是否包含在補丁中 | Toggle whether the file is included in the custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` a `` | 切換所有檔案是否包含在補丁中 | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. |
|
||||
| `` <enter> `` | 輸入檔案以將選定的行添加至補丁(或切換目錄折疊) | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. |
|
||||
| `` ` `` | 切換檔案樹狀視圖 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` / `` | 開始搜尋 | |
|
||||
|
||||
## 收藏 (Stash)
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: 套用
|
||||
<kbd>g</kbd>: 還原
|
||||
<kbd>d</kbd>: 捨棄
|
||||
<kbd>n</kbd>: 新分支
|
||||
<kbd>r</kbd>: 重新命名收藏
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: 檢視所選項目的檔案
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | 套用 | Apply the stash entry to your working directory. |
|
||||
| `` g `` | 還原 | Apply the stash entry to your working directory and remove the stash entry. |
|
||||
| `` d `` | 捨棄 | Remove the stash entry from the stash list. |
|
||||
| `` n `` | 新分支 | Create a new branch from the selected stash entry. This works by git checking out the commit that the stash entry was created from, creating a new branch from that commit, then applying the stash entry to the new branch as an additional commit. |
|
||||
| `` r `` | 重新命名收藏 | |
|
||||
| `` <enter> `` | 檢視所選項目的檔案 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 本地分支
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 複製分支名稱到剪貼簿
|
||||
<kbd>i</kbd>: 顯示 git-flow 選項
|
||||
<kbd><space></kbd>: 檢出
|
||||
<kbd>n</kbd>: 新分支
|
||||
<kbd>o</kbd>: 建立拉取請求
|
||||
<kbd>O</kbd>: 建立拉取請求選項
|
||||
<kbd><c-y></kbd>: 複製拉取請求的 URL 到剪貼板
|
||||
<kbd>c</kbd>: 根據名稱檢出
|
||||
<kbd>F</kbd>: 強制檢出
|
||||
<kbd>d</kbd>: 刪除分支
|
||||
<kbd>r</kbd>: 將已檢出的分支變基至此分支
|
||||
<kbd>M</kbd>: 合併到當前檢出的分支
|
||||
<kbd>f</kbd>: 從上游快進此分支
|
||||
<kbd>T</kbd>: 建立標籤
|
||||
<kbd>g</kbd>: 檢視重設選項
|
||||
<kbd>R</kbd>: 重新命名分支
|
||||
<kbd>u</kbd>: 設定/取消設定上游
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: 檢視提交
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 複製分支名稱到剪貼簿 | |
|
||||
| `` i `` | 顯示 git-flow 選項 | |
|
||||
| `` <space> `` | 檢出 | Checkout selected item. |
|
||||
| `` n `` | 新分支 | |
|
||||
| `` o `` | 建立拉取請求 | |
|
||||
| `` O `` | 建立拉取請求選項 | |
|
||||
| `` <c-y> `` | 複製拉取請求的 URL 到剪貼板 | |
|
||||
| `` c `` | 根據名稱檢出 | Checkout by name. In the input box you can enter '-' to switch to the last branch. |
|
||||
| `` F `` | 強制檢出 | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||
| `` r `` | 將已檢出的分支變基至此分支 | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` M `` | 合併到當前檢出的分支 | Merge selected branch into currently checked out branch. |
|
||||
| `` f `` | 從上游快進此分支 | Fast-forward selected branch from its upstream. |
|
||||
| `` T `` | 建立標籤 | |
|
||||
| `` s `` | Sort order | |
|
||||
| `` g `` | 檢視重設選項 | |
|
||||
| `` R `` | 重新命名分支 | |
|
||||
| `` u `` | View upstream options | View options relating to the branch's upstream e.g. setting/unsetting the upstream and resetting to the upstream. |
|
||||
| `` <enter> `` | 檢視提交 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 標籤
|
||||
|
||||
<pre>
|
||||
<kbd><space></kbd>: 檢出
|
||||
<kbd>d</kbd>: 刪除標籤
|
||||
<kbd>P</kbd>: 推送標籤
|
||||
<kbd>n</kbd>: 建立標籤
|
||||
<kbd>g</kbd>: 檢視重設選項
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: 檢視提交
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <space> `` | 檢出 | Checkout the selected tag tag as a detached HEAD. |
|
||||
| `` n `` | 建立標籤 | Create new tag from current commit. You'll be prompted to enter a tag name and optional description. |
|
||||
| `` d `` | Delete | View delete options for local/remote tag. |
|
||||
| `` P `` | 推送標籤 | Push the selected tag to a remote. You'll be prompted to select a remote. |
|
||||
| `` g `` | Reset | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | 檢視提交 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 檔案
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 複製檔案名稱到剪貼簿
|
||||
<kbd>d</kbd>: 檢視“捨棄更改”的選項
|
||||
<kbd><space></kbd>: 切換預存
|
||||
<kbd><c-b></kbd>: 篩選檔案 (預存/未預存)
|
||||
<kbd>c</kbd>: 提交變更
|
||||
<kbd>w</kbd>: 沒有預提交 hook 就提交更改
|
||||
<kbd>A</kbd>: 修正上次提交
|
||||
<kbd>C</kbd>: 使用 git 編輯器提交變更
|
||||
<kbd>e</kbd>: 編輯檔案
|
||||
<kbd>o</kbd>: 開啟檔案
|
||||
<kbd>i</kbd>: 忽略或排除檔案
|
||||
<kbd>r</kbd>: 重新整理檔案
|
||||
<kbd>s</kbd>: 收藏所有變更
|
||||
<kbd>S</kbd>: 檢視收藏選項
|
||||
<kbd>a</kbd>: 全部預存/取消預存
|
||||
<kbd><enter></kbd>: 選擇檔案中的單個程式碼塊/行,或展開/折疊目錄
|
||||
<kbd>g</kbd>: 檢視上游重設選項
|
||||
<kbd>D</kbd>: 檢視重設選項
|
||||
<kbd>`</kbd>: 切換檔案樹狀視圖
|
||||
<kbd>M</kbd>: 開啟外部合併工具 (git mergetool)
|
||||
<kbd>f</kbd>: 擷取
|
||||
<kbd>/</kbd>: 開始搜尋
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 複製檔案名稱到剪貼簿 | |
|
||||
| `` <space> `` | 切換預存 | Toggle staged for selected file. |
|
||||
| `` <c-b> `` | 篩選檔案 (預存/未預存) | |
|
||||
| `` y `` | Copy to clipboard | |
|
||||
| `` c `` | 提交變更 | Commit staged changes. |
|
||||
| `` w `` | 沒有預提交 hook 就提交更改 | |
|
||||
| `` A `` | 修正上次提交 | |
|
||||
| `` C `` | 使用 git 編輯器提交變更 | |
|
||||
| `` <c-f> `` | Find base commit for fixup | Find the commit that your current changes are building upon, for the sake of amending/fixing up the commit. This spares you from having to look through your branch's commits one-by-one to see which commit should be amended/fixed up. See docs: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md> |
|
||||
| `` e `` | Edit | Open file in external editor. |
|
||||
| `` o `` | 開啟檔案 | Open file in default application. |
|
||||
| `` i `` | 忽略或排除檔案 | |
|
||||
| `` r `` | 重新整理檔案 | |
|
||||
| `` s `` | Stash | Stash all changes. For other variations of stashing, use the view stash options keybinding. |
|
||||
| `` S `` | 檢視收藏選項 | View stash options (e.g. stash all, stash staged, stash unstaged). |
|
||||
| `` a `` | 全部預存/取消預存 | Toggle staged/unstaged for all files in working tree. |
|
||||
| `` <enter> `` | 選擇檔案中的單個程式碼塊/行,或展開/折疊目錄 | If the selected item is a file, focus the staging view so you can stage individual hunks/lines. If the selected item is a directory, collapse/expand it. |
|
||||
| `` d `` | 檢視“捨棄更改”的選項 | View options for discarding changes to the selected file. |
|
||||
| `` g `` | 檢視上游重設選項 | |
|
||||
| `` D `` | Reset | View reset options for working tree (e.g. nuking the working tree). |
|
||||
| `` ` `` | 切換檔案樹狀視圖 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. |
|
||||
| `` <c-t> `` | Open external diff tool (git difftool) | |
|
||||
| `` M `` | 開啟外部合併工具 (git mergetool) | Run `git mergetool`. |
|
||||
| `` f `` | 擷取 | Fetch changes from remote. |
|
||||
| `` / `` | 開始搜尋 | |
|
||||
|
||||
## 狀態
|
||||
|
||||
<pre>
|
||||
<kbd>o</kbd>: 開啟設定檔案
|
||||
<kbd>e</kbd>: 編輯設定檔案
|
||||
<kbd>u</kbd>: 檢查更新
|
||||
<kbd><enter></kbd>: 切換到最近使用的版本庫
|
||||
<kbd>a</kbd>: 顯示所有分支日誌
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` o `` | 開啟設定檔案 | Open file in default application. |
|
||||
| `` e `` | 編輯設定檔案 | Open file in external editor. |
|
||||
| `` u `` | 檢查更新 | |
|
||||
| `` <enter> `` | 切換到最近使用的版本庫 | |
|
||||
| `` a `` | 顯示所有分支日誌 | |
|
||||
|
||||
## 確認面板
|
||||
|
||||
<pre>
|
||||
<kbd><enter></kbd>: 確認
|
||||
<kbd><esc></kbd>: 關閉/取消
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | 確認 | |
|
||||
| `` <esc> `` | 關閉/取消 | |
|
||||
|
||||
## 遠端
|
||||
|
||||
<pre>
|
||||
<kbd>f</kbd>: 擷取遠端
|
||||
<kbd>n</kbd>: 新增遠端
|
||||
<kbd>d</kbd>: 移除遠端
|
||||
<kbd>e</kbd>: 編輯遠端
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <enter> `` | View branches | |
|
||||
| `` n `` | 新增遠端 | |
|
||||
| `` d `` | Remove | Remove the selected remote. Any local branches tracking a remote branch from the remote will be unaffected. |
|
||||
| `` e `` | Edit | 編輯遠端 |
|
||||
| `` f `` | 擷取 | 擷取遠端 |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
## 遠端分支
|
||||
|
||||
<pre>
|
||||
<kbd><c-o></kbd>: 複製分支名稱到剪貼簿
|
||||
<kbd><space></kbd>: 檢出
|
||||
<kbd>n</kbd>: 新分支
|
||||
<kbd>M</kbd>: 合併到當前檢出的分支
|
||||
<kbd>r</kbd>: 將已檢出的分支變基至此分支
|
||||
<kbd>d</kbd>: 刪除分支
|
||||
<kbd>u</kbd>: 將此分支設為當前分支之上游
|
||||
<kbd>g</kbd>: 檢視重設選項
|
||||
<kbd>w</kbd>: View worktree options
|
||||
<kbd><enter></kbd>: 檢視提交
|
||||
<kbd>/</kbd>: Filter the current view by text
|
||||
</pre>
|
||||
| Key | Action | Info |
|
||||
|-----|--------|-------------|
|
||||
| `` <c-o> `` | 複製分支名稱到剪貼簿 | |
|
||||
| `` <space> `` | 檢出 | Checkout a new local branch based on the selected remote branch. The new branch will track the remote branch. |
|
||||
| `` n `` | 新分支 | |
|
||||
| `` M `` | 合併到當前檢出的分支 | Merge selected branch into currently checked out branch. |
|
||||
| `` r `` | 將已檢出的分支變基至此分支 | Rebase the checked-out branch onto the selected branch. |
|
||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||
| `` u `` | Set as upstream | 將此分支設為當前分支之上游 |
|
||||
| `` s `` | Sort order | |
|
||||
| `` g `` | 檢視重設選項 | View reset options (soft/mixed/hard) for resetting onto selected item. |
|
||||
| `` <enter> `` | 檢視提交 | |
|
||||
| `` w `` | View worktree options | |
|
||||
| `` / `` | Filter the current view by text | |
|
||||
|
||||
25
go.mod
25
go.mod
@@ -9,23 +9,25 @@ require (
|
||||
github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
|
||||
github.com/creack/pty v1.1.11
|
||||
github.com/fsmiamoto/git-todo-parser v0.0.5
|
||||
github.com/go-errors/errors v1.4.2
|
||||
github.com/gdamore/tcell/v2 v2.7.1-0.20240121011954-0393f5eb0b1a
|
||||
github.com/go-errors/errors v1.5.1
|
||||
github.com/gookit/color v1.4.2
|
||||
github.com/imdario/mergo v0.3.11
|
||||
github.com/integrii/flaggy v1.4.0
|
||||
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68
|
||||
github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20230806095321-ac7b03108825
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20240129213945-26fc8669eb5b
|
||||
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10
|
||||
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5
|
||||
github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e
|
||||
github.com/jesseduffield/yaml v2.1.0+incompatible
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
|
||||
github.com/karimkhaleel/jsonschema v0.0.0-20231001195015-d933f0d94ea3
|
||||
github.com/kyokomi/emoji/v2 v2.2.8
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0
|
||||
github.com/mattn/go-runewidth v0.0.15
|
||||
github.com/mgutz/str v1.2.0
|
||||
github.com/pmezard/go-difflib v1.0.0
|
||||
github.com/mitchellh/go-ps v1.0.0
|
||||
github.com/sahilm/fuzzy v0.1.0
|
||||
github.com/samber/lo v1.31.0
|
||||
github.com/sanity-io/litter v1.5.2
|
||||
@@ -33,8 +35,7 @@ require (
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/spf13/afero v1.9.5
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad
|
||||
github.com/stefanhaller/tcell/v2 v2.6.2-0.20230806061358-2dfa11eddb68
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778
|
||||
golang.org/x/exp v0.0.0-20220318154914-8dddf5d87bd8
|
||||
gopkg.in/ozeidan/fuzzy-patricia.v3 v3.0.0
|
||||
@@ -42,6 +43,8 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/emirpasic/gods v1.12.0 // indirect
|
||||
github.com/fatih/color v1.9.0 // indirect
|
||||
@@ -51,24 +54,28 @@ require (
|
||||
github.com/go-logfmt/logfmt v0.5.0 // indirect
|
||||
github.com/gobwas/glob v0.2.3 // indirect
|
||||
github.com/google/go-cmp v0.5.6 // indirect
|
||||
github.com/invopop/jsonschema v0.10.0 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd // indirect
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.11 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/onsi/ginkgo v1.10.3 // indirect
|
||||
github.com/onsi/gomega v1.7.1 // indirect
|
||||
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.6 // indirect
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
|
||||
github.com/xanzy/ssh-agent v0.2.1 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/sys v0.11.0 // indirect
|
||||
golang.org/x/term v0.11.0 // indirect
|
||||
golang.org/x/text v0.12.0 // indirect
|
||||
golang.org/x/sys v0.16.0 // indirect
|
||||
golang.org/x/term v0.16.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
)
|
||||
|
||||
58
go.sum
58
go.sum
@@ -51,6 +51,10 @@ github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn
|
||||
github.com/aybabtme/humanlog v0.4.1 h1:D8d9um55rrthJsP8IGSHBcti9lTb/XknmDAX6Zy8tek=
|
||||
github.com/aybabtme/humanlog v0.4.1/go.mod h1:B0bnQX4FTSU3oftPMTTPvENCy8LqixLDvYJA9TUCAGo=
|
||||
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
|
||||
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
@@ -85,11 +89,14 @@ github.com/fsmiamoto/git-todo-parser v0.0.5/go.mod h1:B+AgTbNE2BARvJqzXygThzqxLI
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
|
||||
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
|
||||
github.com/gdamore/tcell/v2 v2.7.1-0.20240103180601-96e29905643b/go.mod h1:hl/KtAANGBecfIPxk+FzKvThTqI84oplgbPEmVX60b8=
|
||||
github.com/gdamore/tcell/v2 v2.7.1-0.20240121011954-0393f5eb0b1a h1:IgatwqPZL0RPblLezzibmx8GgARDjOQOvrLpCWLmZak=
|
||||
github.com/gdamore/tcell/v2 v2.7.1-0.20240121011954-0393f5eb0b1a/go.mod h1:hl/KtAANGBecfIPxk+FzKvThTqI84oplgbPEmVX60b8=
|
||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
|
||||
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
|
||||
github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
|
||||
github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
|
||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM=
|
||||
@@ -173,14 +180,16 @@ github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/integrii/flaggy v1.4.0 h1:A1x7SYx4jqu5NSrY14z8Z+0UyX2S5ygfJJrfolWR3zM=
|
||||
github.com/integrii/flaggy v1.4.0/go.mod h1:tnTxHeTJbah0gQ6/K0RW0J7fMUBk9MCF5blhm43LNpI=
|
||||
github.com/invopop/jsonschema v0.10.0 h1:c1ktzNLBun3LyQQhyty5WE3lulbOdIIyOVlkmDLehcE=
|
||||
github.com/invopop/jsonschema v0.10.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 h1:EQP2Tv8TIcC6Y4RI+1ZbJDOHfGJ570tPeYVCqo7/tws=
|
||||
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk=
|
||||
github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d h1:bO+OmbreIv91rCe8NmscRwhFSqkDJtzWCPV4Y+SQuXE=
|
||||
github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20230806095321-ac7b03108825 h1:4Ea8qV/BbZAGcXd8MAufDsbwwfz2pbRZdqIodC/XHZs=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20230806095321-ac7b03108825/go.mod h1:trXE7RRGL2hTsv+Ntk+SHLtRobg9JE138n3Ug/X2Cf4=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20240129213945-26fc8669eb5b h1:QASuIUc76BuFmSuzzqwzjpsn23r8ybfDqbKsY2WzTrE=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20240129213945-26fc8669eb5b/go.mod h1:9zkyjnUmdL3+sUknJrQy/3HweUu8mVln/3J2wRF/l8M=
|
||||
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 h1:jmpr7KpX2+2GRiE91zTgfq49QvgiqB0nbmlwZ8UnOx0=
|
||||
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10/go.mod h1:aA97kHeNA+sj2Hbki0pvLslmE4CbDyhBeSSTUUnOuVo=
|
||||
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY=
|
||||
@@ -190,10 +199,13 @@ github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e/
|
||||
github.com/jesseduffield/yaml v2.1.0+incompatible h1:HWQJ1gIv2zHKbDYNp0Jwjlj24K8aqpFHnMCynY1EpmE=
|
||||
github.com/jesseduffield/yaml v2.1.0+incompatible/go.mod h1:w0xGhOSIJCGYYW+hnFPTutCy5aACpkcwbmORt5axGqk=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/karimkhaleel/jsonschema v0.0.0-20231001195015-d933f0d94ea3 h1:s995u+gNQADMaixtNOs+jilRC/Q78q0UXSI7+4T0cDE=
|
||||
github.com/karimkhaleel/jsonschema v0.0.0-20231001195015-d933f0d94ea3/go.mod h1:MCbEh21gjOzxc31udr3u4QM9DAdf8TFJCZz3u5hYIxA=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
@@ -214,6 +226,8 @@ github.com/kyokomi/emoji/v2 v2.2.8 h1:jcofPxjHWEkJtkIbcLHvZhxKgCPl6C7MyjTrD4KDqU
|
||||
github.com/kyokomi/emoji/v2 v2.2.8/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
|
||||
@@ -223,13 +237,14 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mgutz/str v1.2.0 h1:4IzWSdIz9qPQWLfKZ0rJcV0jcUDpxvP4JVZ4GXQyvSw=
|
||||
github.com/mgutz/str v1.2.0/go.mod h1:w1v0ofgLaJdoD0HpQ3fycxKD1WtxpjSo151pK/31q6w=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
|
||||
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
@@ -249,8 +264,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rivo/uniseg v0.4.6 h1:Sovz9sDSwbOz9tgUy8JpT+KgCkPYJEN/oYzlJiYTNLg=
|
||||
github.com/rivo/uniseg v0.4.6/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI=
|
||||
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
|
||||
@@ -268,12 +283,11 @@ github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
|
||||
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad h1:fiWzISvDn0Csy5H0iwgAuJGQTUpVfEMJJd4nRFXogbc=
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||
github.com/stefanhaller/tcell/v2 v2.6.2-0.20230806061358-2dfa11eddb68 h1:NSTj9xAKUu85d6pAdNFyblL84BfiOB1rVnzxQO/cYUk=
|
||||
github.com/stefanhaller/tcell/v2 v2.6.2-0.20230806061358-2dfa11eddb68/go.mod h1:PuJ7T6QKbsU7iVOHlhRoV3D/ipIAJsyiV4dbwcVaYj8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v0.0.0-20161117074351-18a02ba4a312/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
@@ -281,10 +295,13 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
|
||||
github.com/urfave/cli v1.20.1-0.20180226030253-8e01ec4cd3e2/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
|
||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
|
||||
@@ -347,6 +364,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -381,6 +399,7 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@@ -403,6 +422,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20170407050850-f3918c30c5c2/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -450,14 +470,15 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -467,8 +488,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -520,6 +541,7 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/env"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui"
|
||||
"github.com/jesseduffield/lazygit/pkg/i18n"
|
||||
integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/logs"
|
||||
"github.com/jesseduffield/lazygit/pkg/updates"
|
||||
)
|
||||
@@ -42,7 +43,7 @@ func Run(
|
||||
common *common.Common,
|
||||
startArgs appTypes.StartArgs,
|
||||
) {
|
||||
app, err := NewApp(config, common)
|
||||
app, err := NewApp(config, startArgs.IntegrationTest, common)
|
||||
|
||||
if err == nil {
|
||||
err = app.Run(startArgs)
|
||||
@@ -62,6 +63,7 @@ func Run(
|
||||
|
||||
func NewCommon(config config.AppConfigurer) (*common.Common, error) {
|
||||
userConfig := config.GetUserConfig()
|
||||
appState := config.GetAppState()
|
||||
|
||||
var err error
|
||||
log := newLogger(config)
|
||||
@@ -74,6 +76,7 @@ func NewCommon(config config.AppConfigurer) (*common.Common, error) {
|
||||
Log: log,
|
||||
Tr: tr,
|
||||
UserConfig: userConfig,
|
||||
AppState: appState,
|
||||
Debug: config.GetDebug(),
|
||||
Fs: afero.NewOsFs(),
|
||||
}, nil
|
||||
@@ -92,7 +95,7 @@ func newLogger(cfg config.AppConfigurer) *logrus.Entry {
|
||||
}
|
||||
|
||||
// NewApp bootstrap a new application
|
||||
func NewApp(config config.AppConfigurer, common *common.Common) (*App, error) {
|
||||
func NewApp(config config.AppConfigurer, test integrationTypes.IntegrationTest, common *common.Common) (*App, error) {
|
||||
app := &App{
|
||||
closers: []io.Closer{},
|
||||
Config: config,
|
||||
@@ -126,7 +129,7 @@ func NewApp(config config.AppConfigurer, common *common.Common) (*App, error) {
|
||||
showRecentRepos = true
|
||||
}
|
||||
|
||||
app.Gui, err = gui.NewGui(common, config, gitVersion, updater, showRecentRepos, dirName)
|
||||
app.Gui, err = gui.NewGui(common, config, gitVersion, updater, showRecentRepos, dirName, test)
|
||||
if err != nil {
|
||||
return app, err
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ const (
|
||||
|
||||
DaemonKindExitImmediately
|
||||
DaemonKindCherryPick
|
||||
DaemonKindMoveTodoUp
|
||||
DaemonKindMoveTodoDown
|
||||
DaemonKindMoveTodosUp
|
||||
DaemonKindMoveTodosDown
|
||||
DaemonKindInsertBreak
|
||||
DaemonKindChangeTodoActions
|
||||
DaemonKindMoveFixupCommitDown
|
||||
@@ -56,8 +56,8 @@ func getInstruction() Instruction {
|
||||
DaemonKindCherryPick: deserializeInstruction[*CherryPickCommitsInstruction],
|
||||
DaemonKindChangeTodoActions: deserializeInstruction[*ChangeTodoActionsInstruction],
|
||||
DaemonKindMoveFixupCommitDown: deserializeInstruction[*MoveFixupCommitDownInstruction],
|
||||
DaemonKindMoveTodoUp: deserializeInstruction[*MoveTodoUpInstruction],
|
||||
DaemonKindMoveTodoDown: deserializeInstruction[*MoveTodoDownInstruction],
|
||||
DaemonKindMoveTodosUp: deserializeInstruction[*MoveTodosUpInstruction],
|
||||
DaemonKindMoveTodosDown: deserializeInstruction[*MoveTodosDownInstruction],
|
||||
DaemonKindInsertBreak: deserializeInstruction[*InsertBreakInstruction],
|
||||
}
|
||||
|
||||
@@ -208,13 +208,15 @@ func (self *ChangeTodoActionsInstruction) SerializedInstructions() string {
|
||||
|
||||
func (self *ChangeTodoActionsInstruction) run(common *common.Common) error {
|
||||
return handleInteractiveRebase(common, func(path string) error {
|
||||
for _, c := range self.Changes {
|
||||
if err := utils.EditRebaseTodo(path, c.Sha, todo.Pick, c.NewAction, getCommentChar()); err != nil {
|
||||
return err
|
||||
changes := lo.Map(self.Changes, func(c ChangeTodoAction, _ int) utils.TodoChange {
|
||||
return utils.TodoChange{
|
||||
Sha: c.Sha,
|
||||
OldAction: todo.Pick,
|
||||
NewAction: c.NewAction,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return nil
|
||||
return utils.EditRebaseTodo(path, changes, getCommentChar())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -247,51 +249,65 @@ func (self *MoveFixupCommitDownInstruction) run(common *common.Common) error {
|
||||
})
|
||||
}
|
||||
|
||||
type MoveTodoUpInstruction struct {
|
||||
Sha string
|
||||
type MoveTodosUpInstruction struct {
|
||||
Shas []string
|
||||
}
|
||||
|
||||
func NewMoveTodoUpInstruction(sha string) Instruction {
|
||||
return &MoveTodoUpInstruction{
|
||||
Sha: sha,
|
||||
func NewMoveTodosUpInstruction(shas []string) Instruction {
|
||||
return &MoveTodosUpInstruction{
|
||||
Shas: shas,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *MoveTodoUpInstruction) Kind() DaemonKind {
|
||||
return DaemonKindMoveTodoUp
|
||||
func (self *MoveTodosUpInstruction) Kind() DaemonKind {
|
||||
return DaemonKindMoveTodosUp
|
||||
}
|
||||
|
||||
func (self *MoveTodoUpInstruction) SerializedInstructions() string {
|
||||
func (self *MoveTodosUpInstruction) SerializedInstructions() string {
|
||||
return serializeInstruction(self)
|
||||
}
|
||||
|
||||
func (self *MoveTodoUpInstruction) run(common *common.Common) error {
|
||||
func (self *MoveTodosUpInstruction) run(common *common.Common) error {
|
||||
todosToMove := lo.Map(self.Shas, func(sha string, _ int) utils.Todo {
|
||||
return utils.Todo{
|
||||
Sha: sha,
|
||||
Action: todo.Pick,
|
||||
}
|
||||
})
|
||||
|
||||
return handleInteractiveRebase(common, func(path string) error {
|
||||
return utils.MoveTodoUp(path, self.Sha, todo.Pick, getCommentChar())
|
||||
return utils.MoveTodosUp(path, todosToMove, getCommentChar())
|
||||
})
|
||||
}
|
||||
|
||||
type MoveTodoDownInstruction struct {
|
||||
Sha string
|
||||
type MoveTodosDownInstruction struct {
|
||||
Shas []string
|
||||
}
|
||||
|
||||
func NewMoveTodoDownInstruction(sha string) Instruction {
|
||||
return &MoveTodoDownInstruction{
|
||||
Sha: sha,
|
||||
func NewMoveTodosDownInstruction(shas []string) Instruction {
|
||||
return &MoveTodosDownInstruction{
|
||||
Shas: shas,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *MoveTodoDownInstruction) Kind() DaemonKind {
|
||||
return DaemonKindMoveTodoDown
|
||||
func (self *MoveTodosDownInstruction) Kind() DaemonKind {
|
||||
return DaemonKindMoveTodosDown
|
||||
}
|
||||
|
||||
func (self *MoveTodoDownInstruction) SerializedInstructions() string {
|
||||
func (self *MoveTodosDownInstruction) SerializedInstructions() string {
|
||||
return serializeInstruction(self)
|
||||
}
|
||||
|
||||
func (self *MoveTodoDownInstruction) run(common *common.Common) error {
|
||||
func (self *MoveTodosDownInstruction) run(common *common.Common) error {
|
||||
todosToMove := lo.Map(self.Shas, func(sha string, _ int) utils.Todo {
|
||||
return utils.Todo{
|
||||
Sha: sha,
|
||||
Action: todo.Pick,
|
||||
}
|
||||
})
|
||||
|
||||
return handleInteractiveRebase(common, func(path string) error {
|
||||
return utils.MoveTodoDown(path, self.Sha, todo.Pick, getCommentChar())
|
||||
return utils.MoveTodosDown(path, todosToMove, getCommentChar())
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -180,10 +180,10 @@ func parseCliArgsAndEnvVars() *cliArgs {
|
||||
useConfigDir := ""
|
||||
flaggy.String(&useConfigDir, "ucd", "use-config-dir", "override default config directory with provided directory")
|
||||
|
||||
workTree := ""
|
||||
workTree := os.Getenv("GIT_WORK_TREE")
|
||||
flaggy.String(&workTree, "w", "work-tree", "equivalent of the --work-tree git argument")
|
||||
|
||||
gitDir := ""
|
||||
gitDir := os.Getenv("GIT_DIR")
|
||||
flaggy.String(&gitDir, "g", "git-dir", "equivalent of the --git-dir git argument")
|
||||
|
||||
customConfigFile := ""
|
||||
|
||||
@@ -27,6 +27,10 @@ func knownError(tr *i18n.TranslationSet, err error) (string, bool) {
|
||||
originalError: "fatal: not a git repository",
|
||||
newError: tr.NotARepository,
|
||||
},
|
||||
{
|
||||
originalError: "getwd: no such file or directory",
|
||||
newError: tr.WorkingDirectoryDoesNotExist,
|
||||
},
|
||||
}
|
||||
|
||||
if mapping, ok := lo.Find(mappings, func(mapping errorMapping) bool {
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
package cheatsheet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
||||
"github.com/pmezard/go-difflib/difflib"
|
||||
)
|
||||
|
||||
func Check() {
|
||||
dir := GetKeybindingsDir()
|
||||
tmpDir := filepath.Join(os.TempDir(), "lazygit_cheatsheet")
|
||||
err := os.RemoveAll(tmpDir)
|
||||
if err != nil {
|
||||
log.Fatalf("Error occurred while checking if cheatsheets are up to date: %v", err)
|
||||
}
|
||||
err = os.Mkdir(tmpDir, 0o700)
|
||||
if err != nil {
|
||||
log.Fatalf("Error occurred while checking if cheatsheets are up to date: %v", err)
|
||||
}
|
||||
|
||||
generateAtDir(tmpDir)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
actualContent := obtainContent(dir)
|
||||
expectedContent := obtainContent(tmpDir)
|
||||
|
||||
if expectedContent == "" {
|
||||
log.Fatal("empty expected content")
|
||||
}
|
||||
|
||||
if actualContent != expectedContent {
|
||||
err := difflib.WriteUnifiedDiff(os.Stdout, difflib.UnifiedDiff{
|
||||
A: difflib.SplitLines(expectedContent),
|
||||
B: difflib.SplitLines(actualContent),
|
||||
FromFile: "Expected",
|
||||
FromDate: "",
|
||||
ToFile: "Actual",
|
||||
ToDate: "",
|
||||
Context: 1,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Error occurred while checking if cheatsheets are up to date: %v", err)
|
||||
}
|
||||
fmt.Printf("\nCheatsheets are out of date. Please run `%s` at the project root and commit the changes. If you run the script and no keybindings files are updated as a result, try rebasing onto master and trying again.\n", CommandToRun())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("\nCheatsheets are up to date")
|
||||
}
|
||||
|
||||
func obtainContent(dir string) string {
|
||||
re := regexp.MustCompile(`Keybindings_\w+\.md$`)
|
||||
|
||||
content := ""
|
||||
err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
|
||||
if re.MatchString(path) {
|
||||
bytes, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
log.Fatalf("Error occurred while checking if cheatsheets are up to date: %v", err)
|
||||
}
|
||||
content += fmt.Sprintf("\n%s\n\n", filepath.Base(path))
|
||||
content += string(bytes)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Error occurred while checking if cheatsheets are up to date: %v", err)
|
||||
}
|
||||
|
||||
return content
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
// This "script" generates a file called Keybindings_{{.LANG}}.md
|
||||
// in current working directory.
|
||||
//go:generate go run generator.go
|
||||
|
||||
// This "script" generates files called Keybindings_{{.LANG}}.md
|
||||
// in the docs/keybindings directory.
|
||||
//
|
||||
// The content of this generated file is a keybindings cheatsheet.
|
||||
// The content of these generated files is a keybindings cheatsheet.
|
||||
//
|
||||
// To generate cheatsheet in english run:
|
||||
// go run scripts/generate_cheatsheet.go
|
||||
// To generate the cheatsheets, run:
|
||||
// go generate pkg/cheatsheet/generate.go
|
||||
|
||||
package cheatsheet
|
||||
|
||||
@@ -12,7 +14,6 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/generics/maps"
|
||||
"github.com/jesseduffield/lazycore/pkg/utils"
|
||||
@@ -42,7 +43,7 @@ type headerWithBindings struct {
|
||||
}
|
||||
|
||||
func CommandToRun() string {
|
||||
return "go run scripts/cheatsheet/main.go generate"
|
||||
return "go generate ./..."
|
||||
}
|
||||
|
||||
func GetKeybindingsDir() string {
|
||||
@@ -59,7 +60,7 @@ func generateAtDir(cheatsheetDir string) {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
mApp, _ := app.NewApp(mConfig, common)
|
||||
mApp, _ := app.NewApp(mConfig, nil, common)
|
||||
path := cheatsheetDir + "/Keybindings_" + lang + ".md"
|
||||
file, err := os.Create(path)
|
||||
if err != nil {
|
||||
@@ -189,11 +190,11 @@ func formatSections(tr *i18n.TranslationSet, bindingSections []*bindingSection)
|
||||
|
||||
for _, section := range bindingSections {
|
||||
content += formatTitle(section.title)
|
||||
content += "<pre>\n"
|
||||
content += "| Key | Action | Info |\n"
|
||||
content += "|-----|--------|-------------|\n"
|
||||
for _, binding := range section.bindings {
|
||||
content += formatBinding(binding)
|
||||
}
|
||||
content += "</pre>\n"
|
||||
}
|
||||
|
||||
return content
|
||||
@@ -204,19 +205,15 @@ func formatTitle(title string) string {
|
||||
}
|
||||
|
||||
func formatBinding(binding *types.Binding) string {
|
||||
result := fmt.Sprintf(" <kbd>%s</kbd>: %s", escapeAngleBrackets(keybindings.LabelFromKey(binding.Key)), binding.Description)
|
||||
action := keybindings.LabelFromKey(binding.Key)
|
||||
description := binding.Description
|
||||
if binding.Alternative != "" {
|
||||
result += fmt.Sprintf(" (%s)", binding.Alternative)
|
||||
action += fmt.Sprintf(" (%s)", binding.Alternative)
|
||||
}
|
||||
result += "\n"
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func escapeAngleBrackets(str string) string {
|
||||
result := strings.ReplaceAll(str, ">", ">")
|
||||
result = strings.ReplaceAll(result, "<", "<")
|
||||
return result
|
||||
// Use backticks for keyboard keys. Two backticks are needed with an inner space
|
||||
// to escape a key that is itself a backtick.
|
||||
return fmt.Sprintf("| `` %s `` | %s | %s |\n", action, description, binding.Tooltip)
|
||||
}
|
||||
|
||||
func italicize(str string) string {
|
||||
|
||||
14
pkg/cheatsheet/generator.go
Normal file
14
pkg/cheatsheet/generator.go
Normal file
@@ -0,0 +1,14 @@
|
||||
//go:build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/cheatsheet"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Printf("Generating cheatsheets in %s...\n", cheatsheet.GetKeybindingsDir())
|
||||
cheatsheet.Generate()
|
||||
}
|
||||
@@ -2,13 +2,9 @@ package commands
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/sasha-s/go-deadlock"
|
||||
"github.com/spf13/afero"
|
||||
|
||||
gogit "github.com/jesseduffield/go-git/v5"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||
@@ -16,12 +12,12 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/patch"
|
||||
"github.com/jesseduffield/lazygit/pkg/common"
|
||||
"github.com/jesseduffield/lazygit/pkg/env"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
// GitCommand is our main git interface
|
||||
type GitCommand struct {
|
||||
Blame *git_commands.BlameCommands
|
||||
Branch *git_commands.BranchCommands
|
||||
Commit *git_commands.CommitCommands
|
||||
Config *git_commands.ConfigCommands
|
||||
@@ -63,43 +59,17 @@ func NewGitCommand(
|
||||
version *git_commands.GitVersion,
|
||||
osCommand *oscommands.OSCommand,
|
||||
gitConfig git_config.IGitConfig,
|
||||
syncMutex *deadlock.Mutex,
|
||||
) (*GitCommand, error) {
|
||||
currentPath, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, utils.WrapError(err)
|
||||
}
|
||||
|
||||
// converting to forward slashes for the sake of windows (which uses backwards slashes). We want everything
|
||||
// to have forward slashes internally
|
||||
currentPath = filepath.ToSlash(currentPath)
|
||||
|
||||
gitDir := env.GetGitDirEnv()
|
||||
if gitDir != "" {
|
||||
// we've been given the git directory explicitly so no need to navigate to it
|
||||
_, err := cmn.Fs.Stat(gitDir)
|
||||
if err != nil {
|
||||
return nil, utils.WrapError(err)
|
||||
}
|
||||
} else {
|
||||
// we haven't been given the git dir explicitly so we assume it's in the current working directory as `.git/` (or an ancestor directory)
|
||||
|
||||
rootDirectory, err := findWorktreeRoot(cmn.Fs, currentPath)
|
||||
if err != nil {
|
||||
return nil, utils.WrapError(err)
|
||||
}
|
||||
currentPath = rootDirectory
|
||||
err = os.Chdir(rootDirectory)
|
||||
if err != nil {
|
||||
return nil, utils.WrapError(err)
|
||||
}
|
||||
}
|
||||
|
||||
repoPaths, err := git_commands.GetRepoPaths(cmn.Fs, currentPath)
|
||||
repoPaths, err := git_commands.GetRepoPaths(osCommand.Cmd, version)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("Error getting repo paths: %v", err)
|
||||
}
|
||||
|
||||
err = os.Chdir(repoPaths.WorktreePath())
|
||||
if err != nil {
|
||||
return nil, utils.WrapError(err)
|
||||
}
|
||||
|
||||
repository, err := gogit.PlainOpenWithOptions(
|
||||
repoPaths.WorktreeGitDirPath(),
|
||||
&gogit.PlainOpenOptions{DetectDotGit: false, EnableDotGitCommonDir: true},
|
||||
@@ -118,7 +88,6 @@ func NewGitCommand(
|
||||
gitConfig,
|
||||
repoPaths,
|
||||
repository,
|
||||
syncMutex,
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -129,7 +98,6 @@ func NewGitCommandAux(
|
||||
gitConfig git_config.IGitConfig,
|
||||
repoPaths *git_commands.RepoPaths,
|
||||
repo *gogit.Repository,
|
||||
syncMutex *deadlock.Mutex,
|
||||
) *GitCommand {
|
||||
cmd := NewGitCmdObjBuilder(cmn.Log, osCommand.Cmd)
|
||||
|
||||
@@ -140,7 +108,7 @@ func NewGitCommandAux(
|
||||
// common ones are: cmn, osCommand, dotGitDir, configCommands
|
||||
configCommands := git_commands.NewConfigCommands(cmn, gitConfig, repo)
|
||||
|
||||
gitCommon := git_commands.NewGitCommon(cmn, version, cmd, osCommand, repoPaths, repo, configCommands, syncMutex)
|
||||
gitCommon := git_commands.NewGitCommon(cmn, version, cmd, osCommand, repoPaths, repo, configCommands)
|
||||
|
||||
fileLoader := git_commands.NewFileLoader(gitCommon, cmd, configCommands)
|
||||
statusCommands := git_commands.NewStatusCommands(gitCommon)
|
||||
@@ -159,13 +127,12 @@ func NewGitCommandAux(
|
||||
stashCommands := git_commands.NewStashCommands(gitCommon, fileLoader, workingTreeCommands)
|
||||
patchBuilder := patch.NewPatchBuilder(cmn.Log,
|
||||
func(from string, to string, reverse bool, filename string, plain bool) (string, error) {
|
||||
// TODO: make patch builder take Gui.IgnoreWhitespaceInDiffView into
|
||||
// account. For now we just pass false.
|
||||
return workingTreeCommands.ShowFileDiff(from, to, reverse, filename, plain, false)
|
||||
return workingTreeCommands.ShowFileDiff(from, to, reverse, filename, plain)
|
||||
})
|
||||
patchCommands := git_commands.NewPatchCommands(gitCommon, rebaseCommands, commitCommands, statusCommands, stashCommands, patchBuilder)
|
||||
bisectCommands := git_commands.NewBisectCommands(gitCommon)
|
||||
worktreeCommands := git_commands.NewWorktreeCommands(gitCommon)
|
||||
blameCommands := git_commands.NewBlameCommands(gitCommon)
|
||||
|
||||
branchLoader := git_commands.NewBranchLoader(cmn, cmd, branchCommands.CurrentBranchInfo, configCommands)
|
||||
commitFileLoader := git_commands.NewCommitFileLoader(cmn, cmd)
|
||||
@@ -177,6 +144,7 @@ func NewGitCommandAux(
|
||||
tagLoader := git_commands.NewTagLoader(cmn, cmd)
|
||||
|
||||
return &GitCommand{
|
||||
Blame: blameCommands,
|
||||
Branch: branchCommands,
|
||||
Commit: commitCommands,
|
||||
Config: configCommands,
|
||||
@@ -211,32 +179,6 @@ func NewGitCommandAux(
|
||||
}
|
||||
}
|
||||
|
||||
// this returns the root of the current worktree. So if you start lazygit from within
|
||||
// a subdirectory of the worktree, it will start in the context of the root of that worktree
|
||||
func findWorktreeRoot(fs afero.Fs, currentPath string) (string, error) {
|
||||
for {
|
||||
// we don't care if .git is a directory or a file: either is okay.
|
||||
_, err := fs.Stat(path.Join(currentPath, ".git"))
|
||||
|
||||
if err == nil {
|
||||
return currentPath, nil
|
||||
}
|
||||
|
||||
if !os.IsNotExist(err) {
|
||||
return "", utils.WrapError(err)
|
||||
}
|
||||
|
||||
currentPath = path.Dir(currentPath)
|
||||
|
||||
atRoot := currentPath == path.Dir(currentPath)
|
||||
if atRoot {
|
||||
// we should never really land here: the code that creates GitCommand should
|
||||
// verify we're in a git directory
|
||||
return "", errors.New("Must open lazygit in a git repository")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func VerifyInGitRepo(osCommand *oscommands.OSCommand) error {
|
||||
return osCommand.Cmd.New(git_commands.NewGitCmd("rev-parse").Arg("--git-dir").ToArgv()).DontLog().Run()
|
||||
}
|
||||
|
||||
33
pkg/commands/git_commands/blame.go
Normal file
33
pkg/commands/git_commands/blame.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package git_commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type BlameCommands struct {
|
||||
*GitCommon
|
||||
}
|
||||
|
||||
func NewBlameCommands(gitCommon *GitCommon) *BlameCommands {
|
||||
return &BlameCommands{
|
||||
GitCommon: gitCommon,
|
||||
}
|
||||
}
|
||||
|
||||
// Blame a range of lines. For each line, output the hash of the commit where
|
||||
// the line last changed, then a space, then a description of the commit (author
|
||||
// and date), another space, and then the line. For example:
|
||||
//
|
||||
// ac90ebac688fe8bc2ffd922157a9d2c54681d2aa (Stefan Haller 2023-08-01 14:54:56 +0200 11) func NewBlameCommands(gitCommon *GitCommon) *BlameCommands {
|
||||
// ac90ebac688fe8bc2ffd922157a9d2c54681d2aa (Stefan Haller 2023-08-01 14:54:56 +0200 12) return &BlameCommands{
|
||||
// ac90ebac688fe8bc2ffd922157a9d2c54681d2aa (Stefan Haller 2023-08-01 14:54:56 +0200 13) GitCommon: gitCommon,
|
||||
func (self *BlameCommands) BlameLineRange(filename string, commit string, firstLine int, numLines int) (string, error) {
|
||||
cmdArgs := NewGitCmd("blame").
|
||||
Arg("-l").
|
||||
Arg(fmt.Sprintf("-L%d,+%d", firstLine, numLines)).
|
||||
Arg(commit).
|
||||
Arg("--").
|
||||
Arg(filename)
|
||||
|
||||
return self.cmd.New(cmdArgs.ToArgv()).RunWithOutput()
|
||||
}
|
||||
@@ -85,8 +85,8 @@ func (self *BranchCommands) CurrentBranchName() (string, error) {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Delete delete branch
|
||||
func (self *BranchCommands) Delete(branch string, force bool) error {
|
||||
// LocalDelete delete branch locally
|
||||
func (self *BranchCommands) LocalDelete(branch string, force bool) error {
|
||||
cmdArgs := NewGitCmd("branch").
|
||||
ArgIfElse(force, "-D", "-d").
|
||||
Arg(branch).
|
||||
|
||||
@@ -3,6 +3,7 @@ package git_commands
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/generics/set"
|
||||
@@ -62,33 +63,34 @@ func NewBranchLoader(
|
||||
func (self *BranchLoader) Load(reflogCommits []*models.Commit) ([]*models.Branch, error) {
|
||||
branches := self.obtainBranches()
|
||||
|
||||
reflogBranches := self.obtainReflogBranches(reflogCommits)
|
||||
|
||||
// loop through reflog branches. If there is a match, merge them, then remove it from the branches and keep it in the reflog branches
|
||||
branchesWithRecency := make([]*models.Branch, 0)
|
||||
outer:
|
||||
for _, reflogBranch := range reflogBranches {
|
||||
for j, branch := range branches {
|
||||
if branch.Head {
|
||||
continue
|
||||
}
|
||||
if strings.EqualFold(reflogBranch.Name, branch.Name) {
|
||||
branch.Recency = reflogBranch.Recency
|
||||
branchesWithRecency = append(branchesWithRecency, branch)
|
||||
branches = utils.Remove(branches, j)
|
||||
continue outer
|
||||
if self.AppState.LocalBranchSortOrder == "recency" {
|
||||
reflogBranches := self.obtainReflogBranches(reflogCommits)
|
||||
// loop through reflog branches. If there is a match, merge them, then remove it from the branches and keep it in the reflog branches
|
||||
branchesWithRecency := make([]*models.Branch, 0)
|
||||
outer:
|
||||
for _, reflogBranch := range reflogBranches {
|
||||
for j, branch := range branches {
|
||||
if branch.Head {
|
||||
continue
|
||||
}
|
||||
if strings.EqualFold(reflogBranch.Name, branch.Name) {
|
||||
branch.Recency = reflogBranch.Recency
|
||||
branchesWithRecency = append(branchesWithRecency, branch)
|
||||
branches = utils.Remove(branches, j)
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort branches that don't have a recency value alphabetically
|
||||
// (we're really doing this for the sake of deterministic behaviour across git versions)
|
||||
slices.SortFunc(branches, func(a *models.Branch, b *models.Branch) bool {
|
||||
return a.Name < b.Name
|
||||
})
|
||||
|
||||
branches = utils.Prepend(branches, branchesWithRecency...)
|
||||
}
|
||||
|
||||
// Sort branches that don't have a recency value alphabetically
|
||||
// (we're really doing this for the sake of deterministic behaviour across git versions)
|
||||
slices.SortFunc(branches, func(a *models.Branch, b *models.Branch) bool {
|
||||
return a.Name < b.Name
|
||||
})
|
||||
|
||||
branches = utils.Prepend(branches, branchesWithRecency...)
|
||||
|
||||
foundHead := false
|
||||
for i, branch := range branches {
|
||||
if branch.Head {
|
||||
@@ -144,7 +146,8 @@ func (self *BranchLoader) obtainBranches() []*models.Branch {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
return obtainBranch(split), true
|
||||
storeCommitDateAsRecency := self.AppState.LocalBranchSortOrder != "recency"
|
||||
return obtainBranch(split, storeCommitDateAsRecency), true
|
||||
})
|
||||
}
|
||||
|
||||
@@ -156,8 +159,18 @@ func (self *BranchLoader) getRawBranches() (string, error) {
|
||||
"%00",
|
||||
)
|
||||
|
||||
var sortOrder string
|
||||
switch strings.ToLower(self.AppState.LocalBranchSortOrder) {
|
||||
case "recency", "date":
|
||||
sortOrder = "-committerdate"
|
||||
case "alphabetical":
|
||||
sortOrder = "refname"
|
||||
default:
|
||||
sortOrder = "refname"
|
||||
}
|
||||
|
||||
cmdArgs := NewGitCmd("for-each-ref").
|
||||
Arg("--sort=-committerdate").
|
||||
Arg(fmt.Sprintf("--sort=%s", sortOrder)).
|
||||
Arg(fmt.Sprintf("--format=%s", format)).
|
||||
Arg("refs/heads").
|
||||
ToArgv()
|
||||
@@ -172,22 +185,32 @@ var branchFields = []string{
|
||||
"upstream:track",
|
||||
"subject",
|
||||
"objectname",
|
||||
"committerdate:unix",
|
||||
}
|
||||
|
||||
// Obtain branch information from parsed line output of getRawBranches()
|
||||
func obtainBranch(split []string) *models.Branch {
|
||||
func obtainBranch(split []string, storeCommitDateAsRecency bool) *models.Branch {
|
||||
headMarker := split[0]
|
||||
fullName := split[1]
|
||||
upstreamName := split[2]
|
||||
track := split[3]
|
||||
subject := split[4]
|
||||
commitHash := split[5]
|
||||
commitDate := split[6]
|
||||
|
||||
name := strings.TrimPrefix(fullName, "heads/")
|
||||
pushables, pullables, gone := parseUpstreamInfo(upstreamName, track)
|
||||
|
||||
recency := ""
|
||||
if storeCommitDateAsRecency {
|
||||
if unixTimestamp, err := strconv.ParseInt(commitDate, 10, 64); err == nil {
|
||||
recency = utils.UnixToTimeAgo(unixTimestamp)
|
||||
}
|
||||
}
|
||||
|
||||
return &models.Branch{
|
||||
Name: name,
|
||||
Recency: recency,
|
||||
Pushables: pushables,
|
||||
Pullables: pullables,
|
||||
UpstreamGone: gone,
|
||||
|
||||
@@ -2,7 +2,9 @@ package git_commands
|
||||
|
||||
// "*|feat/detect-purge|origin/feat/detect-purge|[ahead 1]"
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -10,15 +12,21 @@ import (
|
||||
|
||||
func TestObtainBranch(t *testing.T) {
|
||||
type scenario struct {
|
||||
testName string
|
||||
input []string
|
||||
expectedBranch *models.Branch
|
||||
testName string
|
||||
input []string
|
||||
storeCommitDateAsRecency bool
|
||||
expectedBranch *models.Branch
|
||||
}
|
||||
|
||||
// Use a time stamp of 2 1/2 hours ago, resulting in a recency string of "2h"
|
||||
now := time.Now().Unix()
|
||||
timeStamp := strconv.Itoa(int(now - 2.5*60*60))
|
||||
|
||||
scenarios := []scenario{
|
||||
{
|
||||
testName: "TrimHeads",
|
||||
input: []string{"", "heads/a_branch", "", "", "subject", "123"},
|
||||
testName: "TrimHeads",
|
||||
input: []string{"", "heads/a_branch", "", "", "subject", "123", timeStamp},
|
||||
storeCommitDateAsRecency: false,
|
||||
expectedBranch: &models.Branch{
|
||||
Name: "a_branch",
|
||||
Pushables: "?",
|
||||
@@ -29,8 +37,9 @@ func TestObtainBranch(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "NoUpstream",
|
||||
input: []string{"", "a_branch", "", "", "subject", "123"},
|
||||
testName: "NoUpstream",
|
||||
input: []string{"", "a_branch", "", "", "subject", "123", timeStamp},
|
||||
storeCommitDateAsRecency: false,
|
||||
expectedBranch: &models.Branch{
|
||||
Name: "a_branch",
|
||||
Pushables: "?",
|
||||
@@ -41,8 +50,9 @@ func TestObtainBranch(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "IsHead",
|
||||
input: []string{"*", "a_branch", "", "", "subject", "123"},
|
||||
testName: "IsHead",
|
||||
input: []string{"*", "a_branch", "", "", "subject", "123", timeStamp},
|
||||
storeCommitDateAsRecency: false,
|
||||
expectedBranch: &models.Branch{
|
||||
Name: "a_branch",
|
||||
Pushables: "?",
|
||||
@@ -53,8 +63,9 @@ func TestObtainBranch(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "IsBehindAndAhead",
|
||||
input: []string{"", "a_branch", "a_remote/a_branch", "[behind 2, ahead 3]", "subject", "123"},
|
||||
testName: "IsBehindAndAhead",
|
||||
input: []string{"", "a_branch", "a_remote/a_branch", "[behind 2, ahead 3]", "subject", "123", timeStamp},
|
||||
storeCommitDateAsRecency: false,
|
||||
expectedBranch: &models.Branch{
|
||||
Name: "a_branch",
|
||||
Pushables: "3",
|
||||
@@ -65,8 +76,9 @@ func TestObtainBranch(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "RemoteBranchIsGone",
|
||||
input: []string{"", "a_branch", "a_remote/a_branch", "[gone]", "subject", "123"},
|
||||
testName: "RemoteBranchIsGone",
|
||||
input: []string{"", "a_branch", "a_remote/a_branch", "[gone]", "subject", "123", timeStamp},
|
||||
storeCommitDateAsRecency: false,
|
||||
expectedBranch: &models.Branch{
|
||||
Name: "a_branch",
|
||||
UpstreamGone: true,
|
||||
@@ -77,11 +89,25 @@ func TestObtainBranch(t *testing.T) {
|
||||
CommitHash: "123",
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "WithCommitDateAsRecency",
|
||||
input: []string{"", "a_branch", "", "", "subject", "123", timeStamp},
|
||||
storeCommitDateAsRecency: true,
|
||||
expectedBranch: &models.Branch{
|
||||
Name: "a_branch",
|
||||
Recency: "2h",
|
||||
Pushables: "?",
|
||||
Pullables: "?",
|
||||
Head: false,
|
||||
Subject: "subject",
|
||||
CommitHash: "123",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
branch := obtainBranch(s.input)
|
||||
branch := obtainBranch(s.input, s.storeCommitDateAsRecency)
|
||||
assert.EqualValues(t, s.expectedBranch, branch)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ func TestBranchDeleteBranch(t *testing.T) {
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
instance := buildBranchCommands(commonDeps{runner: s.runner})
|
||||
|
||||
s.test(instance.Delete("test", s.force))
|
||||
s.test(instance.LocalDelete("test", s.force))
|
||||
s.runner.CheckForMissingCalls()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -38,6 +38,22 @@ func (self *CommitCommands) SetAuthor(value string) error {
|
||||
return self.cmd.New(cmdArgs).Run()
|
||||
}
|
||||
|
||||
// Add a commit's coauthor using Github/Gitlab Co-authored-by metadata. Value is expected to be of the form 'Name <Email>'
|
||||
func (self *CommitCommands) AddCoAuthor(sha string, value string) error {
|
||||
message, err := self.GetCommitMessage(sha)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
message = message + fmt.Sprintf("\nCo-authored-by: %s", value)
|
||||
|
||||
cmdArgs := NewGitCmd("commit").
|
||||
Arg("--allow-empty", "--amend", "--only", "-m", message).
|
||||
ToArgv()
|
||||
|
||||
return self.cmd.New(cmdArgs).Run()
|
||||
}
|
||||
|
||||
// ResetToCommit reset to commit
|
||||
func (self *CommitCommands) ResetToCommit(sha string, strength string, envVars []string) error {
|
||||
cmdArgs := NewGitCmd("reset").Arg("--"+strength, sha).ToArgv()
|
||||
@@ -68,6 +84,19 @@ func (self *CommitCommands) RewordLastCommitInEditorCmdObj() oscommands.ICmdObj
|
||||
return self.cmd.New(NewGitCmd("commit").Arg("--allow-empty", "--amend", "--only").ToArgv())
|
||||
}
|
||||
|
||||
func (self *CommitCommands) RewordLastCommitInEditorWithMessageFileCmdObj(tmpMessageFile string) oscommands.ICmdObj {
|
||||
return self.cmd.New(NewGitCmd("commit").
|
||||
Arg("--allow-empty", "--amend", "--only", "--edit", "--file="+tmpMessageFile).ToArgv())
|
||||
}
|
||||
|
||||
func (self *CommitCommands) CommitInEditorWithMessageFileCmdObj(tmpMessageFile string) oscommands.ICmdObj {
|
||||
return self.cmd.New(NewGitCmd("commit").
|
||||
Arg("--edit").
|
||||
Arg("--file="+tmpMessageFile).
|
||||
ArgIf(self.signoffFlag() != "", self.signoffFlag()).
|
||||
ToArgv())
|
||||
}
|
||||
|
||||
// RewordLastCommit rewords the topmost commit with the given message
|
||||
func (self *CommitCommands) RewordLastCommit(summary string, description string) error {
|
||||
messageArgs := self.commitMessageArgs(summary, description)
|
||||
@@ -108,15 +137,23 @@ func (self *CommitCommands) signoffFlag() string {
|
||||
}
|
||||
|
||||
func (self *CommitCommands) GetCommitMessage(commitSha string) (string, error) {
|
||||
cmdArgs := NewGitCmd("rev-list").
|
||||
cmdArgs := NewGitCmd("log").
|
||||
Arg("--format=%B", "--max-count=1", commitSha).
|
||||
ToArgv()
|
||||
|
||||
messageWithHeader, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
|
||||
message := strings.Join(strings.SplitAfter(messageWithHeader, "\n")[1:], "")
|
||||
message, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
|
||||
return strings.TrimSpace(message), err
|
||||
}
|
||||
|
||||
func (self *CommitCommands) GetCommitSubject(commitSha string) (string, error) {
|
||||
cmdArgs := NewGitCmd("log").
|
||||
Arg("--format=%s", "--max-count=1", commitSha).
|
||||
ToArgv()
|
||||
|
||||
subject, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
|
||||
return strings.TrimSpace(subject), err
|
||||
}
|
||||
|
||||
func (self *CommitCommands) GetCommitDiff(commitSha string) (string, error) {
|
||||
cmdArgs := NewGitCmd("show").Arg("--no-color", commitSha).ToArgv()
|
||||
|
||||
@@ -161,6 +198,20 @@ func (self *CommitCommands) GetCommitMessagesFirstLine(shas []string) (string, e
|
||||
return self.cmd.New(cmdArgs).DontLog().RunWithOutput()
|
||||
}
|
||||
|
||||
// Example output:
|
||||
//
|
||||
// cd50c79ae Preserve the commit message correctly even if the description has blank lines
|
||||
// 3ebba5f32 Add test demonstrating a bug with preserving the commit message
|
||||
// 9a423c388 Remove unused function
|
||||
func (self *CommitCommands) GetShasAndCommitMessagesFirstLine(shas []string) (string, error) {
|
||||
cmdArgs := NewGitCmd("show").
|
||||
Arg("--no-patch", "--pretty=format:%h %s").
|
||||
Arg(shas...).
|
||||
ToArgv()
|
||||
|
||||
return self.cmd.New(cmdArgs).DontLog().RunWithOutput()
|
||||
}
|
||||
|
||||
func (self *CommitCommands) GetCommitsOneline(shas []string) (string, error) {
|
||||
cmdArgs := NewGitCmd("show").
|
||||
Arg("--no-patch", "--oneline").
|
||||
@@ -183,10 +234,13 @@ func (self *CommitCommands) AmendHeadCmdObj() oscommands.ICmdObj {
|
||||
return self.cmd.New(cmdArgs)
|
||||
}
|
||||
|
||||
func (self *CommitCommands) ShowCmdObj(sha string, filterPath string, ignoreWhitespace bool) oscommands.ICmdObj {
|
||||
contextSize := self.UserConfig.Git.DiffContextSize
|
||||
func (self *CommitCommands) ShowCmdObj(sha string, filterPath string) oscommands.ICmdObj {
|
||||
contextSize := self.AppState.DiffContextSize
|
||||
|
||||
extDiffCmd := self.UserConfig.Git.Paging.ExternalDiffCommand
|
||||
cmdArgs := NewGitCmd("show").
|
||||
ConfigIf(extDiffCmd != "", "diff.external="+extDiffCmd).
|
||||
ArgIfElse(extDiffCmd != "", "--ext-diff", "--no-ext-diff").
|
||||
Arg("--submodule").
|
||||
Arg("--color="+self.UserConfig.Git.Paging.ColorArg).
|
||||
Arg(fmt.Sprintf("--unified=%d", contextSize)).
|
||||
@@ -194,8 +248,9 @@ func (self *CommitCommands) ShowCmdObj(sha string, filterPath string, ignoreWhit
|
||||
Arg("--decorate").
|
||||
Arg("-p").
|
||||
Arg(sha).
|
||||
ArgIf(ignoreWhitespace, "--ignore-all-space").
|
||||
ArgIf(self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space").
|
||||
ArgIf(filterPath != "", "--", filterPath).
|
||||
Dir(self.repoPaths.worktreePath).
|
||||
ToArgv()
|
||||
|
||||
return self.cmd.New(cmdArgs).DontLog()
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -65,8 +66,11 @@ type GetCommitsOptions struct {
|
||||
FilterPath string
|
||||
IncludeRebaseCommits bool
|
||||
RefName string // e.g. "HEAD" or "my_branch"
|
||||
RefForPushedStatus string // the ref to use for determining pushed/unpushed status
|
||||
// determines if we show the whole git graph i.e. pass the '--all' flag
|
||||
All bool
|
||||
// If non-empty, show divergence from this ref (left-right log)
|
||||
RefToShowDivergenceFrom string
|
||||
}
|
||||
|
||||
// GetCommits obtains the commits of the current branch
|
||||
@@ -92,22 +96,26 @@ func (self *CommitLoader) GetCommits(opts GetCommitsOptions) ([]*models.Commit,
|
||||
defer wg.Done()
|
||||
|
||||
logErr = self.getLogCmd(opts).RunAndProcessLines(func(line string) (bool, error) {
|
||||
commit := self.extractCommitFromLine(line)
|
||||
commit := self.extractCommitFromLine(line, opts.RefToShowDivergenceFrom != "")
|
||||
commits = append(commits, commit)
|
||||
return false, nil
|
||||
})
|
||||
})
|
||||
|
||||
var ancestor string
|
||||
var remoteAncestor string
|
||||
go utils.Safe(func() {
|
||||
defer wg.Done()
|
||||
|
||||
ancestor = self.getMergeBase(opts.RefName)
|
||||
if opts.RefToShowDivergenceFrom != "" {
|
||||
remoteAncestor = self.getMergeBase(opts.RefToShowDivergenceFrom)
|
||||
}
|
||||
})
|
||||
|
||||
passedFirstPushedCommit := false
|
||||
// I can get this before
|
||||
firstPushedCommit, err := self.getFirstPushedCommit(opts.RefName)
|
||||
firstPushedCommit, err := self.getFirstPushedCommit(opts.RefForPushedStatus)
|
||||
if err != nil {
|
||||
// must have no upstream branch so we'll consider everything as pushed
|
||||
passedFirstPushedCommit = true
|
||||
@@ -123,10 +131,12 @@ func (self *CommitLoader) GetCommits(opts GetCommitsOptions) ([]*models.Commit,
|
||||
if commit.Sha == firstPushedCommit {
|
||||
passedFirstPushedCommit = true
|
||||
}
|
||||
if passedFirstPushedCommit {
|
||||
commit.Status = models.StatusPushed
|
||||
} else {
|
||||
commit.Status = models.StatusUnpushed
|
||||
if commit.Status != models.StatusRebasing {
|
||||
if passedFirstPushedCommit {
|
||||
commit.Status = models.StatusPushed
|
||||
} else {
|
||||
commit.Status = models.StatusUnpushed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,8 +144,23 @@ func (self *CommitLoader) GetCommits(opts GetCommitsOptions) ([]*models.Commit,
|
||||
return commits, nil
|
||||
}
|
||||
|
||||
if ancestor != "" {
|
||||
commits = setCommitMergedStatuses(ancestor, commits)
|
||||
if opts.RefToShowDivergenceFrom != "" {
|
||||
sort.SliceStable(commits, func(i, j int) bool {
|
||||
// In the divergence view we want incoming commits to come first
|
||||
return commits[i].Divergence > commits[j].Divergence
|
||||
})
|
||||
|
||||
_, localSectionStart, found := lo.FindIndexOf(commits, func(commit *models.Commit) bool {
|
||||
return commit.Divergence == models.DivergenceLeft
|
||||
})
|
||||
if !found {
|
||||
localSectionStart = len(commits)
|
||||
}
|
||||
|
||||
setCommitMergedStatuses(remoteAncestor, commits[:localSectionStart])
|
||||
setCommitMergedStatuses(ancestor, commits[localSectionStart:])
|
||||
} else {
|
||||
setCommitMergedStatuses(ancestor, commits)
|
||||
}
|
||||
|
||||
return commits, nil
|
||||
@@ -176,8 +201,8 @@ func (self *CommitLoader) MergeRebasingCommits(commits []*models.Commit) ([]*mod
|
||||
// then puts them into a commit object
|
||||
// example input:
|
||||
// 8ad01fe32fcc20f07bc6693f87aa4977c327f1e1|10 hours ago|Jesse Duffield| (HEAD -> master, tag: v0.15.2)|refresh commits when adding a tag
|
||||
func (self *CommitLoader) extractCommitFromLine(line string) *models.Commit {
|
||||
split := strings.SplitN(line, "\x00", 7)
|
||||
func (self *CommitLoader) extractCommitFromLine(line string, showDivergence bool) *models.Commit {
|
||||
split := strings.SplitN(line, "\x00", 8)
|
||||
|
||||
sha := split[0]
|
||||
unixTimestamp := split[1]
|
||||
@@ -186,6 +211,10 @@ func (self *CommitLoader) extractCommitFromLine(line string) *models.Commit {
|
||||
extraInfo := strings.TrimSpace(split[4])
|
||||
parentHashes := split[5]
|
||||
message := split[6]
|
||||
divergence := models.DivergenceNone
|
||||
if showDivergence {
|
||||
divergence = lo.Ternary(split[7] == "<", models.DivergenceLeft, models.DivergenceRight)
|
||||
}
|
||||
|
||||
tags := []string{}
|
||||
|
||||
@@ -219,6 +248,7 @@ func (self *CommitLoader) extractCommitFromLine(line string) *models.Commit {
|
||||
AuthorName: authorName,
|
||||
AuthorEmail: authorEmail,
|
||||
Parents: parents,
|
||||
Divergence: divergence,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,7 +278,7 @@ func (self *CommitLoader) getHydratedRebasingCommits(rebaseMode enums.RebaseMode
|
||||
|
||||
fullCommits := map[string]*models.Commit{}
|
||||
err = cmdObj.RunAndProcessLines(func(line string) (bool, error) {
|
||||
commit := self.extractCommitFromLine(line)
|
||||
commit := self.extractCommitFromLine(line, false)
|
||||
fullCommits[commit.Sha] = commit
|
||||
return false, nil
|
||||
})
|
||||
@@ -492,7 +522,11 @@ func (self *CommitLoader) commitFromPatch(content string) *models.Commit {
|
||||
}
|
||||
}
|
||||
|
||||
func setCommitMergedStatuses(ancestor string, commits []*models.Commit) []*models.Commit {
|
||||
func setCommitMergedStatuses(ancestor string, commits []*models.Commit) {
|
||||
if ancestor == "" {
|
||||
return
|
||||
}
|
||||
|
||||
passedAncestor := false
|
||||
for i, commit := range commits {
|
||||
// some commits aren't really commits and don't have sha's, such as the update-ref todo
|
||||
@@ -506,7 +540,6 @@ func setCommitMergedStatuses(ancestor string, commits []*models.Commit) []*model
|
||||
commits[i].Status = models.StatusMerged
|
||||
}
|
||||
}
|
||||
return commits
|
||||
}
|
||||
|
||||
func (self *CommitLoader) getMergeBase(refName string) string {
|
||||
@@ -619,8 +652,13 @@ func (self *CommitLoader) getFirstPushedCommit(refName string) (string, error) {
|
||||
func (self *CommitLoader) getLogCmd(opts GetCommitsOptions) oscommands.ICmdObj {
|
||||
config := self.UserConfig.Git.Log
|
||||
|
||||
refSpec := opts.RefName
|
||||
if opts.RefToShowDivergenceFrom != "" {
|
||||
refSpec += "..." + opts.RefToShowDivergenceFrom
|
||||
}
|
||||
|
||||
cmdArgs := NewGitCmd("log").
|
||||
Arg(opts.RefName).
|
||||
Arg(refSpec).
|
||||
ArgIf(config.Order != "default", "--"+config.Order).
|
||||
ArgIf(opts.All, "--all").
|
||||
Arg("--oneline").
|
||||
@@ -629,6 +667,7 @@ func (self *CommitLoader) getLogCmd(opts GetCommitsOptions) oscommands.ICmdObj {
|
||||
ArgIf(opts.Limit, "-300").
|
||||
ArgIf(opts.FilterPath != "", "--follow").
|
||||
Arg("--no-show-signature").
|
||||
ArgIf(opts.RefToShowDivergenceFrom != "", "--left-right").
|
||||
Arg("--").
|
||||
ArgIf(opts.FilterPath != "", opts.FilterPath).
|
||||
ToArgv()
|
||||
@@ -636,4 +675,4 @@ func (self *CommitLoader) getLogCmd(opts GetCommitsOptions) oscommands.ICmdObj {
|
||||
return self.cmd.New(cmdArgs).DontLog()
|
||||
}
|
||||
|
||||
const prettyFormat = `--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s`
|
||||
const prettyFormat = `--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s%x00%m`
|
||||
|
||||
@@ -42,10 +42,10 @@ func TestGetCommits(t *testing.T) {
|
||||
testName: "should return no commits if there are none",
|
||||
logOrder: "topo-order",
|
||||
rebaseMode: enums.REBASE_MODE_NONE,
|
||||
opts: GetCommitsOptions{RefName: "HEAD", IncludeRebaseCommits: false},
|
||||
opts: GetCommitsOptions{RefName: "HEAD", RefForPushedStatus: "mybranch", IncludeRebaseCommits: false},
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"merge-base", "HEAD", "HEAD@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
|
||||
ExpectGitArgs([]string{"log", "HEAD", "--topo-order", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s", "--abbrev=40", "--no-show-signature", "--"}, "", nil),
|
||||
ExpectGitArgs([]string{"merge-base", "mybranch", "mybranch@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
|
||||
ExpectGitArgs([]string{"log", "HEAD", "--topo-order", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s%x00%m", "--abbrev=40", "--no-show-signature", "--"}, "", nil),
|
||||
|
||||
expectedCommits: []*models.Commit{},
|
||||
expectedError: nil,
|
||||
@@ -54,10 +54,10 @@ func TestGetCommits(t *testing.T) {
|
||||
testName: "should use proper upstream name for branch",
|
||||
logOrder: "topo-order",
|
||||
rebaseMode: enums.REBASE_MODE_NONE,
|
||||
opts: GetCommitsOptions{RefName: "refs/heads/mybranch", IncludeRebaseCommits: false},
|
||||
opts: GetCommitsOptions{RefName: "refs/heads/mybranch", RefForPushedStatus: "refs/heads/mybranch", IncludeRebaseCommits: false},
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"merge-base", "refs/heads/mybranch", "mybranch@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
|
||||
ExpectGitArgs([]string{"log", "refs/heads/mybranch", "--topo-order", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s", "--abbrev=40", "--no-show-signature", "--"}, "", nil),
|
||||
ExpectGitArgs([]string{"log", "refs/heads/mybranch", "--topo-order", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s%x00%m", "--abbrev=40", "--no-show-signature", "--"}, "", nil),
|
||||
|
||||
expectedCommits: []*models.Commit{},
|
||||
expectedError: nil,
|
||||
@@ -66,13 +66,13 @@ func TestGetCommits(t *testing.T) {
|
||||
testName: "should return commits if they are present",
|
||||
logOrder: "topo-order",
|
||||
rebaseMode: enums.REBASE_MODE_NONE,
|
||||
opts: GetCommitsOptions{RefName: "HEAD", IncludeRebaseCommits: false},
|
||||
opts: GetCommitsOptions{RefName: "HEAD", RefForPushedStatus: "mybranch", IncludeRebaseCommits: false},
|
||||
mainBranches: []string{"master", "main", "develop"},
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
// here it's seeing which commits are yet to be pushed
|
||||
ExpectGitArgs([]string{"merge-base", "HEAD", "HEAD@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
|
||||
ExpectGitArgs([]string{"merge-base", "mybranch", "mybranch@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
|
||||
// here it's actually getting all the commits in a formatted form, one per line
|
||||
ExpectGitArgs([]string{"log", "HEAD", "--topo-order", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s", "--abbrev=40", "--no-show-signature", "--"}, commitsOutput, nil).
|
||||
ExpectGitArgs([]string{"log", "HEAD", "--topo-order", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s%x00%m", "--abbrev=40", "--no-show-signature", "--"}, commitsOutput, nil).
|
||||
// here it's testing which of the configured main branches have an upstream
|
||||
ExpectGitArgs([]string{"rev-parse", "--symbolic-full-name", "master@{u}"}, "refs/remotes/origin/master", nil). // this one does
|
||||
ExpectGitArgs([]string{"rev-parse", "--symbolic-full-name", "main@{u}"}, "", errors.New("error")). // this one doesn't, so it checks origin instead
|
||||
@@ -203,13 +203,13 @@ func TestGetCommits(t *testing.T) {
|
||||
testName: "should not call merge-base for mainBranches if none exist",
|
||||
logOrder: "topo-order",
|
||||
rebaseMode: enums.REBASE_MODE_NONE,
|
||||
opts: GetCommitsOptions{RefName: "HEAD", IncludeRebaseCommits: false},
|
||||
opts: GetCommitsOptions{RefName: "HEAD", RefForPushedStatus: "mybranch", IncludeRebaseCommits: false},
|
||||
mainBranches: []string{"master", "main"},
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
// here it's seeing which commits are yet to be pushed
|
||||
ExpectGitArgs([]string{"merge-base", "HEAD", "HEAD@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
|
||||
ExpectGitArgs([]string{"merge-base", "mybranch", "mybranch@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
|
||||
// here it's actually getting all the commits in a formatted form, one per line
|
||||
ExpectGitArgs([]string{"log", "HEAD", "--topo-order", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s", "--abbrev=40", "--no-show-signature", "--"}, singleCommitOutput, nil).
|
||||
ExpectGitArgs([]string{"log", "HEAD", "--topo-order", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s%x00%m", "--abbrev=40", "--no-show-signature", "--"}, singleCommitOutput, nil).
|
||||
// here it's testing which of the configured main branches exist; neither does
|
||||
ExpectGitArgs([]string{"rev-parse", "--symbolic-full-name", "master@{u}"}, "", errors.New("error")).
|
||||
ExpectGitArgs([]string{"rev-parse", "--verify", "--quiet", "refs/remotes/origin/master"}, "", errors.New("error")).
|
||||
@@ -240,13 +240,13 @@ func TestGetCommits(t *testing.T) {
|
||||
testName: "should call merge-base for all main branches that exist",
|
||||
logOrder: "topo-order",
|
||||
rebaseMode: enums.REBASE_MODE_NONE,
|
||||
opts: GetCommitsOptions{RefName: "HEAD", IncludeRebaseCommits: false},
|
||||
opts: GetCommitsOptions{RefName: "HEAD", RefForPushedStatus: "mybranch", IncludeRebaseCommits: false},
|
||||
mainBranches: []string{"master", "main", "develop", "1.0-hotfixes"},
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
// here it's seeing which commits are yet to be pushed
|
||||
ExpectGitArgs([]string{"merge-base", "HEAD", "HEAD@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
|
||||
ExpectGitArgs([]string{"merge-base", "mybranch", "mybranch@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
|
||||
// here it's actually getting all the commits in a formatted form, one per line
|
||||
ExpectGitArgs([]string{"log", "HEAD", "--topo-order", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s", "--abbrev=40", "--no-show-signature", "--"}, singleCommitOutput, nil).
|
||||
ExpectGitArgs([]string{"log", "HEAD", "--topo-order", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s%x00%m", "--abbrev=40", "--no-show-signature", "--"}, singleCommitOutput, nil).
|
||||
// here it's testing which of the configured main branches exist
|
||||
ExpectGitArgs([]string{"rev-parse", "--symbolic-full-name", "master@{u}"}, "refs/remotes/origin/master", nil).
|
||||
ExpectGitArgs([]string{"rev-parse", "--symbolic-full-name", "main@{u}"}, "", errors.New("error")).
|
||||
@@ -279,10 +279,10 @@ func TestGetCommits(t *testing.T) {
|
||||
testName: "should not specify order if `log.order` is `default`",
|
||||
logOrder: "default",
|
||||
rebaseMode: enums.REBASE_MODE_NONE,
|
||||
opts: GetCommitsOptions{RefName: "HEAD", IncludeRebaseCommits: false},
|
||||
opts: GetCommitsOptions{RefName: "HEAD", RefForPushedStatus: "mybranch", IncludeRebaseCommits: false},
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"merge-base", "HEAD", "HEAD@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
|
||||
ExpectGitArgs([]string{"log", "HEAD", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s", "--abbrev=40", "--no-show-signature", "--"}, "", nil),
|
||||
ExpectGitArgs([]string{"merge-base", "mybranch", "mybranch@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
|
||||
ExpectGitArgs([]string{"log", "HEAD", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s%x00%m", "--abbrev=40", "--no-show-signature", "--"}, "", nil),
|
||||
|
||||
expectedCommits: []*models.Commit{},
|
||||
expectedError: nil,
|
||||
@@ -291,10 +291,10 @@ func TestGetCommits(t *testing.T) {
|
||||
testName: "should set filter path",
|
||||
logOrder: "default",
|
||||
rebaseMode: enums.REBASE_MODE_NONE,
|
||||
opts: GetCommitsOptions{RefName: "HEAD", FilterPath: "src"},
|
||||
opts: GetCommitsOptions{RefName: "HEAD", RefForPushedStatus: "mybranch", FilterPath: "src"},
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"merge-base", "HEAD", "HEAD@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
|
||||
ExpectGitArgs([]string{"log", "HEAD", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s", "--abbrev=40", "--follow", "--no-show-signature", "--", "src"}, "", nil),
|
||||
ExpectGitArgs([]string{"merge-base", "mybranch", "mybranch@{u}"}, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil).
|
||||
ExpectGitArgs([]string{"log", "HEAD", "--oneline", "--pretty=format:%H%x00%at%x00%aN%x00%ae%x00%D%x00%p%x00%s%x00%m", "--abbrev=40", "--follow", "--no-show-signature", "--", "src"}, "", nil),
|
||||
|
||||
expectedCommits: []*models.Commit{},
|
||||
expectedError: nil,
|
||||
@@ -548,7 +548,8 @@ func TestCommitLoader_setCommitMergedStatuses(t *testing.T) {
|
||||
|
||||
for _, scenario := range scenarios {
|
||||
t.Run(scenario.testName, func(t *testing.T) {
|
||||
expectedCommits := setCommitMergedStatuses(scenario.ancestor, scenario.commits)
|
||||
expectedCommits := scenario.commits
|
||||
setCommitMergedStatuses(scenario.ancestor, expectedCommits)
|
||||
assert.Equal(t, scenario.expectedCommits, expectedCommits)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -186,6 +186,7 @@ func TestCommitShowCmdObj(t *testing.T) {
|
||||
filterPath string
|
||||
contextSize int
|
||||
ignoreWhitespace bool
|
||||
extDiffCmd string
|
||||
expected []string
|
||||
}
|
||||
|
||||
@@ -195,28 +196,40 @@ func TestCommitShowCmdObj(t *testing.T) {
|
||||
filterPath: "",
|
||||
contextSize: 3,
|
||||
ignoreWhitespace: false,
|
||||
expected: []string{"show", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890"},
|
||||
extDiffCmd: "",
|
||||
expected: []string{"-C", "/path/to/worktree", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890"},
|
||||
},
|
||||
{
|
||||
testName: "Default case with filter path",
|
||||
filterPath: "file.txt",
|
||||
contextSize: 3,
|
||||
ignoreWhitespace: false,
|
||||
expected: []string{"show", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890", "--", "file.txt"},
|
||||
extDiffCmd: "",
|
||||
expected: []string{"-C", "/path/to/worktree", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890", "--", "file.txt"},
|
||||
},
|
||||
{
|
||||
testName: "Show diff with custom context size",
|
||||
filterPath: "",
|
||||
contextSize: 77,
|
||||
ignoreWhitespace: false,
|
||||
expected: []string{"show", "--submodule", "--color=always", "--unified=77", "--stat", "--decorate", "-p", "1234567890"},
|
||||
extDiffCmd: "",
|
||||
expected: []string{"-C", "/path/to/worktree", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=77", "--stat", "--decorate", "-p", "1234567890"},
|
||||
},
|
||||
{
|
||||
testName: "Show diff, ignoring whitespace",
|
||||
filterPath: "",
|
||||
contextSize: 77,
|
||||
ignoreWhitespace: true,
|
||||
expected: []string{"show", "--submodule", "--color=always", "--unified=77", "--stat", "--decorate", "-p", "1234567890", "--ignore-all-space"},
|
||||
extDiffCmd: "",
|
||||
expected: []string{"-C", "/path/to/worktree", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=77", "--stat", "--decorate", "-p", "1234567890", "--ignore-all-space"},
|
||||
},
|
||||
{
|
||||
testName: "Show diff with external diff command",
|
||||
filterPath: "",
|
||||
contextSize: 3,
|
||||
ignoreWhitespace: false,
|
||||
extDiffCmd: "difft --color=always",
|
||||
expected: []string{"-C", "/path/to/worktree", "-c", "diff.external=difft --color=always", "show", "--ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890"},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -224,12 +237,18 @@ func TestCommitShowCmdObj(t *testing.T) {
|
||||
s := s
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
userConfig := config.GetDefaultConfig()
|
||||
userConfig.Git.DiffContextSize = s.contextSize
|
||||
userConfig.Git.Paging.ExternalDiffCommand = s.extDiffCmd
|
||||
appState := &config.AppState{}
|
||||
appState.IgnoreWhitespaceInDiffView = s.ignoreWhitespace
|
||||
appState.DiffContextSize = s.contextSize
|
||||
|
||||
runner := oscommands.NewFakeRunner(t).ExpectGitArgs(s.expected, "", nil)
|
||||
instance := buildCommitCommands(commonDeps{userConfig: userConfig, runner: runner})
|
||||
repoPaths := RepoPaths{
|
||||
worktreePath: "/path/to/worktree",
|
||||
}
|
||||
instance := buildCommitCommands(commonDeps{userConfig: userConfig, appState: appState, runner: runner, repoPaths: &repoPaths})
|
||||
|
||||
assert.NoError(t, instance.ShowCmdObj("1234567890", s.filterPath, s.ignoreWhitespace).Run())
|
||||
assert.NoError(t, instance.ShowCmdObj("1234567890", s.filterPath).Run())
|
||||
runner.CheckForMissingCalls()
|
||||
})
|
||||
}
|
||||
@@ -244,19 +263,17 @@ func TestGetCommitMsg(t *testing.T) {
|
||||
scenarios := []scenario{
|
||||
{
|
||||
"empty",
|
||||
` commit deadbeef`,
|
||||
``,
|
||||
``,
|
||||
},
|
||||
{
|
||||
"no line breaks (single line)",
|
||||
`commit deadbeef
|
||||
use generics to DRY up context code`,
|
||||
`use generics to DRY up context code`,
|
||||
`use generics to DRY up context code`,
|
||||
},
|
||||
{
|
||||
"with line breaks",
|
||||
`commit deadbeef
|
||||
Merge pull request #1750 from mark2185/fix-issue-template
|
||||
`Merge pull request #1750 from mark2185/fix-issue-template
|
||||
|
||||
'git-rev parse' should be 'git rev-parse'`,
|
||||
`Merge pull request #1750 from mark2185/fix-issue-template
|
||||
@@ -269,7 +286,7 @@ Merge pull request #1750 from mark2185/fix-issue-template
|
||||
s := s
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
instance := buildCommitCommands(commonDeps{
|
||||
runner: oscommands.NewFakeRunner(t).ExpectGitArgs([]string{"rev-list", "--format=%B", "--max-count=1", "deadbeef"}, s.input, nil),
|
||||
runner: oscommands.NewFakeRunner(t).ExpectGitArgs([]string{"log", "--format=%B", "--max-count=1", "deadbeef"}, s.input, nil),
|
||||
})
|
||||
|
||||
output, err := instance.GetCommitMessage("deadbeef")
|
||||
@@ -290,15 +307,14 @@ func TestGetCommitMessageFromHistory(t *testing.T) {
|
||||
scenarios := []scenario{
|
||||
{
|
||||
"Empty message",
|
||||
oscommands.NewFakeRunner(t).ExpectGitArgs([]string{"log", "-1", "--skip=2", "--pretty=%H"}, "", nil).ExpectGitArgs([]string{"rev-list", "--format=%B", "--max-count=1"}, "", nil),
|
||||
oscommands.NewFakeRunner(t).ExpectGitArgs([]string{"log", "-1", "--skip=2", "--pretty=%H"}, "", nil).ExpectGitArgs([]string{"log", "--format=%B", "--max-count=1"}, "", nil),
|
||||
func(output string, err error) {
|
||||
assert.Error(t, err)
|
||||
},
|
||||
},
|
||||
{
|
||||
"Default case to retrieve a commit in history",
|
||||
oscommands.NewFakeRunner(t).ExpectGitArgs([]string{"log", "-1", "--skip=2", "--pretty=%H"}, "sha3 \n", nil).ExpectGitArgs([]string{"rev-list", "--format=%B", "--max-count=1", "sha3"}, `commit sha3
|
||||
use generics to DRY up context code`, nil),
|
||||
oscommands.NewFakeRunner(t).ExpectGitArgs([]string{"log", "-1", "--skip=2", "--pretty=%H"}, "sha3 \n", nil).ExpectGitArgs([]string{"log", "--format=%B", "--max-count=1", "sha3"}, `use generics to DRY up context code`, nil),
|
||||
func(output string, err error) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "use generics to DRY up context code", output)
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
gogit "github.com/jesseduffield/go-git/v5"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/common"
|
||||
"github.com/sasha-s/go-deadlock"
|
||||
)
|
||||
|
||||
type GitCommon struct {
|
||||
@@ -15,8 +14,6 @@ type GitCommon struct {
|
||||
repoPaths *RepoPaths
|
||||
repo *gogit.Repository
|
||||
config *ConfigCommands
|
||||
// mutex for doing things like push/pull/fetch
|
||||
syncMutex *deadlock.Mutex
|
||||
}
|
||||
|
||||
func NewGitCommon(
|
||||
@@ -27,7 +24,6 @@ func NewGitCommon(
|
||||
repoPaths *RepoPaths,
|
||||
repo *gogit.Repository,
|
||||
config *ConfigCommands,
|
||||
syncMutex *deadlock.Mutex,
|
||||
) *GitCommon {
|
||||
return &GitCommon{
|
||||
Common: cmn,
|
||||
@@ -37,6 +33,5 @@ func NewGitCommon(
|
||||
repoPaths: repoPaths,
|
||||
repo: repo,
|
||||
config: config,
|
||||
syncMutex: syncMutex,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func (self *ConfigCommands) GetPager(width int) string {
|
||||
"columnWidth": strconv.Itoa(width/2 - 6),
|
||||
}
|
||||
|
||||
pagerTemplate := self.UserConfig.Git.Paging.Pager
|
||||
pagerTemplate := string(self.UserConfig.Git.Paging.Pager)
|
||||
return utils.ResolvePlaceholderString(pagerTemplate, templateValues)
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
type commonDeps struct {
|
||||
runner *oscommands.FakeCmdObjRunner
|
||||
userConfig *config.UserConfig
|
||||
appState *config.AppState
|
||||
gitVersion *GitVersion
|
||||
gitConfig *git_config.FakeGitConfig
|
||||
getenv func(string) string
|
||||
@@ -32,7 +33,7 @@ func buildGitCommon(deps commonDeps) *GitCommon {
|
||||
|
||||
gitCommon.Common = deps.common
|
||||
if gitCommon.Common == nil {
|
||||
gitCommon.Common = utils.NewDummyCommonWithUserConfig(deps.userConfig)
|
||||
gitCommon.Common = utils.NewDummyCommonWithUserConfigAndAppState(deps.userConfig, deps.appState)
|
||||
}
|
||||
|
||||
if deps.fs != nil {
|
||||
|
||||
@@ -14,6 +14,80 @@ func NewDiffCommands(gitCommon *GitCommon) *DiffCommands {
|
||||
|
||||
func (self *DiffCommands) DiffCmdObj(diffArgs []string) oscommands.ICmdObj {
|
||||
return self.cmd.New(
|
||||
NewGitCmd("diff").Arg("--submodule", "--no-ext-diff", "--color").Arg(diffArgs...).ToArgv(),
|
||||
NewGitCmd("diff").
|
||||
Arg("--submodule", "--no-ext-diff", "--color").
|
||||
Arg(diffArgs...).
|
||||
Dir(self.repoPaths.worktreePath).
|
||||
ToArgv(),
|
||||
)
|
||||
}
|
||||
|
||||
func (self *DiffCommands) internalDiffCmdObj(diffArgs ...string) *GitCommandBuilder {
|
||||
return NewGitCmd("diff").
|
||||
Arg("--no-ext-diff", "--no-color").
|
||||
Arg(diffArgs...).
|
||||
Dir(self.repoPaths.worktreePath)
|
||||
}
|
||||
|
||||
func (self *DiffCommands) GetPathDiff(path string, staged bool) (string, error) {
|
||||
return self.cmd.New(
|
||||
self.internalDiffCmdObj().
|
||||
ArgIf(staged, "--staged").
|
||||
Arg(path).
|
||||
ToArgv(),
|
||||
).RunWithOutput()
|
||||
}
|
||||
|
||||
func (self *DiffCommands) GetAllDiff(staged bool) (string, error) {
|
||||
return self.cmd.New(
|
||||
self.internalDiffCmdObj().
|
||||
ArgIf(staged, "--staged").
|
||||
ToArgv(),
|
||||
).RunWithOutput()
|
||||
}
|
||||
|
||||
type DiffToolCmdOptions struct {
|
||||
// The path to show a diff for. Pass "." for the entire repo.
|
||||
Filepath string
|
||||
|
||||
// The commit against which to show the diff. Leave empty to show a diff of
|
||||
// the working copy.
|
||||
FromCommit string
|
||||
|
||||
// The commit to diff against FromCommit. Leave empty to diff the working
|
||||
// copy against FromCommit. Leave both FromCommit and ToCommit empty to show
|
||||
// the diff of the unstaged working copy changes against the index if Staged
|
||||
// is false, or the staged changes against HEAD if Staged is true.
|
||||
ToCommit string
|
||||
|
||||
// Whether to reverse the left and right sides of the diff.
|
||||
Reverse bool
|
||||
|
||||
// Whether the given Filepath is a directory. We'll pass --dir-diff to
|
||||
// git-difftool in that case.
|
||||
IsDirectory bool
|
||||
|
||||
// Whether to show the staged or the unstaged changes. Must be false if both
|
||||
// FromCommit and ToCommit are non-empty.
|
||||
Staged bool
|
||||
}
|
||||
|
||||
func (self *DiffCommands) OpenDiffToolCmdObj(opts DiffToolCmdOptions) oscommands.ICmdObj {
|
||||
return self.cmd.New(NewGitCmd("difftool").
|
||||
Arg("--no-prompt").
|
||||
ArgIf(opts.IsDirectory, "--dir-diff").
|
||||
ArgIf(opts.Staged, "--cached").
|
||||
ArgIf(opts.FromCommit != "", opts.FromCommit).
|
||||
ArgIf(opts.ToCommit != "", opts.ToCommit).
|
||||
ArgIf(opts.Reverse, "-R").
|
||||
Arg("--", opts.Filepath).
|
||||
ToArgv())
|
||||
}
|
||||
|
||||
func (self *DiffCommands) DiffIndexCmdObj(diffArgs ...string) oscommands.ICmdObj {
|
||||
return self.cmd.New(
|
||||
NewGitCmd("diff-index").
|
||||
Arg("--submodule", "--no-ext-diff", "--no-color", "--patch").
|
||||
Arg(diffArgs...).ToArgv(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -83,14 +83,14 @@ func (self *FileCommands) GetEditCmdStr(filename string) (string, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
template, editInTerminal := config.GetEditTemplate(&self.UserConfig.OS, self.guessDefaultEditor)
|
||||
template, suspend := config.GetEditTemplate(&self.UserConfig.OS, self.guessDefaultEditor)
|
||||
|
||||
templateValues := map[string]string{
|
||||
"filename": self.cmd.Quote(filename),
|
||||
}
|
||||
|
||||
cmdStr := utils.ResolvePlaceholderString(template, templateValues)
|
||||
return cmdStr, editInTerminal
|
||||
return cmdStr, suspend
|
||||
}
|
||||
|
||||
func (self *FileCommands) GetEditAtLineCmdStr(filename string, lineNumber int) (string, bool) {
|
||||
@@ -101,7 +101,7 @@ func (self *FileCommands) GetEditAtLineCmdStr(filename string, lineNumber int) (
|
||||
}
|
||||
}
|
||||
|
||||
template, editInTerminal := config.GetEditAtLineTemplate(&self.UserConfig.OS, self.guessDefaultEditor)
|
||||
template, suspend := config.GetEditAtLineTemplate(&self.UserConfig.OS, self.guessDefaultEditor)
|
||||
|
||||
templateValues := map[string]string{
|
||||
"filename": self.cmd.Quote(filename),
|
||||
@@ -109,7 +109,7 @@ func (self *FileCommands) GetEditAtLineCmdStr(filename string, lineNumber int) (
|
||||
}
|
||||
|
||||
cmdStr := utils.ResolvePlaceholderString(template, templateValues)
|
||||
return cmdStr, editInTerminal
|
||||
return cmdStr, suspend
|
||||
}
|
||||
|
||||
func (self *FileCommands) GetEditAtLineAndWaitCmdStr(filename string, lineNumber int) string {
|
||||
@@ -131,15 +131,15 @@ func (self *FileCommands) GetEditAtLineAndWaitCmdStr(filename string, lineNumber
|
||||
return cmdStr
|
||||
}
|
||||
|
||||
func (self *FileCommands) GetOpenDirInEditorCmdStr(path string) string {
|
||||
template := config.GetOpenDirInEditorTemplate(&self.UserConfig.OS, self.guessDefaultEditor)
|
||||
func (self *FileCommands) GetOpenDirInEditorCmdStr(path string) (string, bool) {
|
||||
template, suspend := config.GetOpenDirInEditorTemplate(&self.UserConfig.OS, self.guessDefaultEditor)
|
||||
|
||||
templateValues := map[string]string{
|
||||
"dir": self.cmd.Quote(path),
|
||||
}
|
||||
|
||||
cmdStr := utils.ResolvePlaceholderString(template, templateValues)
|
||||
return cmdStr
|
||||
return cmdStr, suspend
|
||||
}
|
||||
|
||||
func (self *FileCommands) guessDefaultEditor() string {
|
||||
|
||||
@@ -179,34 +179,34 @@ func TestEditFileCmdStrLegacy(t *testing.T) {
|
||||
|
||||
func TestEditFileCmd(t *testing.T) {
|
||||
type scenario struct {
|
||||
filename string
|
||||
osConfig config.OSConfig
|
||||
expectedCmdStr string
|
||||
expectedEditInTerminal bool
|
||||
filename string
|
||||
osConfig config.OSConfig
|
||||
expectedCmdStr string
|
||||
suspend bool
|
||||
}
|
||||
|
||||
scenarios := []scenario{
|
||||
{
|
||||
filename: "test",
|
||||
osConfig: config.OSConfig{},
|
||||
expectedCmdStr: `vim -- "test"`,
|
||||
expectedEditInTerminal: true,
|
||||
filename: "test",
|
||||
osConfig: config.OSConfig{},
|
||||
expectedCmdStr: `vim -- "test"`,
|
||||
suspend: true,
|
||||
},
|
||||
{
|
||||
filename: "test",
|
||||
osConfig: config.OSConfig{
|
||||
Edit: "nano {{filename}}",
|
||||
},
|
||||
expectedCmdStr: `nano "test"`,
|
||||
expectedEditInTerminal: true,
|
||||
expectedCmdStr: `nano "test"`,
|
||||
suspend: true,
|
||||
},
|
||||
{
|
||||
filename: "file/with space",
|
||||
osConfig: config.OSConfig{
|
||||
EditPreset: "sublime",
|
||||
},
|
||||
expectedCmdStr: `subl -- "file/with space"`,
|
||||
expectedEditInTerminal: false,
|
||||
expectedCmdStr: `subl -- "file/with space"`,
|
||||
suspend: false,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -218,28 +218,28 @@ func TestEditFileCmd(t *testing.T) {
|
||||
userConfig: userConfig,
|
||||
})
|
||||
|
||||
cmdStr, editInTerminal := instance.GetEditCmdStr(s.filename)
|
||||
cmdStr, suspend := instance.GetEditCmdStr(s.filename)
|
||||
assert.Equal(t, s.expectedCmdStr, cmdStr)
|
||||
assert.Equal(t, s.expectedEditInTerminal, editInTerminal)
|
||||
assert.Equal(t, s.suspend, suspend)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEditFileAtLineCmd(t *testing.T) {
|
||||
type scenario struct {
|
||||
filename string
|
||||
lineNumber int
|
||||
osConfig config.OSConfig
|
||||
expectedCmdStr string
|
||||
expectedEditInTerminal bool
|
||||
filename string
|
||||
lineNumber int
|
||||
osConfig config.OSConfig
|
||||
expectedCmdStr string
|
||||
suspend bool
|
||||
}
|
||||
|
||||
scenarios := []scenario{
|
||||
{
|
||||
filename: "test",
|
||||
lineNumber: 42,
|
||||
osConfig: config.OSConfig{},
|
||||
expectedCmdStr: `vim +42 -- "test"`,
|
||||
expectedEditInTerminal: true,
|
||||
filename: "test",
|
||||
lineNumber: 42,
|
||||
osConfig: config.OSConfig{},
|
||||
expectedCmdStr: `vim +42 -- "test"`,
|
||||
suspend: true,
|
||||
},
|
||||
{
|
||||
filename: "test",
|
||||
@@ -247,8 +247,8 @@ func TestEditFileAtLineCmd(t *testing.T) {
|
||||
osConfig: config.OSConfig{
|
||||
EditAtLine: "nano +{{line}} {{filename}}",
|
||||
},
|
||||
expectedCmdStr: `nano +35 "test"`,
|
||||
expectedEditInTerminal: true,
|
||||
expectedCmdStr: `nano +35 "test"`,
|
||||
suspend: true,
|
||||
},
|
||||
{
|
||||
filename: "file/with space",
|
||||
@@ -256,8 +256,8 @@ func TestEditFileAtLineCmd(t *testing.T) {
|
||||
osConfig: config.OSConfig{
|
||||
EditPreset: "sublime",
|
||||
},
|
||||
expectedCmdStr: `subl -- "file/with space":12`,
|
||||
expectedEditInTerminal: false,
|
||||
expectedCmdStr: `subl -- "file/with space":12`,
|
||||
suspend: false,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -269,9 +269,9 @@ func TestEditFileAtLineCmd(t *testing.T) {
|
||||
userConfig: userConfig,
|
||||
})
|
||||
|
||||
cmdStr, editInTerminal := instance.GetEditAtLineCmdStr(s.filename, s.lineNumber)
|
||||
cmdStr, suspend := instance.GetEditAtLineCmdStr(s.filename, s.lineNumber)
|
||||
assert.Equal(t, s.expectedCmdStr, cmdStr)
|
||||
assert.Equal(t, s.expectedEditInTerminal, editInTerminal)
|
||||
assert.Equal(t, s.suspend, suspend)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,14 @@ func (self *GitCommandBuilder) Config(value string) *GitCommandBuilder {
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *GitCommandBuilder) ConfigIf(condition bool, ifTrue string) *GitCommandBuilder {
|
||||
if condition {
|
||||
self.Config(ifTrue)
|
||||
}
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
// the -C arg will make git do a `cd` to the directory before doing anything else
|
||||
func (self *GitCommandBuilder) Dir(path string) *GitCommandBuilder {
|
||||
// repo path comes before the command
|
||||
|
||||
@@ -79,6 +79,12 @@ func (self *RebaseCommands) SetCommitAuthor(commits []*models.Commit, index int,
|
||||
})
|
||||
}
|
||||
|
||||
func (self *RebaseCommands) AddCommitCoAuthor(commits []*models.Commit, index int, value string) error {
|
||||
return self.GenericAmend(commits, index, func() error {
|
||||
return self.commit.AddCoAuthor(commits[index].Sha, value)
|
||||
})
|
||||
}
|
||||
|
||||
func (self *RebaseCommands) GenericAmend(commits []*models.Commit, index int, f func() error) error {
|
||||
if models.IsHeadCommit(commits, index) {
|
||||
// we've selected the top commit so no rebase is required
|
||||
@@ -99,58 +105,49 @@ func (self *RebaseCommands) GenericAmend(commits []*models.Commit, index int, f
|
||||
return self.ContinueRebase()
|
||||
}
|
||||
|
||||
func (self *RebaseCommands) MoveCommitDown(commits []*models.Commit, index int) error {
|
||||
baseShaOrRoot := getBaseShaOrRoot(commits, index+2)
|
||||
func (self *RebaseCommands) MoveCommitsDown(commits []*models.Commit, startIdx int, endIdx int) error {
|
||||
baseShaOrRoot := getBaseShaOrRoot(commits, endIdx+2)
|
||||
|
||||
sha := commits[index].Sha
|
||||
|
||||
msg := utils.ResolvePlaceholderString(
|
||||
self.Tr.Log.MoveCommitDown,
|
||||
map[string]string{
|
||||
"shortSha": utils.ShortSha(sha),
|
||||
},
|
||||
)
|
||||
self.os.LogCommand(msg, false)
|
||||
shas := lo.Map(commits[startIdx:endIdx+1], func(commit *models.Commit, _ int) string {
|
||||
return commit.Sha
|
||||
})
|
||||
|
||||
return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
|
||||
baseShaOrRoot: baseShaOrRoot,
|
||||
instruction: daemon.NewMoveTodoDownInstruction(sha),
|
||||
instruction: daemon.NewMoveTodosDownInstruction(shas),
|
||||
overrideEditor: true,
|
||||
}).Run()
|
||||
}
|
||||
|
||||
func (self *RebaseCommands) MoveCommitUp(commits []*models.Commit, index int) error {
|
||||
baseShaOrRoot := getBaseShaOrRoot(commits, index+1)
|
||||
func (self *RebaseCommands) MoveCommitsUp(commits []*models.Commit, startIdx int, endIdx int) error {
|
||||
baseShaOrRoot := getBaseShaOrRoot(commits, endIdx+1)
|
||||
|
||||
sha := commits[index].Sha
|
||||
|
||||
msg := utils.ResolvePlaceholderString(
|
||||
self.Tr.Log.MoveCommitUp,
|
||||
map[string]string{
|
||||
"shortSha": utils.ShortSha(sha),
|
||||
},
|
||||
)
|
||||
self.os.LogCommand(msg, false)
|
||||
shas := lo.Map(commits[startIdx:endIdx+1], func(commit *models.Commit, _ int) string {
|
||||
return commit.Sha
|
||||
})
|
||||
|
||||
return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
|
||||
baseShaOrRoot: baseShaOrRoot,
|
||||
instruction: daemon.NewMoveTodoUpInstruction(sha),
|
||||
instruction: daemon.NewMoveTodosUpInstruction(shas),
|
||||
overrideEditor: true,
|
||||
}).Run()
|
||||
}
|
||||
|
||||
func (self *RebaseCommands) InteractiveRebase(commits []*models.Commit, index int, action todo.TodoCommand) error {
|
||||
baseIndex := index + 1
|
||||
func (self *RebaseCommands) InteractiveRebase(commits []*models.Commit, startIdx int, endIdx int, action todo.TodoCommand) error {
|
||||
baseIndex := endIdx + 1
|
||||
if action == todo.Squash || action == todo.Fixup {
|
||||
baseIndex++
|
||||
}
|
||||
|
||||
baseShaOrRoot := getBaseShaOrRoot(commits, baseIndex)
|
||||
|
||||
changes := []daemon.ChangeTodoAction{{
|
||||
Sha: commits[index].Sha,
|
||||
NewAction: action,
|
||||
}}
|
||||
changes := lo.Map(commits[startIdx:endIdx+1], func(commit *models.Commit, _ int) daemon.ChangeTodoAction {
|
||||
return daemon.ChangeTodoAction{
|
||||
Sha: commit.Sha,
|
||||
NewAction: action,
|
||||
}
|
||||
})
|
||||
|
||||
self.os.LogCommand(logTodoChanges(changes), false)
|
||||
|
||||
return self.PrepareInteractiveRebaseCommand(PrepareInteractiveRebaseCommandOpts{
|
||||
@@ -194,7 +191,7 @@ func logTodoChanges(changes []daemon.ChangeTodoAction) string {
|
||||
changeTodoStr := strings.Join(lo.Map(changes, func(c daemon.ChangeTodoAction, _ int) string {
|
||||
return fmt.Sprintf("%s:%s", c.Sha, c.NewAction)
|
||||
}), "\n")
|
||||
return fmt.Sprintf("Changing TODO actions: %s", changeTodoStr)
|
||||
return fmt.Sprintf("Changing TODO actions:\n%s", changeTodoStr)
|
||||
}
|
||||
|
||||
type PrepareInteractiveRebaseCommandOpts struct {
|
||||
@@ -215,9 +212,9 @@ func (self *RebaseCommands) PrepareInteractiveRebaseCommand(opts PrepareInteract
|
||||
Arg("--interactive").
|
||||
Arg("--autostash").
|
||||
Arg("--keep-empty").
|
||||
ArgIf(opts.keepCommitsThatBecomeEmpty && !self.version.IsOlderThan(2, 26, 0), "--empty=keep").
|
||||
ArgIf(opts.keepCommitsThatBecomeEmpty && self.version.IsAtLeast(2, 26, 0), "--empty=keep").
|
||||
Arg("--no-autosquash").
|
||||
ArgIf(!self.version.IsOlderThan(2, 22, 0), "--rebase-merges").
|
||||
ArgIf(self.version.IsAtLeast(2, 22, 0), "--rebase-merges").
|
||||
ArgIf(opts.onto != "", "--onto", opts.onto).
|
||||
Arg(opts.baseShaOrRoot).
|
||||
ToArgv()
|
||||
@@ -275,22 +272,45 @@ func (self *RebaseCommands) AmendTo(commits []*models.Commit, commitIndex int) e
|
||||
}).Run()
|
||||
}
|
||||
|
||||
// EditRebaseTodo sets the action for a given rebase commit in the git-rebase-todo file
|
||||
func (self *RebaseCommands) EditRebaseTodo(commit *models.Commit, action todo.TodoCommand) error {
|
||||
// Sets the action for the given commits in the git-rebase-todo file
|
||||
func (self *RebaseCommands) EditRebaseTodo(commits []*models.Commit, action todo.TodoCommand) error {
|
||||
commitsWithAction := lo.Map(commits, func(commit *models.Commit, _ int) utils.TodoChange {
|
||||
return utils.TodoChange{
|
||||
Sha: commit.Sha,
|
||||
OldAction: commit.Action,
|
||||
NewAction: action,
|
||||
}
|
||||
})
|
||||
|
||||
return utils.EditRebaseTodo(
|
||||
filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo"), commit.Sha, commit.Action, action, self.config.GetCoreCommentChar())
|
||||
filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo"),
|
||||
commitsWithAction,
|
||||
self.config.GetCoreCommentChar(),
|
||||
)
|
||||
}
|
||||
|
||||
// MoveTodoDown moves a rebase todo item down by one position
|
||||
func (self *RebaseCommands) MoveTodoDown(commit *models.Commit) error {
|
||||
func (self *RebaseCommands) MoveTodosDown(commits []*models.Commit) error {
|
||||
fileName := filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo")
|
||||
return utils.MoveTodoDown(fileName, commit.Sha, commit.Action, self.config.GetCoreCommentChar())
|
||||
todosToMove := lo.Map(commits, func(commit *models.Commit, _ int) utils.Todo {
|
||||
return utils.Todo{
|
||||
Sha: commit.Sha,
|
||||
Action: commit.Action,
|
||||
}
|
||||
})
|
||||
|
||||
return utils.MoveTodosDown(fileName, todosToMove, self.config.GetCoreCommentChar())
|
||||
}
|
||||
|
||||
// MoveTodoDown moves a rebase todo item down by one position
|
||||
func (self *RebaseCommands) MoveTodoUp(commit *models.Commit) error {
|
||||
func (self *RebaseCommands) MoveTodosUp(commits []*models.Commit) error {
|
||||
fileName := filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge/git-rebase-todo")
|
||||
return utils.MoveTodoUp(fileName, commit.Sha, commit.Action, self.config.GetCoreCommentChar())
|
||||
todosToMove := lo.Map(commits, func(commit *models.Commit, _ int) utils.Todo {
|
||||
return utils.Todo{
|
||||
Sha: commit.Sha,
|
||||
Action: commit.Action,
|
||||
}
|
||||
})
|
||||
|
||||
return utils.MoveTodosUp(fileName, todosToMove, self.config.GetCoreCommentChar())
|
||||
}
|
||||
|
||||
// SquashAllAboveFixupCommits squashes all fixup! commits above the given one
|
||||
@@ -451,6 +471,20 @@ func (self *RebaseCommands) CherryPickCommits(commits []*models.Commit) error {
|
||||
}).Run()
|
||||
}
|
||||
|
||||
// CherryPickCommitsDuringRebase simply prepends the given commits to the existing git-rebase-todo file
|
||||
func (self *RebaseCommands) CherryPickCommitsDuringRebase(commits []*models.Commit) error {
|
||||
todoLines := lo.Map(commits, func(commit *models.Commit, _ int) daemon.TodoLine {
|
||||
return daemon.TodoLine{
|
||||
Action: "pick",
|
||||
Commit: commit,
|
||||
}
|
||||
})
|
||||
|
||||
todo := daemon.TodoLinesToString(todoLines)
|
||||
filePath := filepath.Join(self.repoPaths.worktreeGitDirPath, "rebase-merge/git-rebase-todo")
|
||||
return utils.PrependStrToTodoFile(filePath, []byte(todo))
|
||||
}
|
||||
|
||||
// we can't start an interactive rebase from the first commit without passing the
|
||||
// '--root' arg
|
||||
func getBaseShaOrRoot(commits []*models.Commit, index int) string {
|
||||
|
||||
@@ -2,6 +2,7 @@ package git_commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
)
|
||||
@@ -53,7 +54,15 @@ func (self *RemoteCommands) DeleteRemoteBranch(task gocui.Task, remoteName strin
|
||||
Arg(remoteName, "--delete", branchName).
|
||||
ToArgv()
|
||||
|
||||
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).WithMutex(self.syncMutex).Run()
|
||||
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).Run()
|
||||
}
|
||||
|
||||
func (self *RemoteCommands) DeleteRemoteTag(task gocui.Task, remoteName string, tagName string) error {
|
||||
cmdArgs := NewGitCmd("push").
|
||||
Arg(remoteName, "--delete", tagName).
|
||||
ToArgv()
|
||||
|
||||
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).Run()
|
||||
}
|
||||
|
||||
// CheckRemoteBranchExists Returns remote branch
|
||||
@@ -66,3 +75,14 @@ func (self *RemoteCommands) CheckRemoteBranchExists(branchName string) bool {
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// Resolve what might be a aliased URL into a full URL
|
||||
// SEE: `man -P 'less +/--get-url +n' git-ls-remote`
|
||||
func (self *RemoteCommands) GetRemoteURL(remoteName string) (string, error) {
|
||||
cmdArgs := NewGitCmd("ls-remote").
|
||||
Arg("--get-url", remoteName).
|
||||
ToArgv()
|
||||
|
||||
url, err := self.cmd.New(cmdArgs).RunWithOutput()
|
||||
return strings.TrimSpace(url), err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package git_commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -83,14 +84,23 @@ func (self *RemoteLoader) GetRemotes() ([]*models.Remote, error) {
|
||||
func (self *RemoteLoader) getRemoteBranchesByRemoteName() (map[string][]*models.RemoteBranch, error) {
|
||||
remoteBranchesByRemoteName := make(map[string][]*models.RemoteBranch)
|
||||
|
||||
cmdArgs := NewGitCmd("branch").Arg("-r").ToArgv()
|
||||
err := self.cmd.New(cmdArgs).DontLog().RunAndProcessLines(func(line string) (bool, error) {
|
||||
// excluding lines like 'origin/HEAD -> origin/master' (there will be a separate
|
||||
// line for 'origin/master')
|
||||
if strings.Contains(line, "->") {
|
||||
return false, nil
|
||||
}
|
||||
var sortOrder string
|
||||
switch strings.ToLower(self.AppState.RemoteBranchSortOrder) {
|
||||
case "alphabetical":
|
||||
sortOrder = "refname"
|
||||
case "date":
|
||||
sortOrder = "-committerdate"
|
||||
default:
|
||||
sortOrder = "refname"
|
||||
}
|
||||
|
||||
cmdArgs := NewGitCmd("for-each-ref").
|
||||
Arg(fmt.Sprintf("--sort=%s", sortOrder)).
|
||||
Arg("--format=%(refname:short)").
|
||||
Arg("refs/remotes").
|
||||
ToArgv()
|
||||
|
||||
err := self.cmd.New(cmdArgs).DontLog().RunAndProcessLines(func(line string) (bool, error) {
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
split := strings.SplitN(line, "/", 2)
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
package git_commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
ioFs "io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/jesseduffield/lazygit/pkg/env"
|
||||
"github.com/samber/lo"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
type RepoPaths struct {
|
||||
currentPath string
|
||||
worktreePath string
|
||||
worktreeGitDirPath string
|
||||
repoPath string
|
||||
@@ -23,12 +20,7 @@ type RepoPaths struct {
|
||||
repoName string
|
||||
}
|
||||
|
||||
// Current working directory of the program. Currently, this will always
|
||||
// be the same as WorktreePath(), but in future we may support running
|
||||
// lazygit from inside a subdirectory of the worktree.
|
||||
func (self *RepoPaths) CurrentPath() string {
|
||||
return self.currentPath
|
||||
}
|
||||
var gitPathFormatVersion GitVersion = GitVersion{2, 31, 0, ""}
|
||||
|
||||
// Path to the current worktree. If we're in the main worktree, this will
|
||||
// be the same as RepoPath()
|
||||
@@ -65,7 +57,6 @@ func (self *RepoPaths) RepoName() string {
|
||||
// Returns the repo paths for a typical repo
|
||||
func MockRepoPaths(currentPath string) *RepoPaths {
|
||||
return &RepoPaths{
|
||||
currentPath: currentPath,
|
||||
worktreePath: currentPath,
|
||||
worktreeGitDirPath: path.Join(currentPath, ".git"),
|
||||
repoPath: currentPath,
|
||||
@@ -75,44 +66,41 @@ func MockRepoPaths(currentPath string) *RepoPaths {
|
||||
}
|
||||
|
||||
func GetRepoPaths(
|
||||
fs afero.Fs,
|
||||
currentPath string,
|
||||
cmd oscommands.ICmdObjBuilder,
|
||||
version *GitVersion,
|
||||
) (*RepoPaths, error) {
|
||||
return getRepoPathsAux(afero.NewOsFs(), resolveSymlink, currentPath)
|
||||
}
|
||||
|
||||
func getRepoPathsAux(
|
||||
fs afero.Fs,
|
||||
resolveSymlinkFn func(string) (string, error),
|
||||
currentPath string,
|
||||
) (*RepoPaths, error) {
|
||||
worktreePath := currentPath
|
||||
repoGitDirPath, repoPath, err := getCurrentRepoGitDirPath(fs, resolveSymlinkFn, currentPath)
|
||||
gitDirOutput, err := callGitRevParse(cmd, version, "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--show-superproject-working-tree")
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to get repo git dir path: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var worktreeGitDirPath string
|
||||
if env.GetWorkTreeEnv() != "" {
|
||||
// This env is set when you pass --work-tree to lazygit. In that case,
|
||||
// we're not dealing with a linked work-tree, we're dealing with a 'specified'
|
||||
// worktree (for lack of a better term). In this case, the worktree has no
|
||||
// .git file and it just contains a bunch of files: it has no idea it's
|
||||
// pointed to by a bare repo. As such it does not have its own git dir within
|
||||
// the bare repo's git dir. Instead, we just use the bare repo's git dir.
|
||||
worktreeGitDirPath = repoGitDirPath
|
||||
} else {
|
||||
var err error
|
||||
worktreeGitDirPath, err = getWorktreeGitDirPath(fs, currentPath)
|
||||
gitDirResults := strings.Split(utils.NormalizeLinefeeds(gitDirOutput), "\n")
|
||||
worktreePath := gitDirResults[0]
|
||||
worktreeGitDirPath := gitDirResults[1]
|
||||
repoGitDirPath := gitDirResults[2]
|
||||
if version.IsOlderThanVersion(&gitPathFormatVersion) {
|
||||
repoGitDirPath, err = filepath.Abs(repoGitDirPath)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("failed to get worktree git dir path: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// If we're in a submodule, --show-superproject-working-tree will return
|
||||
// a value, meaning gitDirResults will be length 4. In that case
|
||||
// return the worktree path as the repoPath. Otherwise we're in a
|
||||
// normal repo or a worktree so return the parent of the git common
|
||||
// dir (repoGitDirPath)
|
||||
isSubmodule := len(gitDirResults) == 4
|
||||
|
||||
var repoPath string
|
||||
if isSubmodule {
|
||||
repoPath = worktreePath
|
||||
} else {
|
||||
repoPath = path.Dir(repoGitDirPath)
|
||||
}
|
||||
repoName := path.Base(repoPath)
|
||||
|
||||
return &RepoPaths{
|
||||
currentPath: currentPath,
|
||||
worktreePath: worktreePath,
|
||||
worktreeGitDirPath: worktreeGitDirPath,
|
||||
repoPath: repoPath,
|
||||
@@ -121,123 +109,31 @@ func getRepoPathsAux(
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Returns the path of the git-dir for the worktree. For linked worktrees, the worktree has
|
||||
// a .git file that points to the git-dir (which itself lives in the git-dir
|
||||
// of the repo)
|
||||
func getWorktreeGitDirPath(fs afero.Fs, worktreePath string) (string, error) {
|
||||
// if .git is a file, we're in a linked worktree, otherwise we're in
|
||||
// the main worktree
|
||||
dotGitPath := path.Join(worktreePath, ".git")
|
||||
gitFileInfo, err := fs.Stat(dotGitPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if gitFileInfo.IsDir() {
|
||||
return dotGitPath, nil
|
||||
}
|
||||
|
||||
return linkedWorktreeGitDirPath(fs, worktreePath)
|
||||
func callGitRevParse(
|
||||
cmd oscommands.ICmdObjBuilder,
|
||||
version *GitVersion,
|
||||
gitRevArgs ...string,
|
||||
) (string, error) {
|
||||
return callGitRevParseWithDir(cmd, version, "", gitRevArgs...)
|
||||
}
|
||||
|
||||
func linkedWorktreeGitDirPath(fs afero.Fs, worktreePath string) (string, error) {
|
||||
dotGitPath := path.Join(worktreePath, ".git")
|
||||
gitFileContents, err := afero.ReadFile(fs, dotGitPath)
|
||||
func callGitRevParseWithDir(
|
||||
cmd oscommands.ICmdObjBuilder,
|
||||
version *GitVersion,
|
||||
dir string,
|
||||
gitRevArgs ...string,
|
||||
) (string, error) {
|
||||
gitRevParse := NewGitCmd("rev-parse").ArgIf(version.IsAtLeastVersion(&gitPathFormatVersion), "--path-format=absolute").Arg(gitRevArgs...)
|
||||
if dir != "" {
|
||||
gitRevParse.Dir(dir)
|
||||
}
|
||||
|
||||
gitCmd := cmd.New(gitRevParse.ToArgv()).DontLog()
|
||||
res, err := gitCmd.RunWithOutput()
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.Errorf("'%s' failed: %v", gitCmd.ToString(), err)
|
||||
}
|
||||
|
||||
// The file will have `gitdir: /path/to/.git/worktrees/<worktree-name>`
|
||||
gitDirLine := lo.Filter(strings.Split(string(gitFileContents), "\n"), func(line string, _ int) bool {
|
||||
return strings.HasPrefix(line, "gitdir: ")
|
||||
})
|
||||
|
||||
if len(gitDirLine) == 0 {
|
||||
return "", errors.New(fmt.Sprintf("%s is a file which suggests we are in a submodule or a worktree but the file's contents do not contain a gitdir pointing to the actual .git directory", dotGitPath))
|
||||
}
|
||||
|
||||
gitDir := strings.TrimPrefix(gitDirLine[0], "gitdir: ")
|
||||
|
||||
// For windows support
|
||||
gitDir = filepath.ToSlash(gitDir)
|
||||
|
||||
return gitDir, nil
|
||||
}
|
||||
|
||||
func getCurrentRepoGitDirPath(
|
||||
fs afero.Fs,
|
||||
resolveSymlinkFn func(string) (string, error),
|
||||
currentPath string,
|
||||
) (string, string, error) {
|
||||
var unresolvedGitPath string
|
||||
if env.GetGitDirEnv() != "" {
|
||||
unresolvedGitPath = env.GetGitDirEnv()
|
||||
} else {
|
||||
unresolvedGitPath = path.Join(currentPath, ".git")
|
||||
}
|
||||
|
||||
gitPath, err := resolveSymlinkFn(unresolvedGitPath)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
// check if .git is a file or a directory
|
||||
gitFileInfo, err := fs.Stat(gitPath)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
if gitFileInfo.IsDir() {
|
||||
// must be in the main worktree
|
||||
return gitPath, path.Dir(gitPath), nil
|
||||
}
|
||||
|
||||
// either in a submodule, or worktree
|
||||
worktreeGitPath, err := linkedWorktreeGitDirPath(fs, currentPath)
|
||||
if err != nil {
|
||||
return "", "", errors.Errorf("could not find git dir for %s: %v", currentPath, err)
|
||||
}
|
||||
|
||||
_, err = fs.Stat(worktreeGitPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// hardcoding error to get around windows-specific error message
|
||||
return "", "", errors.Errorf("could not find git dir for %s. %s does not exist", currentPath, worktreeGitPath)
|
||||
}
|
||||
return "", "", errors.Errorf("could not find git dir for %s: %v", currentPath, err)
|
||||
}
|
||||
|
||||
// confirm whether the next directory up is the worktrees directory
|
||||
parent := path.Dir(worktreeGitPath)
|
||||
if path.Base(parent) == "worktrees" {
|
||||
gitDirPath := path.Dir(parent)
|
||||
return gitDirPath, path.Dir(gitDirPath), nil
|
||||
}
|
||||
|
||||
// Unlike worktrees, submodules can be nested arbitrarily deep, so we check
|
||||
// if the `modules` directory is anywhere up the chain.
|
||||
if strings.Contains(worktreeGitPath, "/modules/") {
|
||||
// For submodules, we just return the path directly
|
||||
return worktreeGitPath, currentPath, nil
|
||||
}
|
||||
|
||||
// If this error causes issues, we could relax the constraint and just always
|
||||
// return the path
|
||||
return "", "", errors.Errorf("could not find git dir for %s: path is not under `worktrees` or `modules` directories", currentPath)
|
||||
}
|
||||
|
||||
// takes a path containing a symlink and returns the true path
|
||||
func resolveSymlink(path string) (string, error) {
|
||||
l, err := os.Lstat(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if l.Mode()&os.ModeSymlink == 0 {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
return filepath.EvalSymlinks(path)
|
||||
return strings.TrimSpace(res), nil
|
||||
}
|
||||
|
||||
// Returns the paths of linked worktrees
|
||||
|
||||
@@ -1,34 +1,50 @@
|
||||
package git_commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func mockResolveSymlinkFn(p string) (string, error) { return p, nil }
|
||||
type (
|
||||
argFn func() []string
|
||||
errFn func(getRevParseArgs argFn) error
|
||||
)
|
||||
|
||||
type Scenario struct {
|
||||
Name string
|
||||
BeforeFunc func(fs afero.Fs)
|
||||
BeforeFunc func(runner *oscommands.FakeCmdObjRunner, getRevParseArgs argFn)
|
||||
Path string
|
||||
Expected *RepoPaths
|
||||
Err error
|
||||
Err errFn
|
||||
}
|
||||
|
||||
func TestGetRepoPathsAux(t *testing.T) {
|
||||
func TestGetRepoPaths(t *testing.T) {
|
||||
scenarios := []Scenario{
|
||||
{
|
||||
Name: "typical case",
|
||||
BeforeFunc: func(fs afero.Fs) {
|
||||
BeforeFunc: func(runner *oscommands.FakeCmdObjRunner, getRevParseArgs argFn) {
|
||||
// setup for main worktree
|
||||
_ = fs.MkdirAll("/path/to/repo/.git", 0o755)
|
||||
expectedOutput := []string{
|
||||
// --show-toplevel
|
||||
"/path/to/repo",
|
||||
// --git-dir
|
||||
"/path/to/repo/.git",
|
||||
// --git-common-dir
|
||||
"/path/to/repo/.git",
|
||||
// --show-superproject-working-tree
|
||||
}
|
||||
runner.ExpectGitArgs(
|
||||
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--show-superproject-working-tree"),
|
||||
strings.Join(expectedOutput, "\n"),
|
||||
nil)
|
||||
},
|
||||
Path: "/path/to/repo",
|
||||
Expected: &RepoPaths{
|
||||
currentPath: "/path/to/repo",
|
||||
worktreePath: "/path/to/repo",
|
||||
worktreeGitDirPath: "/path/to/repo/.git",
|
||||
repoPath: "/path/to/repo",
|
||||
@@ -37,53 +53,26 @@ func TestGetRepoPathsAux(t *testing.T) {
|
||||
},
|
||||
Err: nil,
|
||||
},
|
||||
{
|
||||
Name: "linked worktree",
|
||||
BeforeFunc: func(fs afero.Fs) {
|
||||
// setup for linked worktree
|
||||
_ = fs.MkdirAll("/path/to/repo/.git/worktrees/worktree1", 0o755)
|
||||
_ = afero.WriteFile(fs, "/path/to/repo/worktree1/.git", []byte("gitdir: /path/to/repo/.git/worktrees/worktree1"), 0o644)
|
||||
},
|
||||
Path: "/path/to/repo/worktree1",
|
||||
Expected: &RepoPaths{
|
||||
currentPath: "/path/to/repo/worktree1",
|
||||
worktreePath: "/path/to/repo/worktree1",
|
||||
worktreeGitDirPath: "/path/to/repo/.git/worktrees/worktree1",
|
||||
repoPath: "/path/to/repo",
|
||||
repoGitDirPath: "/path/to/repo/.git",
|
||||
repoName: "repo",
|
||||
},
|
||||
Err: nil,
|
||||
},
|
||||
{
|
||||
Name: "worktree .git file missing gitdir directive",
|
||||
BeforeFunc: func(fs afero.Fs) {
|
||||
_ = fs.MkdirAll("/path/to/repo/.git/worktrees/worktree2", 0o755)
|
||||
_ = afero.WriteFile(fs, "/path/to/repo/worktree2/.git", []byte("blah"), 0o644)
|
||||
},
|
||||
Path: "/path/to/repo/worktree2",
|
||||
Expected: nil,
|
||||
Err: errors.New("failed to get repo git dir path: could not find git dir for /path/to/repo/worktree2: /path/to/repo/worktree2/.git is a file which suggests we are in a submodule or a worktree but the file's contents do not contain a gitdir pointing to the actual .git directory"),
|
||||
},
|
||||
{
|
||||
Name: "worktree .git file gitdir directive points to a non-existing directory",
|
||||
BeforeFunc: func(fs afero.Fs) {
|
||||
_ = fs.MkdirAll("/path/to/repo/.git/worktrees/worktree2", 0o755)
|
||||
_ = afero.WriteFile(fs, "/path/to/repo/worktree2/.git", []byte("gitdir: /nonexistant"), 0o644)
|
||||
},
|
||||
Path: "/path/to/repo/worktree2",
|
||||
Expected: nil,
|
||||
Err: errors.New("failed to get repo git dir path: could not find git dir for /path/to/repo/worktree2. /nonexistant does not exist"),
|
||||
},
|
||||
{
|
||||
Name: "submodule",
|
||||
BeforeFunc: func(fs afero.Fs) {
|
||||
_ = fs.MkdirAll("/path/to/repo/.git/modules/submodule1", 0o755)
|
||||
_ = afero.WriteFile(fs, "/path/to/repo/submodule1/.git", []byte("gitdir: /path/to/repo/.git/modules/submodule1"), 0o644)
|
||||
BeforeFunc: func(runner *oscommands.FakeCmdObjRunner, getRevParseArgs argFn) {
|
||||
expectedOutput := []string{
|
||||
// --show-toplevel
|
||||
"/path/to/repo/submodule1",
|
||||
// --git-dir
|
||||
"/path/to/repo/.git/modules/submodule1",
|
||||
// --git-common-dir
|
||||
"/path/to/repo/.git/modules/submodule1",
|
||||
// --show-superproject-working-tree
|
||||
"/path/to/repo",
|
||||
}
|
||||
runner.ExpectGitArgs(
|
||||
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--show-superproject-working-tree"),
|
||||
strings.Join(expectedOutput, "\n"),
|
||||
nil)
|
||||
},
|
||||
Path: "/path/to/repo/submodule1",
|
||||
Expected: &RepoPaths{
|
||||
currentPath: "/path/to/repo/submodule1",
|
||||
worktreePath: "/path/to/repo/submodule1",
|
||||
worktreeGitDirPath: "/path/to/repo/.git/modules/submodule1",
|
||||
repoPath: "/path/to/repo/submodule1",
|
||||
@@ -93,49 +82,52 @@ func TestGetRepoPathsAux(t *testing.T) {
|
||||
Err: nil,
|
||||
},
|
||||
{
|
||||
Name: "submodule in nested directory",
|
||||
BeforeFunc: func(fs afero.Fs) {
|
||||
_ = fs.MkdirAll("/path/to/repo/.git/modules/my/submodule1", 0o755)
|
||||
_ = afero.WriteFile(fs, "/path/to/repo/my/submodule1/.git", []byte("gitdir: /path/to/repo/.git/modules/my/submodule1"), 0o644)
|
||||
Name: "git rev-parse returns an error",
|
||||
BeforeFunc: func(runner *oscommands.FakeCmdObjRunner, getRevParseArgs argFn) {
|
||||
runner.ExpectGitArgs(
|
||||
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--show-superproject-working-tree"),
|
||||
"",
|
||||
errors.New("fatal: invalid gitfile format: /path/to/repo/worktree2/.git"))
|
||||
},
|
||||
Path: "/path/to/repo/my/submodule1",
|
||||
Expected: &RepoPaths{
|
||||
currentPath: "/path/to/repo/my/submodule1",
|
||||
worktreePath: "/path/to/repo/my/submodule1",
|
||||
worktreeGitDirPath: "/path/to/repo/.git/modules/my/submodule1",
|
||||
repoPath: "/path/to/repo/my/submodule1",
|
||||
repoGitDirPath: "/path/to/repo/.git/modules/my/submodule1",
|
||||
repoName: "submodule1",
|
||||
},
|
||||
Err: nil,
|
||||
},
|
||||
{
|
||||
Name: "submodule git dir not under .git/modules",
|
||||
BeforeFunc: func(fs afero.Fs) {
|
||||
_ = fs.MkdirAll("/random/submodule1", 0o755)
|
||||
_ = afero.WriteFile(fs, "/path/to/repo/my/submodule1/.git", []byte("gitdir: /random/submodule1"), 0o644)
|
||||
},
|
||||
Path: "/path/to/repo/my/submodule1",
|
||||
Path: "/path/to/repo/worktree2",
|
||||
Expected: nil,
|
||||
Err: errors.New("failed to get repo git dir path: could not find git dir for /path/to/repo/my/submodule1: path is not under `worktrees` or `modules` directories"),
|
||||
Err: func(getRevParseArgs argFn) error {
|
||||
args := strings.Join(getRevParseArgs(), " ")
|
||||
return errors.New(
|
||||
fmt.Sprintf("'git %v --show-toplevel --absolute-git-dir --git-common-dir --show-superproject-working-tree' failed: fatal: invalid gitfile format: /path/to/repo/worktree2/.git", args),
|
||||
)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
s := s
|
||||
t.Run(s.Name, func(t *testing.T) {
|
||||
fs := afero.NewMemMapFs()
|
||||
runner := oscommands.NewFakeRunner(t)
|
||||
cmd := oscommands.NewDummyCmdObjBuilder(runner)
|
||||
|
||||
version, err := GetGitVersion(oscommands.NewDummyOSCommand())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
getRevParseArgs := func() []string {
|
||||
args := []string{"rev-parse"}
|
||||
if version.IsAtLeast(2, 31, 0) {
|
||||
args = append(args, "--path-format=absolute")
|
||||
}
|
||||
return args
|
||||
}
|
||||
// prepare the filesystem for the scenario
|
||||
s.BeforeFunc(fs)
|
||||
s.BeforeFunc(runner, getRevParseArgs)
|
||||
|
||||
// run the function with the scenario path
|
||||
repoPaths, err := getRepoPathsAux(fs, mockResolveSymlinkFn, s.Path)
|
||||
repoPaths, err := GetRepoPaths(cmd, version)
|
||||
|
||||
// check the error and the paths
|
||||
if s.Err != nil {
|
||||
scenarioErr := s.Err(getRevParseArgs)
|
||||
assert.Error(t, err)
|
||||
assert.EqualError(t, err, s.Err.Error())
|
||||
assert.EqualError(t, err, scenarioErr.Error())
|
||||
} else {
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, s.Expected, repoPaths)
|
||||
|
||||
@@ -80,14 +80,15 @@ func (self *StashCommands) Sha(index int) (string, error) {
|
||||
return strings.Trim(sha, "\r\n"), err
|
||||
}
|
||||
|
||||
func (self *StashCommands) ShowStashEntryCmdObj(index int, ignoreWhitespace bool) oscommands.ICmdObj {
|
||||
func (self *StashCommands) ShowStashEntryCmdObj(index int) oscommands.ICmdObj {
|
||||
cmdArgs := NewGitCmd("stash").Arg("show").
|
||||
Arg("-p").
|
||||
Arg("--stat").
|
||||
Arg(fmt.Sprintf("--color=%s", self.UserConfig.Git.Paging.ColorArg)).
|
||||
Arg(fmt.Sprintf("--unified=%d", self.UserConfig.Git.DiffContextSize)).
|
||||
ArgIf(ignoreWhitespace, "--ignore-all-space").
|
||||
Arg(fmt.Sprintf("--unified=%d", self.AppState.DiffContextSize)).
|
||||
ArgIf(self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space").
|
||||
Arg(fmt.Sprintf("stash@{%d}", index)).
|
||||
Dir(self.repoPaths.worktreePath).
|
||||
ToArgv()
|
||||
|
||||
return self.cmd.New(cmdArgs).DontLog()
|
||||
|
||||
@@ -32,14 +32,14 @@ func (self *StashLoader) GetStashEntries(filterPath string) []*models.StashEntry
|
||||
return self.getUnfilteredStashEntries()
|
||||
}
|
||||
|
||||
cmdArgs := NewGitCmd("stash").Arg("list", "--name-only").ToArgv()
|
||||
cmdArgs := NewGitCmd("stash").Arg("list", "-z", "--name-only", "--pretty=%ct|%gs").ToArgv()
|
||||
rawString, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
|
||||
if err != nil {
|
||||
return self.getUnfilteredStashEntries()
|
||||
}
|
||||
stashEntries := []*models.StashEntry{}
|
||||
var currentStashEntry *models.StashEntry
|
||||
lines := utils.SplitLines(rawString)
|
||||
lines := utils.SplitNul(rawString)
|
||||
isAStash := func(line string) bool { return strings.HasPrefix(line, "stash@{") }
|
||||
re := regexp.MustCompile(`stash@\{(\d+)\}`)
|
||||
|
||||
@@ -66,7 +66,7 @@ outer:
|
||||
}
|
||||
|
||||
func (self *StashLoader) getUnfilteredStashEntries() []*models.StashEntry {
|
||||
cmdArgs := NewGitCmd("stash").Arg("list", "-z", "--pretty=%gs").ToArgv()
|
||||
cmdArgs := NewGitCmd("stash").Arg("list", "-z", "--pretty=%ct|%gs").ToArgv()
|
||||
|
||||
rawString, _ := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
|
||||
return lo.Map(utils.SplitNul(rawString), func(line string, index int) *models.StashEntry {
|
||||
@@ -75,8 +75,23 @@ func (self *StashLoader) getUnfilteredStashEntries() []*models.StashEntry {
|
||||
}
|
||||
|
||||
func (c *StashLoader) stashEntryFromLine(line string, index int) *models.StashEntry {
|
||||
return &models.StashEntry{
|
||||
model := &models.StashEntry{
|
||||
Name: line,
|
||||
Index: index,
|
||||
}
|
||||
|
||||
tstr, msg, ok := strings.Cut(line, "|")
|
||||
if !ok {
|
||||
return model
|
||||
}
|
||||
|
||||
t, err := strconv.ParseInt(tstr, 10, 64)
|
||||
if err != nil {
|
||||
return model
|
||||
}
|
||||
|
||||
model.Name = msg
|
||||
model.Recency = utils.UnixToTimeAgo(t)
|
||||
|
||||
return model
|
||||
}
|
||||
|
||||
@@ -22,14 +22,14 @@ func TestGetStashEntries(t *testing.T) {
|
||||
"No stash entries found",
|
||||
"",
|
||||
oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"stash", "list", "-z", "--pretty=%gs"}, "", nil),
|
||||
ExpectGitArgs([]string{"stash", "list", "-z", "--pretty=%ct|%gs"}, "", nil),
|
||||
[]*models.StashEntry{},
|
||||
},
|
||||
{
|
||||
"Several stash entries found",
|
||||
"",
|
||||
oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"stash", "list", "-z", "--pretty=%gs"},
|
||||
ExpectGitArgs([]string{"stash", "list", "-z", "--pretty=%ct|%gs"},
|
||||
"WIP on add-pkg-commands-test: 55c6af2 increase parallel build\x00WIP on master: bb86a3f update github template\x00",
|
||||
nil,
|
||||
),
|
||||
|
||||
@@ -112,21 +112,21 @@ func TestStashStashEntryCmdObj(t *testing.T) {
|
||||
index: 5,
|
||||
contextSize: 3,
|
||||
ignoreWhitespace: false,
|
||||
expected: []string{"git", "stash", "show", "-p", "--stat", "--color=always", "--unified=3", "stash@{5}"},
|
||||
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "--color=always", "--unified=3", "stash@{5}"},
|
||||
},
|
||||
{
|
||||
testName: "Show diff with custom context size",
|
||||
index: 5,
|
||||
contextSize: 77,
|
||||
ignoreWhitespace: false,
|
||||
expected: []string{"git", "stash", "show", "-p", "--stat", "--color=always", "--unified=77", "stash@{5}"},
|
||||
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "--color=always", "--unified=77", "stash@{5}"},
|
||||
},
|
||||
{
|
||||
testName: "Default case",
|
||||
index: 5,
|
||||
contextSize: 3,
|
||||
ignoreWhitespace: true,
|
||||
expected: []string{"git", "stash", "show", "-p", "--stat", "--color=always", "--unified=3", "--ignore-all-space", "stash@{5}"},
|
||||
expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "--color=always", "--unified=3", "--ignore-all-space", "stash@{5}"},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -134,10 +134,15 @@ func TestStashStashEntryCmdObj(t *testing.T) {
|
||||
s := s
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
userConfig := config.GetDefaultConfig()
|
||||
userConfig.Git.DiffContextSize = s.contextSize
|
||||
instance := buildStashCommands(commonDeps{userConfig: userConfig})
|
||||
appState := &config.AppState{}
|
||||
appState.IgnoreWhitespaceInDiffView = s.ignoreWhitespace
|
||||
appState.DiffContextSize = s.contextSize
|
||||
repoPaths := RepoPaths{
|
||||
worktreePath: "/path/to/worktree",
|
||||
}
|
||||
instance := buildStashCommands(commonDeps{userConfig: userConfig, appState: appState, repoPaths: &repoPaths})
|
||||
|
||||
cmdStr := instance.ShowStashEntryCmdObj(s.index, s.ignoreWhitespace).Args()
|
||||
cmdStr := instance.ShowStashEntryCmdObj(s.index).Args()
|
||||
assert.Equal(t, s.expected, cmdStr)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -25,19 +25,16 @@ func NewStatusCommands(
|
||||
// RebaseMode returns "" for non-rebase mode, "normal" for normal rebase
|
||||
// and "interactive" for interactive rebase
|
||||
func (self *StatusCommands) RebaseMode() (enums.RebaseMode, error) {
|
||||
exists, err := self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-apply"))
|
||||
if err != nil {
|
||||
return enums.REBASE_MODE_NONE, err
|
||||
}
|
||||
if exists {
|
||||
ok, err := self.IsInNormalRebase()
|
||||
if err == nil && ok {
|
||||
return enums.REBASE_MODE_NORMAL, nil
|
||||
}
|
||||
exists, err = self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge"))
|
||||
if exists {
|
||||
ok, err = self.IsInInteractiveRebase()
|
||||
if err == nil && ok {
|
||||
return enums.REBASE_MODE_INTERACTIVE, err
|
||||
} else {
|
||||
return enums.REBASE_MODE_NONE, err
|
||||
}
|
||||
|
||||
return enums.REBASE_MODE_NONE, err
|
||||
}
|
||||
|
||||
func (self *StatusCommands) WorkingTreeState() enums.RebaseMode {
|
||||
@@ -68,6 +65,14 @@ func IsBareRepo(osCommand *oscommands.OSCommand) (bool, error) {
|
||||
return strconv.ParseBool(strings.TrimSpace(res))
|
||||
}
|
||||
|
||||
func (self *StatusCommands) IsInNormalRebase() (bool, error) {
|
||||
return self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-apply"))
|
||||
}
|
||||
|
||||
func (self *StatusCommands) IsInInteractiveRebase() (bool, error) {
|
||||
return self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "rebase-merge"))
|
||||
}
|
||||
|
||||
// IsInMergeState states whether we are still mid-merge
|
||||
func (self *StatusCommands) IsInMergeState() (bool, error) {
|
||||
return self.os.FileExists(filepath.Join(self.repoPaths.WorktreeGitDirPath(), "MERGE_HEAD"))
|
||||
|
||||
@@ -36,7 +36,7 @@ func (self *SyncCommands) PushCmdObj(task gocui.Task, opts PushOpts) (oscommands
|
||||
ArgIf(opts.UpstreamBranch != "", opts.UpstreamBranch).
|
||||
ToArgv()
|
||||
|
||||
cmdObj := self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).WithMutex(self.syncMutex)
|
||||
cmdObj := self.cmd.New(cmdArgs).PromptOnCredentialRequest(task)
|
||||
return cmdObj, nil
|
||||
}
|
||||
|
||||
@@ -49,10 +49,16 @@ func (self *SyncCommands) Push(task gocui.Task, opts PushOpts) error {
|
||||
return cmdObj.Run()
|
||||
}
|
||||
|
||||
func (self *SyncCommands) fetchCommandBuilder(fetchAll bool) *GitCommandBuilder {
|
||||
return NewGitCmd("fetch").
|
||||
ArgIf(fetchAll, "--all").
|
||||
// avoid writing to .git/FETCH_HEAD; this allows running a pull
|
||||
// concurrently without getting errors
|
||||
ArgIf(self.version.IsAtLeast(2, 29, 0), "--no-write-fetch-head")
|
||||
}
|
||||
|
||||
func (self *SyncCommands) FetchCmdObj(task gocui.Task) oscommands.ICmdObj {
|
||||
cmdArgs := NewGitCmd("fetch").
|
||||
ArgIf(self.UserConfig.Git.FetchAll, "--all").
|
||||
ToArgv()
|
||||
cmdArgs := self.fetchCommandBuilder(self.UserConfig.Git.FetchAll).ToArgv()
|
||||
|
||||
cmdObj := self.cmd.New(cmdArgs)
|
||||
cmdObj.PromptOnCredentialRequest(task)
|
||||
@@ -64,13 +70,10 @@ func (self *SyncCommands) Fetch(task gocui.Task) error {
|
||||
}
|
||||
|
||||
func (self *SyncCommands) FetchBackgroundCmdObj() oscommands.ICmdObj {
|
||||
cmdArgs := NewGitCmd("fetch").
|
||||
ArgIf(self.UserConfig.Git.FetchAll, "--all").
|
||||
ToArgv()
|
||||
cmdArgs := self.fetchCommandBuilder(self.UserConfig.Git.FetchAll).ToArgv()
|
||||
|
||||
cmdObj := self.cmd.New(cmdArgs)
|
||||
cmdObj.DontLog().FailOnCredentialRequest()
|
||||
cmdObj.WithMutex(self.syncMutex)
|
||||
return cmdObj
|
||||
}
|
||||
|
||||
@@ -96,7 +99,7 @@ func (self *SyncCommands) Pull(task gocui.Task, opts PullOptions) error {
|
||||
|
||||
// setting GIT_SEQUENCE_EDITOR to ':' as a way of skipping it, in case the user
|
||||
// has 'pull.rebase = interactive' configured.
|
||||
return self.cmd.New(cmdArgs).AddEnvVars("GIT_SEQUENCE_EDITOR=:").PromptOnCredentialRequest(task).WithMutex(self.syncMutex).Run()
|
||||
return self.cmd.New(cmdArgs).AddEnvVars("GIT_SEQUENCE_EDITOR=:").PromptOnCredentialRequest(task).Run()
|
||||
}
|
||||
|
||||
func (self *SyncCommands) FastForward(
|
||||
@@ -105,18 +108,18 @@ func (self *SyncCommands) FastForward(
|
||||
remoteName string,
|
||||
remoteBranchName string,
|
||||
) error {
|
||||
cmdArgs := NewGitCmd("fetch").
|
||||
cmdArgs := self.fetchCommandBuilder(false).
|
||||
Arg(remoteName).
|
||||
Arg(remoteBranchName + ":" + branchName).
|
||||
ToArgv()
|
||||
|
||||
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).WithMutex(self.syncMutex).Run()
|
||||
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).Run()
|
||||
}
|
||||
|
||||
func (self *SyncCommands) FetchRemote(task gocui.Task, remoteName string) error {
|
||||
cmdArgs := NewGitCmd("fetch").
|
||||
cmdArgs := self.fetchCommandBuilder(false).
|
||||
Arg(remoteName).
|
||||
ToArgv()
|
||||
|
||||
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).WithMutex(self.syncMutex).Run()
|
||||
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).Run()
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func (self *TagCommands) HasTag(tagName string) bool {
|
||||
return self.cmd.New(cmdArgs).Run() == nil
|
||||
}
|
||||
|
||||
func (self *TagCommands) Delete(tagName string) error {
|
||||
func (self *TagCommands) LocalDelete(tagName string) error {
|
||||
cmdArgs := NewGitCmd("tag").Arg("-d", tagName).
|
||||
ToArgv()
|
||||
|
||||
@@ -52,5 +52,5 @@ func (self *TagCommands) Push(task gocui.Task, remoteName string, tagName string
|
||||
cmdArgs := NewGitCmd("push").Arg(remoteName, "tag", tagName).
|
||||
ToArgv()
|
||||
|
||||
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).WithMutex(self.syncMutex).Run()
|
||||
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).Run()
|
||||
}
|
||||
|
||||
@@ -69,3 +69,11 @@ func (v *GitVersion) IsOlderThan(major, minor, patch int) bool {
|
||||
func (v *GitVersion) IsOlderThanVersion(version *GitVersion) bool {
|
||||
return v.IsOlderThan(version.Major, version.Minor, version.Patch)
|
||||
}
|
||||
|
||||
func (v *GitVersion) IsAtLeast(major, minor, patch int) bool {
|
||||
return !v.IsOlderThan(major, minor, patch)
|
||||
}
|
||||
|
||||
func (v *GitVersion) IsAtLeastVersion(version *GitVersion) bool {
|
||||
return v.IsAtLeast(version.Major, version.Minor, version.Patch)
|
||||
}
|
||||
|
||||
@@ -45,3 +45,12 @@ func TestGitVersionIsOlderThan(t *testing.T) {
|
||||
assert.True(t, (&GitVersion{2, 0, 1, ""}).IsOlderThan(2, 1, 0))
|
||||
assert.True(t, (&GitVersion{2, 0, 1, ""}).IsOlderThan(3, 0, 0))
|
||||
}
|
||||
|
||||
func TestGitVersionIsAtLeast(t *testing.T) {
|
||||
assert.True(t, (&GitVersion{2, 0, 0, ""}).IsAtLeast(1, 99, 99))
|
||||
assert.True(t, (&GitVersion{2, 0, 0, ""}).IsAtLeast(2, 0, 0))
|
||||
assert.True(t, (&GitVersion{2, 1, 0, ""}).IsAtLeast(2, 0, 9))
|
||||
|
||||
assert.False(t, (&GitVersion{2, 0, 1, ""}).IsAtLeast(2, 1, 0))
|
||||
assert.False(t, (&GitVersion{2, 0, 1, ""}).IsAtLeast(3, 0, 0))
|
||||
}
|
||||
|
||||
@@ -31,10 +31,6 @@ func (self *WorkingTreeCommands) OpenMergeToolCmdObj() oscommands.ICmdObj {
|
||||
return self.cmd.New(NewGitCmd("mergetool").ToArgv())
|
||||
}
|
||||
|
||||
func (self *WorkingTreeCommands) OpenMergeTool() error {
|
||||
return self.OpenMergeToolCmdObj().Run()
|
||||
}
|
||||
|
||||
// StageFile stages a file
|
||||
func (self *WorkingTreeCommands) StageFile(path string) error {
|
||||
return self.StageFiles([]string{path})
|
||||
@@ -61,21 +57,20 @@ func (self *WorkingTreeCommands) UnstageAll() error {
|
||||
// UnStageFile unstages a file
|
||||
// we accept an array of filenames for the cases where a file has been renamed i.e.
|
||||
// we accept the current name and the previous name
|
||||
func (self *WorkingTreeCommands) UnStageFile(fileNames []string, reset bool) error {
|
||||
for _, name := range fileNames {
|
||||
var cmdArgs []string
|
||||
if reset {
|
||||
cmdArgs = NewGitCmd("reset").Arg("HEAD", "--", name).ToArgv()
|
||||
} else {
|
||||
cmdArgs = NewGitCmd("rm").Arg("--cached", "--force", "--", name).ToArgv()
|
||||
}
|
||||
|
||||
err := self.cmd.New(cmdArgs).Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func (self *WorkingTreeCommands) UnStageFile(paths []string, tracked bool) error {
|
||||
if tracked {
|
||||
return self.UnstageTrackedFiles(paths)
|
||||
} else {
|
||||
return self.UnstageUntrackedFiles(paths)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *WorkingTreeCommands) UnstageTrackedFiles(paths []string) error {
|
||||
return self.cmd.New(NewGitCmd("reset").Arg("HEAD", "--").Arg(paths...).ToArgv()).Run()
|
||||
}
|
||||
|
||||
func (self *WorkingTreeCommands) UnstageUntrackedFiles(paths []string) error {
|
||||
return self.cmd.New(NewGitCmd("rm").Arg("--cached", "--force", "--").Arg(paths...).ToArgv()).Run()
|
||||
}
|
||||
|
||||
func (self *WorkingTreeCommands) BeforeAndAfterFileForRename(file *models.File) (*models.File, *models.File, error) {
|
||||
@@ -169,6 +164,7 @@ func (self *WorkingTreeCommands) DiscardAllFileChanges(file *models.File) error
|
||||
if file.Added {
|
||||
return self.os.RemoveFile(file.Name)
|
||||
}
|
||||
|
||||
return self.DiscardUnstagedFileChanges(file)
|
||||
}
|
||||
|
||||
@@ -176,6 +172,8 @@ type IFileNode interface {
|
||||
ForEachFile(cb func(*models.File) error) error
|
||||
GetFilePathsMatching(test func(*models.File) bool) []string
|
||||
GetPath() string
|
||||
// Returns file if the node is not a directory, otherwise returns nil
|
||||
GetFile() *models.File
|
||||
}
|
||||
|
||||
func (self *WorkingTreeCommands) DiscardAllDirChanges(node IFileNode) error {
|
||||
@@ -184,13 +182,24 @@ func (self *WorkingTreeCommands) DiscardAllDirChanges(node IFileNode) error {
|
||||
}
|
||||
|
||||
func (self *WorkingTreeCommands) DiscardUnstagedDirChanges(node IFileNode) error {
|
||||
if err := self.RemoveUntrackedDirFiles(node); err != nil {
|
||||
return err
|
||||
}
|
||||
file := node.GetFile()
|
||||
if file == nil {
|
||||
if err := self.RemoveUntrackedDirFiles(node); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmdArgs := NewGitCmd("checkout").Arg("--", node.GetPath()).ToArgv()
|
||||
if err := self.cmd.New(cmdArgs).Run(); err != nil {
|
||||
return err
|
||||
cmdArgs := NewGitCmd("checkout").Arg("--", node.GetPath()).ToArgv()
|
||||
if err := self.cmd.New(cmdArgs).Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if file.Added && !file.HasStagedChanges {
|
||||
return self.os.RemoveFile(file.Name)
|
||||
}
|
||||
|
||||
if err := self.DiscardUnstagedFileChanges(file); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -211,7 +220,6 @@ func (self *WorkingTreeCommands) RemoveUntrackedDirFiles(node IFileNode) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DiscardUnstagedFileChanges directly
|
||||
func (self *WorkingTreeCommands) DiscardUnstagedFileChanges(file *models.File) error {
|
||||
cmdArgs := NewGitCmd("checkout").Arg("--", file.Name).ToArgv()
|
||||
return self.cmd.New(cmdArgs).Run()
|
||||
@@ -228,34 +236,38 @@ func (self *WorkingTreeCommands) Exclude(filename string) error {
|
||||
}
|
||||
|
||||
// WorktreeFileDiff returns the diff of a file
|
||||
func (self *WorkingTreeCommands) WorktreeFileDiff(file *models.File, plain bool, cached bool, ignoreWhitespace bool) string {
|
||||
func (self *WorkingTreeCommands) WorktreeFileDiff(file *models.File, plain bool, cached bool) string {
|
||||
// for now we assume an error means the file was deleted
|
||||
s, _ := self.WorktreeFileDiffCmdObj(file, plain, cached, ignoreWhitespace).RunWithOutput()
|
||||
s, _ := self.WorktreeFileDiffCmdObj(file, plain, cached).RunWithOutput()
|
||||
return s
|
||||
}
|
||||
|
||||
func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain bool, cached bool, ignoreWhitespace bool) oscommands.ICmdObj {
|
||||
func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain bool, cached bool) oscommands.ICmdObj {
|
||||
colorArg := self.UserConfig.Git.Paging.ColorArg
|
||||
if plain {
|
||||
colorArg = "never"
|
||||
}
|
||||
|
||||
contextSize := self.UserConfig.Git.DiffContextSize
|
||||
contextSize := self.AppState.DiffContextSize
|
||||
prevPath := node.GetPreviousPath()
|
||||
noIndex := !node.GetIsTracked() && !node.GetHasStagedChanges() && !cached && node.GetIsFile()
|
||||
extDiffCmd := self.UserConfig.Git.Paging.ExternalDiffCommand
|
||||
useExtDiff := extDiffCmd != "" && !plain
|
||||
|
||||
cmdArgs := NewGitCmd("diff").
|
||||
ConfigIf(useExtDiff, "diff.external="+extDiffCmd).
|
||||
ArgIfElse(useExtDiff, "--ext-diff", "--no-ext-diff").
|
||||
Arg("--submodule").
|
||||
Arg("--no-ext-diff").
|
||||
Arg(fmt.Sprintf("--unified=%d", contextSize)).
|
||||
Arg(fmt.Sprintf("--color=%s", colorArg)).
|
||||
ArgIf(ignoreWhitespace, "--ignore-all-space").
|
||||
ArgIf(!plain && self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space").
|
||||
ArgIf(cached, "--cached").
|
||||
ArgIf(noIndex, "--no-index").
|
||||
Arg("--").
|
||||
ArgIf(noIndex, "/dev/null").
|
||||
Arg(node.GetPath()).
|
||||
ArgIf(prevPath != "", prevPath).
|
||||
Dir(self.repoPaths.worktreePath).
|
||||
ToArgv()
|
||||
|
||||
return self.cmd.New(cmdArgs).DontLog()
|
||||
@@ -263,34 +275,35 @@ func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain
|
||||
|
||||
// ShowFileDiff get the diff of specified from and to. Typically this will be used for a single commit so it'll be 123abc^..123abc
|
||||
// but when we're in diff mode it could be any 'from' to any 'to'. The reverse flag is also here thanks to diff mode.
|
||||
func (self *WorkingTreeCommands) ShowFileDiff(from string, to string, reverse bool, fileName string, plain bool,
|
||||
ignoreWhitespace bool,
|
||||
) (string, error) {
|
||||
return self.ShowFileDiffCmdObj(from, to, reverse, fileName, plain, ignoreWhitespace).RunWithOutput()
|
||||
func (self *WorkingTreeCommands) ShowFileDiff(from string, to string, reverse bool, fileName string, plain bool) (string, error) {
|
||||
return self.ShowFileDiffCmdObj(from, to, reverse, fileName, plain).RunWithOutput()
|
||||
}
|
||||
|
||||
func (self *WorkingTreeCommands) ShowFileDiffCmdObj(from string, to string, reverse bool, fileName string, plain bool,
|
||||
ignoreWhitespace bool,
|
||||
) oscommands.ICmdObj {
|
||||
contextSize := self.UserConfig.Git.DiffContextSize
|
||||
func (self *WorkingTreeCommands) ShowFileDiffCmdObj(from string, to string, reverse bool, fileName string, plain bool) oscommands.ICmdObj {
|
||||
contextSize := self.AppState.DiffContextSize
|
||||
|
||||
colorArg := self.UserConfig.Git.Paging.ColorArg
|
||||
if plain {
|
||||
colorArg = "never"
|
||||
}
|
||||
|
||||
extDiffCmd := self.UserConfig.Git.Paging.ExternalDiffCommand
|
||||
useExtDiff := extDiffCmd != "" && !plain
|
||||
|
||||
cmdArgs := NewGitCmd("diff").
|
||||
ConfigIf(useExtDiff, "diff.external="+extDiffCmd).
|
||||
ArgIfElse(useExtDiff, "--ext-diff", "--no-ext-diff").
|
||||
Arg("--submodule").
|
||||
Arg("--no-ext-diff").
|
||||
Arg(fmt.Sprintf("--unified=%d", contextSize)).
|
||||
Arg("--no-renames").
|
||||
Arg(fmt.Sprintf("--color=%s", colorArg)).
|
||||
Arg(from).
|
||||
Arg(to).
|
||||
ArgIf(reverse, "-R").
|
||||
ArgIf(ignoreWhitespace, "--ignore-all-space").
|
||||
ArgIf(!plain && self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space").
|
||||
Arg("--").
|
||||
Arg(fileName).
|
||||
Dir(self.repoPaths.worktreePath).
|
||||
ToArgv()
|
||||
|
||||
return self.cmd.New(cmdArgs).DontLog()
|
||||
|
||||
@@ -231,7 +231,7 @@ func TestWorkingTreeDiff(t *testing.T) {
|
||||
ignoreWhitespace: false,
|
||||
contextSize: 3,
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"diff", "--submodule", "--no-ext-diff", "--unified=3", "--color=always", "--", "test.txt"}, expectedResult, nil),
|
||||
ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=always", "--", "test.txt"}, expectedResult, nil),
|
||||
},
|
||||
{
|
||||
testName: "cached",
|
||||
@@ -245,7 +245,7 @@ func TestWorkingTreeDiff(t *testing.T) {
|
||||
ignoreWhitespace: false,
|
||||
contextSize: 3,
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"diff", "--submodule", "--no-ext-diff", "--unified=3", "--color=always", "--cached", "--", "test.txt"}, expectedResult, nil),
|
||||
ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=always", "--cached", "--", "test.txt"}, expectedResult, nil),
|
||||
},
|
||||
{
|
||||
testName: "plain",
|
||||
@@ -259,7 +259,7 @@ func TestWorkingTreeDiff(t *testing.T) {
|
||||
ignoreWhitespace: false,
|
||||
contextSize: 3,
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"diff", "--submodule", "--no-ext-diff", "--unified=3", "--color=never", "--", "test.txt"}, expectedResult, nil),
|
||||
ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=never", "--", "test.txt"}, expectedResult, nil),
|
||||
},
|
||||
{
|
||||
testName: "File not tracked and file has no staged changes",
|
||||
@@ -273,7 +273,7 @@ func TestWorkingTreeDiff(t *testing.T) {
|
||||
ignoreWhitespace: false,
|
||||
contextSize: 3,
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"diff", "--submodule", "--no-ext-diff", "--unified=3", "--color=always", "--no-index", "--", "/dev/null", "test.txt"}, expectedResult, nil),
|
||||
ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=always", "--no-index", "--", "/dev/null", "test.txt"}, expectedResult, nil),
|
||||
},
|
||||
{
|
||||
testName: "Default case (ignore whitespace)",
|
||||
@@ -287,7 +287,7 @@ func TestWorkingTreeDiff(t *testing.T) {
|
||||
ignoreWhitespace: true,
|
||||
contextSize: 3,
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"diff", "--submodule", "--no-ext-diff", "--unified=3", "--color=always", "--ignore-all-space", "--", "test.txt"}, expectedResult, nil),
|
||||
ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=always", "--ignore-all-space", "--", "test.txt"}, expectedResult, nil),
|
||||
},
|
||||
{
|
||||
testName: "Show diff with custom context size",
|
||||
@@ -301,7 +301,7 @@ func TestWorkingTreeDiff(t *testing.T) {
|
||||
ignoreWhitespace: false,
|
||||
contextSize: 17,
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"diff", "--submodule", "--no-ext-diff", "--unified=17", "--color=always", "--", "test.txt"}, expectedResult, nil),
|
||||
ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=17", "--color=always", "--", "test.txt"}, expectedResult, nil),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -309,10 +309,15 @@ func TestWorkingTreeDiff(t *testing.T) {
|
||||
s := s
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
userConfig := config.GetDefaultConfig()
|
||||
userConfig.Git.DiffContextSize = s.contextSize
|
||||
appState := &config.AppState{}
|
||||
appState.IgnoreWhitespaceInDiffView = s.ignoreWhitespace
|
||||
appState.DiffContextSize = s.contextSize
|
||||
repoPaths := RepoPaths{
|
||||
worktreePath: "/path/to/worktree",
|
||||
}
|
||||
|
||||
instance := buildWorkingTreeCommands(commonDeps{runner: s.runner, userConfig: userConfig})
|
||||
result := instance.WorktreeFileDiff(s.file, s.plain, s.cached, s.ignoreWhitespace)
|
||||
instance := buildWorkingTreeCommands(commonDeps{runner: s.runner, userConfig: userConfig, appState: appState, repoPaths: &repoPaths})
|
||||
result := instance.WorktreeFileDiff(s.file, s.plain, s.cached)
|
||||
assert.Equal(t, expectedResult, result)
|
||||
s.runner.CheckForMissingCalls()
|
||||
})
|
||||
@@ -343,7 +348,7 @@ func TestWorkingTreeShowFileDiff(t *testing.T) {
|
||||
ignoreWhitespace: false,
|
||||
contextSize: 3,
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"diff", "--submodule", "--no-ext-diff", "--unified=3", "--no-renames", "--color=always", "1234567890", "0987654321", "--", "test.txt"}, expectedResult, nil),
|
||||
ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--no-renames", "--color=always", "1234567890", "0987654321", "--", "test.txt"}, expectedResult, nil),
|
||||
},
|
||||
{
|
||||
testName: "Show diff with custom context size",
|
||||
@@ -354,7 +359,7 @@ func TestWorkingTreeShowFileDiff(t *testing.T) {
|
||||
ignoreWhitespace: false,
|
||||
contextSize: 123,
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"diff", "--submodule", "--no-ext-diff", "--unified=123", "--no-renames", "--color=always", "1234567890", "0987654321", "--", "test.txt"}, expectedResult, nil),
|
||||
ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=123", "--no-renames", "--color=always", "1234567890", "0987654321", "--", "test.txt"}, expectedResult, nil),
|
||||
},
|
||||
{
|
||||
testName: "Default case (ignore whitespace)",
|
||||
@@ -365,7 +370,7 @@ func TestWorkingTreeShowFileDiff(t *testing.T) {
|
||||
ignoreWhitespace: true,
|
||||
contextSize: 3,
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
ExpectGitArgs([]string{"diff", "--submodule", "--no-ext-diff", "--unified=3", "--no-renames", "--color=always", "1234567890", "0987654321", "--ignore-all-space", "--", "test.txt"}, expectedResult, nil),
|
||||
ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--no-renames", "--color=always", "1234567890", "0987654321", "--ignore-all-space", "--", "test.txt"}, expectedResult, nil),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -373,11 +378,16 @@ func TestWorkingTreeShowFileDiff(t *testing.T) {
|
||||
s := s
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
userConfig := config.GetDefaultConfig()
|
||||
userConfig.Git.DiffContextSize = s.contextSize
|
||||
appState := &config.AppState{}
|
||||
appState.IgnoreWhitespaceInDiffView = s.ignoreWhitespace
|
||||
appState.DiffContextSize = s.contextSize
|
||||
repoPaths := RepoPaths{
|
||||
worktreePath: "/path/to/worktree",
|
||||
}
|
||||
|
||||
instance := buildWorkingTreeCommands(commonDeps{runner: s.runner, userConfig: userConfig})
|
||||
instance := buildWorkingTreeCommands(commonDeps{runner: s.runner, userConfig: userConfig, appState: appState, repoPaths: &repoPaths})
|
||||
|
||||
result, err := instance.ShowFileDiff(s.from, s.to, s.reverse, "test.txt", s.plain, s.ignoreWhitespace)
|
||||
result, err := instance.ShowFileDiff(s.from, s.to, s.reverse, "test.txt", s.plain)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, expectedResult, result)
|
||||
s.runner.CheckForMissingCalls()
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
iofs "io/fs"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
@@ -57,18 +58,14 @@ func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) {
|
||||
isCurrent := path == worktreePath
|
||||
isPathMissing := self.pathExists(path)
|
||||
|
||||
var gitDir string
|
||||
gitDir, err := getWorktreeGitDirPath(self.Fs, path)
|
||||
if err != nil {
|
||||
self.Log.Warnf("Could not find git dir for worktree %s: %v", path, err)
|
||||
}
|
||||
|
||||
current = &models.Worktree{
|
||||
IsMain: isMain,
|
||||
IsCurrent: isCurrent,
|
||||
IsPathMissing: isPathMissing,
|
||||
Path: path,
|
||||
GitDir: gitDir,
|
||||
// we defer populating GitDir until a loop below so that
|
||||
// we can parallelize the calls to git rev-parse
|
||||
GitDir: "",
|
||||
}
|
||||
} else if strings.HasPrefix(splitLine, "branch ") {
|
||||
branch := strings.SplitN(splitLine, " ", 2)[1]
|
||||
@@ -76,6 +73,28 @@ func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) {
|
||||
}
|
||||
}
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(len(worktrees))
|
||||
for _, worktree := range worktrees {
|
||||
worktree := worktree
|
||||
|
||||
go utils.Safe(func() {
|
||||
defer wg.Done()
|
||||
|
||||
if worktree.IsPathMissing {
|
||||
return
|
||||
}
|
||||
gitDir, err := callGitRevParseWithDir(self.cmd, self.version, worktree.Path, "--absolute-git-dir")
|
||||
if err != nil {
|
||||
self.Log.Warnf("Could not find git dir for worktree %s: %v", worktree.Path, err)
|
||||
return
|
||||
}
|
||||
|
||||
worktree.GitDir = gitDir
|
||||
})
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
names := getUniqueNamesFromPaths(lo.Map(worktrees, func(worktree *models.Worktree, _ int) string {
|
||||
return worktree.Path
|
||||
}))
|
||||
|
||||
@@ -14,7 +14,7 @@ func TestGetWorktrees(t *testing.T) {
|
||||
type scenario struct {
|
||||
testName string
|
||||
repoPaths *RepoPaths
|
||||
before func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs)
|
||||
before func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs, getRevParseArgs argFn)
|
||||
expectedWorktrees []*models.Worktree
|
||||
expectedErr string
|
||||
}
|
||||
@@ -26,7 +26,7 @@ func TestGetWorktrees(t *testing.T) {
|
||||
repoPath: "/path/to/repo",
|
||||
worktreePath: "/path/to/repo",
|
||||
},
|
||||
before: func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs) {
|
||||
before: func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs, getRevParseArgs argFn) {
|
||||
runner.ExpectGitArgs([]string{"worktree", "list", "--porcelain"},
|
||||
`worktree /path/to/repo
|
||||
HEAD d85cc9d281fa6ae1665c68365fc70e75e82a042d
|
||||
@@ -34,6 +34,8 @@ branch refs/heads/mybranch
|
||||
`,
|
||||
nil)
|
||||
|
||||
gitArgsMainWorktree := append(append([]string{"-C", "/path/to/repo"}, getRevParseArgs()...), "--absolute-git-dir")
|
||||
runner.ExpectGitArgs(gitArgsMainWorktree, "/path/to/repo/.git", nil)
|
||||
_ = fs.MkdirAll("/path/to/repo/.git", 0o755)
|
||||
},
|
||||
expectedWorktrees: []*models.Worktree{
|
||||
@@ -55,7 +57,7 @@ branch refs/heads/mybranch
|
||||
repoPath: "/path/to/repo",
|
||||
worktreePath: "/path/to/repo",
|
||||
},
|
||||
before: func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs) {
|
||||
before: func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs, getRevParseArgs argFn) {
|
||||
runner.ExpectGitArgs([]string{"worktree", "list", "--porcelain"},
|
||||
`worktree /path/to/repo
|
||||
HEAD d85cc9d281fa6ae1665c68365fc70e75e82a042d
|
||||
@@ -66,6 +68,10 @@ HEAD 775955775e79b8f5b4c4b56f82fbf657e2d5e4de
|
||||
branch refs/heads/mybranch-worktree
|
||||
`,
|
||||
nil)
|
||||
gitArgsMainWorktree := append(append([]string{"-C", "/path/to/repo"}, getRevParseArgs()...), "--absolute-git-dir")
|
||||
runner.ExpectGitArgs(gitArgsMainWorktree, "/path/to/repo/.git", nil)
|
||||
gitArgsLinkedWorktree := append(append([]string{"-C", "/path/to/repo-worktree"}, getRevParseArgs()...), "--absolute-git-dir")
|
||||
runner.ExpectGitArgs(gitArgsLinkedWorktree, "/path/to/repo/.git/worktrees/repo-worktree", nil)
|
||||
|
||||
_ = fs.MkdirAll("/path/to/repo/.git", 0o755)
|
||||
_ = fs.MkdirAll("/path/to/repo-worktree", 0o755)
|
||||
@@ -100,7 +106,7 @@ branch refs/heads/mybranch-worktree
|
||||
repoPath: "/path/to/repo",
|
||||
worktreePath: "/path/to/repo",
|
||||
},
|
||||
before: func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs) {
|
||||
before: func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs, getRevParseArgs argFn) {
|
||||
runner.ExpectGitArgs([]string{"worktree", "list", "--porcelain"},
|
||||
`worktree /path/to/worktree
|
||||
HEAD 775955775e79b8f5b4c4b56f82fbf657e2d5e4de
|
||||
@@ -129,7 +135,7 @@ branch refs/heads/missingbranch
|
||||
repoPath: "/path/to/repo",
|
||||
worktreePath: "/path/to/repo-worktree",
|
||||
},
|
||||
before: func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs) {
|
||||
before: func(runner *oscommands.FakeCmdObjRunner, fs afero.Fs, getRevParseArgs argFn) {
|
||||
runner.ExpectGitArgs([]string{"worktree", "list", "--porcelain"},
|
||||
`worktree /path/to/repo
|
||||
HEAD d85cc9d281fa6ae1665c68365fc70e75e82a042d
|
||||
@@ -140,6 +146,10 @@ HEAD 775955775e79b8f5b4c4b56f82fbf657e2d5e4de
|
||||
branch refs/heads/mybranch-worktree
|
||||
`,
|
||||
nil)
|
||||
gitArgsMainWorktree := append(append([]string{"-C", "/path/to/repo"}, getRevParseArgs()...), "--absolute-git-dir")
|
||||
runner.ExpectGitArgs(gitArgsMainWorktree, "/path/to/repo/.git", nil)
|
||||
gitArgsLinkedWorktree := append(append([]string{"-C", "/path/to/repo-worktree"}, getRevParseArgs()...), "--absolute-git-dir")
|
||||
runner.ExpectGitArgs(gitArgsLinkedWorktree, "/path/to/repo/.git/worktrees/repo-worktree", nil)
|
||||
|
||||
_ = fs.MkdirAll("/path/to/repo/.git", 0o755)
|
||||
_ = fs.MkdirAll("/path/to/repo-worktree", 0o755)
|
||||
@@ -175,10 +185,23 @@ branch refs/heads/mybranch-worktree
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
runner := oscommands.NewFakeRunner(t)
|
||||
fs := afero.NewMemMapFs()
|
||||
s.before(runner, fs)
|
||||
version, err := GetGitVersion(oscommands.NewDummyOSCommand())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
getRevParseArgs := func() []string {
|
||||
args := []string{"rev-parse"}
|
||||
if version.IsAtLeast(2, 31, 0) {
|
||||
args = append(args, "--path-format=absolute")
|
||||
}
|
||||
return args
|
||||
}
|
||||
|
||||
s.before(runner, fs, getRevParseArgs)
|
||||
|
||||
loader := &WorktreeLoader{
|
||||
GitCommon: buildGitCommon(commonDeps{runner: runner, fs: fs, repoPaths: s.repoPaths}),
|
||||
GitCommon: buildGitCommon(commonDeps{runner: runner, fs: fs, repoPaths: s.repoPaths, gitVersion: version}),
|
||||
}
|
||||
|
||||
worktrees, err := loader.GetWorktrees()
|
||||
@@ -186,7 +209,7 @@ branch refs/heads/mybranch-worktree
|
||||
assert.EqualError(t, errors.New(s.expectedErr), err.Error())
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, worktrees, s.expectedWorktrees)
|
||||
assert.EqualValues(t, s.expectedWorktrees, worktrees)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestFindWorktreeRoot(t *testing.T) {
|
||||
type scenario struct {
|
||||
testName string
|
||||
currentPath string
|
||||
before func(fs afero.Fs)
|
||||
expectedPath string
|
||||
expectedErr string
|
||||
}
|
||||
|
||||
scenarios := []scenario{
|
||||
{
|
||||
testName: "at root of worktree",
|
||||
currentPath: "/path/to/repo",
|
||||
before: func(fs afero.Fs) {
|
||||
_ = fs.MkdirAll("/path/to/repo/.git", 0o755)
|
||||
},
|
||||
expectedPath: "/path/to/repo",
|
||||
expectedErr: "",
|
||||
},
|
||||
{
|
||||
testName: "inside worktree",
|
||||
currentPath: "/path/to/repo/subdir",
|
||||
before: func(fs afero.Fs) {
|
||||
_ = fs.MkdirAll("/path/to/repo/.git", 0o755)
|
||||
_ = fs.MkdirAll("/path/to/repo/subdir", 0o755)
|
||||
},
|
||||
expectedPath: "/path/to/repo",
|
||||
expectedErr: "",
|
||||
},
|
||||
{
|
||||
testName: "not in a git repo",
|
||||
currentPath: "/path/to/dir",
|
||||
before: func(fs afero.Fs) {},
|
||||
expectedPath: "",
|
||||
expectedErr: "Must open lazygit in a git repository",
|
||||
},
|
||||
{
|
||||
testName: "In linked worktree",
|
||||
currentPath: "/path/to/worktree",
|
||||
before: func(fs afero.Fs) {
|
||||
_ = fs.MkdirAll("/path/to/worktree", 0o755)
|
||||
_ = afero.WriteFile(fs, "/path/to/worktree/.git", []byte("blah"), 0o755)
|
||||
},
|
||||
expectedPath: "/path/to/worktree",
|
||||
expectedErr: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
s := s
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
fs := afero.NewMemMapFs()
|
||||
s.before(fs)
|
||||
|
||||
root, err := findWorktreeRoot(fs, s.currentPath)
|
||||
if s.expectedErr != "" {
|
||||
assert.EqualError(t, errors.New(s.expectedErr), err.Error())
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, s.expectedPath, root)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -99,33 +99,30 @@ func (self *HostingServiceMgr) getCandidateServiceDomains() []ServiceDomain {
|
||||
|
||||
serviceDomains := slices.Clone(defaultServiceDomains)
|
||||
|
||||
if len(self.configServiceDomains) > 0 {
|
||||
for gitDomain, typeAndDomain := range self.configServiceDomains {
|
||||
splitData := strings.Split(typeAndDomain, ":")
|
||||
if len(splitData) != 2 {
|
||||
self.log.Errorf("Unexpected format for git service: '%s'. Expected something like 'github.com:github.com'", typeAndDomain)
|
||||
continue
|
||||
}
|
||||
for gitDomain, typeAndDomain := range self.configServiceDomains {
|
||||
provider, webDomain, success := strings.Cut(typeAndDomain, ":")
|
||||
|
||||
provider := splitData[0]
|
||||
webDomain := splitData[1]
|
||||
|
||||
serviceDefinition, ok := serviceDefinitionByProvider[provider]
|
||||
if !ok {
|
||||
providerNames := lo.Map(serviceDefinitions, func(serviceDefinition ServiceDefinition, _ int) string {
|
||||
return serviceDefinition.provider
|
||||
})
|
||||
|
||||
self.log.Errorf("Unknown git service type: '%s'. Expected one of %s", provider, strings.Join(providerNames, ", "))
|
||||
continue
|
||||
}
|
||||
|
||||
serviceDomains = append(serviceDomains, ServiceDomain{
|
||||
gitDomain: gitDomain,
|
||||
webDomain: webDomain,
|
||||
serviceDefinition: serviceDefinition,
|
||||
})
|
||||
// we allow for one ':' for specifying the TCP port
|
||||
if !success || strings.Count(webDomain, ":") > 1 {
|
||||
self.log.Errorf("Unexpected format for git service: '%s'. Expected something like 'github.com:github.com'", typeAndDomain)
|
||||
continue
|
||||
}
|
||||
|
||||
serviceDefinition, ok := serviceDefinitionByProvider[provider]
|
||||
if !ok {
|
||||
providerNames := lo.Map(serviceDefinitions, func(serviceDefinition ServiceDefinition, _ int) string {
|
||||
return serviceDefinition.provider
|
||||
})
|
||||
|
||||
self.log.Errorf("Unknown git service type: '%s'. Expected one of %s", provider, strings.Join(providerNames, ", "))
|
||||
continue
|
||||
}
|
||||
|
||||
serviceDomains = append(serviceDomains, ServiceDomain{
|
||||
gitDomain: gitDomain,
|
||||
webDomain: webDomain,
|
||||
serviceDefinition: serviceDefinition,
|
||||
})
|
||||
}
|
||||
|
||||
return serviceDomains
|
||||
|
||||
@@ -340,6 +340,30 @@ func TestGetPullRequestURL(t *testing.T) {
|
||||
},
|
||||
expectedLoggedErrors: nil,
|
||||
},
|
||||
{
|
||||
testName: "Does not log error when config service webDomain contains a port",
|
||||
from: "feature/profile-page",
|
||||
remoteUrl: "git@my.domain.test:johndoe/social_network.git",
|
||||
configServiceDomains: map[string]string{
|
||||
"my.domain.test": "gitlab:my.domain.test:1111",
|
||||
},
|
||||
test: func(url string, err error) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "https://my.domain.test:1111/johndoe/social_network/-/merge_requests/new?merge_request[source_branch]=feature%2Fprofile-page", url)
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "Logs error when webDomain contains more than one colon",
|
||||
from: "feature/profile-page",
|
||||
remoteUrl: "git@my.domain.test:johndoe/social_network.git",
|
||||
configServiceDomains: map[string]string{
|
||||
"my.domain.test": "gitlab:my.domain.test:1111:2222",
|
||||
},
|
||||
test: func(url string, err error) {
|
||||
assert.Error(t, err)
|
||||
},
|
||||
expectedLoggedErrors: []string{"Unexpected format for git service: 'gitlab:my.domain.test:1111:2222'. Expected something like 'github.com:github.com'"},
|
||||
},
|
||||
{
|
||||
testName: "Logs error when config service domain is malformed",
|
||||
from: "feature/profile-page",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package models
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Branch : A git branch
|
||||
// duplicating this for now
|
||||
type Branch struct {
|
||||
@@ -43,10 +45,30 @@ func (b *Branch) ParentRefName() string {
|
||||
return b.RefName() + "^"
|
||||
}
|
||||
|
||||
func (b *Branch) FullUpstreamRefName() string {
|
||||
if b.UpstreamRemote == "" || b.UpstreamBranch == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf("refs/remotes/%s/%s", b.UpstreamRemote, b.UpstreamBranch)
|
||||
}
|
||||
|
||||
func (b *Branch) ShortUpstreamRefName() string {
|
||||
if b.UpstreamRemote == "" || b.UpstreamBranch == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s", b.UpstreamRemote, b.UpstreamBranch)
|
||||
}
|
||||
|
||||
func (b *Branch) ID() string {
|
||||
return b.RefName()
|
||||
}
|
||||
|
||||
func (b *Branch) URN() string {
|
||||
return "branch-" + b.ID()
|
||||
}
|
||||
|
||||
func (b *Branch) Description() string {
|
||||
return b.RefName()
|
||||
}
|
||||
|
||||
@@ -30,6 +30,17 @@ const (
|
||||
ActionConflict = todo.Comment + 1
|
||||
)
|
||||
|
||||
type Divergence int
|
||||
|
||||
// For a divergence log (left/right comparison of two refs) this is set to
|
||||
// either DivergenceLeft or DivergenceRight for each commit; for normal
|
||||
// commit views it is always DivergenceNone.
|
||||
const (
|
||||
DivergenceNone Divergence = iota
|
||||
DivergenceLeft
|
||||
DivergenceRight
|
||||
)
|
||||
|
||||
// Commit : A git commit
|
||||
type Commit struct {
|
||||
Sha string
|
||||
@@ -41,6 +52,7 @@ type Commit struct {
|
||||
AuthorName string // something like 'Jesse Duffield'
|
||||
AuthorEmail string // something like 'jessedduffield@gmail.com'
|
||||
UnixTimestamp int64
|
||||
Divergence Divergence // set to DivergenceNone unless we are showing the divergence view
|
||||
|
||||
// SHAs of parent commits (will be multiple if it's a merge commit)
|
||||
Parents []string
|
||||
|
||||
@@ -15,6 +15,10 @@ func (r *Remote) ID() string {
|
||||
return r.RefName()
|
||||
}
|
||||
|
||||
func (r *Remote) URN() string {
|
||||
return "remote-" + r.ID()
|
||||
}
|
||||
|
||||
func (r *Remote) Description() string {
|
||||
return r.RefName()
|
||||
}
|
||||
|
||||
@@ -4,8 +4,9 @@ import "fmt"
|
||||
|
||||
// StashEntry : A git stash entry
|
||||
type StashEntry struct {
|
||||
Index int
|
||||
Name string
|
||||
Index int
|
||||
Recency string
|
||||
Name string
|
||||
}
|
||||
|
||||
func (s *StashEntry) FullRefName() string {
|
||||
|
||||
@@ -24,6 +24,10 @@ func (t *Tag) ID() string {
|
||||
return t.RefName()
|
||||
}
|
||||
|
||||
func (t *Tag) URN() string {
|
||||
return "tag-" + t.ID()
|
||||
}
|
||||
|
||||
func (t *Tag) Description() string {
|
||||
return t.Message
|
||||
}
|
||||
|
||||
@@ -27,8 +27,14 @@ type CmdObjBuilder struct {
|
||||
var _ ICmdObjBuilder = &CmdObjBuilder{}
|
||||
|
||||
func (self *CmdObjBuilder) New(args []string) ICmdObj {
|
||||
cmdObj := self.NewWithEnviron(args, os.Environ())
|
||||
return cmdObj
|
||||
}
|
||||
|
||||
// A command with explicit environment from env
|
||||
func (self *CmdObjBuilder) NewWithEnviron(args []string, env []string) ICmdObj {
|
||||
cmd := exec.Command(args[0], args[1:]...)
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Env = env
|
||||
|
||||
return &CmdObj{
|
||||
cmd: cmd,
|
||||
|
||||
@@ -14,11 +14,6 @@ type patchPresenter struct {
|
||||
// if true, all following fields are ignored
|
||||
plain bool
|
||||
|
||||
isFocused bool
|
||||
// first line index for selected cursor range
|
||||
firstLineIndex int
|
||||
// last line index for selected cursor range
|
||||
lastLineIndex int
|
||||
// line indices for tagged lines (e.g. lines added to a custom patch)
|
||||
incLineIndices *set.Set[int]
|
||||
}
|
||||
@@ -44,11 +39,6 @@ func formatRangePlain(patch *Patch, startIdx int, endIdx int) string {
|
||||
}
|
||||
|
||||
type FormatViewOpts struct {
|
||||
IsFocused bool
|
||||
// first line index for selected cursor range
|
||||
FirstLineIndex int
|
||||
// last line index for selected cursor range
|
||||
LastLineIndex int
|
||||
// line indices for tagged lines (e.g. lines added to a custom patch)
|
||||
IncLineIndices *set.Set[int]
|
||||
}
|
||||
@@ -63,9 +53,6 @@ func formatView(patch *Patch, opts FormatViewOpts) string {
|
||||
presenter := &patchPresenter{
|
||||
patch: patch,
|
||||
plain: false,
|
||||
isFocused: opts.IsFocused,
|
||||
firstLineIndex: opts.FirstLineIndex,
|
||||
lastLineIndex: opts.LastLineIndex,
|
||||
incLineIndices: includedLineIndices,
|
||||
}
|
||||
return presenter.format()
|
||||
@@ -112,7 +99,6 @@ func (self *patchPresenter) format() string {
|
||||
self.formatLineAux(
|
||||
hunk.headerContext,
|
||||
theme.DefaultTextColor,
|
||||
lineIdx,
|
||||
false,
|
||||
),
|
||||
)
|
||||
@@ -139,23 +125,17 @@ func (self *patchPresenter) patchLineStyle(patchLine *PatchLine) style.TextStyle
|
||||
func (self *patchPresenter) formatLine(str string, textStyle style.TextStyle, index int) string {
|
||||
included := self.incLineIndices.Includes(index)
|
||||
|
||||
return self.formatLineAux(str, textStyle, index, included)
|
||||
return self.formatLineAux(str, textStyle, included)
|
||||
}
|
||||
|
||||
// 'selected' means you've got it highlighted with your cursor
|
||||
// 'included' means the line has been included in the patch (only applicable when
|
||||
// building a patch)
|
||||
func (self *patchPresenter) formatLineAux(str string, textStyle style.TextStyle, index int, included bool) string {
|
||||
func (self *patchPresenter) formatLineAux(str string, textStyle style.TextStyle, included bool) string {
|
||||
if self.plain {
|
||||
return str
|
||||
}
|
||||
|
||||
selected := self.isFocused && index >= self.firstLineIndex && index <= self.lastLineIndex
|
||||
|
||||
if selected {
|
||||
textStyle = textStyle.MergeStyle(theme.SelectedRangeBgColor)
|
||||
}
|
||||
|
||||
firstCharStyle := textStyle
|
||||
if included {
|
||||
firstCharStyle = firstCharStyle.MergeStyle(style.BgGreen)
|
||||
|
||||
@@ -97,12 +97,12 @@ func (self *Patch) LineNumberOfLine(idx int) int {
|
||||
idxInHunk := idx - hunkStartIdx
|
||||
|
||||
if idxInHunk == 0 {
|
||||
return hunk.oldStart
|
||||
return hunk.newStart
|
||||
}
|
||||
|
||||
lines := hunk.bodyLines[:idxInHunk-1]
|
||||
offset := nLinesWithKind(lines, []PatchLineKind{ADDITION, CONTEXT})
|
||||
return hunk.oldStart + offset
|
||||
return hunk.newStart + offset
|
||||
}
|
||||
|
||||
// Returns hunk index containing the line at the given patch line index
|
||||
@@ -149,3 +149,8 @@ func (self *Patch) LineCount() int {
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Returns the number of hunks of the patch
|
||||
func (self *Patch) HunkCount() int {
|
||||
return len(self.hunks)
|
||||
}
|
||||
|
||||
@@ -80,13 +80,15 @@ func (p *PatchBuilder) PatchToApply(reverse bool) string {
|
||||
}
|
||||
|
||||
func (p *PatchBuilder) addFileWhole(info *fileInfo) {
|
||||
info.mode = WHOLE
|
||||
lineCount := len(strings.Split(info.diff, "\n"))
|
||||
// add every line index
|
||||
// TODO: add tests and then use lo.Range to simplify
|
||||
info.includedLineIndices = make([]int, lineCount)
|
||||
for i := 0; i < lineCount; i++ {
|
||||
info.includedLineIndices[i] = i
|
||||
if info.mode != WHOLE {
|
||||
info.mode = WHOLE
|
||||
lineCount := len(strings.Split(info.diff, "\n"))
|
||||
// add every line index
|
||||
// TODO: add tests and then use lo.Range to simplify
|
||||
info.includedLineIndices = make([]int, lineCount)
|
||||
for i := 0; i < lineCount; i++ {
|
||||
info.includedLineIndices[i] = i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,9 +199,7 @@ func (p *PatchBuilder) RenderPatchForFile(filename string, plain bool, reverse b
|
||||
if plain {
|
||||
return patch.FormatPlain()
|
||||
} else {
|
||||
return patch.FormatView(FormatViewOpts{
|
||||
IsFocused: false,
|
||||
})
|
||||
return patch.FormatView(FormatViewOpts{})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,29 @@ index e48a11c..b2ab81b 100644
|
||||
...
|
||||
`
|
||||
|
||||
const twoHunksWithMoreAdditionsThanRemovals = `diff --git a/filename b/filename
|
||||
index bac359d75..6e5b89f36 100644
|
||||
--- a/filename
|
||||
+++ b/filename
|
||||
@@ -1,5 +1,6 @@
|
||||
apple
|
||||
-grape
|
||||
+orange
|
||||
+kiwi
|
||||
...
|
||||
...
|
||||
...
|
||||
@@ -8,6 +9,8 @@ grape
|
||||
...
|
||||
...
|
||||
...
|
||||
+pear
|
||||
+lemon
|
||||
...
|
||||
...
|
||||
...
|
||||
`
|
||||
|
||||
const twoChangesInOneHunk = `diff --git a/filename b/filename
|
||||
index 9320895..6d79956 100644
|
||||
--- a/filename
|
||||
@@ -572,6 +595,12 @@ func TestLineNumberOfLine(t *testing.T) {
|
||||
indexes: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 1000},
|
||||
expecteds: []int{1, 1, 1, 1, 1, 1, 2, 2, 3, 4, 5, 8, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15},
|
||||
},
|
||||
{
|
||||
testName: "twoHunksWithMoreAdditionsThanRemovals",
|
||||
patchStr: twoHunksWithMoreAdditionsThanRemovals,
|
||||
indexes: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 1000},
|
||||
expecteds: []int{1, 1, 1, 1, 1, 1, 2, 2, 3, 4, 5, 6, 9, 9, 10, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16},
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
|
||||
@@ -12,3 +12,11 @@ const (
|
||||
REBASE_MODE_REBASING
|
||||
REBASE_MODE_MERGING
|
||||
)
|
||||
|
||||
func (self RebaseMode) IsMerging() bool {
|
||||
return self == REBASE_MODE_MERGING
|
||||
}
|
||||
|
||||
func (self RebaseMode) IsRebasing() bool {
|
||||
return self == REBASE_MODE_INTERACTIVE || self == REBASE_MODE_NORMAL || self == REBASE_MODE_REBASING
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ type Common struct {
|
||||
Log *logrus.Entry
|
||||
Tr *i18n.TranslationSet
|
||||
UserConfig *config.UserConfig
|
||||
AppState *config.AppState
|
||||
Debug bool
|
||||
// for interacting with the filesystem. We use afero rather than the default
|
||||
// `os` package for the sake of mocking the filesystem in tests
|
||||
|
||||
@@ -283,11 +283,13 @@ func (c *AppConfig) SaveAppState() error {
|
||||
|
||||
// loadAppState loads recorded AppState from file
|
||||
func loadAppState() (*AppState, error) {
|
||||
appState := getDefaultAppState()
|
||||
|
||||
filepath, err := configFilePath("state.yml")
|
||||
if err != nil {
|
||||
if os.IsPermission(err) {
|
||||
// apparently when people have read-only permissions they prefer us to fail silently
|
||||
return getDefaultAppState(), nil
|
||||
return appState, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
@@ -298,10 +300,9 @@ func loadAppState() (*AppState, error) {
|
||||
}
|
||||
|
||||
if len(appStateBytes) == 0 {
|
||||
return getDefaultAppState(), nil
|
||||
return appState, nil
|
||||
}
|
||||
|
||||
appState := &AppState{}
|
||||
err = yaml.Unmarshal(appStateBytes, appState)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -321,13 +322,19 @@ type AppState struct {
|
||||
CustomCommandsHistory []string
|
||||
HideCommandLog bool
|
||||
IgnoreWhitespaceInDiffView bool
|
||||
DiffContextSize int
|
||||
LocalBranchSortOrder string
|
||||
RemoteBranchSortOrder string
|
||||
}
|
||||
|
||||
func getDefaultAppState() *AppState {
|
||||
return &AppState{
|
||||
LastUpdateCheck: 0,
|
||||
RecentRepos: []string{},
|
||||
StartupPopupVersion: 0,
|
||||
LastUpdateCheck: 0,
|
||||
RecentRepos: []string{},
|
||||
StartupPopupVersion: 0,
|
||||
DiffContextSize: 3,
|
||||
LocalBranchSortOrder: "recency",
|
||||
RemoteBranchSortOrder: "alphabetical",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,13 +28,13 @@ func GetEditAtLineAndWaitTemplate(osConfig *OSConfig, guessDefaultEditor func()
|
||||
return template
|
||||
}
|
||||
|
||||
func GetOpenDirInEditorTemplate(osConfig *OSConfig, guessDefaultEditor func() string) string {
|
||||
func GetOpenDirInEditorTemplate(osConfig *OSConfig, guessDefaultEditor func() string) (string, bool) {
|
||||
preset := getPreset(osConfig, guessDefaultEditor)
|
||||
template := osConfig.OpenDirInEditor
|
||||
if template == "" {
|
||||
template = preset.openDirInEditorTemplate
|
||||
}
|
||||
return template
|
||||
return template, getEditInTerminal(osConfig, preset)
|
||||
}
|
||||
|
||||
type editPreset struct {
|
||||
@@ -42,16 +42,26 @@ type editPreset struct {
|
||||
editAtLineTemplate string
|
||||
editAtLineAndWaitTemplate string
|
||||
openDirInEditorTemplate string
|
||||
editInTerminal bool
|
||||
suspend bool
|
||||
}
|
||||
|
||||
// IF YOU ADD A PRESET TO THIS FUNCTION YOU MUST UPDATE THE `Supported presets` SECTION OF docs/Config.md
|
||||
func getPreset(osConfig *OSConfig, guessDefaultEditor func() string) *editPreset {
|
||||
presets := map[string]*editPreset{
|
||||
"vi": standardTerminalEditorPreset("vi"),
|
||||
"vim": standardTerminalEditorPreset("vim"),
|
||||
"nvim": standardTerminalEditorPreset("nvim"),
|
||||
"vi": standardTerminalEditorPreset("vi"),
|
||||
"vim": standardTerminalEditorPreset("vim"),
|
||||
"nvim": standardTerminalEditorPreset("nvim"),
|
||||
"nvim-remote": {
|
||||
editTemplate: `nvim --server "$NVIM" --remote-tab {{filename}}`,
|
||||
editAtLineTemplate: `nvim --server "$NVIM" --remote-tab {{filename}}; [ -z "$NVIM" ] || nvim --server "$NVIM" --remote-send ":{{line}}<CR>"`,
|
||||
// No remote-wait support yet. See https://github.com/neovim/neovim/pull/17856
|
||||
editAtLineAndWaitTemplate: `nvim +{{line}} {{filename}}`,
|
||||
openDirInEditorTemplate: `nvim --server "$NVIM" --remote-tab {{dir}}`,
|
||||
suspend: false,
|
||||
},
|
||||
"lvim": standardTerminalEditorPreset("lvim"),
|
||||
"emacs": standardTerminalEditorPreset("emacs"),
|
||||
"micro": standardTerminalEditorPreset("micro"),
|
||||
"nano": standardTerminalEditorPreset("nano"),
|
||||
"kakoune": standardTerminalEditorPreset("kak"),
|
||||
"helix": {
|
||||
@@ -59,35 +69,35 @@ func getPreset(osConfig *OSConfig, guessDefaultEditor func() string) *editPreset
|
||||
editAtLineTemplate: "hx -- {{filename}}:{{line}}",
|
||||
editAtLineAndWaitTemplate: "hx -- {{filename}}:{{line}}",
|
||||
openDirInEditorTemplate: "hx -- {{dir}}",
|
||||
editInTerminal: true,
|
||||
suspend: true,
|
||||
},
|
||||
"vscode": {
|
||||
editTemplate: "code --reuse-window -- {{filename}}",
|
||||
editAtLineTemplate: "code --reuse-window --goto -- {{filename}}:{{line}}",
|
||||
editAtLineAndWaitTemplate: "code --reuse-window --goto --wait -- {{filename}}:{{line}}",
|
||||
openDirInEditorTemplate: "code -- {{dir}}",
|
||||
editInTerminal: false,
|
||||
suspend: false,
|
||||
},
|
||||
"sublime": {
|
||||
editTemplate: "subl -- {{filename}}",
|
||||
editAtLineTemplate: "subl -- {{filename}}:{{line}}",
|
||||
editAtLineAndWaitTemplate: "subl --wait -- {{filename}}:{{line}}",
|
||||
openDirInEditorTemplate: "subl -- {{dir}}",
|
||||
editInTerminal: false,
|
||||
suspend: false,
|
||||
},
|
||||
"bbedit": {
|
||||
editTemplate: "bbedit -- {{filename}}",
|
||||
editAtLineTemplate: "bbedit +{{line}} -- {{filename}}",
|
||||
editAtLineAndWaitTemplate: "bbedit +{{line}} --wait -- {{filename}}",
|
||||
openDirInEditorTemplate: "bbedit -- {{dir}}",
|
||||
editInTerminal: false,
|
||||
suspend: false,
|
||||
},
|
||||
"xcode": {
|
||||
editTemplate: "xed -- {{filename}}",
|
||||
editAtLineTemplate: "xed --line {{line}} -- {{filename}}",
|
||||
editAtLineAndWaitTemplate: "xed --line {{line}} --wait -- {{filename}}",
|
||||
openDirInEditorTemplate: "xed -- {{dir}}",
|
||||
editInTerminal: false,
|
||||
suspend: false,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -123,13 +133,13 @@ func standardTerminalEditorPreset(editor string) *editPreset {
|
||||
editAtLineTemplate: editor + " +{{line}} -- {{filename}}",
|
||||
editAtLineAndWaitTemplate: editor + " +{{line}} -- {{filename}}",
|
||||
openDirInEditorTemplate: editor + " -- {{dir}}",
|
||||
editInTerminal: true,
|
||||
suspend: true,
|
||||
}
|
||||
}
|
||||
|
||||
func getEditInTerminal(osConfig *OSConfig, preset *editPreset) bool {
|
||||
if osConfig.EditInTerminal != nil {
|
||||
return *osConfig.EditInTerminal
|
||||
if osConfig.SuspendOnEdit != nil {
|
||||
return *osConfig.SuspendOnEdit
|
||||
}
|
||||
return preset.editInTerminal
|
||||
return preset.suspend
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ func TestGetEditTemplate(t *testing.T) {
|
||||
expectedEditTemplate string
|
||||
expectedEditAtLineTemplate string
|
||||
expectedEditAtLineAndWaitTemplate string
|
||||
expectedEditInTerminal bool
|
||||
expectedSuspend bool
|
||||
}{
|
||||
{
|
||||
"Default template is vim",
|
||||
@@ -52,9 +52,9 @@ func TestGetEditTemplate(t *testing.T) {
|
||||
{
|
||||
"Overriding a preset with explicit config (edit)",
|
||||
&OSConfig{
|
||||
EditPreset: "vscode",
|
||||
Edit: "myeditor {{filename}}",
|
||||
EditInTerminal: &trueVal,
|
||||
EditPreset: "vscode",
|
||||
Edit: "myeditor {{filename}}",
|
||||
SuspendOnEdit: &trueVal,
|
||||
},
|
||||
func() string { return "" },
|
||||
"myeditor {{filename}}",
|
||||
@@ -65,9 +65,9 @@ func TestGetEditTemplate(t *testing.T) {
|
||||
{
|
||||
"Overriding a preset with explicit config (edit at line)",
|
||||
&OSConfig{
|
||||
EditPreset: "vscode",
|
||||
EditAtLine: "myeditor --line={{line}} {{filename}}",
|
||||
EditInTerminal: &trueVal,
|
||||
EditPreset: "vscode",
|
||||
EditAtLine: "myeditor --line={{line}} {{filename}}",
|
||||
SuspendOnEdit: &trueVal,
|
||||
},
|
||||
func() string { return "" },
|
||||
"code --reuse-window -- {{filename}}",
|
||||
@@ -80,7 +80,7 @@ func TestGetEditTemplate(t *testing.T) {
|
||||
&OSConfig{
|
||||
EditPreset: "vscode",
|
||||
EditAtLineAndWait: "myeditor --line={{line}} -w {{filename}}",
|
||||
EditInTerminal: &trueVal,
|
||||
SuspendOnEdit: &trueVal,
|
||||
},
|
||||
func() string { return "" },
|
||||
"code --reuse-window -- {{filename}}",
|
||||
@@ -111,13 +111,13 @@ func TestGetEditTemplate(t *testing.T) {
|
||||
}
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.name, func(t *testing.T) {
|
||||
template, editInTerminal := GetEditTemplate(s.osConfig, s.guessDefaultEditor)
|
||||
template, suspend := GetEditTemplate(s.osConfig, s.guessDefaultEditor)
|
||||
assert.Equal(t, s.expectedEditTemplate, template)
|
||||
assert.Equal(t, s.expectedEditInTerminal, editInTerminal)
|
||||
assert.Equal(t, s.expectedSuspend, suspend)
|
||||
|
||||
template, editInTerminal = GetEditAtLineTemplate(s.osConfig, s.guessDefaultEditor)
|
||||
template, suspend = GetEditAtLineTemplate(s.osConfig, s.guessDefaultEditor)
|
||||
assert.Equal(t, s.expectedEditAtLineTemplate, template)
|
||||
assert.Equal(t, s.expectedEditInTerminal, editInTerminal)
|
||||
assert.Equal(t, s.expectedSuspend, suspend)
|
||||
|
||||
template = GetEditAtLineAndWaitTemplate(s.osConfig, s.guessDefaultEditor)
|
||||
assert.Equal(t, s.expectedEditAtLineAndWaitTemplate, template)
|
||||
|
||||
@@ -2,144 +2,288 @@ package config
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/karimkhaleel/jsonschema"
|
||||
)
|
||||
|
||||
type UserConfig struct {
|
||||
Gui GuiConfig `yaml:"gui"`
|
||||
Git GitConfig `yaml:"git"`
|
||||
Update UpdateConfig `yaml:"update"`
|
||||
Refresher RefresherConfig `yaml:"refresher"`
|
||||
ConfirmOnQuit bool `yaml:"confirmOnQuit"`
|
||||
QuitOnTopLevelReturn bool `yaml:"quitOnTopLevelReturn"`
|
||||
Keybinding KeybindingConfig `yaml:"keybinding"`
|
||||
// OS determines what defaults are set for opening files and links
|
||||
OS OSConfig `yaml:"os,omitempty"`
|
||||
DisableStartupPopups bool `yaml:"disableStartupPopups"`
|
||||
CustomCommands []CustomCommand `yaml:"customCommands"`
|
||||
Services map[string]string `yaml:"services"`
|
||||
NotARepository string `yaml:"notARepository"`
|
||||
PromptToReturnFromSubprocess bool `yaml:"promptToReturnFromSubprocess"`
|
||||
// Config relating to the Lazygit UI
|
||||
Gui GuiConfig `yaml:"gui"`
|
||||
// Config relating to git
|
||||
Git GitConfig `yaml:"git"`
|
||||
// Periodic update checks
|
||||
Update UpdateConfig `yaml:"update"`
|
||||
// Background refreshes
|
||||
Refresher RefresherConfig `yaml:"refresher"`
|
||||
// If true, show a confirmation popup before quitting Lazygit
|
||||
ConfirmOnQuit bool `yaml:"confirmOnQuit"`
|
||||
// If true, exit Lazygit when the user presses escape in a context where there is nothing to cancel/close
|
||||
QuitOnTopLevelReturn bool `yaml:"quitOnTopLevelReturn"`
|
||||
// Keybindings
|
||||
Keybinding KeybindingConfig `yaml:"keybinding"`
|
||||
// Config relating to things outside of Lazygit like how files are opened, copying to clipboard, etc
|
||||
OS OSConfig `yaml:"os,omitempty"`
|
||||
// If true, don't display introductory popups upon opening Lazygit.
|
||||
// Lazygit sets this to true upon first runninng the program so that you don't see introductory popups every time you open the program.
|
||||
DisableStartupPopups bool `yaml:"disableStartupPopups"`
|
||||
// User-configured commands that can be invoked from within Lazygit
|
||||
CustomCommands []CustomCommand `yaml:"customCommands" jsonschema:"uniqueItems=true"`
|
||||
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-pull-request-urls
|
||||
Services map[string]string `yaml:"services"`
|
||||
// What to do when opening Lazygit outside of a git repo.
|
||||
// - 'prompt': (default) ask whether to initialize a new repo or open in the most recent repo
|
||||
// - 'create': initialize a new repo
|
||||
// - 'skip': open most recent repo
|
||||
// - 'quit': exit Lazygit
|
||||
NotARepository string `yaml:"notARepository" jsonschema:"enum=prompt,enum=create,enum=skip,enum=quit"`
|
||||
// If true, display a confirmation when subprocess terminates. This allows you to view the output of the subprocess before returning to Lazygit.
|
||||
PromptToReturnFromSubprocess bool `yaml:"promptToReturnFromSubprocess"`
|
||||
}
|
||||
|
||||
type RefresherConfig struct {
|
||||
RefreshInterval int `yaml:"refreshInterval"`
|
||||
FetchInterval int `yaml:"fetchInterval"`
|
||||
// File/submodule refresh interval in seconds.
|
||||
// Auto-refresh can be disabled via option 'git.autoRefresh'.
|
||||
RefreshInterval int `yaml:"refreshInterval" jsonschema:"minimum=0"`
|
||||
// Re-fetch interval in seconds.
|
||||
// Auto-fetch can be disabled via option 'git.autoFetch'.
|
||||
FetchInterval int `yaml:"fetchInterval" jsonschema:"minimum=0"`
|
||||
}
|
||||
|
||||
type GuiConfig struct {
|
||||
AuthorColors map[string]string `yaml:"authorColors"`
|
||||
BranchColors map[string]string `yaml:"branchColors"`
|
||||
ScrollHeight int `yaml:"scrollHeight"`
|
||||
ScrollPastBottom bool `yaml:"scrollPastBottom"`
|
||||
MouseEvents bool `yaml:"mouseEvents"`
|
||||
SkipDiscardChangeWarning bool `yaml:"skipDiscardChangeWarning"`
|
||||
SkipStashWarning bool `yaml:"skipStashWarning"`
|
||||
SidePanelWidth float64 `yaml:"sidePanelWidth"`
|
||||
ExpandFocusedSidePanel bool `yaml:"expandFocusedSidePanel"`
|
||||
MainPanelSplitMode string `yaml:"mainPanelSplitMode"`
|
||||
Language string `yaml:"language"`
|
||||
TimeFormat string `yaml:"timeFormat"`
|
||||
ShortTimeFormat string `yaml:"shortTimeFormat"`
|
||||
Theme ThemeConfig `yaml:"theme"`
|
||||
CommitLength CommitLengthConfig `yaml:"commitLength"`
|
||||
SkipNoStagedFilesWarning bool `yaml:"skipNoStagedFilesWarning"`
|
||||
ShowListFooter bool `yaml:"showListFooter"`
|
||||
ShowFileTree bool `yaml:"showFileTree"`
|
||||
ShowRandomTip bool `yaml:"showRandomTip"`
|
||||
ShowCommandLog bool `yaml:"showCommandLog"`
|
||||
ShowBottomLine bool `yaml:"showBottomLine"`
|
||||
ShowIcons bool `yaml:"showIcons"`
|
||||
NerdFontsVersion string `yaml:"nerdFontsVersion"`
|
||||
ShowBranchCommitHash bool `yaml:"showBranchCommitHash"`
|
||||
CommandLogSize int `yaml:"commandLogSize"`
|
||||
SplitDiff string `yaml:"splitDiff"`
|
||||
SkipRewordInEditorWarning bool `yaml:"skipRewordInEditorWarning"`
|
||||
WindowSize string `yaml:"windowSize"`
|
||||
Border string `yaml:"border"`
|
||||
AnimateExplosion bool `yaml:"animateExplosion"`
|
||||
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-author-color
|
||||
AuthorColors map[string]string `yaml:"authorColors"`
|
||||
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color
|
||||
BranchColors map[string]string `yaml:"branchColors"`
|
||||
// The number of lines you scroll by when scrolling the main window
|
||||
ScrollHeight int `yaml:"scrollHeight" jsonschema:"minimum=1"`
|
||||
// If true, allow scrolling past the bottom of the content in the main window
|
||||
ScrollPastBottom bool `yaml:"scrollPastBottom"`
|
||||
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#scroll-off-margin
|
||||
ScrollOffMargin int `yaml:"scrollOffMargin"`
|
||||
// One of: 'margin' (default) | 'jump'
|
||||
ScrollOffBehavior string `yaml:"scrollOffBehavior"`
|
||||
// If true, capture mouse events.
|
||||
// When mouse events are captured, it's a little harder to select text: e.g. requiring you to hold the option key when on macOS.
|
||||
MouseEvents bool `yaml:"mouseEvents"`
|
||||
// If true, do not show a warning when discarding changes in the staging view.
|
||||
SkipDiscardChangeWarning bool `yaml:"skipDiscardChangeWarning"`
|
||||
// If true, do not show warning when applying/popping the stash
|
||||
SkipStashWarning bool `yaml:"skipStashWarning"`
|
||||
// If true, do not show a warning when attempting to commit without any staged files; instead stage all unstaged files.
|
||||
SkipNoStagedFilesWarning bool `yaml:"skipNoStagedFilesWarning"`
|
||||
// If true, do not show a warning when rewording a commit via an external editor
|
||||
SkipRewordInEditorWarning bool `yaml:"skipRewordInEditorWarning"`
|
||||
// Fraction of the total screen width to use for the left side section. You may want to pick a small number (e.g. 0.2) if you're using a narrow screen, so that you can see more of the main section.
|
||||
// Number from 0 to 1.0.
|
||||
SidePanelWidth float64 `yaml:"sidePanelWidth" jsonschema:"maximum=1,minimum=0"`
|
||||
// If true, increase the height of the focused side window; creating an accordion effect.
|
||||
ExpandFocusedSidePanel bool `yaml:"expandFocusedSidePanel"`
|
||||
// Sometimes the main window is split in two (e.g. when the selected file has both staged and unstaged changes). This setting controls how the two sections are split.
|
||||
// Options are:
|
||||
// - 'horizontal': split the window horizontally
|
||||
// - 'vertical': split the window vertically
|
||||
// - 'flexible': (default) split the window horizontally if the window is wide enough, otherwise split vertically
|
||||
MainPanelSplitMode string `yaml:"mainPanelSplitMode" jsonschema:"enum=horizontal,enum=flexible,enum=vertical"`
|
||||
// How the window is split when in half screen mode (i.e. after hitting '+' once).
|
||||
// Possible values:
|
||||
// - 'left': split the window horizontally (side panel on the left, main view on the right)
|
||||
// - 'top': split the window vertically (side panel on top, main view below)
|
||||
EnlargedSideViewLocation string `yaml:"enlargedSideViewLocation"`
|
||||
// One of 'auto' (default) | 'en' | 'zh-CN' | 'zh-TW' | 'pl' | 'nl' | 'ja' | 'ko' | 'ru'
|
||||
Language string `yaml:"language" jsonschema:"enum=auto,enum=en,enum=zh-TW,enum=zh-CN,enum=pl,enum=nl,enum=ja,enum=ko,enum=ru"`
|
||||
// Format used when displaying time e.g. commit time.
|
||||
// Uses Go's time format syntax: https://pkg.go.dev/time#Time.Format
|
||||
TimeFormat string `yaml:"timeFormat"`
|
||||
// Format used when displaying time if the time is less than 24 hours ago.
|
||||
// Uses Go's time format syntax: https://pkg.go.dev/time#Time.Format
|
||||
ShortTimeFormat string `yaml:"shortTimeFormat"`
|
||||
// Config relating to colors and styles.
|
||||
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#color-attributes
|
||||
Theme ThemeConfig `yaml:"theme"`
|
||||
// Config relating to the commit length indicator
|
||||
CommitLength CommitLengthConfig `yaml:"commitLength"`
|
||||
// If true, show the '5 of 20' footer at the bottom of list views
|
||||
ShowListFooter bool `yaml:"showListFooter"`
|
||||
// If true, display the files in the file views as a tree. If false, display the files as a flat list.
|
||||
// This can be toggled from within Lazygit with the '~' key, but that will not change the default.
|
||||
ShowFileTree bool `yaml:"showFileTree"`
|
||||
// If true, show a random tip in the command log when Lazygit starts
|
||||
ShowRandomTip bool `yaml:"showRandomTip"`
|
||||
// If true, show the command log
|
||||
ShowCommandLog bool `yaml:"showCommandLog"`
|
||||
// If true, show the bottom line that contains keybinding info and useful buttons. If false, this line will be hidden except to display a loader for an in-progress action.
|
||||
ShowBottomLine bool `yaml:"showBottomLine"`
|
||||
// If true, show jump-to-window keybindings in window titles.
|
||||
ShowPanelJumps bool `yaml:"showPanelJumps"`
|
||||
// Deprecated: use nerdFontsVersion instead
|
||||
ShowIcons bool `yaml:"showIcons"`
|
||||
// Nerd fonts version to use.
|
||||
// One of: '2' | '3' | empty string (default)
|
||||
// If empty, do not show icons.
|
||||
NerdFontsVersion string `yaml:"nerdFontsVersion" jsonschema:"enum=2,enum=3,enum="`
|
||||
// If true (default), file icons are shown in the file views. Only relevant if NerdFontsVersion is not empty.
|
||||
ShowFileIcons bool `yaml:"showFileIcons"`
|
||||
// If true, show commit hashes alongside branch names in the branches view.
|
||||
ShowBranchCommitHash bool `yaml:"showBranchCommitHash"`
|
||||
// Height of the command log view
|
||||
CommandLogSize int `yaml:"commandLogSize" jsonschema:"minimum=0"`
|
||||
// Whether to split the main window when viewing file changes.
|
||||
// One of: 'auto' | 'always'
|
||||
// If 'auto', only split the main window when a file has both staged and unstaged changes
|
||||
SplitDiff string `yaml:"splitDiff" jsonschema:"enum=auto,enum=always"`
|
||||
// Default size for focused window. Window size can be changed from within Lazygit with '+' and '_' (but this won't change the default).
|
||||
// One of: 'normal' (default) | 'half' | 'full'
|
||||
WindowSize string `yaml:"windowSize" jsonschema:"enum=normal,enum=half,enum=full"`
|
||||
// Window border style.
|
||||
// One of 'rounded' (default) | 'single' | 'double' | 'hidden'
|
||||
Border string `yaml:"border" jsonschema:"enum=single,enum=double,enum=rounded,enum=hidden"`
|
||||
// If true, show a seriously epic explosion animation when nuking the working tree.
|
||||
AnimateExplosion bool `yaml:"animateExplosion"`
|
||||
// Whether to stack UI components on top of each other.
|
||||
// One of 'auto' (default) | 'always' | 'never'
|
||||
PortraitMode string `yaml:"portraitMode"`
|
||||
}
|
||||
|
||||
type ThemeConfig struct {
|
||||
ActiveBorderColor []string `yaml:"activeBorderColor"`
|
||||
InactiveBorderColor []string `yaml:"inactiveBorderColor"`
|
||||
SearchingActiveBorderColor []string `yaml:"searchingActiveBorderColor"`
|
||||
OptionsTextColor []string `yaml:"optionsTextColor"`
|
||||
SelectedLineBgColor []string `yaml:"selectedLineBgColor"`
|
||||
SelectedRangeBgColor []string `yaml:"selectedRangeBgColor"`
|
||||
CherryPickedCommitBgColor []string `yaml:"cherryPickedCommitBgColor"`
|
||||
CherryPickedCommitFgColor []string `yaml:"cherryPickedCommitFgColor"`
|
||||
MarkedBaseCommitBgColor []string `yaml:"markedBaseCommitBgColor"`
|
||||
MarkedBaseCommitFgColor []string `yaml:"markedBaseCommitFgColor"`
|
||||
UnstagedChangesColor []string `yaml:"unstagedChangesColor"`
|
||||
DefaultFgColor []string `yaml:"defaultFgColor"`
|
||||
// Border color of focused window
|
||||
ActiveBorderColor []string `yaml:"activeBorderColor" jsonschema:"minItems=1,uniqueItems=true"`
|
||||
// Border color of non-focused windows
|
||||
InactiveBorderColor []string `yaml:"inactiveBorderColor" jsonschema:"minItems=1,uniqueItems=true"`
|
||||
// Border color of focused window when searching in that window
|
||||
SearchingActiveBorderColor []string `yaml:"searchingActiveBorderColor" jsonschema:"minItems=1,uniqueItems=true"`
|
||||
// Color of keybindings help text in the bottom line
|
||||
OptionsTextColor []string `yaml:"optionsTextColor" jsonschema:"minItems=1,uniqueItems=true"`
|
||||
// Background color of selected line.
|
||||
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#highlighting-the-selected-line
|
||||
SelectedLineBgColor []string `yaml:"selectedLineBgColor" jsonschema:"minItems=1,uniqueItems=true"`
|
||||
// Foreground color of copied commit
|
||||
CherryPickedCommitFgColor []string `yaml:"cherryPickedCommitFgColor" jsonschema:"minItems=1,uniqueItems=true"`
|
||||
// Background color of copied commit
|
||||
CherryPickedCommitBgColor []string `yaml:"cherryPickedCommitBgColor" jsonschema:"minItems=1,uniqueItems=true"`
|
||||
// Foreground color of marked base commit (for rebase)
|
||||
MarkedBaseCommitFgColor []string `yaml:"markedBaseCommitFgColor"`
|
||||
// Background color of marked base commit (for rebase)
|
||||
MarkedBaseCommitBgColor []string `yaml:"markedBaseCommitBgColor"`
|
||||
// Color for file with unstaged changes
|
||||
UnstagedChangesColor []string `yaml:"unstagedChangesColor" jsonschema:"minItems=1,uniqueItems=true"`
|
||||
// Default text color
|
||||
DefaultFgColor []string `yaml:"defaultFgColor" jsonschema:"minItems=1,uniqueItems=true"`
|
||||
}
|
||||
|
||||
type CommitLengthConfig struct {
|
||||
// If true, show an indicator of commit message length
|
||||
Show bool `yaml:"show"`
|
||||
}
|
||||
|
||||
type GitConfig struct {
|
||||
Paging PagingConfig `yaml:"paging"`
|
||||
Commit CommitConfig `yaml:"commit"`
|
||||
Merging MergingConfig `yaml:"merging"`
|
||||
MainBranches []string `yaml:"mainBranches"`
|
||||
SkipHookPrefix string `yaml:"skipHookPrefix"`
|
||||
AutoFetch bool `yaml:"autoFetch"`
|
||||
AutoRefresh bool `yaml:"autoRefresh"`
|
||||
FetchAll bool `yaml:"fetchAll"`
|
||||
BranchLogCmd string `yaml:"branchLogCmd"`
|
||||
AllBranchesLogCmd string `yaml:"allBranchesLogCmd"`
|
||||
OverrideGpg bool `yaml:"overrideGpg"`
|
||||
DisableForcePushing bool `yaml:"disableForcePushing"`
|
||||
CommitPrefixes map[string]CommitPrefixConfig `yaml:"commitPrefixes"`
|
||||
// this should really be under 'gui', not 'git'
|
||||
ParseEmoji bool `yaml:"parseEmoji"`
|
||||
Log LogConfig `yaml:"log"`
|
||||
DiffContextSize int `yaml:"diffContextSize"`
|
||||
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Custom_Pagers.md
|
||||
Paging PagingConfig `yaml:"paging"`
|
||||
// Config relating to committing
|
||||
Commit CommitConfig `yaml:"commit"`
|
||||
// Config relating to merging
|
||||
Merging MergingConfig `yaml:"merging"`
|
||||
// list of branches that are considered 'main' branches, used when displaying commits
|
||||
MainBranches []string `yaml:"mainBranches" jsonschema:"uniqueItems=true"`
|
||||
// Prefix to use when skipping hooks. E.g. if set to 'WIP', then pre-commit hooks will be skipped when the commit message starts with 'WIP'
|
||||
SkipHookPrefix string `yaml:"skipHookPrefix"`
|
||||
// If true, periodically fetch from remote
|
||||
AutoFetch bool `yaml:"autoFetch"`
|
||||
// If true, periodically refresh files and submodules
|
||||
AutoRefresh bool `yaml:"autoRefresh"`
|
||||
// If true, pass the --all arg to git fetch
|
||||
FetchAll bool `yaml:"fetchAll"`
|
||||
// Command used when displaying the current branch git log in the main window
|
||||
BranchLogCmd string `yaml:"branchLogCmd"`
|
||||
// Command used to display git log of all branches in the main window
|
||||
AllBranchesLogCmd string `yaml:"allBranchesLogCmd"`
|
||||
// If true, do not spawn a separate process when using GPG
|
||||
OverrideGpg bool `yaml:"overrideGpg"`
|
||||
// If true, do not allow force pushes
|
||||
DisableForcePushing bool `yaml:"disableForcePushing"`
|
||||
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix
|
||||
CommitPrefixes map[string]CommitPrefixConfig `yaml:"commitPrefixes"`
|
||||
// If true, parse emoji strings in commit messages e.g. render :rocket: as 🚀
|
||||
// (This should really be under 'gui', not 'git')
|
||||
ParseEmoji bool `yaml:"parseEmoji"`
|
||||
// Config for showing the log in the commits view
|
||||
Log LogConfig `yaml:"log"`
|
||||
}
|
||||
|
||||
type PagerType string
|
||||
|
||||
func (PagerType) JSONSchemaExtend(schema *jsonschema.Schema) {
|
||||
schema.Examples = []any{
|
||||
"delta --dark --paging=never",
|
||||
"diff-so-fancy",
|
||||
"ydiff -p cat -s --wrap --width={{columnWidth}}",
|
||||
}
|
||||
}
|
||||
|
||||
type PagingConfig struct {
|
||||
ColorArg string `yaml:"colorArg"`
|
||||
Pager string `yaml:"pager"`
|
||||
UseConfig bool `yaml:"useConfig"`
|
||||
// Value of the --color arg in the git diff command. Some pagers want this to be set to 'always' and some want it set to 'never'
|
||||
ColorArg string `yaml:"colorArg" jsonschema:"enum=always,enum=never"`
|
||||
// e.g.
|
||||
// diff-so-fancy
|
||||
// delta --dark --paging=never
|
||||
// ydiff -p cat -s --wrap --width={{columnWidth}}
|
||||
Pager PagerType `yaml:"pager" jsonschema:"minLength=1"`
|
||||
// If true, Lazygit will use whatever pager is specified in `$GIT_PAGER`, `$PAGER`, or your *git config*. If the pager ends with something like ` | less` we will strip that part out, because less doesn't play nice with our rendering approach. If the custom pager uses less under the hood, that will also break rendering (hence the `--paging=never` flag for the `delta` pager).
|
||||
UseConfig bool `yaml:"useConfig"`
|
||||
// e.g. 'difft --color=always'
|
||||
ExternalDiffCommand string `yaml:"externalDiffCommand"`
|
||||
}
|
||||
|
||||
type CommitConfig struct {
|
||||
// If true, pass '--signoff' flag when committing
|
||||
SignOff bool `yaml:"signOff"`
|
||||
}
|
||||
|
||||
type MergingConfig struct {
|
||||
ManualCommit bool `yaml:"manualCommit"`
|
||||
Args string `yaml:"args"`
|
||||
// If true, run merges in a subprocess so that if a commit message is required, Lazygit will not hang
|
||||
// Only applicable to unix users.
|
||||
ManualCommit bool `yaml:"manualCommit"`
|
||||
// Extra args passed to `git merge`, e.g. --no-ff
|
||||
Args string `yaml:"args" jsonschema:"example=--no-ff"`
|
||||
}
|
||||
|
||||
type LogConfig struct {
|
||||
Order string `yaml:"order"` // one of date-order, author-date-order, topo-order
|
||||
ShowGraph string `yaml:"showGraph"` // one of always, never, when-maximised
|
||||
ShowWholeGraph bool `yaml:"showWholeGraph"`
|
||||
// One of: 'date-order' | 'author-date-order' | 'topo-order | default'
|
||||
// 'topo-order' makes it easier to read the git log graph, but commits may not
|
||||
// appear chronologically. See https://git-scm.com/docs/
|
||||
Order string `yaml:"order" jsonschema:"enum=date-order,enum=author-date-order,enum=topo-order,enum=default"`
|
||||
// This determines whether the git graph is rendered in the commits panel
|
||||
// One of 'always' | 'never' | 'when-maximised'
|
||||
ShowGraph string `yaml:"showGraph" jsonschema:"enum=always,enum=never,enum=when-maximised"`
|
||||
// displays the whole git graph by default in the commits view (equivalent to passing the `--all` argument to `git log`)
|
||||
ShowWholeGraph bool `yaml:"showWholeGraph"`
|
||||
}
|
||||
|
||||
type CommitPrefixConfig struct {
|
||||
Pattern string `yaml:"pattern"`
|
||||
Replace string `yaml:"replace"`
|
||||
// pattern to match on. E.g. for 'feature/AB-123' to match on the AB-123 use "^\\w+\\/(\\w+-\\w+).*"
|
||||
Pattern string `yaml:"pattern" jsonschema:"example=^\\w+\\/(\\w+-\\w+).*,minLength=1"`
|
||||
// Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use "[$1] "
|
||||
Replace string `yaml:"replace" jsonschema:"example=[$1] ,minLength=1"`
|
||||
}
|
||||
|
||||
type UpdateConfig struct {
|
||||
Method string `yaml:"method"`
|
||||
Days int64 `yaml:"days"`
|
||||
// One of: 'prompt' (default) | 'background' | 'never'
|
||||
Method string `yaml:"method" jsonschema:"enum=prompt,enum=background,enum=never"`
|
||||
// Period in days between update checks
|
||||
Days int64 `yaml:"days" jsonschema:"minimum=0"`
|
||||
}
|
||||
|
||||
type KeybindingConfig struct {
|
||||
Universal KeybindingUniversalConfig `yaml:"universal"`
|
||||
Status KeybindingStatusConfig `yaml:"status"`
|
||||
Files KeybindingFilesConfig `yaml:"files"`
|
||||
Branches KeybindingBranchesConfig `yaml:"branches"`
|
||||
Worktrees KeybindingWorktreesConfig `yaml:"worktrees"`
|
||||
Commits KeybindingCommitsConfig `yaml:"commits"`
|
||||
Stash KeybindingStashConfig `yaml:"stash"`
|
||||
CommitFiles KeybindingCommitFilesConfig `yaml:"commitFiles"`
|
||||
Main KeybindingMainConfig `yaml:"main"`
|
||||
Submodules KeybindingSubmodulesConfig `yaml:"submodules"`
|
||||
Universal KeybindingUniversalConfig `yaml:"universal"`
|
||||
Status KeybindingStatusConfig `yaml:"status"`
|
||||
Files KeybindingFilesConfig `yaml:"files"`
|
||||
Branches KeybindingBranchesConfig `yaml:"branches"`
|
||||
Worktrees KeybindingWorktreesConfig `yaml:"worktrees"`
|
||||
Commits KeybindingCommitsConfig `yaml:"commits"`
|
||||
Stash KeybindingStashConfig `yaml:"stash"`
|
||||
CommitFiles KeybindingCommitFilesConfig `yaml:"commitFiles"`
|
||||
Main KeybindingMainConfig `yaml:"main"`
|
||||
Submodules KeybindingSubmodulesConfig `yaml:"submodules"`
|
||||
CommitMessage KeybindingCommitMessageConfig `yaml:"commitMessage"`
|
||||
}
|
||||
|
||||
// damn looks like we have some inconsistencies here with -alt and -alt1
|
||||
@@ -159,6 +303,9 @@ type KeybindingUniversalConfig struct {
|
||||
ScrollRight string `yaml:"scrollRight"`
|
||||
GotoTop string `yaml:"gotoTop"`
|
||||
GotoBottom string `yaml:"gotoBottom"`
|
||||
ToggleRangeSelect string `yaml:"toggleRangeSelect"`
|
||||
RangeSelectDown string `yaml:"rangeSelectDown"`
|
||||
RangeSelectUp string `yaml:"rangeSelectUp"`
|
||||
PrevBlock string `yaml:"prevBlock"`
|
||||
NextBlock string `yaml:"nextBlock"`
|
||||
PrevBlockAlt string `yaml:"prevBlock-alt"`
|
||||
@@ -207,6 +354,7 @@ type KeybindingUniversalConfig struct {
|
||||
ToggleWhitespaceInDiffView string `yaml:"toggleWhitespaceInDiffView"`
|
||||
IncreaseContextInDiffView string `yaml:"increaseContextInDiffView"`
|
||||
DecreaseContextInDiffView string `yaml:"decreaseContextInDiffView"`
|
||||
OpenDiffTool string `yaml:"openDiffTool"`
|
||||
}
|
||||
|
||||
type KeybindingStatusConfig struct {
|
||||
@@ -216,20 +364,23 @@ type KeybindingStatusConfig struct {
|
||||
}
|
||||
|
||||
type KeybindingFilesConfig struct {
|
||||
CommitChanges string `yaml:"commitChanges"`
|
||||
CommitChangesWithoutHook string `yaml:"commitChangesWithoutHook"`
|
||||
AmendLastCommit string `yaml:"amendLastCommit"`
|
||||
CommitChangesWithEditor string `yaml:"commitChangesWithEditor"`
|
||||
IgnoreFile string `yaml:"ignoreFile"`
|
||||
RefreshFiles string `yaml:"refreshFiles"`
|
||||
StashAllChanges string `yaml:"stashAllChanges"`
|
||||
ViewStashOptions string `yaml:"viewStashOptions"`
|
||||
ToggleStagedAll string `yaml:"toggleStagedAll"`
|
||||
ViewResetOptions string `yaml:"viewResetOptions"`
|
||||
Fetch string `yaml:"fetch"`
|
||||
ToggleTreeView string `yaml:"toggleTreeView"`
|
||||
OpenMergeTool string `yaml:"openMergeTool"`
|
||||
OpenStatusFilter string `yaml:"openStatusFilter"`
|
||||
Commit string `yaml:"commit"`
|
||||
CommitWithoutHook string `yaml:"commitWithoutHook"`
|
||||
AmendLastCommit string `yaml:"amendLastCommit"`
|
||||
CommitChangesWithEditor string `yaml:"commitChangesWithEditor"`
|
||||
FindBaseCommitForFixup string `yaml:"findBaseCommitForFixup"`
|
||||
ConfirmDiscard string `yaml:"confirmDiscard"`
|
||||
IgnoreFile string `yaml:"ignoreFile"`
|
||||
RefreshFiles string `yaml:"refreshFiles"`
|
||||
Stash string `yaml:"stash"`
|
||||
ViewStashOptions string `yaml:"viewStashOptions"`
|
||||
ToggleStagedAll string `yaml:"toggleStagedAll"`
|
||||
Reset string `yaml:"reset"`
|
||||
Fetch string `yaml:"fetch"`
|
||||
ToggleTreeView string `yaml:"toggleTreeView"`
|
||||
OpenMergeTool string `yaml:"openMergeTool"`
|
||||
OpenStatusFilter string `yaml:"openStatusFilter"`
|
||||
CopyFileInfoToClipboard string `yaml:"copyFileInfoToClipboard"`
|
||||
}
|
||||
|
||||
type KeybindingBranchesConfig struct {
|
||||
@@ -240,13 +391,14 @@ type KeybindingBranchesConfig struct {
|
||||
ForceCheckoutBranch string `yaml:"forceCheckoutBranch"`
|
||||
RebaseBranch string `yaml:"rebaseBranch"`
|
||||
RenameBranch string `yaml:"renameBranch"`
|
||||
MergeIntoCurrentBranch string `yaml:"mergeIntoCurrentBranch"`
|
||||
Merge string `yaml:"merge"`
|
||||
ViewGitFlowOptions string `yaml:"viewGitFlowOptions"`
|
||||
FastForward string `yaml:"fastForward"`
|
||||
CreateTag string `yaml:"createTag"`
|
||||
NewTag string `yaml:"newTag"`
|
||||
PushTag string `yaml:"pushTag"`
|
||||
SetUpstream string `yaml:"setUpstream"`
|
||||
FetchRemote string `yaml:"fetchRemote"`
|
||||
Fetch string `yaml:"fetch"`
|
||||
SortOrder string `yaml:"sortOrder"`
|
||||
}
|
||||
|
||||
type KeybindingWorktreesConfig struct {
|
||||
@@ -254,30 +406,30 @@ type KeybindingWorktreesConfig struct {
|
||||
}
|
||||
|
||||
type KeybindingCommitsConfig struct {
|
||||
SquashDown string `yaml:"squashDown"`
|
||||
RenameCommit string `yaml:"renameCommit"`
|
||||
RenameCommitWithEditor string `yaml:"renameCommitWithEditor"`
|
||||
Squash string `yaml:"squash"`
|
||||
Reword string `yaml:"reword"`
|
||||
RewordWithEditor string `yaml:"rewordWithEditor"`
|
||||
ViewResetOptions string `yaml:"viewResetOptions"`
|
||||
MarkCommitAsFixup string `yaml:"markCommitAsFixup"`
|
||||
Fixup string `yaml:"fixup"`
|
||||
CreateFixupCommit string `yaml:"createFixupCommit"`
|
||||
SquashAboveCommits string `yaml:"squashAboveCommits"`
|
||||
ApplyFixupCommits string `yaml:"applyFixupCommits"`
|
||||
MoveDownCommit string `yaml:"moveDownCommit"`
|
||||
MoveUpCommit string `yaml:"moveUpCommit"`
|
||||
AmendToCommit string `yaml:"amendToCommit"`
|
||||
ResetCommitAuthor string `yaml:"resetCommitAuthor"`
|
||||
PickCommit string `yaml:"pickCommit"`
|
||||
RevertCommit string `yaml:"revertCommit"`
|
||||
Amend string `yaml:"amend"`
|
||||
AmendCommitAttribute string `yaml:"amendCommitAttribute"`
|
||||
Pick string `yaml:"pick"`
|
||||
Revert string `yaml:"revert"`
|
||||
CherryPickCopy string `yaml:"cherryPickCopy"`
|
||||
CherryPickCopyRange string `yaml:"cherryPickCopyRange"`
|
||||
PasteCommits string `yaml:"pasteCommits"`
|
||||
MarkCommitAsBaseForRebase string `yaml:"markCommitAsBaseForRebase"`
|
||||
CreateTag string `yaml:"tagCommit"`
|
||||
CheckoutCommit string `yaml:"checkoutCommit"`
|
||||
Checkout string `yaml:"checkout"`
|
||||
ResetCherryPick string `yaml:"resetCherryPick"`
|
||||
CopyCommitAttributeToClipboard string `yaml:"copyCommitAttributeToClipboard"`
|
||||
OpenLogMenu string `yaml:"openLogMenu"`
|
||||
OpenInBrowser string `yaml:"openInBrowser"`
|
||||
ViewBisectOptions string `yaml:"viewBisectOptions"`
|
||||
StartInteractiveRebase string `yaml:"startInteractiveRebase"`
|
||||
}
|
||||
|
||||
type KeybindingStashConfig struct {
|
||||
@@ -286,15 +438,13 @@ type KeybindingStashConfig struct {
|
||||
}
|
||||
|
||||
type KeybindingCommitFilesConfig struct {
|
||||
CheckoutCommitFile string `yaml:"checkoutCommitFile"`
|
||||
Checkout string `yaml:"checkout"`
|
||||
}
|
||||
|
||||
type KeybindingMainConfig struct {
|
||||
ToggleDragSelect string `yaml:"toggleDragSelect"`
|
||||
ToggleDragSelectAlt string `yaml:"toggleDragSelect-alt"`
|
||||
ToggleSelectHunk string `yaml:"toggleSelectHunk"`
|
||||
PickBothHunks string `yaml:"pickBothHunks"`
|
||||
EditSelectHunk string `yaml:"editSelectHunk"`
|
||||
ToggleSelectHunk string `yaml:"toggleSelectHunk"`
|
||||
PickBothHunks string `yaml:"pickBothHunks"`
|
||||
EditSelectHunk string `yaml:"editSelectHunk"`
|
||||
}
|
||||
|
||||
type KeybindingSubmodulesConfig struct {
|
||||
@@ -303,6 +453,10 @@ type KeybindingSubmodulesConfig struct {
|
||||
BulkMenu string `yaml:"bulkMenu"`
|
||||
}
|
||||
|
||||
type KeybindingCommitMessageConfig struct {
|
||||
SwitchToEditor string `yaml:"switchToEditor"`
|
||||
}
|
||||
|
||||
// OSConfig contains config on the level of the os
|
||||
type OSConfig struct {
|
||||
// Command for editing a file. Should contain "{{filename}}".
|
||||
@@ -316,17 +470,17 @@ type OSConfig struct {
|
||||
// window is closed.
|
||||
EditAtLineAndWait string `yaml:"editAtLineAndWait,omitempty"`
|
||||
|
||||
// Whether the given edit commands use the terminal. Used to decide whether
|
||||
// lazygit needs to suspend to the background before calling the editor.
|
||||
// Whether lazygit suspends until an edit process returns
|
||||
// Pointer to bool so that we can distinguish unset (nil) from false.
|
||||
EditInTerminal *bool `yaml:"editInTerminal,omitempty"`
|
||||
// We're naming this `editInTerminal` for backwards compatibility
|
||||
SuspendOnEdit *bool `yaml:"editInTerminal,omitempty"`
|
||||
|
||||
// For opening a directory in an editor
|
||||
OpenDirInEditor string `yaml:"openDirInEditor,omitempty"`
|
||||
|
||||
// A built-in preset that sets all of the above settings. Supported presets
|
||||
// are defined in the getPreset function in editor_presets.go.
|
||||
EditPreset string `yaml:"editPreset,omitempty"`
|
||||
EditPreset string `yaml:"editPreset,omitempty" jsonschema:"example=vim,example=nvim,example=emacs,example=nano,example=vscode,example=sublime,example=kakoune,example=helix,example=xcode"`
|
||||
|
||||
// Command for opening a file, as if the file is double-clicked. Should
|
||||
// contain "{{filename}}", but doesn't support "{{line}}".
|
||||
@@ -358,7 +512,8 @@ type OSConfig struct {
|
||||
// Deprecated: use OpenLink instead.
|
||||
OpenLinkCommand string `yaml:"openLinkCommand,omitempty"`
|
||||
|
||||
// CopyToClipboardCmd is the command for copying to clipboard
|
||||
// CopyToClipboardCmd is the command for copying to clipboard.
|
||||
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-command-for-copying-to-clipboard
|
||||
CopyToClipboardCmd string `yaml:"copyToClipboardCmd,omitempty"`
|
||||
}
|
||||
|
||||
@@ -367,50 +522,79 @@ type CustomCommandAfterHook struct {
|
||||
}
|
||||
|
||||
type CustomCommand struct {
|
||||
Key string `yaml:"key"`
|
||||
Context string `yaml:"context"`
|
||||
Command string `yaml:"command"`
|
||||
Subprocess bool `yaml:"subprocess"`
|
||||
Prompts []CustomCommandPrompt `yaml:"prompts"`
|
||||
LoadingText string `yaml:"loadingText"`
|
||||
Description string `yaml:"description"`
|
||||
Stream bool `yaml:"stream"`
|
||||
ShowOutput bool `yaml:"showOutput"`
|
||||
After CustomCommandAfterHook `yaml:"after"`
|
||||
// The key to trigger the command. Use a single letter or one of the values from https://github.com/jesseduffield/lazygit/blob/master/docs/keybindings/Custom_Keybindings.md
|
||||
Key string `yaml:"key"`
|
||||
// The context in which to listen for the key
|
||||
Context string `yaml:"context" jsonschema:"enum=status,enum=files,enum=worktrees,enum=localBranches,enum=remotes,enum=remoteBranches,enum=tags,enum=commits,enum=reflogCommits,enum=subCommits,enum=commitFiles,enum=stash,enum=global"`
|
||||
// The command to run (using Go template syntax for placeholder values)
|
||||
Command string `yaml:"command" jsonschema:"example=git fetch {{.Form.Remote}} {{.Form.Branch}} && git checkout FETCH_HEAD"`
|
||||
// If true, run the command in a subprocess (e.g. if the command requires user input)
|
||||
Subprocess bool `yaml:"subprocess"`
|
||||
// A list of prompts that will request user input before running the final command
|
||||
Prompts []CustomCommandPrompt `yaml:"prompts"`
|
||||
// Text to display while waiting for command to finish
|
||||
LoadingText string `yaml:"loadingText" jsonschema:"example=Loading..."`
|
||||
// Label for the custom command when displayed in the keybindings menu
|
||||
Description string `yaml:"description"`
|
||||
// If true, stream the command's output to the Command Log panel
|
||||
Stream bool `yaml:"stream"`
|
||||
// If true, show the command's output in a popup within Lazygit
|
||||
ShowOutput bool `yaml:"showOutput"`
|
||||
// Actions to take after the command has completed
|
||||
After CustomCommandAfterHook `yaml:"after"`
|
||||
}
|
||||
|
||||
type CustomCommandPrompt struct {
|
||||
// one of 'input', 'menu', 'confirm', or 'menuFromCommand'
|
||||
Type string `yaml:"type"`
|
||||
Key string `yaml:"key"`
|
||||
// One of: 'input' | 'menu' | 'confirm' | 'menuFromCommand'
|
||||
Type string `yaml:"type"`
|
||||
// Used to reference the entered value from within the custom command. E.g. a prompt with `key: 'Branch'` can be referred to as `{{.Form.Branch}}` in the command
|
||||
Key string `yaml:"key"`
|
||||
// The title to display in the popup panel
|
||||
Title string `yaml:"title"`
|
||||
|
||||
// these only apply to input prompts
|
||||
InitialValue string `yaml:"initialValue"`
|
||||
Suggestions CustomCommandSuggestions `yaml:"suggestions"`
|
||||
// The initial value to appear in the text box.
|
||||
// Only for input prompts.
|
||||
InitialValue string `yaml:"initialValue"`
|
||||
// Shows suggestions as the input is entered
|
||||
// Only for input prompts.
|
||||
Suggestions CustomCommandSuggestions `yaml:"suggestions"`
|
||||
|
||||
// this only applies to confirm prompts
|
||||
Body string `yaml:"body"`
|
||||
// The message of the confirmation prompt.
|
||||
// Only for confirm prompts.
|
||||
Body string `yaml:"body" jsonschema:"example=Are you sure you want to push to the remote?"`
|
||||
|
||||
// this only applies to menus
|
||||
Options []CustomCommandMenuOption
|
||||
// Menu options.
|
||||
// Only for menu prompts.
|
||||
Options []CustomCommandMenuOption `yaml:"options"`
|
||||
|
||||
// this only applies to menuFromCommand
|
||||
Command string `yaml:"command"`
|
||||
Filter string `yaml:"filter"`
|
||||
ValueFormat string `yaml:"valueFormat"`
|
||||
LabelFormat string `yaml:"labelFormat"`
|
||||
// The command to run to generate menu options
|
||||
// Only for menuFromCommand prompts.
|
||||
Command string `yaml:"command" jsonschema:"example=git fetch {{.Form.Remote}} {{.Form.Branch}} && git checkout FETCH_HEAD"`
|
||||
// The regexp to run specifying groups which are going to be kept from the command's output.
|
||||
// Only for menuFromCommand prompts.
|
||||
Filter string `yaml:"filter" jsonschema:"example=.*{{.SelectedRemote.Name }}/(?P<branch>.*)"`
|
||||
// How to format matched groups from the filter to construct a menu item's value.
|
||||
// Only for menuFromCommand prompts.
|
||||
ValueFormat string `yaml:"valueFormat" jsonschema:"example={{ .branch }}"`
|
||||
// Like valueFormat but for the labels. If `labelFormat` is not specified, `valueFormat` is shown instead.
|
||||
// Only for menuFromCommand prompts.
|
||||
LabelFormat string `yaml:"labelFormat" jsonschema:"example={{ .branch | green }}"`
|
||||
}
|
||||
|
||||
type CustomCommandSuggestions struct {
|
||||
Preset string `yaml:"preset"`
|
||||
Command string `yaml:"command"`
|
||||
// Uses built-in logic to obtain the suggestions. One of 'authors' | 'branches' | 'files' | 'refs' | 'remotes' | 'remoteBranches' | 'tags'
|
||||
Preset string `yaml:"preset" jsonschema:"enum=authors,enum=branches,enum=files,enum=refs,enum=remotes,enum=remoteBranches,enum=tags"`
|
||||
// Command to run such that each line in the output becomes a suggestion. Mutually exclusive with 'preset' field.
|
||||
Command string `yaml:"command" jsonschema:"example=git fetch {{.Form.Remote}} {{.Form.Branch}} && git checkout FETCH_HEAD"`
|
||||
}
|
||||
|
||||
type CustomCommandMenuOption struct {
|
||||
Name string `yaml:"name"`
|
||||
// The first part of the label
|
||||
Name string `yaml:"name"`
|
||||
// The second part of the label
|
||||
Description string `yaml:"description"`
|
||||
Value string `yaml:"value"`
|
||||
// The value that will be used in the command
|
||||
Value string `yaml:"value" jsonschema:"example=feature,minLength=1"`
|
||||
}
|
||||
|
||||
func GetDefaultConfig() *UserConfig {
|
||||
@@ -418,12 +602,15 @@ func GetDefaultConfig() *UserConfig {
|
||||
Gui: GuiConfig{
|
||||
ScrollHeight: 2,
|
||||
ScrollPastBottom: true,
|
||||
ScrollOffMargin: 2,
|
||||
ScrollOffBehavior: "margin",
|
||||
MouseEvents: true,
|
||||
SkipDiscardChangeWarning: false,
|
||||
SkipStashWarning: false,
|
||||
SidePanelWidth: 0.3333,
|
||||
ExpandFocusedSidePanel: false,
|
||||
MainPanelSplitMode: "flexible",
|
||||
EnlargedSideViewLocation: "left",
|
||||
Language: "auto",
|
||||
TimeFormat: "02 Jan 06",
|
||||
ShortTimeFormat: time.Kitchen,
|
||||
@@ -433,7 +620,6 @@ func GetDefaultConfig() *UserConfig {
|
||||
InactiveBorderColor: []string{"default"},
|
||||
OptionsTextColor: []string{"blue"},
|
||||
SelectedLineBgColor: []string{"blue"},
|
||||
SelectedRangeBgColor: []string{"blue"},
|
||||
CherryPickedCommitBgColor: []string{"cyan"},
|
||||
CherryPickedCommitFgColor: []string{"blue"},
|
||||
MarkedBaseCommitBgColor: []string{"yellow"},
|
||||
@@ -446,22 +632,26 @@ func GetDefaultConfig() *UserConfig {
|
||||
ShowListFooter: true,
|
||||
ShowCommandLog: true,
|
||||
ShowBottomLine: true,
|
||||
ShowPanelJumps: true,
|
||||
ShowFileTree: true,
|
||||
ShowRandomTip: true,
|
||||
ShowIcons: false,
|
||||
NerdFontsVersion: "",
|
||||
ShowFileIcons: true,
|
||||
ShowBranchCommitHash: false,
|
||||
CommandLogSize: 8,
|
||||
SplitDiff: "auto",
|
||||
SkipRewordInEditorWarning: false,
|
||||
Border: "single",
|
||||
Border: "rounded",
|
||||
AnimateExplosion: true,
|
||||
PortraitMode: "auto",
|
||||
},
|
||||
Git: GitConfig{
|
||||
Paging: PagingConfig{
|
||||
ColorArg: "always",
|
||||
Pager: "",
|
||||
UseConfig: false,
|
||||
ColorArg: "always",
|
||||
Pager: "",
|
||||
UseConfig: false,
|
||||
ExternalDiffCommand: "",
|
||||
},
|
||||
Commit: CommitConfig{
|
||||
SignOff: false,
|
||||
@@ -485,7 +675,6 @@ func GetDefaultConfig() *UserConfig {
|
||||
DisableForcePushing: false,
|
||||
CommitPrefixes: map[string]CommitPrefixConfig(nil),
|
||||
ParseEmoji: false,
|
||||
DiffContextSize: 3,
|
||||
},
|
||||
Refresher: RefresherConfig{
|
||||
RefreshInterval: 10,
|
||||
@@ -514,6 +703,9 @@ func GetDefaultConfig() *UserConfig {
|
||||
ScrollRight: "L",
|
||||
GotoTop: "<",
|
||||
GotoBottom: ">",
|
||||
ToggleRangeSelect: "v",
|
||||
RangeSelectDown: "<s-down>",
|
||||
RangeSelectUp: "<s-up>",
|
||||
PrevBlock: "<left>",
|
||||
NextBlock: "<right>",
|
||||
PrevBlockAlt: "h",
|
||||
@@ -524,7 +716,7 @@ func GetDefaultConfig() *UserConfig {
|
||||
NextMatch: "n",
|
||||
PrevMatch: "N",
|
||||
StartSearch: "/",
|
||||
OptionMenu: "",
|
||||
OptionMenu: "<disabled>",
|
||||
OptionMenuAlt1: "?",
|
||||
Select: "<space>",
|
||||
GoInto: "<enter>",
|
||||
@@ -562,6 +754,7 @@ func GetDefaultConfig() *UserConfig {
|
||||
ToggleWhitespaceInDiffView: "<c-w>",
|
||||
IncreaseContextInDiffView: "}",
|
||||
DecreaseContextInDiffView: "{",
|
||||
OpenDiffTool: "<c-t>",
|
||||
},
|
||||
Status: KeybindingStatusConfig{
|
||||
CheckForUpdate: "u",
|
||||
@@ -569,20 +762,23 @@ func GetDefaultConfig() *UserConfig {
|
||||
AllBranchesLogGraph: "a",
|
||||
},
|
||||
Files: KeybindingFilesConfig{
|
||||
CommitChanges: "c",
|
||||
CommitChangesWithoutHook: "w",
|
||||
AmendLastCommit: "A",
|
||||
CommitChangesWithEditor: "C",
|
||||
IgnoreFile: "i",
|
||||
RefreshFiles: "r",
|
||||
StashAllChanges: "s",
|
||||
ViewStashOptions: "S",
|
||||
ToggleStagedAll: "a",
|
||||
ViewResetOptions: "D",
|
||||
Fetch: "f",
|
||||
ToggleTreeView: "`",
|
||||
OpenMergeTool: "M",
|
||||
OpenStatusFilter: "<c-b>",
|
||||
Commit: "c",
|
||||
CommitWithoutHook: "w",
|
||||
AmendLastCommit: "A",
|
||||
CommitChangesWithEditor: "C",
|
||||
FindBaseCommitForFixup: "<c-f>",
|
||||
IgnoreFile: "i",
|
||||
RefreshFiles: "r",
|
||||
Stash: "s",
|
||||
ViewStashOptions: "S",
|
||||
ToggleStagedAll: "a",
|
||||
Reset: "D",
|
||||
Fetch: "f",
|
||||
ToggleTreeView: "`",
|
||||
OpenMergeTool: "M",
|
||||
OpenStatusFilter: "<c-b>",
|
||||
ConfirmDiscard: "x",
|
||||
CopyFileInfoToClipboard: "y",
|
||||
},
|
||||
Branches: KeybindingBranchesConfig{
|
||||
CopyPullRequestURL: "<c-y>",
|
||||
@@ -592,62 +788,64 @@ func GetDefaultConfig() *UserConfig {
|
||||
ForceCheckoutBranch: "F",
|
||||
RebaseBranch: "r",
|
||||
RenameBranch: "R",
|
||||
MergeIntoCurrentBranch: "M",
|
||||
Merge: "M",
|
||||
ViewGitFlowOptions: "i",
|
||||
FastForward: "f",
|
||||
CreateTag: "T",
|
||||
NewTag: "T",
|
||||
PushTag: "P",
|
||||
SetUpstream: "u",
|
||||
FetchRemote: "f",
|
||||
Fetch: "f",
|
||||
SortOrder: "s",
|
||||
},
|
||||
Worktrees: KeybindingWorktreesConfig{
|
||||
ViewWorktreeOptions: "w",
|
||||
},
|
||||
Commits: KeybindingCommitsConfig{
|
||||
SquashDown: "s",
|
||||
RenameCommit: "r",
|
||||
RenameCommitWithEditor: "R",
|
||||
Squash: "s",
|
||||
Reword: "r",
|
||||
RewordWithEditor: "R",
|
||||
ViewResetOptions: "g",
|
||||
MarkCommitAsFixup: "f",
|
||||
Fixup: "f",
|
||||
CreateFixupCommit: "F",
|
||||
SquashAboveCommits: "S",
|
||||
ApplyFixupCommits: "S",
|
||||
MoveDownCommit: "<c-j>",
|
||||
MoveUpCommit: "<c-k>",
|
||||
AmendToCommit: "A",
|
||||
ResetCommitAuthor: "a",
|
||||
PickCommit: "p",
|
||||
RevertCommit: "t",
|
||||
CherryPickCopy: "c",
|
||||
CherryPickCopyRange: "C",
|
||||
PasteCommits: "v",
|
||||
Amend: "A",
|
||||
AmendCommitAttribute: "a",
|
||||
Pick: "p",
|
||||
Revert: "t",
|
||||
CherryPickCopy: "C",
|
||||
PasteCommits: "V",
|
||||
MarkCommitAsBaseForRebase: "B",
|
||||
CreateTag: "T",
|
||||
CheckoutCommit: "<space>",
|
||||
Checkout: "<space>",
|
||||
ResetCherryPick: "<c-R>",
|
||||
CopyCommitAttributeToClipboard: "y",
|
||||
OpenLogMenu: "<c-l>",
|
||||
OpenInBrowser: "o",
|
||||
ViewBisectOptions: "b",
|
||||
StartInteractiveRebase: "i",
|
||||
},
|
||||
Stash: KeybindingStashConfig{
|
||||
PopStash: "g",
|
||||
RenameStash: "r",
|
||||
},
|
||||
CommitFiles: KeybindingCommitFilesConfig{
|
||||
CheckoutCommitFile: "c",
|
||||
Checkout: "c",
|
||||
},
|
||||
Main: KeybindingMainConfig{
|
||||
ToggleDragSelect: "v",
|
||||
ToggleDragSelectAlt: "V",
|
||||
ToggleSelectHunk: "a",
|
||||
PickBothHunks: "b",
|
||||
EditSelectHunk: "E",
|
||||
ToggleSelectHunk: "a",
|
||||
PickBothHunks: "b",
|
||||
EditSelectHunk: "E",
|
||||
},
|
||||
Submodules: KeybindingSubmodulesConfig{
|
||||
Init: "i",
|
||||
Update: "u",
|
||||
BulkMenu: "b",
|
||||
},
|
||||
CommitMessage: KeybindingCommitMessageConfig{
|
||||
SwitchToEditor: "<c-o>",
|
||||
},
|
||||
},
|
||||
OS: OSConfig{},
|
||||
DisableStartupPopups: false,
|
||||
|
||||
@@ -8,6 +8,7 @@ type Docs struct {
|
||||
Undoing string
|
||||
Config string
|
||||
Tutorial string
|
||||
CustomPatchDemo string
|
||||
}
|
||||
|
||||
var Links = struct {
|
||||
@@ -31,5 +32,6 @@ var Links = struct {
|
||||
Undoing: "https://github.com/jesseduffield/lazygit/blob/master/docs/Undoing.md",
|
||||
Config: "https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md",
|
||||
Tutorial: "https://youtu.be/VDXvbHZYeKY",
|
||||
CustomPatchDemo: "https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ func (gui *Gui) getRandomTip() string {
|
||||
),
|
||||
fmt.Sprintf(
|
||||
"To revert a commit, press '%s' on that commit",
|
||||
formattedKey(config.Commits.RevertCommit),
|
||||
formattedKey(config.Commits.Revert),
|
||||
),
|
||||
fmt.Sprintf(
|
||||
"To escape a mode, for example cherry-picking, patch-building, diffing, or filtering mode, you can just spam the '%s' button. Unless of course you have `quitOnTopLevelReturn` enabled in your config",
|
||||
@@ -151,7 +151,7 @@ func (gui *Gui) getRandomTip() string {
|
||||
),
|
||||
fmt.Sprintf(
|
||||
"You can append your staged changes to an older commit by pressing '%s' on that commit",
|
||||
formattedKey(config.Commits.AmendToCommit),
|
||||
formattedKey(config.Commits.Amend),
|
||||
),
|
||||
fmt.Sprintf(
|
||||
"You can amend the last commit with your new file changes by pressing '%s' in the files panel",
|
||||
|
||||
@@ -245,8 +245,6 @@ func (self *ContextMgr) ActivateContext(c types.Context, opts types.OnFocusOpts)
|
||||
|
||||
self.gui.c.GocuiGui().Cursor = v.Editable
|
||||
|
||||
self.gui.renderContextOptionsMap(c)
|
||||
|
||||
if err := c.HandleFocus(opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -20,10 +20,11 @@ type BaseContext struct {
|
||||
onFocusFn onFocusFn
|
||||
onFocusLostFn onFocusLostFn
|
||||
|
||||
focusable bool
|
||||
transient bool
|
||||
hasControlledBounds bool
|
||||
highlightOnFocus bool
|
||||
focusable bool
|
||||
transient bool
|
||||
hasControlledBounds bool
|
||||
needsRerenderOnWidthChange bool
|
||||
highlightOnFocus bool
|
||||
|
||||
*ParentContextMgr
|
||||
}
|
||||
@@ -36,14 +37,15 @@ type (
|
||||
var _ types.IBaseContext = &BaseContext{}
|
||||
|
||||
type NewBaseContextOpts struct {
|
||||
Kind types.ContextKind
|
||||
Key types.ContextKey
|
||||
View *gocui.View
|
||||
WindowName string
|
||||
Focusable bool
|
||||
Transient bool
|
||||
HasUncontrolledBounds bool // negating for the sake of making false the default
|
||||
HighlightOnFocus bool
|
||||
Kind types.ContextKind
|
||||
Key types.ContextKey
|
||||
View *gocui.View
|
||||
WindowName string
|
||||
Focusable bool
|
||||
Transient bool
|
||||
HasUncontrolledBounds bool // negating for the sake of making false the default
|
||||
HighlightOnFocus bool
|
||||
NeedsRerenderOnWidthChange bool
|
||||
|
||||
OnGetOptionsMap func() map[string]string
|
||||
}
|
||||
@@ -54,17 +56,18 @@ func NewBaseContext(opts NewBaseContextOpts) *BaseContext {
|
||||
hasControlledBounds := !opts.HasUncontrolledBounds
|
||||
|
||||
return &BaseContext{
|
||||
kind: opts.Kind,
|
||||
key: opts.Key,
|
||||
view: opts.View,
|
||||
windowName: opts.WindowName,
|
||||
onGetOptionsMap: opts.OnGetOptionsMap,
|
||||
focusable: opts.Focusable,
|
||||
transient: opts.Transient,
|
||||
hasControlledBounds: hasControlledBounds,
|
||||
highlightOnFocus: opts.HighlightOnFocus,
|
||||
ParentContextMgr: &ParentContextMgr{},
|
||||
viewTrait: viewTrait,
|
||||
kind: opts.Kind,
|
||||
key: opts.Key,
|
||||
view: opts.View,
|
||||
windowName: opts.WindowName,
|
||||
onGetOptionsMap: opts.OnGetOptionsMap,
|
||||
focusable: opts.Focusable,
|
||||
transient: opts.Transient,
|
||||
hasControlledBounds: hasControlledBounds,
|
||||
highlightOnFocus: opts.HighlightOnFocus,
|
||||
needsRerenderOnWidthChange: opts.NeedsRerenderOnWidthChange,
|
||||
ParentContextMgr: &ParentContextMgr{},
|
||||
viewTrait: viewTrait,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +193,10 @@ func (self *BaseContext) HasControlledBounds() bool {
|
||||
return self.hasControlledBounds
|
||||
}
|
||||
|
||||
func (self *BaseContext) NeedsRerenderOnWidthChange() bool {
|
||||
return self.needsRerenderOnWidthChange
|
||||
}
|
||||
|
||||
func (self *BaseContext) Title() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -24,11 +24,13 @@ func NewBranchesContext(c *ContextCommon) *BranchesContext {
|
||||
},
|
||||
)
|
||||
|
||||
getDisplayStrings := func(startIdx int, length int) [][]string {
|
||||
getDisplayStrings := func(_ int, _ int) [][]string {
|
||||
return presentation.GetBranchListDisplayStrings(
|
||||
viewModel.GetItems(),
|
||||
c.State().GetItemOperation,
|
||||
c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL,
|
||||
c.Modes().Diffing.Ref,
|
||||
c.Views().Branches.Width(),
|
||||
c.Tr,
|
||||
c.UserConfig,
|
||||
c.Model().Worktrees,
|
||||
@@ -39,30 +41,24 @@ func NewBranchesContext(c *ContextCommon) *BranchesContext {
|
||||
FilteredListViewModel: viewModel,
|
||||
ListContextTrait: &ListContextTrait{
|
||||
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
|
||||
View: c.Views().Branches,
|
||||
WindowName: "branches",
|
||||
Key: LOCAL_BRANCHES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
View: c.Views().Branches,
|
||||
WindowName: "branches",
|
||||
Key: LOCAL_BRANCHES_CONTEXT_KEY,
|
||||
Kind: types.SIDE_CONTEXT,
|
||||
Focusable: true,
|
||||
NeedsRerenderOnWidthChange: true,
|
||||
})),
|
||||
list: viewModel,
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
ListRenderer: ListRenderer{
|
||||
list: viewModel,
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
},
|
||||
c: c,
|
||||
},
|
||||
}
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
func (self *BranchesContext) GetSelectedItemId() string {
|
||||
item := self.GetSelected()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return item.ID()
|
||||
}
|
||||
|
||||
func (self *BranchesContext) GetSelectedRef() types.Ref {
|
||||
branch := self.GetSelected()
|
||||
if branch == nil {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/presentation/icons"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/samber/lo"
|
||||
@@ -28,12 +29,13 @@ func NewCommitFilesContext(c *ContextCommon) *CommitFilesContext {
|
||||
c.UserConfig.Gui.ShowFileTree,
|
||||
)
|
||||
|
||||
getDisplayStrings := func(startIdx int, length int) [][]string {
|
||||
getDisplayStrings := func(_ int, _ int) [][]string {
|
||||
if viewModel.Len() == 0 {
|
||||
return [][]string{{style.FgRed.Sprint("(none)")}}
|
||||
}
|
||||
|
||||
lines := presentation.RenderCommitFileTree(viewModel, c.Modes().Diffing.Ref, c.Git().Patch.PatchBuilder)
|
||||
showFileIcons := icons.IsIconEnabled() && c.UserConfig.Gui.ShowFileIcons
|
||||
lines := presentation.RenderCommitFileTree(viewModel, c.Git().Patch.PatchBuilder, showFileIcons)
|
||||
return lo.Map(lines, func(line string, _ int) []string {
|
||||
return []string{line}
|
||||
})
|
||||
@@ -54,29 +56,22 @@ func NewCommitFilesContext(c *ContextCommon) *CommitFilesContext {
|
||||
Transient: true,
|
||||
}),
|
||||
),
|
||||
list: viewModel,
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
c: c,
|
||||
ListRenderer: ListRenderer{
|
||||
list: viewModel,
|
||||
getDisplayStrings: getDisplayStrings,
|
||||
},
|
||||
c: c,
|
||||
},
|
||||
}
|
||||
|
||||
ctx.GetView().SetOnSelectItem(ctx.SearchTrait.onSelectItemWrapper(func(selectedLineIdx int) error {
|
||||
ctx.GetList().SetSelectedLineIdx(selectedLineIdx)
|
||||
ctx.GetList().SetSelection(selectedLineIdx)
|
||||
return ctx.HandleFocus(types.OnFocusOpts{})
|
||||
}))
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (self *CommitFilesContext) GetSelectedItemId() string {
|
||||
item := self.GetSelected()
|
||||
if item == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return item.ID()
|
||||
}
|
||||
|
||||
func (self *CommitFilesContext) GetDiffTerminals() []string {
|
||||
return []string{self.GetRef().RefName()}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,10 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type CommitMessageContext struct {
|
||||
@@ -32,6 +35,8 @@ type CommitMessageViewModel struct {
|
||||
preservedMessage string
|
||||
// invoked when pressing enter in the commit message panel
|
||||
onConfirm func(string, string) error
|
||||
// invoked when pressing the switch-to-editor key binding
|
||||
onSwitchToEditor func(string) error
|
||||
|
||||
// The message typed in before cycling through history
|
||||
// We store this separately to 'preservedMessage' because 'preservedMessage'
|
||||
@@ -98,12 +103,21 @@ func (self *CommitMessageContext) SetPanelState(
|
||||
descriptionTitle string,
|
||||
preserveMessage bool,
|
||||
onConfirm func(string, string) error,
|
||||
onSwitchToEditor func(string) error,
|
||||
) {
|
||||
self.viewModel.selectedindex = index
|
||||
self.viewModel.preserveMessage = preserveMessage
|
||||
self.viewModel.onConfirm = onConfirm
|
||||
self.viewModel.onSwitchToEditor = onSwitchToEditor
|
||||
self.GetView().Title = summaryTitle
|
||||
self.c.Views().CommitDescription.Title = descriptionTitle
|
||||
|
||||
subtitleTemplate := lo.Ternary(onSwitchToEditor != nil, self.c.Tr.CommitDescriptionSubTitle, self.c.Tr.CommitDescriptionSubTitleNoSwitch)
|
||||
self.c.Views().CommitDescription.Subtitle = utils.ResolvePlaceholderString(subtitleTemplate,
|
||||
map[string]string{
|
||||
"togglePanelKeyBinding": keybindings.Label(self.c.UserConfig.Keybinding.Universal.TogglePanel),
|
||||
"switchToEditorKeyBinding": keybindings.Label(self.c.UserConfig.Keybinding.CommitMessage.SwitchToEditor),
|
||||
})
|
||||
}
|
||||
|
||||
func (self *CommitMessageContext) RenderCommitLength() {
|
||||
@@ -117,3 +131,11 @@ func (self *CommitMessageContext) RenderCommitLength() {
|
||||
func getBufferLength(view *gocui.View) string {
|
||||
return " " + strconv.Itoa(strings.Count(view.TextArea.GetContent(), "")-1) + " "
|
||||
}
|
||||
|
||||
func (self *CommitMessageContext) SwitchToEditor(message string) error {
|
||||
return self.viewModel.onSwitchToEditor(message)
|
||||
}
|
||||
|
||||
func (self *CommitMessageContext) CanSwitchToEditor() bool {
|
||||
return self.viewModel.onSwitchToEditor != nil
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user