Compare commits

..
Author SHA1 Message Date
Jesse Duffield 76ed204795 Add convenience builder for git commands
Adds a convenience builder for git commands. Applies it in a couple of places that benefit from it.

I've got a larger PR that does a more sweeping change but I want some reviews on that before I go ahead with it.
2023-05-20 16:12:34 +10:00
61 changed files with 1204 additions and 1617 deletions
+2 -2
View File
@@ -5,8 +5,8 @@
"tasks": [
{
"label": "Generate cheatsheet",
"type": "shell",
"command": "go run scripts/cheatsheet/main.go generate",
"type": "process",
"command": "go run scripts/cheatsheet/main.go ",
"problemMatcher": [],
},
{
+1 -4
View File
@@ -65,8 +65,6 @@ gui:
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'
# For marking recent commits which changed the selected file
experimentalMarkCommitsWhichChangedFile: false
git:
paging:
colorArg: always
@@ -90,7 +88,7 @@ git:
# displays the whole git graph by default in the commits panel (equivalent to passing the `--all` argument to `git log`)
showWholeGraph: false
skipHookPrefix: WIP
# The main branches. We colour commits green if they belong to one of these branches,
# The main branches. We colour commits green if they belong to one of these branches,
# so that you can easily see which commits are unique to your branch (coloured in yellow)
mainBranches: [master, main]
autoFetch: true
@@ -349,7 +347,6 @@ The available attributes are:
- default
- reverse # useful for high-contrast
- underline
- strikethrough
## Highlighting the selected line
+72 -74
View File
@@ -2,30 +2,28 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
# Lazygit Keybindings
_Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Global Keybindings
<pre>
<kbd>&lt;c-r&gt;</kbd>: switch to a recent repo
<kbd>&lt;pgup&gt;</kbd>: scroll up main panel (fn+up/shift+k)
<kbd>&lt;pgdown&gt;</kbd>: scroll down main panel (fn+down/shift+j)
<kbd>ctrl+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>&lt;c-p&gt;</kbd>: view custom patch options
<kbd>ctrl+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>&lt;c-s&gt;</kbd>: view filter-by-path options
<kbd>ctrl+s</kbd>: view filter-by-path options
<kbd>W</kbd>: open diff menu
<kbd>&lt;c-e&gt;</kbd>: open diff menu
<kbd>&lt;c-w&gt;</kbd>: Toggle whether or not whitespace changes are shown in the diff view
<kbd>ctrl+e</kbd>: open diff menu
<kbd>ctrl+w</kbd>: Toggle whether or not whitespace changes are shown in the diff view
<kbd>z</kbd>: undo (via reflog) (experimental)
<kbd>&lt;c-z&gt;</kbd>: redo (via reflog) (experimental)
<kbd>ctrl+z</kbd>: redo (via reflog) (experimental)
<kbd>P</kbd>: push
<kbd>p</kbd>: pull
</pre>
@@ -35,9 +33,9 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<pre>
<kbd>,</kbd>: previous page
<kbd>.</kbd>: next page
<kbd>&lt;</kbd>: scroll to top
<kbd><</kbd>: scroll to top
<kbd>/</kbd>: start search
<kbd>&gt;</kbd>: scroll to bottom
<kbd>></kbd>: scroll to bottom
<kbd>H</kbd>: scroll left
<kbd>L</kbd>: scroll right
<kbd>]</kbd>: next tab
@@ -47,29 +45,29 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Commit Files
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy the committed file name to the clipboard
<kbd>ctrl+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>&lt;space&gt;</kbd>: toggle file included in patch
<kbd>space</kbd>: toggle file included in patch
<kbd>a</kbd>: toggle all files included in patch
<kbd>&lt;enter&gt;</kbd>: enter file to add selected lines to the patch (or toggle directory collapsed)
<kbd>enter</kbd>: enter file to add selected lines to the patch (or toggle directory collapsed)
<kbd>`</kbd>: toggle file tree view
</pre>
## Commit Summary
<pre>
<kbd>&lt;enter&gt;</kbd>: confirm
<kbd>&lt;esc&gt;</kbd>: close
<kbd>enter</kbd>: confirm
<kbd>esc</kbd>: close
</pre>
## Commits
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy commit SHA to clipboard
<kbd>&lt;c-r&gt;</kbd>: reset cherry-picked (copied) commits selection
<kbd>ctrl+o</kbd>: copy commit SHA to clipboard
<kbd>ctrl+r</kbd>: reset cherry-picked (copied) commits selection
<kbd>b</kbd>: view bisect options
<kbd>s</kbd>: squash down
<kbd>f</kbd>: fixup commit
@@ -80,38 +78,38 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<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>&lt;c-j&gt;</kbd>: move commit down one
<kbd>&lt;c-k&gt;</kbd>: move commit up one
<kbd>ctrl+j</kbd>: move commit down one
<kbd>ctrl+k</kbd>: move commit up one
<kbd>v</kbd>: paste commits (cherry-pick)
<kbd>A</kbd>: amend commit with staged changes
<kbd>a</kbd>: reset commit author
<kbd>t</kbd>: revert commit
<kbd>T</kbd>: tag commit
<kbd>&lt;c-l&gt;</kbd>: open log menu
<kbd>&lt;space&gt;</kbd>: checkout commit
<kbd>ctrl+l</kbd>: open log menu
<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>&lt;enter&gt;</kbd>: view selected item's files
<kbd>enter</kbd>: view selected item's files
</pre>
## Confirmation Panel
<pre>
<kbd>&lt;enter&gt;</kbd>: confirm
<kbd>&lt;esc&gt;</kbd>: close/cancel
<kbd>enter</kbd>: confirm
<kbd>esc</kbd>: close/cancel
</pre>
## Files
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy the file name to the clipboard
<kbd>ctrl+o</kbd>: copy the file name to the clipboard
<kbd>d</kbd>: view 'discard changes' options
<kbd>&lt;space&gt;</kbd>: toggle staged
<kbd>&lt;c-b&gt;</kbd>: Filter files (staged/unstaged)
<kbd>space</kbd>: toggle staged
<kbd>ctrl+b</kbd>: Filter files (staged/unstaged)
<kbd>c</kbd>: commit changes
<kbd>w</kbd>: commit changes without pre-commit hook
<kbd>A</kbd>: amend last commit
@@ -123,7 +121,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>s</kbd>: stash all changes
<kbd>S</kbd>: view stash options
<kbd>a</kbd>: stage/unstage all
<kbd>&lt;enter&gt;</kbd>: stage individual hunks/lines for file, or collapse/expand for directory
<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
@@ -134,13 +132,13 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Local Branches
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy branch name to clipboard
<kbd>ctrl+o</kbd>: copy branch name to clipboard
<kbd>i</kbd>: show git-flow options
<kbd>&lt;space&gt;</kbd>: checkout
<kbd>space</kbd>: checkout
<kbd>n</kbd>: new branch
<kbd>o</kbd>: create pull request
<kbd>O</kbd>: create pull request options
<kbd>&lt;c-y&gt;</kbd>: copy pull request URL to clipboard
<kbd>ctrl+y</kbd>: copy pull request URL to clipboard
<kbd>c</kbd>: checkout by name
<kbd>F</kbd>: force checkout
<kbd>d</kbd>: delete branch
@@ -151,7 +149,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>g</kbd>: view reset options
<kbd>R</kbd>: rename branch
<kbd>u</kbd>: set/unset upstream
<kbd>&lt;enter&gt;</kbd>: view commits
<kbd>enter</kbd>: view commits
</pre>
## Main Panel (Merging)
@@ -159,53 +157,53 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<pre>
<kbd>e</kbd>: edit file
<kbd>o</kbd>: open file
<kbd>&lt;left&gt;</kbd>: select previous conflict
<kbd>&lt;right&gt;</kbd>: select next conflict
<kbd>&lt;up&gt;</kbd>: select previous hunk
<kbd>&lt;down&gt;</kbd>: select next hunk
<kbd>◀</kbd>: select previous conflict
<kbd>▶</kbd>: select next conflict
<kbd>▲</kbd>: select previous hunk
<kbd>▼</kbd>: select next hunk
<kbd>z</kbd>: undo
<kbd>M</kbd>: open external merge tool (git mergetool)
<kbd>&lt;space&gt;</kbd>: pick hunk
<kbd>space</kbd>: pick hunk
<kbd>b</kbd>: pick all hunks
<kbd>&lt;esc&gt;</kbd>: return to files panel
<kbd>esc</kbd>: return to files panel
</pre>
## Main Panel (Normal)
<pre>
<kbd>mouse wheel down</kbd>: scroll down (fn+up)
<kbd>mouse wheel up</kbd>: scroll up (fn+down)
<kbd>mouse wheel ▼</kbd>: scroll down (fn+up)
<kbd>mouse wheel ▲</kbd>: scroll up (fn+down)
</pre>
## Main Panel (Patch Building)
<pre>
<kbd>&lt;left&gt;</kbd>: select previous hunk
<kbd>&lt;right&gt;</kbd>: select next hunk
<kbd>◀</kbd>: select previous hunk
<kbd>▶</kbd>: select next hunk
<kbd>v</kbd>: toggle drag select
<kbd>V</kbd>: toggle drag select
<kbd>a</kbd>: toggle select hunk
<kbd>&lt;c-o&gt;</kbd>: copy the selected text to the clipboard
<kbd>ctrl+o</kbd>: copy the selected text to the clipboard
<kbd>o</kbd>: open file
<kbd>e</kbd>: edit file
<kbd>&lt;space&gt;</kbd>: add/remove line(s) to patch
<kbd>&lt;esc&gt;</kbd>: exit custom patch builder
<kbd>space</kbd>: add/remove line(s) to patch
<kbd>esc</kbd>: exit custom patch builder
</pre>
## Main Panel (Staging)
<pre>
<kbd>&lt;left&gt;</kbd>: select previous hunk
<kbd>&lt;right&gt;</kbd>: select next hunk
<kbd>◀</kbd>: select previous hunk
<kbd>▶</kbd>: select next hunk
<kbd>v</kbd>: toggle drag select
<kbd>V</kbd>: toggle drag select
<kbd>a</kbd>: toggle select hunk
<kbd>&lt;c-o&gt;</kbd>: copy the selected text to the clipboard
<kbd>ctrl+o</kbd>: copy the selected text to the clipboard
<kbd>o</kbd>: open file
<kbd>e</kbd>: edit file
<kbd>&lt;esc&gt;</kbd>: return to files panel
<kbd>&lt;tab&gt;</kbd>: switch to other panel (staged/unstaged changes)
<kbd>&lt;space&gt;</kbd>: toggle line staged / unstaged
<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>: delete change (git reset)
<kbd>E</kbd>: edit hunk
<kbd>c</kbd>: commit changes
@@ -216,38 +214,38 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Menu
<pre>
<kbd>&lt;enter&gt;</kbd>: execute
<kbd>&lt;esc&gt;</kbd>: close
<kbd>enter</kbd>: execute
<kbd>esc</kbd>: close
</pre>
## Reflog
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy commit SHA to clipboard
<kbd>&lt;space&gt;</kbd>: checkout commit
<kbd>ctrl+o</kbd>: copy commit SHA to clipboard
<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>&lt;c-r&gt;</kbd>: reset cherry-picked (copied) commits selection
<kbd>&lt;enter&gt;</kbd>: view commits
<kbd>ctrl+r</kbd>: reset cherry-picked (copied) commits selection
<kbd>enter</kbd>: view commits
</pre>
## Remote Branches
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy branch name to clipboard
<kbd>&lt;space&gt;</kbd>: checkout
<kbd>ctrl+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>&lt;esc&gt;</kbd>: Return to remotes list
<kbd>esc</kbd>: Return to remotes list
<kbd>g</kbd>: view reset options
<kbd>&lt;enter&gt;</kbd>: view commits
<kbd>enter</kbd>: view commits
</pre>
## Remotes
@@ -262,12 +260,12 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Stash
<pre>
<kbd>&lt;space&gt;</kbd>: apply
<kbd>space</kbd>: apply
<kbd>g</kbd>: pop
<kbd>d</kbd>: drop
<kbd>n</kbd>: new branch
<kbd>r</kbd>: rename stash
<kbd>&lt;enter&gt;</kbd>: view selected item's files
<kbd>enter</kbd>: view selected item's files
</pre>
## Status
@@ -276,30 +274,30 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>o</kbd>: open config file
<kbd>e</kbd>: edit config file
<kbd>u</kbd>: check for update
<kbd>&lt;enter&gt;</kbd>: switch to a recent repo
<kbd>enter</kbd>: switch to a recent repo
<kbd>a</kbd>: show all branch logs
</pre>
## Sub-commits
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy commit SHA to clipboard
<kbd>&lt;space&gt;</kbd>: checkout commit
<kbd>ctrl+o</kbd>: copy commit SHA to clipboard
<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>&lt;c-r&gt;</kbd>: reset cherry-picked (copied) commits selection
<kbd>&lt;enter&gt;</kbd>: view selected item's files
<kbd>ctrl+r</kbd>: reset cherry-picked (copied) commits selection
<kbd>enter</kbd>: view selected item's files
</pre>
## Submodules
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy submodule name to clipboard
<kbd>&lt;enter&gt;</kbd>: enter submodule
<kbd>ctrl+o</kbd>: copy submodule name to clipboard
<kbd>enter</kbd>: enter submodule
<kbd>d</kbd>: remove submodule
<kbd>u</kbd>: update submodule
<kbd>n</kbd>: add new submodule
@@ -311,10 +309,10 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Tags
<pre>
<kbd>&lt;space&gt;</kbd>: checkout
<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>&lt;enter&gt;</kbd>: view commits
<kbd>enter</kbd>: view commits
</pre>
+72 -74
View File
@@ -2,30 +2,28 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
# Lazygit キーバインド
_Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## グローバルキーバインド
<pre>
<kbd>&lt;c-r&gt;</kbd>: 最近使用したリポジトリに切り替え
<kbd>&lt;pgup&gt;</kbd>: メインパネルを上にスクロール (fn+up/shift+k)
<kbd>&lt;pgdown&gt;</kbd>: メインパネルを下にスクロール (fn+down/shift+j)
<kbd>ctrl+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>&lt;c-p&gt;</kbd>: view custom patch options
<kbd>ctrl+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>&lt;c-s&gt;</kbd>: view filter-by-path options
<kbd>ctrl+s</kbd>: view filter-by-path options
<kbd>W</kbd>: 差分メニューを開く
<kbd>&lt;c-e&gt;</kbd>: 差分メニューを開く
<kbd>&lt;c-w&gt;</kbd>: 空白文字の差分の表示有無を切り替え
<kbd>ctrl+e</kbd>: 差分メニューを開く
<kbd>ctrl+w</kbd>: 空白文字の差分の表示有無を切り替え
<kbd>z</kbd>: アンドゥ (via reflog) (experimental)
<kbd>&lt;c-z&gt;</kbd>: リドゥ (via reflog) (experimental)
<kbd>ctrl+z</kbd>: リドゥ (via reflog) (experimental)
<kbd>P</kbd>: push
<kbd>p</kbd>: pull
</pre>
@@ -35,9 +33,9 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<pre>
<kbd>,</kbd>: 前のページ
<kbd>.</kbd>: 次のページ
<kbd>&lt;</kbd>: 最上部までスクロール
<kbd><</kbd>: 最上部までスクロール
<kbd>/</kbd>: 検索を開始
<kbd>&gt;</kbd>: 最下部までスクロール
<kbd>></kbd>: 最下部までスクロール
<kbd>H</kbd>: 左スクロール
<kbd>L</kbd>: 右スクロール
<kbd>]</kbd>: 次のタブ
@@ -47,34 +45,34 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Stash
<pre>
<kbd>&lt;space&gt;</kbd>: 適用
<kbd>space</kbd>: 適用
<kbd>g</kbd>: pop
<kbd>d</kbd>: drop
<kbd>n</kbd>: 新しいブランチを作成
<kbd>r</kbd>: Stashを変更
<kbd>&lt;enter&gt;</kbd>: view selected item's files
<kbd>enter</kbd>: view selected item's files
</pre>
## Sub-commits
<pre>
<kbd>&lt;c-o&gt;</kbd>: コミットのSHAをクリップボードにコピー
<kbd>&lt;space&gt;</kbd>: コミットをチェックアウト
<kbd>ctrl+o</kbd>: コミットのSHAをクリップボードにコピー
<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>&lt;c-r&gt;</kbd>: reset cherry-picked (copied) commits selection
<kbd>&lt;enter&gt;</kbd>: view selected item's files
<kbd>ctrl+r</kbd>: reset cherry-picked (copied) commits selection
<kbd>enter</kbd>: view selected item's files
</pre>
## コミット
<pre>
<kbd>&lt;c-o&gt;</kbd>: コミットのSHAをクリップボードにコピー
<kbd>&lt;c-r&gt;</kbd>: reset cherry-picked (copied) commits selection
<kbd>ctrl+o</kbd>: コミットのSHAをクリップボードにコピー
<kbd>ctrl+r</kbd>: reset cherry-picked (copied) commits selection
<kbd>b</kbd>: view bisect options
<kbd>s</kbd>: squash down
<kbd>f</kbd>: fixup commit
@@ -85,50 +83,50 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>p</kbd>: pick commit (when mid-rebase)
<kbd>F</kbd>: このコミットに対するfixupコミットを作成
<kbd>S</kbd>: squash all 'fixup!' commits above selected commit (autosquash)
<kbd>&lt;c-j&gt;</kbd>: コミットを1つ下に移動
<kbd>&lt;c-k&gt;</kbd>: コミットを1つ上に移動
<kbd>ctrl+j</kbd>: コミットを1つ下に移動
<kbd>ctrl+k</kbd>: コミットを1つ上に移動
<kbd>v</kbd>: コミットを貼り付け (cherry-pick)
<kbd>A</kbd>: ステージされた変更でamendコミット
<kbd>a</kbd>: reset commit author
<kbd>t</kbd>: コミットをrevert
<kbd>T</kbd>: タグを作成
<kbd>&lt;c-l&gt;</kbd>: ログメニューを開く
<kbd>&lt;space&gt;</kbd>: コミットをチェックアウト
<kbd>ctrl+l</kbd>: ログメニューを開く
<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>&lt;enter&gt;</kbd>: view selected item's files
<kbd>enter</kbd>: view selected item's files
</pre>
## コミットファイル
<pre>
<kbd>&lt;c-o&gt;</kbd>: コミットされたファイル名をクリップボードにコピー
<kbd>ctrl+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>&lt;space&gt;</kbd>: toggle file included in patch
<kbd>space</kbd>: toggle file included in patch
<kbd>a</kbd>: toggle all files included in patch
<kbd>&lt;enter&gt;</kbd>: enter file to add selected lines to the patch (or toggle directory collapsed)
<kbd>enter</kbd>: enter file to add selected lines to the patch (or toggle directory collapsed)
<kbd>`</kbd>: ファイルツリーの表示を切り替え
</pre>
## コミットメッセージ
<pre>
<kbd>&lt;enter&gt;</kbd>: 確認
<kbd>&lt;esc&gt;</kbd>: 閉じる
<kbd>enter</kbd>: 確認
<kbd>esc</kbd>: 閉じる
</pre>
## サブモジュール
<pre>
<kbd>&lt;c-o&gt;</kbd>: サブモジュール名をクリップボードにコピー
<kbd>&lt;enter&gt;</kbd>: サブモジュールを開く
<kbd>ctrl+o</kbd>: サブモジュール名をクリップボードにコピー
<kbd>enter</kbd>: サブモジュールを開く
<kbd>d</kbd>: サブモジュールを削除
<kbd>u</kbd>: サブモジュールを更新
<kbd>n</kbd>: サブモジュールを新規追加
@@ -143,28 +141,28 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>o</kbd>: 設定ファイルを開く
<kbd>e</kbd>: 設定ファイルを編集
<kbd>u</kbd>: 更新を確認
<kbd>&lt;enter&gt;</kbd>: 最近使用したリポジトリに切り替え
<kbd>enter</kbd>: 最近使用したリポジトリに切り替え
<kbd>a</kbd>: すべてのブランチログを表示
</pre>
## タグ
<pre>
<kbd>&lt;space&gt;</kbd>: チェックアウト
<kbd>space</kbd>: チェックアウト
<kbd>d</kbd>: タグを削除
<kbd>P</kbd>: タグをpush
<kbd>n</kbd>: タグを作成
<kbd>g</kbd>: view reset options
<kbd>&lt;enter&gt;</kbd>: コミットを閲覧
<kbd>enter</kbd>: コミットを閲覧
</pre>
## ファイル
<pre>
<kbd>&lt;c-o&gt;</kbd>: ファイル名をクリップボードにコピー
<kbd>ctrl+o</kbd>: ファイル名をクリップボードにコピー
<kbd>d</kbd>: view 'discard changes' options
<kbd>&lt;space&gt;</kbd>: ステージ/アンステージ
<kbd>&lt;c-b&gt;</kbd>: ファイルをフィルタ (ステージ/アンステージ)
<kbd>space</kbd>: ステージ/アンステージ
<kbd>ctrl+b</kbd>: ファイルをフィルタ (ステージ/アンステージ)
<kbd>c</kbd>: 変更をコミット
<kbd>w</kbd>: pre-commitフックを実行せずに変更をコミット
<kbd>A</kbd>: 最新のコミットにamend
@@ -176,7 +174,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>s</kbd>: 変更をstash
<kbd>S</kbd>: view stash options
<kbd>a</kbd>: すべての変更をステージ/アンステージ
<kbd>&lt;enter&gt;</kbd>: stage individual hunks/lines for file, or collapse/expand for directory
<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>: ファイルツリーの表示を切り替え
@@ -187,13 +185,13 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## ブランチ
<pre>
<kbd>&lt;c-o&gt;</kbd>: ブランチ名をクリップボードにコピー
<kbd>ctrl+o</kbd>: ブランチ名をクリップボードにコピー
<kbd>i</kbd>: show git-flow options
<kbd>&lt;space&gt;</kbd>: チェックアウト
<kbd>space</kbd>: チェックアウト
<kbd>n</kbd>: 新しいブランチを作成
<kbd>o</kbd>: Pull Requestを作成
<kbd>O</kbd>: create pull request options
<kbd>&lt;c-y&gt;</kbd>: Pull RequestのURLをクリップボードにコピー
<kbd>ctrl+y</kbd>: Pull RequestのURLをクリップボードにコピー
<kbd>c</kbd>: checkout by name
<kbd>F</kbd>: force checkout
<kbd>d</kbd>: ブランチを削除
@@ -204,7 +202,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>g</kbd>: view reset options
<kbd>R</kbd>: ブランチ名を変更
<kbd>u</kbd>: set/unset upstream
<kbd>&lt;enter&gt;</kbd>: コミットを閲覧
<kbd>enter</kbd>: コミットを閲覧
</pre>
## メインパネル (Merging)
@@ -212,53 +210,53 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<pre>
<kbd>e</kbd>: ファイルを編集
<kbd>o</kbd>: ファイルを開く
<kbd>&lt;left&gt;</kbd>: 前のコンフリクトを選択
<kbd>&lt;right&gt;</kbd>: 次のコンフリクトを選択
<kbd>&lt;up&gt;</kbd>: 前のhunkを選択
<kbd>&lt;down&gt;</kbd>: 次のhunkを選択
<kbd>◀</kbd>: 前のコンフリクトを選択
<kbd>▶</kbd>: 次のコンフリクトを選択
<kbd>▲</kbd>: 前のhunkを選択
<kbd>▼</kbd>: 次のhunkを選択
<kbd>z</kbd>: アンドゥ
<kbd>M</kbd>: git mergetoolを開く
<kbd>&lt;space&gt;</kbd>: pick hunk
<kbd>space</kbd>: pick hunk
<kbd>b</kbd>: pick all hunks
<kbd>&lt;esc&gt;</kbd>: ファイル一覧に戻る
<kbd>esc</kbd>: ファイル一覧に戻る
</pre>
## メインパネル (Normal)
<pre>
<kbd>mouse wheel down</kbd>: 下にスクロール (fn+up)
<kbd>mouse wheel up</kbd>: 上にスクロール (fn+down)
<kbd>mouse wheel ▼</kbd>: 下にスクロール (fn+up)
<kbd>mouse wheel ▲</kbd>: 上にスクロール (fn+down)
</pre>
## メインパネル (Patch Building)
<pre>
<kbd>&lt;left&gt;</kbd>: 前のhunkを選択
<kbd>&lt;right&gt;</kbd>: 次のhunkを選択
<kbd>◀</kbd>: 前のhunkを選択
<kbd>▶</kbd>: 次のhunkを選択
<kbd>v</kbd>: 範囲選択を切り替え
<kbd>V</kbd>: 範囲選択を切り替え
<kbd>a</kbd>: hunk選択を切り替え
<kbd>&lt;c-o&gt;</kbd>: 選択されたテキストをクリップボードにコピー
<kbd>ctrl+o</kbd>: 選択されたテキストをクリップボードにコピー
<kbd>o</kbd>: ファイルを開く
<kbd>e</kbd>: ファイルを編集
<kbd>&lt;space&gt;</kbd>: 行をパッチに追加/削除
<kbd>&lt;esc&gt;</kbd>: exit custom patch builder
<kbd>space</kbd>: 行をパッチに追加/削除
<kbd>esc</kbd>: exit custom patch builder
</pre>
## メインパネル (Staging)
<pre>
<kbd>&lt;left&gt;</kbd>: 前のhunkを選択
<kbd>&lt;right&gt;</kbd>: 次のhunkを選択
<kbd>◀</kbd>: 前のhunkを選択
<kbd>▶</kbd>: 次のhunkを選択
<kbd>v</kbd>: 範囲選択を切り替え
<kbd>V</kbd>: 範囲選択を切り替え
<kbd>a</kbd>: hunk選択を切り替え
<kbd>&lt;c-o&gt;</kbd>: 選択されたテキストをクリップボードにコピー
<kbd>ctrl+o</kbd>: 選択されたテキストをクリップボードにコピー
<kbd>o</kbd>: ファイルを開く
<kbd>e</kbd>: ファイルを編集
<kbd>&lt;esc&gt;</kbd>: ファイル一覧に戻る
<kbd>&lt;tab&gt;</kbd>: パネルを切り替え
<kbd>&lt;space&gt;</kbd>: 選択行をステージ/アンステージ
<kbd>esc</kbd>: ファイル一覧に戻る
<kbd>tab</kbd>: パネルを切り替え
<kbd>space</kbd>: 選択行をステージ/アンステージ
<kbd>d</kbd>: 変更を削除 (git reset)
<kbd>E</kbd>: edit hunk
<kbd>c</kbd>: 変更をコミット
@@ -269,8 +267,8 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## メニュー
<pre>
<kbd>&lt;enter&gt;</kbd>: 実行
<kbd>&lt;esc&gt;</kbd>: 閉じる
<kbd>enter</kbd>: 実行
<kbd>esc</kbd>: 閉じる
</pre>
## リモート
@@ -285,36 +283,36 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## リモートブランチ
<pre>
<kbd>&lt;c-o&gt;</kbd>: ブランチ名をクリップボードにコピー
<kbd>&lt;space&gt;</kbd>: チェックアウト
<kbd>ctrl+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>&lt;esc&gt;</kbd>: リモート一覧に戻る
<kbd>esc</kbd>: リモート一覧に戻る
<kbd>g</kbd>: view reset options
<kbd>&lt;enter&gt;</kbd>: コミットを閲覧
<kbd>enter</kbd>: コミットを閲覧
</pre>
## 参照ログ
<pre>
<kbd>&lt;c-o&gt;</kbd>: コミットのSHAをクリップボードにコピー
<kbd>&lt;space&gt;</kbd>: コミットをチェックアウト
<kbd>ctrl+o</kbd>: コミットのSHAをクリップボードにコピー
<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>&lt;c-r&gt;</kbd>: reset cherry-picked (copied) commits selection
<kbd>&lt;enter&gt;</kbd>: コミットを閲覧
<kbd>ctrl+r</kbd>: reset cherry-picked (copied) commits selection
<kbd>enter</kbd>: コミットを閲覧
</pre>
## 確認パネル
<pre>
<kbd>&lt;enter&gt;</kbd>: 確認
<kbd>&lt;esc&gt;</kbd>: 閉じる/キャンセル
<kbd>enter</kbd>: 確認
<kbd>esc</kbd>: 閉じる/キャンセル
</pre>
+72 -74
View File
@@ -2,30 +2,28 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
# Lazygit 키 바인딩
_Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## 글로벌 키 바인딩
<pre>
<kbd>&lt;c-r&gt;</kbd>: 최근에 사용한 저장소로 전환
<kbd>&lt;pgup&gt;</kbd>: 메인 패널을 위로 스크롤 (fn+up/shift+k)
<kbd>&lt;pgdown&gt;</kbd>: 메인 패널을 아래로로 스크롤 (fn+down/shift+j)
<kbd>ctrl+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>&lt;c-p&gt;</kbd>: 커스텀 Patch 옵션 보기
<kbd>ctrl+p</kbd>: 커스텀 Patch 옵션 보기
<kbd>m</kbd>: view merge/rebase options
<kbd>R</kbd>: 새로고침
<kbd>+</kbd>: 다음 스크린 모드 (normal/half/fullscreen)
<kbd>_</kbd>: 이전 스크린 모드
<kbd>?</kbd>: 매뉴 열기
<kbd>&lt;c-s&gt;</kbd>: view filter-by-path options
<kbd>ctrl+s</kbd>: view filter-by-path options
<kbd>W</kbd>: Diff 메뉴 열기
<kbd>&lt;c-e&gt;</kbd>: Diff 메뉴 열기
<kbd>&lt;c-w&gt;</kbd>: 공백문자를 Diff 뷰에서 표시 여부 전환
<kbd>ctrl+e</kbd>: Diff 메뉴 열기
<kbd>ctrl+w</kbd>: 공백문자를 Diff 뷰에서 표시 여부 전환
<kbd>z</kbd>: 되돌리기 (reflog) (실험적)
<kbd>&lt;c-z&gt;</kbd>: 다시 실행 (reflog) (실험적)
<kbd>ctrl+z</kbd>: 다시 실행 (reflog) (실험적)
<kbd>P</kbd>: 푸시
<kbd>p</kbd>: 업데이트
</pre>
@@ -35,9 +33,9 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<pre>
<kbd>,</kbd>: 이전 페이지
<kbd>.</kbd>: 다음 페이지
<kbd>&lt;</kbd>: 맨 위로 스크롤
<kbd><</kbd>: 맨 위로 스크롤
<kbd>/</kbd>: 검색 시작
<kbd>&gt;</kbd>: 맨 아래로 스크롤
<kbd>></kbd>: 맨 아래로 스크롤
<kbd>H</kbd>: 우 스크롤
<kbd>L</kbd>: 좌 스크롤
<kbd>]</kbd>: 이전 탭
@@ -47,49 +45,49 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Reflog
<pre>
<kbd>&lt;c-o&gt;</kbd>: 커밋 SHA를 클립보드에 복사
<kbd>&lt;space&gt;</kbd>: 커밋을 체크아웃
<kbd>ctrl+o</kbd>: 커밋 SHA를 클립보드에 복사
<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>&lt;c-r&gt;</kbd>: reset cherry-picked (copied) commits selection
<kbd>&lt;enter&gt;</kbd>: 커밋 보기
<kbd>ctrl+r</kbd>: reset cherry-picked (copied) commits selection
<kbd>enter</kbd>: 커밋 보기
</pre>
## Stash
<pre>
<kbd>&lt;space&gt;</kbd>: 적용
<kbd>space</kbd>: 적용
<kbd>g</kbd>: pop
<kbd>d</kbd>: drop
<kbd>n</kbd>: 새 브랜치 생성
<kbd>r</kbd>: rename stash
<kbd>&lt;enter&gt;</kbd>: view selected item's files
<kbd>enter</kbd>: view selected item's files
</pre>
## Sub-commits
<pre>
<kbd>&lt;c-o&gt;</kbd>: 커밋 SHA를 클립보드에 복사
<kbd>&lt;space&gt;</kbd>: 커밋을 체크아웃
<kbd>ctrl+o</kbd>: 커밋 SHA를 클립보드에 복사
<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>&lt;c-r&gt;</kbd>: reset cherry-picked (copied) commits selection
<kbd>&lt;enter&gt;</kbd>: view selected item's files
<kbd>ctrl+r</kbd>: reset cherry-picked (copied) commits selection
<kbd>enter</kbd>: view selected item's files
</pre>
## 메뉴
<pre>
<kbd>&lt;enter&gt;</kbd>: 실행
<kbd>&lt;esc&gt;</kbd>: 닫기
<kbd>enter</kbd>: 실행
<kbd>esc</kbd>: 닫기
</pre>
## 메인 패널 (Merging)
@@ -97,53 +95,53 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<pre>
<kbd>e</kbd>: 파일 편집
<kbd>o</kbd>: 파일 닫기
<kbd>&lt;left&gt;</kbd>: 이전 충돌을 선택
<kbd>&lt;right&gt;</kbd>: 다음 충돌을 선택
<kbd>&lt;up&gt;</kbd>: 이전 hunk를 선택
<kbd>&lt;down&gt;</kbd>: 다음 hunk를 선택
<kbd>◀</kbd>: 이전 충돌을 선택
<kbd>▶</kbd>: 다음 충돌을 선택
<kbd>▲</kbd>: 이전 hunk를 선택
<kbd>▼</kbd>: 다음 hunk를 선택
<kbd>z</kbd>: 되돌리기
<kbd>M</kbd>: git mergetool를 열기
<kbd>&lt;space&gt;</kbd>: pick hunk
<kbd>space</kbd>: pick hunk
<kbd>b</kbd>: pick all hunks
<kbd>&lt;esc&gt;</kbd>: 파일 목록으로 돌아가기
<kbd>esc</kbd>: 파일 목록으로 돌아가기
</pre>
## 메인 패널 (Normal)
<pre>
<kbd>mouse wheel down</kbd>: 아래로 스크롤 (fn+up)
<kbd>mouse wheel up</kbd>: 위로 스크롤 (fn+down)
<kbd>mouse wheel ▼</kbd>: 아래로 스크롤 (fn+up)
<kbd>mouse wheel ▲</kbd>: 위로 스크롤 (fn+down)
</pre>
## 메인 패널 (Patch Building)
<pre>
<kbd>&lt;left&gt;</kbd>: 이전 hunk를 선택
<kbd>&lt;right&gt;</kbd>: 다음 hunk를 선택
<kbd>◀</kbd>: 이전 hunk를 선택
<kbd>▶</kbd>: 다음 hunk를 선택
<kbd>v</kbd>: 드래그 선택 전환
<kbd>V</kbd>: 드래그 선택 전환
<kbd>a</kbd>: toggle select hunk
<kbd>&lt;c-o&gt;</kbd>: 선택한 텍스트를 클립보드에 복사
<kbd>ctrl+o</kbd>: 선택한 텍스트를 클립보드에 복사
<kbd>o</kbd>: 파일 닫기
<kbd>e</kbd>: 파일 편집
<kbd>&lt;space&gt;</kbd>: line(s)을 패치에 추가/삭제
<kbd>&lt;esc&gt;</kbd>: exit custom patch builder
<kbd>space</kbd>: line(s)을 패치에 추가/삭제
<kbd>esc</kbd>: exit custom patch builder
</pre>
## 메인 패널 (Staging)
<pre>
<kbd>&lt;left&gt;</kbd>: 이전 hunk를 선택
<kbd>&lt;right&gt;</kbd>: 다음 hunk를 선택
<kbd>◀</kbd>: 이전 hunk를 선택
<kbd>▶</kbd>: 다음 hunk를 선택
<kbd>v</kbd>: 드래그 선택 전환
<kbd>V</kbd>: 드래그 선택 전환
<kbd>a</kbd>: toggle select hunk
<kbd>&lt;c-o&gt;</kbd>: 선택한 텍스트를 클립보드에 복사
<kbd>ctrl+o</kbd>: 선택한 텍스트를 클립보드에 복사
<kbd>o</kbd>: 파일 닫기
<kbd>e</kbd>: 파일 편집
<kbd>&lt;esc&gt;</kbd>: 파일 목록으로 돌아가기
<kbd>&lt;tab&gt;</kbd>: 패널 전환
<kbd>&lt;space&gt;</kbd>: 선택한 행을 staged / unstaged
<kbd>esc</kbd>: 파일 목록으로 돌아가기
<kbd>tab</kbd>: 패널 전환
<kbd>space</kbd>: 선택한 행을 staged / unstaged
<kbd>d</kbd>: 변경을 삭제 (git reset)
<kbd>E</kbd>: edit hunk
<kbd>c</kbd>: 커밋 변경내용
@@ -154,13 +152,13 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## 브랜치
<pre>
<kbd>&lt;c-o&gt;</kbd>: 브랜치명을 클립보드에 복사
<kbd>ctrl+o</kbd>: 브랜치명을 클립보드에 복사
<kbd>i</kbd>: git-flow 옵션 보기
<kbd>&lt;space&gt;</kbd>: 체크아웃
<kbd>space</kbd>: 체크아웃
<kbd>n</kbd>: 새 브랜치 생성
<kbd>o</kbd>: 풀 리퀘스트 생성
<kbd>O</kbd>: 풀 리퀘스트 생성 옵션
<kbd>&lt;c-y&gt;</kbd>: 풀 리퀘스트 URL을 클립보드에 복사
<kbd>ctrl+y</kbd>: 풀 리퀘스트 URL을 클립보드에 복사
<kbd>c</kbd>: 이름으로 체크아웃
<kbd>F</kbd>: 강제 체크아웃
<kbd>d</kbd>: 브랜치 삭제
@@ -171,7 +169,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>g</kbd>: view reset options
<kbd>R</kbd>: 브랜치 이름 변경
<kbd>u</kbd>: set/unset upstream
<kbd>&lt;enter&gt;</kbd>: 커밋 보기
<kbd>enter</kbd>: 커밋 보기
</pre>
## 상태
@@ -180,15 +178,15 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>o</kbd>: 설정 파일 열기
<kbd>e</kbd>: 설정 파일 수정
<kbd>u</kbd>: 업데이트 확인
<kbd>&lt;enter&gt;</kbd>: 최근에 사용한 저장소로 전환
<kbd>enter</kbd>: 최근에 사용한 저장소로 전환
<kbd>a</kbd>: 모든 브랜치 로그 표시
</pre>
## 서브모듈
<pre>
<kbd>&lt;c-o&gt;</kbd>: 서브모듈 이름을 클립보드에 복사
<kbd>&lt;enter&gt;</kbd>: 서브모듈 열기
<kbd>ctrl+o</kbd>: 서브모듈 이름을 클립보드에 복사
<kbd>enter</kbd>: 서브모듈 열기
<kbd>d</kbd>: 서브모듈 삭제
<kbd>u</kbd>: 서브모듈 업데이트
<kbd>n</kbd>: 새로운 서브모듈 추가
@@ -209,23 +207,23 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## 원격 브랜치
<pre>
<kbd>&lt;c-o&gt;</kbd>: 브랜치명을 클립보드에 복사
<kbd>&lt;space&gt;</kbd>: 체크아웃
<kbd>ctrl+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>&lt;esc&gt;</kbd>: 원격목록으로 돌아가기
<kbd>esc</kbd>: 원격목록으로 돌아가기
<kbd>g</kbd>: view reset options
<kbd>&lt;enter&gt;</kbd>: 커밋 보기
<kbd>enter</kbd>: 커밋 보기
</pre>
## 커밋
<pre>
<kbd>&lt;c-o&gt;</kbd>: 커밋 SHA를 클립보드에 복사
<kbd>&lt;c-r&gt;</kbd>: reset cherry-picked (copied) commits selection
<kbd>ctrl+o</kbd>: 커밋 SHA를 클립보드에 복사
<kbd>ctrl+r</kbd>: reset cherry-picked (copied) commits selection
<kbd>b</kbd>: bisect 옵션 보기
<kbd>s</kbd>: squash down
<kbd>f</kbd>: fixup commit
@@ -236,63 +234,63 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<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>&lt;c-j&gt;</kbd>: 커밋을 1개 아래로 이동
<kbd>&lt;c-k&gt;</kbd>: 커밋을 1개 위로 이동
<kbd>ctrl+j</kbd>: 커밋을 1개 아래로 이동
<kbd>ctrl+k</kbd>: 커밋을 1개 위로 이동
<kbd>v</kbd>: 커밋을 붙여넣기 (cherry-pick)
<kbd>A</kbd>: amend commit with staged changes
<kbd>a</kbd>: reset commit author
<kbd>t</kbd>: 커밋 되돌리기
<kbd>T</kbd>: tag commit
<kbd>&lt;c-l&gt;</kbd>: 로그 메뉴 열기
<kbd>&lt;space&gt;</kbd>: 커밋을 체크아웃
<kbd>ctrl+l</kbd>: 로그 메뉴 열기
<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>&lt;enter&gt;</kbd>: view selected item's files
<kbd>enter</kbd>: view selected item's files
</pre>
## 커밋 파일
<pre>
<kbd>&lt;c-o&gt;</kbd>: 커밋한 파일명을 클립보드에 복사
<kbd>ctrl+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>&lt;space&gt;</kbd>: toggle file included in patch
<kbd>space</kbd>: toggle file included in patch
<kbd>a</kbd>: toggle all files included in patch
<kbd>&lt;enter&gt;</kbd>: enter file to add selected lines to the patch (or toggle directory collapsed)
<kbd>enter</kbd>: enter file to add selected lines to the patch (or toggle directory collapsed)
<kbd>`</kbd>: 파일 트리뷰로 전환
</pre>
## 커밋메시지
<pre>
<kbd>&lt;enter&gt;</kbd>: 확인
<kbd>&lt;esc&gt;</kbd>: 닫기
<kbd>enter</kbd>: 확인
<kbd>esc</kbd>: 닫기
</pre>
## 태그
<pre>
<kbd>&lt;space&gt;</kbd>: 체크아웃
<kbd>space</kbd>: 체크아웃
<kbd>d</kbd>: 태그 삭제
<kbd>P</kbd>: 태그를 push
<kbd>n</kbd>: 태그를 생성
<kbd>g</kbd>: view reset options
<kbd>&lt;enter&gt;</kbd>: 커밋 보기
<kbd>enter</kbd>: 커밋 보기
</pre>
## 파일
<pre>
<kbd>&lt;c-o&gt;</kbd>: 파일명을 클립보드에 복사
<kbd>ctrl+o</kbd>: 파일명을 클립보드에 복사
<kbd>d</kbd>: view 'discard changes' options
<kbd>&lt;space&gt;</kbd>: Staged 전환
<kbd>&lt;c-b&gt;</kbd>: 파일을 필터하기 (Staged/unstaged)
<kbd>space</kbd>: Staged 전환
<kbd>ctrl+b</kbd>: 파일을 필터하기 (Staged/unstaged)
<kbd>c</kbd>: 커밋 변경내용
<kbd>w</kbd>: commit changes without pre-commit hook
<kbd>A</kbd>: 마지맛 커밋 수정
@@ -304,7 +302,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>s</kbd>: 변경사항을 Stash
<kbd>S</kbd>: Stash 옵션 보기
<kbd>a</kbd>: 모든 변경을 Staged/unstaged으로 전환
<kbd>&lt;enter&gt;</kbd>: stage individual hunks/lines for file, or collapse/expand for directory
<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>: 파일 트리뷰로 전환
@@ -315,6 +313,6 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## 확인 패널
<pre>
<kbd>&lt;enter&gt;</kbd>: 확인
<kbd>&lt;esc&gt;</kbd>: 닫기/취소
<kbd>enter</kbd>: 확인
<kbd>esc</kbd>: 닫기/취소
</pre>
+72 -74
View File
@@ -2,30 +2,28 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
# Lazygit Sneltoetsen
_Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Globale Sneltoetsen
<pre>
<kbd>&lt;c-r&gt;</kbd>: wissel naar een recente repo
<kbd>&lt;pgup&gt;</kbd>: scroll naar beneden vanaf hoofdpaneel (fn+up/shift+k)
<kbd>&lt;pgdown&gt;</kbd>: scroll naar beneden vanaf hoofdpaneel (fn+down/shift+j)
<kbd>ctrl+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>&lt;c-p&gt;</kbd>: bekijk aangepaste patch opties
<kbd>ctrl+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>&lt;c-s&gt;</kbd>: bekijk scoping opties
<kbd>ctrl+s</kbd>: bekijk scoping opties
<kbd>W</kbd>: open diff menu
<kbd>&lt;c-e&gt;</kbd>: open diff menu
<kbd>&lt;c-w&gt;</kbd>: Toggle whether or not whitespace changes are shown in the diff view
<kbd>ctrl+e</kbd>: open diff menu
<kbd>ctrl+w</kbd>: Toggle whether or not whitespace changes are shown in the diff view
<kbd>z</kbd>: ongedaan maken (via reflog) (experimenteel)
<kbd>&lt;c-z&gt;</kbd>: redo (via reflog) (experimenteel)
<kbd>ctrl+z</kbd>: redo (via reflog) (experimenteel)
<kbd>P</kbd>: push
<kbd>p</kbd>: pull
</pre>
@@ -35,9 +33,9 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<pre>
<kbd>,</kbd>: vorige pagina
<kbd>.</kbd>: volgende pagina
<kbd>&lt;</kbd>: scroll naar boven
<kbd><</kbd>: scroll naar boven
<kbd>/</kbd>: start met zoeken
<kbd>&gt;</kbd>: scroll naar beneden
<kbd>></kbd>: scroll naar beneden
<kbd>H</kbd>: scroll left
<kbd>L</kbd>: scroll right
<kbd>]</kbd>: volgende tabblad
@@ -47,10 +45,10 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Bestanden
<pre>
<kbd>&lt;c-o&gt;</kbd>: kopieer de bestandsnaam naar het klembord
<kbd>ctrl+o</kbd>: kopieer de bestandsnaam naar het klembord
<kbd>d</kbd>: bekijk 'veranderingen ongedaan maken' opties
<kbd>&lt;space&gt;</kbd>: toggle staged
<kbd>&lt;c-b&gt;</kbd>: Filter files (staged/unstaged)
<kbd>space</kbd>: toggle staged
<kbd>ctrl+b</kbd>: Filter files (staged/unstaged)
<kbd>c</kbd>: commit veranderingen
<kbd>w</kbd>: commit veranderingen zonder pre-commit hook
<kbd>A</kbd>: wijzig laatste commit
@@ -62,7 +60,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>s</kbd>: stash-bestanden
<kbd>S</kbd>: bekijk stash opties
<kbd>a</kbd>: toggle staged alle
<kbd>&lt;enter&gt;</kbd>: stage individuele hunks/lijnen
<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
@@ -73,20 +71,20 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Bevestigingspaneel
<pre>
<kbd>&lt;enter&gt;</kbd>: bevestig
<kbd>&lt;esc&gt;</kbd>: sluiten
<kbd>enter</kbd>: bevestig
<kbd>esc</kbd>: sluiten
</pre>
## Branches
<pre>
<kbd>&lt;c-o&gt;</kbd>: kopieer branch name naar klembord
<kbd>ctrl+o</kbd>: kopieer branch name naar klembord
<kbd>i</kbd>: laat git-flow opties zien
<kbd>&lt;space&gt;</kbd>: uitchecken
<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>&lt;c-y&gt;</kbd>: kopieer de URL van het pull-verzoek naar het klembord
<kbd>ctrl+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
@@ -97,35 +95,35 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>g</kbd>: bekijk reset opties
<kbd>R</kbd>: hernoem branch
<kbd>u</kbd>: set/unset upstream
<kbd>&lt;enter&gt;</kbd>: bekijk commits
<kbd>enter</kbd>: bekijk commits
</pre>
## Commit Bericht
<pre>
<kbd>&lt;enter&gt;</kbd>: bevestig
<kbd>&lt;esc&gt;</kbd>: sluiten
<kbd>enter</kbd>: bevestig
<kbd>esc</kbd>: sluiten
</pre>
## Commit bestanden
<pre>
<kbd>&lt;c-o&gt;</kbd>: kopieer de vastgelegde bestandsnaam naar het klembord
<kbd>ctrl+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>&lt;space&gt;</kbd>: toggle bestand inbegrepen in patch
<kbd>space</kbd>: toggle bestand inbegrepen in patch
<kbd>a</kbd>: toggle all files included in patch
<kbd>&lt;enter&gt;</kbd>: enter bestand om geselecteerde regels toe te voegen aan de patch
<kbd>enter</kbd>: enter bestand om geselecteerde regels toe te voegen aan de patch
<kbd>`</kbd>: toggle bestandsboom weergave
</pre>
## Commits
<pre>
<kbd>&lt;c-o&gt;</kbd>: kopieer commit SHA naar klembord
<kbd>&lt;c-r&gt;</kbd>: reset cherry-picked (gekopieerde) commits selectie
<kbd>ctrl+o</kbd>: kopieer commit SHA naar klembord
<kbd>ctrl+r</kbd>: reset cherry-picked (gekopieerde) commits selectie
<kbd>b</kbd>: view bisect options
<kbd>s</kbd>: squash beneden
<kbd>f</kbd>: Fixup commit
@@ -136,29 +134,29 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>p</kbd>: kies commit (wanneer midden in rebase)
<kbd>F</kbd>: creëer fixup commit voor deze commit
<kbd>S</kbd>: squash bovenstaande commits
<kbd>&lt;c-j&gt;</kbd>: verplaats commit 1 naar beneden
<kbd>&lt;c-k&gt;</kbd>: verplaats commit 1 naar boven
<kbd>ctrl+j</kbd>: verplaats commit 1 naar beneden
<kbd>ctrl+k</kbd>: verplaats commit 1 naar boven
<kbd>v</kbd>: plak commits (cherry-pick)
<kbd>A</kbd>: wijzig commit met staged veranderingen
<kbd>a</kbd>: reset commit author
<kbd>t</kbd>: commit ongedaan maken
<kbd>T</kbd>: tag commit
<kbd>&lt;c-l&gt;</kbd>: open log menu
<kbd>&lt;space&gt;</kbd>: checkout commit
<kbd>ctrl+l</kbd>: open log menu
<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>&lt;enter&gt;</kbd>: bekijk gecommite bestanden
<kbd>enter</kbd>: bekijk gecommite bestanden
</pre>
## Menu
<pre>
<kbd>&lt;enter&gt;</kbd>: uitvoeren
<kbd>&lt;esc&gt;</kbd>: sluiten
<kbd>enter</kbd>: uitvoeren
<kbd>esc</kbd>: sluiten
</pre>
## Mergen
@@ -166,67 +164,67 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<pre>
<kbd>e</kbd>: verander bestand
<kbd>o</kbd>: open bestand
<kbd>&lt;left&gt;</kbd>: selecteer voorgaand conflict
<kbd>&lt;right&gt;</kbd>: selecteer volgende conflict
<kbd>&lt;up&gt;</kbd>: selecteer bovenste hunk
<kbd>&lt;down&gt;</kbd>: selecteer onderste hunk
<kbd>◀</kbd>: selecteer voorgaand conflict
<kbd>▶</kbd>: selecteer volgende conflict
<kbd>▲</kbd>: selecteer bovenste hunk
<kbd>▼</kbd>: selecteer onderste hunk
<kbd>z</kbd>: ongedaan maken
<kbd>M</kbd>: open external merge tool (git mergetool)
<kbd>&lt;space&gt;</kbd>: kies hunk
<kbd>space</kbd>: kies hunk
<kbd>b</kbd>: kies bijde hunks
<kbd>&lt;esc&gt;</kbd>: ga terug naar het bestanden paneel
<kbd>esc</kbd>: ga terug naar het bestanden paneel
</pre>
## Normaal
<pre>
<kbd>mouse wheel down</kbd>: scroll omlaag (fn+up)
<kbd>mouse wheel up</kbd>: scroll omhoog (fn+down)
<kbd>mouse wheel ▼</kbd>: scroll omlaag (fn+up)
<kbd>mouse wheel ▲</kbd>: scroll omhoog (fn+down)
</pre>
## Patch Bouwen
<pre>
<kbd>&lt;left&gt;</kbd>: selecteer de vorige hunk
<kbd>&lt;right&gt;</kbd>: selecteer de volgende hunk
<kbd>◀</kbd>: selecteer de vorige hunk
<kbd>▶</kbd>: selecteer de volgende hunk
<kbd>v</kbd>: toggle drag selecteer
<kbd>V</kbd>: toggle drag selecteer
<kbd>a</kbd>: toggle selecteer hunk
<kbd>&lt;c-o&gt;</kbd>: copy the selected text to the clipboard
<kbd>ctrl+o</kbd>: copy the selected text to the clipboard
<kbd>o</kbd>: open bestand
<kbd>e</kbd>: verander bestand
<kbd>&lt;space&gt;</kbd>: voeg toe/verwijder lijn(en) in patch
<kbd>&lt;esc&gt;</kbd>: sluit lijn-bij-lijn modus
<kbd>space</kbd>: voeg toe/verwijder lijn(en) in patch
<kbd>esc</kbd>: sluit lijn-bij-lijn modus
</pre>
## Reflog
<pre>
<kbd>&lt;c-o&gt;</kbd>: kopieer commit SHA naar klembord
<kbd>&lt;space&gt;</kbd>: checkout commit
<kbd>ctrl+o</kbd>: kopieer commit SHA naar klembord
<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>&lt;c-r&gt;</kbd>: reset cherry-picked (gekopieerde) commits selectie
<kbd>&lt;enter&gt;</kbd>: bekijk commits
<kbd>ctrl+r</kbd>: reset cherry-picked (gekopieerde) commits selectie
<kbd>enter</kbd>: bekijk commits
</pre>
## Remote Branches
<pre>
<kbd>&lt;c-o&gt;</kbd>: kopieer branch name naar klembord
<kbd>&lt;space&gt;</kbd>: uitchecken
<kbd>ctrl+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>&lt;esc&gt;</kbd>: ga terug naar remotes lijst
<kbd>esc</kbd>: ga terug naar remotes lijst
<kbd>g</kbd>: bekijk reset opties
<kbd>&lt;enter&gt;</kbd>: bekijk commits
<kbd>enter</kbd>: bekijk commits
</pre>
## Remotes
@@ -241,17 +239,17 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Staging
<pre>
<kbd>&lt;left&gt;</kbd>: selecteer de vorige hunk
<kbd>&lt;right&gt;</kbd>: selecteer de volgende hunk
<kbd>◀</kbd>: selecteer de vorige hunk
<kbd>▶</kbd>: selecteer de volgende hunk
<kbd>v</kbd>: toggle drag selecteer
<kbd>V</kbd>: toggle drag selecteer
<kbd>a</kbd>: toggle selecteer hunk
<kbd>&lt;c-o&gt;</kbd>: copy the selected text to the clipboard
<kbd>ctrl+o</kbd>: copy the selected text to the clipboard
<kbd>o</kbd>: open bestand
<kbd>e</kbd>: verander bestand
<kbd>&lt;esc&gt;</kbd>: ga terug naar het bestanden paneel
<kbd>&lt;tab&gt;</kbd>: ga naar een ander paneel
<kbd>&lt;space&gt;</kbd>: toggle lijnen staged / unstaged
<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
@@ -262,12 +260,12 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Stash
<pre>
<kbd>&lt;space&gt;</kbd>: toepassen
<kbd>space</kbd>: toepassen
<kbd>g</kbd>: pop
<kbd>d</kbd>: laten vallen
<kbd>n</kbd>: nieuwe branch
<kbd>r</kbd>: rename stash
<kbd>&lt;enter&gt;</kbd>: bekijk gecommite bestanden
<kbd>enter</kbd>: bekijk gecommite bestanden
</pre>
## Status
@@ -276,30 +274,30 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>o</kbd>: open config bestand
<kbd>e</kbd>: verander config bestand
<kbd>u</kbd>: check voor updates
<kbd>&lt;enter&gt;</kbd>: wissel naar een recente repo
<kbd>enter</kbd>: wissel naar een recente repo
<kbd>a</kbd>: alle logs van de branch laten zien
</pre>
## Sub-commits
<pre>
<kbd>&lt;c-o&gt;</kbd>: kopieer commit SHA naar klembord
<kbd>&lt;space&gt;</kbd>: checkout commit
<kbd>ctrl+o</kbd>: kopieer commit SHA naar klembord
<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>&lt;c-r&gt;</kbd>: reset cherry-picked (gekopieerde) commits selectie
<kbd>&lt;enter&gt;</kbd>: bekijk gecommite bestanden
<kbd>ctrl+r</kbd>: reset cherry-picked (gekopieerde) commits selectie
<kbd>enter</kbd>: bekijk gecommite bestanden
</pre>
## Submodules
<pre>
<kbd>&lt;c-o&gt;</kbd>: kopieer submodule naam naar klembord
<kbd>&lt;enter&gt;</kbd>: enter submodule
<kbd>ctrl+o</kbd>: kopieer submodule naam naar klembord
<kbd>enter</kbd>: enter submodule
<kbd>d</kbd>: remove submodule
<kbd>u</kbd>: update submodule
<kbd>n</kbd>: voeg nieuwe submodule toe
@@ -311,10 +309,10 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Tags
<pre>
<kbd>&lt;space&gt;</kbd>: uitchecken
<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>&lt;enter&gt;</kbd>: bekijk commits
<kbd>enter</kbd>: bekijk commits
</pre>
+72 -74
View File
@@ -2,30 +2,28 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
# Lazygit Keybindings
_Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Globalne
<pre>
<kbd>&lt;c-r&gt;</kbd>: switch to a recent repo
<kbd>&lt;pgup&gt;</kbd>: scroll up main panel (fn+up/shift+k)
<kbd>&lt;pgdown&gt;</kbd>: scroll down main panel (fn+down/shift+j)
<kbd>ctrl+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>&lt;c-p&gt;</kbd>: view custom patch options
<kbd>ctrl+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>&lt;c-s&gt;</kbd>: view filter-by-path options
<kbd>ctrl+s</kbd>: view filter-by-path options
<kbd>W</kbd>: open diff menu
<kbd>&lt;c-e&gt;</kbd>: open diff menu
<kbd>&lt;c-w&gt;</kbd>: Toggle whether or not whitespace changes are shown in the diff view
<kbd>ctrl+e</kbd>: open diff menu
<kbd>ctrl+w</kbd>: Toggle whether or not whitespace changes are shown in the diff view
<kbd>z</kbd>: undo (via reflog) (experimental)
<kbd>&lt;c-z&gt;</kbd>: redo (via reflog) (experimental)
<kbd>ctrl+z</kbd>: redo (via reflog) (experimental)
<kbd>P</kbd>: push
<kbd>p</kbd>: pull
</pre>
@@ -35,9 +33,9 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<pre>
<kbd>,</kbd>: previous page
<kbd>.</kbd>: next page
<kbd>&lt;</kbd>: scroll to top
<kbd><</kbd>: scroll to top
<kbd>/</kbd>: start search
<kbd>&gt;</kbd>: scroll to bottom
<kbd>></kbd>: scroll to bottom
<kbd>H</kbd>: scroll left
<kbd>L</kbd>: scroll right
<kbd>]</kbd>: next tab
@@ -47,15 +45,15 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Commit Summary
<pre>
<kbd>&lt;enter&gt;</kbd>: potwierdź
<kbd>&lt;esc&gt;</kbd>: zamknij
<kbd>enter</kbd>: potwierdź
<kbd>esc</kbd>: zamknij
</pre>
## Commity
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy commit SHA to clipboard
<kbd>&lt;c-r&gt;</kbd>: reset cherry-picked (copied) commits selection
<kbd>ctrl+o</kbd>: copy commit SHA to clipboard
<kbd>ctrl+r</kbd>: reset cherry-picked (copied) commits selection
<kbd>b</kbd>: view bisect options
<kbd>s</kbd>: ściśnij
<kbd>f</kbd>: napraw commit
@@ -66,41 +64,41 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<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>&lt;c-j&gt;</kbd>: przenieś commit 1 w dół
<kbd>&lt;c-k&gt;</kbd>: przenieś commit 1 w górę
<kbd>ctrl+j</kbd>: przenieś commit 1 w dół
<kbd>ctrl+k</kbd>: przenieś commit 1 w górę
<kbd>v</kbd>: wklej commity (przebieranie)
<kbd>A</kbd>: popraw commit zmianami z poczekalni
<kbd>a</kbd>: reset commit author
<kbd>t</kbd>: odwróć commit
<kbd>T</kbd>: tag commit
<kbd>&lt;c-l&gt;</kbd>: open log menu
<kbd>&lt;space&gt;</kbd>: checkout commit
<kbd>ctrl+l</kbd>: open log menu
<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>&lt;enter&gt;</kbd>: przeglądaj pliki commita
<kbd>enter</kbd>: przeglądaj pliki commita
</pre>
## Confirmation Panel
<pre>
<kbd>&lt;enter&gt;</kbd>: potwierdź
<kbd>&lt;esc&gt;</kbd>: zamknij
<kbd>enter</kbd>: potwierdź
<kbd>esc</kbd>: zamknij
</pre>
## Local Branches
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy branch name to clipboard
<kbd>ctrl+o</kbd>: copy branch name to clipboard
<kbd>i</kbd>: show git-flow options
<kbd>&lt;space&gt;</kbd>: przełącz
<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>&lt;c-y&gt;</kbd>: skopiuj adres URL żądania pobrania do schowka
<kbd>ctrl+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łąź
@@ -111,38 +109,38 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>g</kbd>: wyświetl opcje resetu
<kbd>R</kbd>: rename branch
<kbd>u</kbd>: set/unset upstream
<kbd>&lt;enter&gt;</kbd>: view commits
<kbd>enter</kbd>: view commits
</pre>
## Main Panel (Patch Building)
<pre>
<kbd>&lt;left&gt;</kbd>: poprzedni kawałek
<kbd>&lt;right&gt;</kbd>: następny kawałek
<kbd>◀</kbd>: poprzedni kawałek
<kbd>▶</kbd>: następny kawałek
<kbd>v</kbd>: toggle drag select
<kbd>V</kbd>: toggle drag select
<kbd>a</kbd>: toggle select hunk
<kbd>&lt;c-o&gt;</kbd>: copy the selected text to the clipboard
<kbd>ctrl+o</kbd>: copy the selected text to the clipboard
<kbd>o</kbd>: otwórz plik
<kbd>e</kbd>: edytuj plik
<kbd>&lt;space&gt;</kbd>: add/remove line(s) to patch
<kbd>&lt;esc&gt;</kbd>: wyście z trybu "linia po linii"
<kbd>space</kbd>: add/remove line(s) to patch
<kbd>esc</kbd>: wyście z trybu "linia po linii"
</pre>
## Menu
<pre>
<kbd>&lt;enter&gt;</kbd>: wykonaj
<kbd>&lt;esc&gt;</kbd>: zamknij
<kbd>enter</kbd>: wykonaj
<kbd>esc</kbd>: zamknij
</pre>
## Pliki
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy the file name to the clipboard
<kbd>ctrl+o</kbd>: copy the file name to the clipboard
<kbd>d</kbd>: pokaż opcje porzucania zmian
<kbd>&lt;space&gt;</kbd>: przełącz stan poczekalni
<kbd>&lt;c-b&gt;</kbd>: Filter files (staged/unstaged)
<kbd>space</kbd>: przełącz stan poczekalni
<kbd>ctrl+b</kbd>: Filter files (staged/unstaged)
<kbd>c</kbd>: Zatwierdź zmiany
<kbd>w</kbd>: zatwierdź zmiany bez skryptu pre-commit
<kbd>A</kbd>: Zmień ostatni commit
@@ -154,7 +152,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>s</kbd>: przechowaj zmiany
<kbd>S</kbd>: wyświetl opcje schowka
<kbd>a</kbd>: przełącz stan poczekalni wszystkich
<kbd>&lt;enter&gt;</kbd>: zatwierdź pojedyncze linie
<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
@@ -165,31 +163,31 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Pliki commita
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy the committed file name to the clipboard
<kbd>ctrl+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>&lt;space&gt;</kbd>: toggle file included in patch
<kbd>space</kbd>: toggle file included in patch
<kbd>a</kbd>: toggle all files included in patch
<kbd>&lt;enter&gt;</kbd>: enter file to add selected lines to the patch (or toggle directory collapsed)
<kbd>enter</kbd>: enter file to add selected lines to the patch (or toggle directory collapsed)
<kbd>`</kbd>: toggle file tree view
</pre>
## Poczekalnia
<pre>
<kbd>&lt;left&gt;</kbd>: poprzedni kawałek
<kbd>&lt;right&gt;</kbd>: następny kawałek
<kbd>◀</kbd>: poprzedni kawałek
<kbd>▶</kbd>: następny kawałek
<kbd>v</kbd>: toggle drag select
<kbd>V</kbd>: toggle drag select
<kbd>a</kbd>: toggle select hunk
<kbd>&lt;c-o&gt;</kbd>: copy the selected text to the clipboard
<kbd>ctrl+o</kbd>: copy the selected text to the clipboard
<kbd>o</kbd>: otwórz plik
<kbd>e</kbd>: edytuj plik
<kbd>&lt;esc&gt;</kbd>: wróć do panelu plików
<kbd>&lt;tab&gt;</kbd>: switch to other panel (staged/unstaged changes)
<kbd>&lt;space&gt;</kbd>: toggle line staged / unstaged
<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>: delete change (git reset)
<kbd>E</kbd>: edit hunk
<kbd>c</kbd>: Zatwierdź zmiany
@@ -200,31 +198,31 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Reflog
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy commit SHA to clipboard
<kbd>&lt;space&gt;</kbd>: checkout commit
<kbd>ctrl+o</kbd>: copy commit SHA to clipboard
<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>&lt;c-r&gt;</kbd>: reset cherry-picked (copied) commits selection
<kbd>&lt;enter&gt;</kbd>: view commits
<kbd>ctrl+r</kbd>: reset cherry-picked (copied) commits selection
<kbd>enter</kbd>: view commits
</pre>
## Remote Branches
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy branch name to clipboard
<kbd>&lt;space&gt;</kbd>: przełącz
<kbd>ctrl+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>&lt;esc&gt;</kbd>: wróć do listy repozytoriów zdalnych
<kbd>esc</kbd>: wróć do listy repozytoriów zdalnych
<kbd>g</kbd>: wyświetl opcje resetu
<kbd>&lt;enter&gt;</kbd>: view commits
<kbd>enter</kbd>: view commits
</pre>
## Remotes
@@ -241,26 +239,26 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<pre>
<kbd>e</kbd>: edytuj plik
<kbd>o</kbd>: otwórz plik
<kbd>&lt;left&gt;</kbd>: poprzedni konflikt
<kbd>&lt;right&gt;</kbd>: następny konflikt
<kbd>&lt;up&gt;</kbd>: wybierz poprzedni kawałek
<kbd>&lt;down&gt;</kbd>: wybierz następny kawałek
<kbd>◀</kbd>: poprzedni konflikt
<kbd>▶</kbd>: następny konflikt
<kbd>▲</kbd>: wybierz poprzedni kawałek
<kbd>▼</kbd>: wybierz następny kawałek
<kbd>z</kbd>: cofnij
<kbd>M</kbd>: open external merge tool (git mergetool)
<kbd>&lt;space&gt;</kbd>: wybierz kawałek
<kbd>space</kbd>: wybierz kawałek
<kbd>b</kbd>: wybierz wszystkie kawałki
<kbd>&lt;esc&gt;</kbd>: wróć do panelu plików
<kbd>esc</kbd>: wróć do panelu plików
</pre>
## Schowek
<pre>
<kbd>&lt;space&gt;</kbd>: zastosuj
<kbd>space</kbd>: zastosuj
<kbd>g</kbd>: wyciągnij
<kbd>d</kbd>: porzuć
<kbd>n</kbd>: nowa gałąź
<kbd>r</kbd>: rename stash
<kbd>&lt;enter&gt;</kbd>: przeglądaj pliki commita
<kbd>enter</kbd>: przeglądaj pliki commita
</pre>
## Status
@@ -269,30 +267,30 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>o</kbd>: otwórz konfigurację
<kbd>e</kbd>: edytuj konfigurację
<kbd>u</kbd>: sprawdź aktualizacje
<kbd>&lt;enter&gt;</kbd>: switch to a recent repo
<kbd>enter</kbd>: switch to a recent repo
<kbd>a</kbd>: pokaż wszystkie logi gałęzi
</pre>
## Sub-commits
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy commit SHA to clipboard
<kbd>&lt;space&gt;</kbd>: checkout commit
<kbd>ctrl+o</kbd>: copy commit SHA to clipboard
<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>&lt;c-r&gt;</kbd>: reset cherry-picked (copied) commits selection
<kbd>&lt;enter&gt;</kbd>: przeglądaj pliki commita
<kbd>ctrl+r</kbd>: reset cherry-picked (copied) commits selection
<kbd>enter</kbd>: przeglądaj pliki commita
</pre>
## Submodules
<pre>
<kbd>&lt;c-o&gt;</kbd>: copy submodule name to clipboard
<kbd>&lt;enter&gt;</kbd>: enter submodule
<kbd>ctrl+o</kbd>: copy submodule name to clipboard
<kbd>enter</kbd>: enter submodule
<kbd>d</kbd>: remove submodule
<kbd>u</kbd>: update submodule
<kbd>n</kbd>: add new submodule
@@ -304,17 +302,17 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Tags
<pre>
<kbd>&lt;space&gt;</kbd>: przełącz
<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>&lt;enter&gt;</kbd>: view commits
<kbd>enter</kbd>: view commits
</pre>
## Zwykłe
<pre>
<kbd>mouse wheel down</kbd>: przewiń w dół (fn+up)
<kbd>mouse wheel up</kbd>: przewiń w górę (fn+down)
<kbd>mouse wheel ▼</kbd>: przewiń w dół (fn+up)
<kbd>mouse wheel ▲</kbd>: przewiń w górę (fn+down)
</pre>
+72 -74
View File
@@ -2,30 +2,28 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
# Lazygit 按键绑定
_Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## 全局键绑定
<pre>
<kbd>&lt;c-r&gt;</kbd>: 切换到最近的仓库
<kbd>&lt;pgup&gt;</kbd>: 向上滚动主面板 (fn+up/shift+k)
<kbd>&lt;pgdown&gt;</kbd>: 向下滚动主面板 (fn+down/shift+j)
<kbd>ctrl+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>&lt;c-p&gt;</kbd>: 查看自定义补丁选项
<kbd>ctrl+p</kbd>: 查看自定义补丁选项
<kbd>m</kbd>: 查看 合并/变基 选项
<kbd>R</kbd>: 刷新
<kbd>+</kbd>: 下一屏模式(正常/半屏/全屏)
<kbd>_</kbd>: 上一屏模式
<kbd>?</kbd>: 打开菜单
<kbd>&lt;c-s&gt;</kbd>: 查看按路径过滤选项
<kbd>ctrl+s</kbd>: 查看按路径过滤选项
<kbd>W</kbd>: 打开 diff 菜单
<kbd>&lt;c-e&gt;</kbd>: 打开 diff 菜单
<kbd>&lt;c-w&gt;</kbd>: 切换是否在差异视图中显示空白字符差异
<kbd>ctrl+e</kbd>: 打开 diff 菜单
<kbd>ctrl+w</kbd>: 切换是否在差异视图中显示空白字符差异
<kbd>z</kbd>: (通过 reflog)撤销「实验功能」
<kbd>&lt;c-z&gt;</kbd>: (通过 reflog)重做「实验功能」
<kbd>ctrl+z</kbd>: (通过 reflog)重做「实验功能」
<kbd>P</kbd>: 推送
<kbd>p</kbd>: 拉取
</pre>
@@ -35,9 +33,9 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<pre>
<kbd>,</kbd>: 上一页
<kbd>.</kbd>: 下一页
<kbd>&lt;</kbd>: 滚动到顶部
<kbd><</kbd>: 滚动到顶部
<kbd>/</kbd>: 开始搜索
<kbd>&gt;</kbd>: 滚动到底部
<kbd>></kbd>: 滚动到底部
<kbd>H</kbd>: 向左滚动
<kbd>L</kbd>: 向右滚动
<kbd>]</kbd>: 下一个标签
@@ -47,28 +45,28 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## Reflog 页面
<pre>
<kbd>&lt;c-o&gt;</kbd>: 将提交的 SHA 复制到剪贴板
<kbd>&lt;space&gt;</kbd>: 检出提交
<kbd>ctrl+o</kbd>: 将提交的 SHA 复制到剪贴板
<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>&lt;c-r&gt;</kbd>: 重置已拣选(复制)的提交
<kbd>&lt;enter&gt;</kbd>: 查看提交
<kbd>ctrl+r</kbd>: 重置已拣选(复制)的提交
<kbd>enter</kbd>: 查看提交
</pre>
## 分支页面
<pre>
<kbd>&lt;c-o&gt;</kbd>: 将分支名称复制到剪贴板
<kbd>ctrl+o</kbd>: 将分支名称复制到剪贴板
<kbd>i</kbd>: 显示 git-flow 选项
<kbd>&lt;space&gt;</kbd>: 检出
<kbd>space</kbd>: 检出
<kbd>n</kbd>: 新分支
<kbd>o</kbd>: 创建抓取请求
<kbd>O</kbd>: 创建抓取请求选项
<kbd>&lt;c-y&gt;</kbd>: 将抓取请求 URL 复制到剪贴板
<kbd>ctrl+y</kbd>: 将抓取请求 URL 复制到剪贴板
<kbd>c</kbd>: 按名称检出
<kbd>F</kbd>: 强制检出
<kbd>d</kbd>: 删除分支
@@ -79,29 +77,29 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>g</kbd>: 查看重置选项
<kbd>R</kbd>: 重命名分支
<kbd>u</kbd>: set/unset upstream
<kbd>&lt;enter&gt;</kbd>: 查看提交
<kbd>enter</kbd>: 查看提交
</pre>
## 子提交
<pre>
<kbd>&lt;c-o&gt;</kbd>: 将提交的 SHA 复制到剪贴板
<kbd>&lt;space&gt;</kbd>: 检出提交
<kbd>ctrl+o</kbd>: 将提交的 SHA 复制到剪贴板
<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>&lt;c-r&gt;</kbd>: 重置已拣选(复制)的提交
<kbd>&lt;enter&gt;</kbd>: 查看提交的文件
<kbd>ctrl+r</kbd>: 重置已拣选(复制)的提交
<kbd>enter</kbd>: 查看提交的文件
</pre>
## 子模块
<pre>
<kbd>&lt;c-o&gt;</kbd>: 将子模块名称复制到剪贴板
<kbd>&lt;enter&gt;</kbd>: 输入子模块
<kbd>ctrl+o</kbd>: 将子模块名称复制到剪贴板
<kbd>enter</kbd>: 输入子模块
<kbd>d</kbd>: 删除子模块
<kbd>u</kbd>: 更新子模块
<kbd>n</kbd>: 添加新的子模块
@@ -113,8 +111,8 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## 提交
<pre>
<kbd>&lt;c-o&gt;</kbd>: 将提交的 SHA 复制到剪贴板
<kbd>&lt;c-r&gt;</kbd>: 重置已拣选(复制)的提交
<kbd>ctrl+o</kbd>: 将提交的 SHA 复制到剪贴板
<kbd>ctrl+r</kbd>: 重置已拣选(复制)的提交
<kbd>b</kbd>: 查看二分查找选项
<kbd>s</kbd>: 向下压缩
<kbd>f</kbd>: 修正提交(fixup)
@@ -125,52 +123,52 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>p</kbd>: 选择提交(变基过程中)
<kbd>F</kbd>: 为此提交创建修正
<kbd>S</kbd>: 压缩在所选提交之上的所有“fixup!”提交(自动压缩)
<kbd>&lt;c-j&gt;</kbd>: 下移提交
<kbd>&lt;c-k&gt;</kbd>: 上移提交
<kbd>ctrl+j</kbd>: 下移提交
<kbd>ctrl+k</kbd>: 上移提交
<kbd>v</kbd>: 粘贴提交(拣选)
<kbd>A</kbd>: 用已暂存的更改来修补提交
<kbd>a</kbd>: reset commit author
<kbd>t</kbd>: 还原提交
<kbd>T</kbd>: 标签提交
<kbd>&lt;c-l&gt;</kbd>: 打开日志菜单
<kbd>&lt;space&gt;</kbd>: 检出提交
<kbd>ctrl+l</kbd>: 打开日志菜单
<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>&lt;enter&gt;</kbd>: 查看提交的文件
<kbd>enter</kbd>: 查看提交的文件
</pre>
## 提交文件
<pre>
<kbd>&lt;c-o&gt;</kbd>: 将提交的文件名复制到剪贴板
<kbd>ctrl+o</kbd>: 将提交的文件名复制到剪贴板
<kbd>c</kbd>: 检出文件
<kbd>d</kbd>: 放弃对此文件的提交更改
<kbd>o</kbd>: 打开文件
<kbd>e</kbd>: 编辑文件
<kbd>&lt;space&gt;</kbd>: 补丁中包含的切换文件
<kbd>space</kbd>: 补丁中包含的切换文件
<kbd>a</kbd>: toggle all files included in patch
<kbd>&lt;enter&gt;</kbd>: 输入文件以将所选行添加到补丁中(或切换目录折叠)
<kbd>enter</kbd>: 输入文件以将所选行添加到补丁中(或切换目录折叠)
<kbd>`</kbd>: 切换文件树视图
</pre>
## 提交讯息
<pre>
<kbd>&lt;enter&gt;</kbd>: 确认
<kbd>&lt;esc&gt;</kbd>: 关闭
<kbd>enter</kbd>: 确认
<kbd>esc</kbd>: 关闭
</pre>
## 文件
<pre>
<kbd>&lt;c-o&gt;</kbd>: 将文件名复制到剪贴板
<kbd>ctrl+o</kbd>: 将文件名复制到剪贴板
<kbd>d</kbd>: 查看'放弃更改'选项
<kbd>&lt;space&gt;</kbd>: 切换暂存状态
<kbd>&lt;c-b&gt;</kbd>: Filter files (staged/unstaged)
<kbd>space</kbd>: 切换暂存状态
<kbd>ctrl+b</kbd>: Filter files (staged/unstaged)
<kbd>c</kbd>: 提交更改
<kbd>w</kbd>: 提交更改而无需预先提交钩子
<kbd>A</kbd>: 修补最后一次提交
@@ -182,7 +180,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>s</kbd>: 将所有更改加入贮藏
<kbd>S</kbd>: 查看贮藏选项
<kbd>a</kbd>: 切换所有文件的暂存状态
<kbd>&lt;enter&gt;</kbd>: 暂存单个 块/行 用于文件, 或 折叠/展开 目录
<kbd>enter</kbd>: 暂存单个 块/行 用于文件, 或 折叠/展开 目录
<kbd>g</kbd>: 查看上游重置选项
<kbd>D</kbd>: 查看重置选项
<kbd>`</kbd>: 切换文件树视图
@@ -193,27 +191,27 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## 构建补丁中
<pre>
<kbd>&lt;left&gt;</kbd>: 选择上一个区块
<kbd>&lt;right&gt;</kbd>: 选择下一个区块
<kbd>◀</kbd>: 选择上一个区块
<kbd>▶</kbd>: 选择下一个区块
<kbd>v</kbd>: 切换拖动选择
<kbd>V</kbd>: 切换拖动选择
<kbd>a</kbd>: 切换选择区块
<kbd>&lt;c-o&gt;</kbd>: 将选中文本复制到剪贴板
<kbd>ctrl+o</kbd>: 将选中文本复制到剪贴板
<kbd>o</kbd>: 打开文件
<kbd>e</kbd>: 编辑文件
<kbd>&lt;space&gt;</kbd>: 添加/移除 行到补丁
<kbd>&lt;esc&gt;</kbd>: 退出逐行模式
<kbd>space</kbd>: 添加/移除 行到补丁
<kbd>esc</kbd>: 退出逐行模式
</pre>
## 标签页面
<pre>
<kbd>&lt;space&gt;</kbd>: 检出
<kbd>space</kbd>: 检出
<kbd>d</kbd>: 删除标签
<kbd>P</kbd>: 推送标签
<kbd>n</kbd>: 创建标签
<kbd>g</kbd>: 查看重置选项
<kbd>&lt;enter&gt;</kbd>: 查看提交
<kbd>enter</kbd>: 查看提交
</pre>
## 正在合并
@@ -221,31 +219,31 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<pre>
<kbd>e</kbd>: 编辑文件
<kbd>o</kbd>: 打开文件
<kbd>&lt;left&gt;</kbd>: 选择上一个冲突
<kbd>&lt;right&gt;</kbd>: 选择下一个冲突
<kbd>&lt;up&gt;</kbd>: 选择顶部块
<kbd>&lt;down&gt;</kbd>: 选择底部块
<kbd>◀</kbd>: 选择上一个冲突
<kbd>▶</kbd>: 选择下一个冲突
<kbd>▲</kbd>: 选择顶部块
<kbd>▼</kbd>: 选择底部块
<kbd>z</kbd>: 撤销
<kbd>M</kbd>: 打开外部合并工具 (git mergetool)
<kbd>&lt;space&gt;</kbd>: 选中区块
<kbd>space</kbd>: 选中区块
<kbd>b</kbd>: 选中所有区块
<kbd>&lt;esc&gt;</kbd>: 返回文件面板
<kbd>esc</kbd>: 返回文件面板
</pre>
## 正在暂存
<pre>
<kbd>&lt;left&gt;</kbd>: 选择上一个区块
<kbd>&lt;right&gt;</kbd>: 选择下一个区块
<kbd>◀</kbd>: 选择上一个区块
<kbd>▶</kbd>: 选择下一个区块
<kbd>v</kbd>: 切换拖动选择
<kbd>V</kbd>: 切换拖动选择
<kbd>a</kbd>: 切换选择区块
<kbd>&lt;c-o&gt;</kbd>: 将选中文本复制到剪贴板
<kbd>ctrl+o</kbd>: 将选中文本复制到剪贴板
<kbd>o</kbd>: 打开文件
<kbd>e</kbd>: 编辑文件
<kbd>&lt;esc&gt;</kbd>: 返回文件面板
<kbd>&lt;tab&gt;</kbd>: 切换到其他面板
<kbd>&lt;space&gt;</kbd>: 切换行暂存状态
<kbd>esc</kbd>: 返回文件面板
<kbd>tab</kbd>: 切换到其他面板
<kbd>space</kbd>: 切换行暂存状态
<kbd>d</kbd>: 取消变更 (git reset)
<kbd>E</kbd>: edit hunk
<kbd>c</kbd>: 提交更改
@@ -256,8 +254,8 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
## 正常
<pre>
<kbd>mouse wheel down</kbd>: 向下滚动 (fn+up)
<kbd>mouse wheel up</kbd>: 向上滚动 (fn+down)
<kbd>mouse wheel ▼</kbd>: 向下滚动 (fn+up)
<kbd>mouse wheel ▲</kbd>: 向上滚动 (fn+down)
</pre>
## 状态
@@ -266,48 +264,48 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
<kbd>o</kbd>: 打开配置文件
<kbd>e</kbd>: 编辑配置文件
<kbd>u</kbd>: 检查更新
<kbd>&lt;enter&gt;</kbd>: 切换到最近的仓库
<kbd>enter</kbd>: 切换到最近的仓库
<kbd>a</kbd>: 显示所有分支的日志
</pre>
## 确认面板
<pre>
<kbd>&lt;enter&gt;</kbd>: 确认
<kbd>&lt;esc&gt;</kbd>: 关闭
<kbd>enter</kbd>: 确认
<kbd>esc</kbd>: 关闭
</pre>
## 菜单
<pre>
<kbd>&lt;enter&gt;</kbd>: 执行
<kbd>&lt;esc&gt;</kbd>: 关闭
<kbd>enter</kbd>: 执行
<kbd>esc</kbd>: 关闭
</pre>
## 贮藏
<pre>
<kbd>&lt;space&gt;</kbd>: 应用
<kbd>space</kbd>: 应用
<kbd>g</kbd>: 应用并删除
<kbd>d</kbd>: 删除
<kbd>n</kbd>: 新分支
<kbd>r</kbd>: rename stash
<kbd>&lt;enter&gt;</kbd>: 查看提交的文件
<kbd>enter</kbd>: 查看提交的文件
</pre>
## 远程分支
<pre>
<kbd>&lt;c-o&gt;</kbd>: 将分支名称复制到剪贴板
<kbd>&lt;space&gt;</kbd>: 检出
<kbd>ctrl+o</kbd>: 将分支名称复制到剪贴板
<kbd>space</kbd>: 检出
<kbd>n</kbd>: 新分支
<kbd>M</kbd>: 合并到当前检出的分支
<kbd>r</kbd>: 将已检出的分支变基到该分支
<kbd>d</kbd>: 删除分支
<kbd>u</kbd>: 设置为检出分支的上游
<kbd>&lt;esc&gt;</kbd>: 返回远程仓库列表
<kbd>esc</kbd>: 返回远程仓库列表
<kbd>g</kbd>: 查看重置选项
<kbd>&lt;enter&gt;</kbd>: 查看提交
<kbd>enter</kbd>: 查看提交
</pre>
## 远程页面
+7 -18
View File
@@ -12,7 +12,6 @@ import (
"fmt"
"log"
"os"
"strings"
"github.com/jesseduffield/generics/maps"
"github.com/jesseduffield/generics/slices"
@@ -184,8 +183,6 @@ func getHeader(binding *types.Binding, tr *i18n.TranslationSet) header {
func formatSections(tr *i18n.TranslationSet, bindingSections []*bindingSection) string {
content := fmt.Sprintf("# Lazygit %s\n", tr.Keybindings)
content += fmt.Sprintf("\n%s\n", italicize(tr.KeybindingsLegend))
for _, section := range bindingSections {
content += formatTitle(section.title)
content += "<pre>\n"
@@ -203,21 +200,13 @@ 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)
if binding.Alternative != "" {
result += fmt.Sprintf(" (%s)", binding.Alternative)
return fmt.Sprintf(
" <kbd>%s</kbd>: %s (%s)\n",
keybindings.LabelFromKey(binding.Key),
binding.Description,
binding.Alternative,
)
}
result += "\n"
return result
}
func escapeAngleBrackets(str string) string {
result := strings.ReplaceAll(str, ">", "&gt;")
result = strings.ReplaceAll(result, "<", "&lt;")
return result
}
func italicize(str string) string {
return fmt.Sprintf("_%s_", str)
return fmt.Sprintf(" <kbd>%s</kbd>: %s\n", keybindings.LabelFromKey(binding.Key), binding.Description)
}
+2 -1
View File
@@ -117,7 +117,8 @@ func NewGitCommandAux(
workingTreeCommands := git_commands.NewWorkingTreeCommands(gitCommon, submoduleCommands, fileLoader)
rebaseCommands := git_commands.NewRebaseCommands(gitCommon, commitCommands, workingTreeCommands)
stashCommands := git_commands.NewStashCommands(gitCommon, fileLoader, workingTreeCommands)
patchBuilder := patch.NewPatchBuilder(cmn.Log,
// TODO: have patch builder take workingTreeCommands in its entirety
patchBuilder := patch.NewPatchBuilder(cmn.Log, workingTreeCommands.ApplyPatch,
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.
+10 -16
View File
@@ -1,6 +1,7 @@
package git_commands
import (
"fmt"
"os"
"path/filepath"
"strings"
@@ -97,15 +98,13 @@ func (self *BisectCommands) GetInfo() *BisectInfo {
}
func (self *BisectCommands) Reset() error {
cmdStr := NewGitCmd("bisect").Arg("reset").ToString()
return self.cmd.New(cmdStr).StreamOutput().Run()
return self.cmd.New("git bisect reset").StreamOutput().Run()
}
func (self *BisectCommands) Mark(ref string, term string) error {
cmdStr := NewGitCmd("bisect").Arg(term, ref).ToString()
return self.cmd.New(cmdStr).
return self.cmd.New(
fmt.Sprintf("git bisect %s %s", term, ref),
).
IgnoreEmptyError().
StreamOutput().
Run()
@@ -116,9 +115,7 @@ func (self *BisectCommands) Skip(ref string) error {
}
func (self *BisectCommands) Start() error {
cmdStr := NewGitCmd("bisect").Arg("start").ToString()
return self.cmd.New(cmdStr).StreamOutput().Run()
return self.cmd.New("git bisect start").StreamOutput().Run()
}
// tells us whether we've found our problem commit(s). We return a string slice of
@@ -140,8 +137,7 @@ func (self *BisectCommands) IsDone() (bool, []string, error) {
done := false
candidates := []string{}
cmdStr := NewGitCmd("rev-list").Arg(newSha).ToString()
err := self.cmd.New(cmdStr).RunAndProcessLines(func(line string) (bool, error) {
err := self.cmd.New(fmt.Sprintf("git rev-list %s", newSha)).RunAndProcessLines(func(line string) (bool, error) {
sha := strings.TrimSpace(line)
if status, ok := info.statusMap[sha]; ok {
@@ -171,11 +167,9 @@ func (self *BisectCommands) IsDone() (bool, []string, error) {
// bisecting is actually a descendant of our current bisect commit. If it's not, we need to
// render the commits from the bad commit.
func (self *BisectCommands) ReachableFromStart(bisectInfo *BisectInfo) bool {
cmdStr := NewGitCmd("merge-base").
Arg("--is-ancestor", bisectInfo.GetNewSha(), bisectInfo.GetStartSha()).
ToString()
err := self.cmd.New(cmdStr).DontLog().Run()
err := self.cmd.New(
fmt.Sprintf("git merge-base --is-ancestor %s %s", bisectInfo.GetNewSha(), bisectInfo.GetStartSha()),
).DontLog().Run()
return err == nil
}
+32 -72
View File
@@ -20,20 +20,12 @@ func NewBranchCommands(gitCommon *GitCommon) *BranchCommands {
// New creates a new branch
func (self *BranchCommands) New(name string, base string) error {
cmdStr := NewGitCmd("checkout").
Arg("-b", self.cmd.Quote(name), self.cmd.Quote(base)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git checkout -b %s %s", self.cmd.Quote(name), self.cmd.Quote(base))).Run()
}
// CurrentBranchInfo get the current branch information.
func (self *BranchCommands) CurrentBranchInfo() (BranchInfo, error) {
branchName, err := self.cmd.New(
NewGitCmd("symbolic-ref").
Arg("--short", "HEAD").
ToString(),
).DontLog().RunWithOutput()
branchName, err := self.cmd.New("git symbolic-ref --short HEAD").DontLog().RunWithOutput()
if err == nil && branchName != "HEAD\n" {
trimmedBranchName := strings.TrimSpace(branchName)
return BranchInfo{
@@ -42,11 +34,7 @@ func (self *BranchCommands) CurrentBranchInfo() (BranchInfo, error) {
DetachedHead: false,
}, nil
}
output, err := self.cmd.New(
NewGitCmd("branch").
Arg("--points-at=HEAD", "--format=\"%(HEAD)%00%(objectname)%00%(refname)\"").
ToString(),
).DontLog().RunWithOutput()
output, err := self.cmd.New(`git branch --points-at=HEAD --format="%(HEAD)%00%(objectname)%00%(refname)"`).DontLog().RunWithOutput()
if err != nil {
return BranchInfo{}, err
}
@@ -71,12 +59,13 @@ func (self *BranchCommands) CurrentBranchInfo() (BranchInfo, error) {
// Delete delete branch
func (self *BranchCommands) Delete(branch string, force bool) error {
cmdStr := NewGitCmd("branch").
ArgIfElse(force, "-D", "-d").
Arg(self.cmd.Quote(branch)).
ToString()
command := "git branch -d"
return self.cmd.New(cmdStr).Run()
if force {
command = "git branch -D"
}
return self.cmd.New(fmt.Sprintf("%s %s", command, self.cmd.Quote(branch))).Run()
}
// Checkout checks out a branch (or commit), with --force if you set the force arg to true
@@ -86,12 +75,12 @@ type CheckoutOptions struct {
}
func (self *BranchCommands) Checkout(branch string, options CheckoutOptions) error {
cmdStr := NewGitCmd("checkout").
ArgIf(options.Force, "--force").
Arg(self.cmd.Quote(branch)).
ToString()
forceArg := ""
if options.Force {
forceArg = " --force"
}
return self.cmd.New(cmdStr).
return self.cmd.New(fmt.Sprintf("git checkout%s %s", forceArg, self.cmd.Quote(branch))).
// prevents git from prompting us for input which would freeze the program
// TODO: see if this is actually needed here
AddEnvVars("GIT_TERMINAL_PROMPT=0").
@@ -115,27 +104,15 @@ func (self *BranchCommands) GetGraphCmdObj(branchName string) oscommands.ICmdObj
}
func (self *BranchCommands) SetCurrentBranchUpstream(remoteName string, remoteBranchName string) error {
cmdStr := NewGitCmd("branch").
Arg(fmt.Sprintf("--set-upstream-to=%s/%s", self.cmd.Quote(remoteName), self.cmd.Quote(remoteBranchName))).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git branch --set-upstream-to=%s/%s", self.cmd.Quote(remoteName), self.cmd.Quote(remoteBranchName))).Run()
}
func (self *BranchCommands) SetUpstream(remoteName string, remoteBranchName string, branchName string) error {
cmdStr := NewGitCmd("branch").
Arg(fmt.Sprintf("--set-upstream-to=%s/%s", self.cmd.Quote(remoteName), self.cmd.Quote(remoteBranchName))).
Arg(self.cmd.Quote(branchName)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git branch --set-upstream-to=%s/%s %s", self.cmd.Quote(remoteName), self.cmd.Quote(remoteBranchName), self.cmd.Quote(branchName))).Run()
}
func (self *BranchCommands) UnsetUpstream(branchName string) error {
cmdStr := NewGitCmd("branch").Arg("--unset-upstream", self.cmd.Quote(branchName)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git branch --unset-upstream %s", self.cmd.Quote(branchName))).Run()
}
func (self *BranchCommands) GetCurrentBranchUpstreamDifferenceCount() (string, string) {
@@ -149,49 +126,29 @@ func (self *BranchCommands) GetUpstreamDifferenceCount(branchName string) (strin
// GetCommitDifferences checks how many pushables/pullables there are for the
// current branch
func (self *BranchCommands) GetCommitDifferences(from, to string) (string, string) {
pushableCount, err := self.countDifferences(to, from)
command := "git rev-list %s..%s --count"
pushableCount, err := self.cmd.New(fmt.Sprintf(command, to, from)).DontLog().RunWithOutput()
if err != nil {
return "?", "?"
}
pullableCount, err := self.countDifferences(from, to)
pullableCount, err := self.cmd.New(fmt.Sprintf(command, from, to)).DontLog().RunWithOutput()
if err != nil {
return "?", "?"
}
return strings.TrimSpace(pushableCount), strings.TrimSpace(pullableCount)
}
func (self *BranchCommands) countDifferences(from, to string) (string, error) {
cmdStr := NewGitCmd("rev-list").
Arg(fmt.Sprintf("%s..%s", from, to)).
Arg("--count").
ToString()
return self.cmd.New(cmdStr).DontLog().RunWithOutput()
}
func (self *BranchCommands) IsHeadDetached() bool {
cmdStr := NewGitCmd("symbolic-ref").Arg("-q", "HEAD").ToString()
err := self.cmd.New(cmdStr).DontLog().Run()
err := self.cmd.New("git symbolic-ref -q HEAD").DontLog().Run()
return err != nil
}
func (self *BranchCommands) Rename(oldName string, newName string) error {
cmdStr := NewGitCmd("branch").
Arg("--move", self.cmd.Quote(oldName), self.cmd.Quote(newName)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git branch --move %s %s", self.cmd.Quote(oldName), self.cmd.Quote(newName))).Run()
}
func (self *BranchCommands) GetRawBranches() (string, error) {
cmdStr := NewGitCmd("for-each-ref").
Arg("--sort=-committerdate").
Arg(`--format="%(HEAD)%00%(refname:short)%00%(upstream:short)%00%(upstream:track)"`).
Arg("refs/heads").
ToString()
return self.cmd.New(cmdStr).DontLog().RunWithOutput()
return self.cmd.New(`git for-each-ref --sort=-committerdate --format="%(HEAD)%00%(refname:short)%00%(upstream:short)%00%(upstream:track)" refs/heads`).DontLog().RunWithOutput()
}
type MergeOpts struct {
@@ -199,12 +156,15 @@ type MergeOpts struct {
}
func (self *BranchCommands) Merge(branchName string, opts MergeOpts) error {
command := NewGitCmd("merge").
Arg("--no-edit").
ArgIf(self.UserConfig.Git.Merging.Args != "", self.UserConfig.Git.Merging.Args).
ArgIf(opts.FastForwardOnly, "--ff-only").
Arg(self.cmd.Quote(branchName)).
ToString()
mergeArg := ""
if self.UserConfig.Git.Merging.Args != "" {
mergeArg = " " + self.UserConfig.Git.Merging.Args
}
command := fmt.Sprintf("git merge --no-edit%s %s", mergeArg, self.cmd.Quote(branchName))
if opts.FastForwardOnly {
command = fmt.Sprintf("%s --ff-only", command)
}
return self.cmd.New(command).Run()
}
+43 -113
View File
@@ -3,7 +3,6 @@ package git_commands
import (
"fmt"
"strings"
"time"
"github.com/go-errors/errors"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
@@ -23,27 +22,18 @@ func NewCommitCommands(gitCommon *GitCommon) *CommitCommands {
// ResetAuthor resets the author of the topmost commit
func (self *CommitCommands) ResetAuthor() error {
cmdStr := NewGitCmd("commit").
Arg("--allow-empty", "--only", "--no-edit", "--amend", "--reset-author").
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git commit --allow-empty --only --no-edit --amend --reset-author").Run()
}
// Sets the commit's author to the supplied value. Value is expected to be of the form 'Name <Email>'
func (self *CommitCommands) SetAuthor(value string) error {
cmdStr := NewGitCmd("commit").
Arg("--allow-empty", "--only", "--no-edit", "--amend", "--author="+self.cmd.Quote(value)).
ToString()
return self.cmd.New(cmdStr).Run()
commandStr := fmt.Sprintf("git commit --allow-empty --only --no-edit --amend --author=%s", self.cmd.Quote(value))
return self.cmd.New(commandStr).Run()
}
// ResetToCommit reset to commit
func (self *CommitCommands) ResetToCommit(sha string, strength string, envVars []string) error {
cmdStr := NewGitCmd("reset").Arg("--"+strength, sha).ToString()
return self.cmd.New(cmdStr).
return self.cmd.New(fmt.Sprintf("git reset --%s %s", strength, sha)).
// prevents git from prompting us for input which would freeze the program
// TODO: see if this is actually needed here
AddEnvVars("GIT_TERMINAL_PROMPT=0").
@@ -55,52 +45,38 @@ func (self *CommitCommands) CommitCmdObj(message string) oscommands.ICmdObj {
messageArgs := self.commitMessageArgs(message)
skipHookPrefix := self.UserConfig.Git.SkipHookPrefix
noVerifyFlag := ""
if skipHookPrefix != "" && strings.HasPrefix(message, skipHookPrefix) {
noVerifyFlag = " --no-verify"
}
cmdStr := NewGitCmd("commit").
ArgIf(skipHookPrefix != "" && strings.HasPrefix(message, skipHookPrefix), "--no-verify").
ArgIf(self.signoffFlag() != "", self.signoffFlag()).
Arg(messageArgs...).
ToString()
return self.cmd.New(cmdStr)
return self.cmd.New(fmt.Sprintf("git commit%s%s%s", noVerifyFlag, self.signoffFlag(), messageArgs))
}
// RewordLastCommit rewords the topmost commit with the given message
func (self *CommitCommands) RewordLastCommit(message string) error {
messageArgs := self.commitMessageArgs(message)
cmdStr := NewGitCmd("commit").
Arg("--allow-empty", "--amend", "--only").
Arg(messageArgs...).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git commit --allow-empty --amend --only%s", messageArgs)).Run()
}
func (self *CommitCommands) commitMessageArgs(message string) []string {
func (self *CommitCommands) commitMessageArgs(message string) string {
msg, description, _ := strings.Cut(message, "\n")
args := []string{"-m", self.cmd.Quote(msg)}
descriptionArgs := ""
if description != "" {
args = append(args, "-m", self.cmd.Quote(description))
descriptionArgs = fmt.Sprintf(" -m %s", self.cmd.Quote(description))
}
return args
return fmt.Sprintf(" -m %s%s", self.cmd.Quote(msg), descriptionArgs)
}
// runs git commit without the -m argument meaning it will invoke the user's editor
func (self *CommitCommands) CommitEditorCmdObj() oscommands.ICmdObj {
cmdStr := NewGitCmd("commit").
ArgIf(self.signoffFlag() != "", self.signoffFlag()).
ArgIf(self.verboseFlag() != "", self.verboseFlag()).
ToString()
return self.cmd.New(cmdStr)
return self.cmd.New(fmt.Sprintf("git commit%s%s", self.signoffFlag(), self.verboseFlag()))
}
func (self *CommitCommands) signoffFlag() string {
if self.UserConfig.Git.Commit.SignOff {
return "--signoff"
return " --signoff"
} else {
return ""
}
@@ -109,9 +85,9 @@ func (self *CommitCommands) signoffFlag() string {
func (self *CommitCommands) verboseFlag() string {
switch self.config.UserConfig.Git.Commit.Verbose {
case "always":
return "--verbose"
return " --verbose"
case "never":
return "--no-verbose"
return " --no-verbose"
default:
return ""
}
@@ -119,25 +95,19 @@ func (self *CommitCommands) verboseFlag() string {
// Get the subject of the HEAD commit
func (self *CommitCommands) GetHeadCommitMessage() (string, error) {
cmdStr := NewGitCmd("log").Arg("-1", "--pretty=%s").ToString()
message, err := self.cmd.New(cmdStr).DontLog().RunWithOutput()
message, err := self.cmd.New("git log -1 --pretty=%s").DontLog().RunWithOutput()
return strings.TrimSpace(message), err
}
func (self *CommitCommands) GetCommitMessage(commitSha string) (string, error) {
cmdStr := NewGitCmd("rev-list").
Arg("--format=%B", "--max-count=1", commitSha).
ToString()
cmdStr := "git rev-list --format=%B --max-count=1 " + commitSha
messageWithHeader, err := self.cmd.New(cmdStr).DontLog().RunWithOutput()
message := strings.Join(strings.SplitAfter(messageWithHeader, "\n")[1:], "")
return strings.TrimSpace(message), err
}
func (self *CommitCommands) GetCommitDiff(commitSha string) (string, error) {
cmdStr := NewGitCmd("show").Arg("--no-color", commitSha).ToString()
cmdStr := "git show --no-color " + commitSha
diff, err := self.cmd.New(cmdStr).DontLog().RunWithOutput()
return diff, err
}
@@ -148,10 +118,7 @@ type Author struct {
}
func (self *CommitCommands) GetCommitAuthor(commitSha string) (Author, error) {
cmdStr := NewGitCmd("show").
Arg("--no-patch", "--pretty=format:'%an%x00%ae'", commitSha).
ToString()
cmdStr := "git show --no-patch --pretty=format:'%an%x00%ae' " + commitSha
output, err := self.cmd.New(cmdStr).DontLog().RunWithOutput()
if err != nil {
return Author{}, err
@@ -171,21 +138,15 @@ func (self *CommitCommands) GetCommitMessageFirstLine(sha string) (string, error
}
func (self *CommitCommands) GetCommitMessagesFirstLine(shas []string) (string, error) {
cmdStr := NewGitCmd("show").
Arg("--no-patch", "--pretty=format:%s").
Arg(shas...).
ToString()
return self.cmd.New(cmdStr).DontLog().RunWithOutput()
return self.cmd.New(
fmt.Sprintf("git show --no-patch --pretty=format:%%s %s", strings.Join(shas, " ")),
).DontLog().RunWithOutput()
}
func (self *CommitCommands) GetCommitsOneline(shas []string) (string, error) {
cmdStr := NewGitCmd("show").
Arg("--no-patch", "--oneline").
Arg(shas...).
ToString()
return self.cmd.New(cmdStr).DontLog().RunWithOutput()
return self.cmd.New(
fmt.Sprintf("git show --no-patch --oneline %s", strings.Join(shas, " ")),
).DontLog().RunWithOutput()
}
// AmendHead amends HEAD with whatever is staged in your working tree
@@ -194,76 +155,45 @@ func (self *CommitCommands) AmendHead() error {
}
func (self *CommitCommands) AmendHeadCmdObj() oscommands.ICmdObj {
cmdStr := NewGitCmd("commit").
Arg("--amend", "--no-edit", "--allow-empty").
ToString()
return self.cmd.New(cmdStr)
return self.cmd.New("git commit --amend --no-edit --allow-empty")
}
func (self *CommitCommands) ShowCmdObj(sha string, filterPath string, ignoreWhitespace bool) oscommands.ICmdObj {
contextSize := self.UserConfig.Git.DiffContextSize
filterPathArg := ""
if filterPath != "" {
filterPathArg = fmt.Sprintf(" -- %s", self.cmd.Quote(filterPath))
}
ignoreWhitespaceArg := ""
if ignoreWhitespace {
ignoreWhitespaceArg = " --ignore-all-space"
}
cmdStr := NewGitCmd("show").
Arg("--submodule").
Arg("--color="+self.UserConfig.Git.Paging.ColorArg).
Arg(fmt.Sprintf("--unified=%d", contextSize)).
Arg("--stat").
Arg("-p").
Arg(sha).
ArgIf(ignoreWhitespace, "--ignore-all-space").
ArgIf(filterPath != "", "--", self.cmd.Quote(filterPath)).
ToString()
cmdStr := fmt.Sprintf("git show --submodule --color=%s --unified=%d --stat -p %s%s%s",
self.UserConfig.Git.Paging.ColorArg, contextSize, sha, ignoreWhitespaceArg, filterPathArg)
return self.cmd.New(cmdStr).DontLog()
}
// Revert reverts the selected commit by sha
func (self *CommitCommands) Revert(sha string) error {
cmdStr := NewGitCmd("revert").Arg(sha).ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git revert %s", sha)).Run()
}
func (self *CommitCommands) RevertMerge(sha string, parentNumber int) error {
cmdStr := NewGitCmd("revert").Arg(sha, "-m", fmt.Sprintf("%d", parentNumber)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git revert %s -m %d", sha, parentNumber)).Run()
}
// CreateFixupCommit creates a commit that fixes up a previous commit
func (self *CommitCommands) CreateFixupCommit(sha string) error {
cmdStr := NewGitCmd("commit").Arg("--fixup=" + sha).ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git commit --fixup=%s", sha)).Run()
}
// a value of 0 means the head commit, 1 is the parent commit, etc
func (self *CommitCommands) GetCommitMessageFromHistory(value int) (string, error) {
cmdStr := NewGitCmd("log").Arg("-1", fmt.Sprintf("--skip=%d", value), "--pretty=%H").
ToString()
hash, _ := self.cmd.New(cmdStr).DontLog().RunWithOutput()
hash, _ := self.cmd.New(fmt.Sprintf("git log -1 --skip=%d --pretty=%%H", value)).DontLog().RunWithOutput()
formattedHash := strings.TrimSpace(hash)
if len(formattedHash) == 0 {
return "", ErrInvalidCommitIndex
}
return self.GetCommitMessage(formattedHash)
}
// Returns hashes of recent commits which changed the given file
// Note: This does not look for the last X commits to change a file, instead
// it looks among the last X commits and see which of them happened to have changed the file.
// This is more efficient.
func (self *CommitCommands) GetRecentCommitsWhichChangedFile(path string) []string {
t := time.Now()
// Checking last X commits. Funnily this seems to actually consider more than the last
// X, perhaps because of topological sorting.
cmdStr := NewGitCmd("log").Arg("HEAD~50..HEAD", "--pretty=%H", "--", self.cmd.Quote(path)).
ToString()
hashes, _ := self.cmd.New(cmdStr).DontLog().RunWithOutput()
self.Log.Warn(fmt.Sprintf("GetRecentCommitsWhichChangedFile took %s", time.Since(t)))
return strings.Split(strings.TrimSpace(hashes), "\n")
}
+11 -7
View File
@@ -203,8 +203,11 @@ func (self *CommitLoader) getHydratedRebasingCommits(rebaseMode enums.RebaseMode
cmdObj := self.cmd.New(
NewGitCmd("show").
Config("log.showSignature=false").
Arg("--no-patch", "--oneline", "--abbrev=20", prettyFormat).
Arg(commitShas...).
Arg("--no-patch").
Arg("--oneline").
Arg(strings.Join(commitShas, " ")).
Arg(prettyFormat).
Arg("--abbrev=20").
ToString(),
).DontLog()
@@ -376,7 +379,9 @@ func (self *CommitLoader) getMergeBase(refName string) string {
// return the base commit for the closest one.
output, err := self.cmd.New(
NewGitCmd("merge-base").Arg(self.cmd.Quote(refName), *self.quotedMainBranches).
NewGitCmd("merge-base").
Arg(self.cmd.Quote(refName)).
Arg(*self.quotedMainBranches).
ToString(),
).DontLog().RunWithOutput()
if err != nil {
@@ -394,7 +399,7 @@ func (self *CommitLoader) getExistingMainBranches() string {
func(branchName string, _ int) (string, bool) {
quotedRef := self.cmd.Quote("refs/heads/" + branchName)
if err := self.cmd.New(
NewGitCmd("rev-parse").Arg("--verify", "--quiet", quotedRef).ToString(),
NewGitCmd("rev-parse").Arg("--verify").Arg("--quiet").Arg(quotedRef).ToString(),
).DontLog().Run(); err != nil {
return "", false
}
@@ -444,12 +449,11 @@ func (self *CommitLoader) getLogCmd(opts GetCommitsOptions) oscommands.ICmdObj {
Arg("--abbrev=40").
ArgIf(opts.Limit, "-300").
ArgIf(opts.FilterPath != "", "--follow").
Arg("--no-show-signature").
Arg("--").
ArgIf(opts.FilterPath != "", self.cmd.Quote(opts.FilterPath)).
Arg("--no-show-signature").
ToString()
return self.cmd.New(cmdStr).DontLog()
return self.cmd.New(cmdStr)
}
const prettyFormat = `--pretty=format:"%H%x00%at%x00%aN%x00%ae%x00%d%x00%p%x00%s"`
-21
View File
@@ -7,7 +7,6 @@ import (
gogit "github.com/jesseduffield/go-git/v5"
"github.com/jesseduffield/lazygit/pkg/commands/git_config"
"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/config"
"github.com/jesseduffield/lazygit/pkg/utils"
@@ -118,26 +117,6 @@ func buildWorkingTreeCommands(deps commonDeps) *WorkingTreeCommands {
return NewWorkingTreeCommands(gitCommon, submoduleCommands, fileLoader)
}
func buildPatchCommands(deps commonDeps) *PatchCommands {
gitCommon := buildGitCommon(deps)
rebaseCommands := buildRebaseCommands(deps)
commitCommands := buildCommitCommands(deps)
statusCommands := buildStatusCommands(deps)
stashCommands := buildStashCommands(deps)
loadFileFn := func(from string, to string, reverse bool, filename string, plain bool) (string, error) {
return "", nil
}
patchBuilder := patch.NewPatchBuilder(gitCommon.Log, loadFileFn)
return NewPatchCommands(gitCommon, rebaseCommands, commitCommands, statusCommands, stashCommands, patchBuilder)
}
func buildStatusCommands(deps commonDeps) *StatusCommands {
gitCommon := buildGitCommon(deps)
return NewStatusCommands(gitCommon)
}
func buildStashCommands(deps commonDeps) *StashCommands {
gitCommon := buildGitCommon(deps)
fileLoader := buildFileLoader(gitCommon)
+7 -9
View File
@@ -42,7 +42,7 @@ func (self *FileLoader) GetStatusFiles(opts GetStatusFileOptions) []*models.File
}
untrackedFilesArg := fmt.Sprintf("--untracked-files=%s", untrackedFilesSetting)
statuses, err := self.gitStatus(GitStatusOptions{NoRenames: opts.NoRenames, UntrackedFilesArg: untrackedFilesArg})
statuses, err := self.GitStatus(GitStatusOptions{NoRenames: opts.NoRenames, UntrackedFilesArg: untrackedFilesArg})
if err != nil {
self.Log.Error(err)
}
@@ -81,15 +81,13 @@ type FileStatus struct {
PreviousName string
}
func (c *FileLoader) gitStatus(opts GitStatusOptions) ([]FileStatus, error) {
cmdStr := NewGitCmd("status").
Arg(opts.UntrackedFilesArg).
Arg("--porcelain").
Arg("-z").
ArgIf(opts.NoRenames, "--no-renames").
ToString()
func (c *FileLoader) GitStatus(opts GitStatusOptions) ([]FileStatus, error) {
noRenamesFlag := ""
if opts.NoRenames {
noRenamesFlag = " --no-renames"
}
statusLines, _, err := c.cmd.New(cmdStr).DontLog().RunWithOutputs()
statusLines, _, err := c.cmd.New(fmt.Sprintf("git status %s --porcelain -z%s", opts.UntrackedFilesArg, noRenamesFlag)).DontLog().RunWithOutputs()
if err != nil {
return []FileStatus{}, err
}
+2 -7
View File
@@ -34,7 +34,6 @@ func (self *FlowCommands) FinishCmdObj(branchName string) (oscommands.ICmdObj, e
branchType := ""
for _, line := range strings.Split(strings.TrimSpace(prefixes), "\n") {
if strings.HasPrefix(line, "gitflow.prefix.") && strings.HasSuffix(line, prefix) {
regex := regexp.MustCompile("gitflow.prefix.([^ ]*) .*")
matches := regex.FindAllStringSubmatch(line, 1)
@@ -49,13 +48,9 @@ func (self *FlowCommands) FinishCmdObj(branchName string) (oscommands.ICmdObj, e
return nil, errors.New(self.Tr.NotAGitFlowBranch)
}
cmdStr := NewGitCmd("flow").Arg(branchType, "finish", suffix).ToString()
return self.cmd.New(cmdStr), nil
return self.cmd.New("git flow " + branchType + " finish " + suffix), nil
}
func (self *FlowCommands) StartCmdObj(branchType string, name string) oscommands.ICmdObj {
cmdStr := NewGitCmd("flow").Arg(branchType, "start", name).ToString()
return self.cmd.New(cmdStr)
return self.cmd.New("git flow " + branchType + " start " + name)
}
@@ -1,54 +1,65 @@
package git_commands
import "strings"
import "fmt"
// convenience struct for building git commands. Especially useful when
// including conditional args
type GitCommandBuilder struct {
// command string
args []string
command string
}
func NewGitCmd(command string) *GitCommandBuilder {
return &GitCommandBuilder{args: []string{command}}
return &GitCommandBuilder{command: command}
}
func (self *GitCommandBuilder) Arg(args ...string) *GitCommandBuilder {
self.args = append(self.args, args...)
func (self *GitCommandBuilder) Arg(flag string) *GitCommandBuilder {
if flag == "" {
return self
}
self.command += " " + flag
return self
}
func (self *GitCommandBuilder) ArgIf(condition bool, ifTrue ...string) *GitCommandBuilder {
if condition {
self.Arg(ifTrue...)
func (self *GitCommandBuilder) ArgIf(include bool, flag string) *GitCommandBuilder {
if include {
return self.Arg(flag)
}
return self
}
func (self *GitCommandBuilder) ArgIfElse(condition bool, ifTrue string, ifFalse string) *GitCommandBuilder {
if condition {
return self.Arg(ifTrue)
func (self *GitCommandBuilder) ArgIfElse(isTrue bool, onTrue string, onFalse string) *GitCommandBuilder {
if isTrue {
return self.Arg(onTrue)
} else {
return self.Arg(ifFalse)
return self.Arg(onFalse)
}
}
func (self *GitCommandBuilder) Args(args []string) *GitCommandBuilder {
for _, arg := range args {
self.Arg(arg)
}
return self
}
func (self *GitCommandBuilder) Config(value string) *GitCommandBuilder {
// config settings come before the command
self.args = append([]string{"-c", value}, self.args...)
self.command = fmt.Sprintf("-c %s %s", value, self.command)
return self
}
func (self *GitCommandBuilder) RepoPath(value string) *GitCommandBuilder {
// repo path comes before the command
self.args = append([]string{"-C", value}, self.args...)
self.command = fmt.Sprintf("-C %s %s", value, self.command)
return self
}
func (self *GitCommandBuilder) ToString() string {
return "git " + strings.Join(self.args, " ")
return "git " + self.command
}
@@ -37,7 +37,7 @@ func TestGitCommandBuilder(t *testing.T) {
expected: "git push -b",
},
{
input: NewGitCmd("push").Arg("-a", "-b").ToString(),
input: NewGitCmd("push").Args([]string{"-a", "-b"}).ToString(),
expected: "git push -a -b",
},
{
+9 -61
View File
@@ -2,8 +2,6 @@ package git_commands
import (
"fmt"
"path/filepath"
"time"
"github.com/fsmiamoto/git-todo-parser/todo"
"github.com/go-errors/errors"
@@ -11,7 +9,6 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/patch"
"github.com/jesseduffield/lazygit/pkg/commands/types/enums"
"github.com/jesseduffield/lazygit/pkg/utils"
)
type PatchCommands struct {
@@ -42,53 +39,6 @@ func NewPatchCommands(
}
}
type ApplyPatchOpts struct {
ThreeWay bool
Cached bool
Index bool
Reverse bool
}
func (self *PatchCommands) ApplyCustomPatch(reverse bool) error {
patch := self.PatchBuilder.PatchToApply(reverse)
return self.ApplyPatch(patch, ApplyPatchOpts{
Index: true,
ThreeWay: true,
Reverse: reverse,
})
}
func (self *PatchCommands) ApplyPatch(patch string, opts ApplyPatchOpts) error {
filepath, err := self.SaveTemporaryPatch(patch)
if err != nil {
return err
}
return self.applyPatchFile(filepath, opts)
}
func (self *PatchCommands) applyPatchFile(filepath string, opts ApplyPatchOpts) error {
cmdStr := NewGitCmd("apply").
ArgIf(opts.ThreeWay, "--3way").
ArgIf(opts.Cached, "--cached").
ArgIf(opts.Index, "--index").
ArgIf(opts.Reverse, "--reverse").
Arg(self.cmd.Quote(filepath)).
ToString()
return self.cmd.New(cmdStr).Run()
}
func (self *PatchCommands) SaveTemporaryPatch(patch string) (string, error) {
filepath := filepath.Join(self.os.GetTempDir(), utils.GetCurrentRepoName(), time.Now().Format("Jan _2 15.04.05.000000000")+".patch")
self.Log.Infof("saving temporary patch to %s", filepath)
if err := self.os.CreateFileWithContent(filepath, patch); err != nil {
return "", err
}
return filepath, nil
}
// DeletePatchesFromCommit applies a patch in reverse for a commit
func (self *PatchCommands) DeletePatchesFromCommit(commits []*models.Commit, commitIndex int) error {
if err := self.rebase.BeginInteractiveRebaseForCommit(commits, commitIndex); err != nil {
@@ -96,7 +46,7 @@ func (self *PatchCommands) DeletePatchesFromCommit(commits []*models.Commit, com
}
// apply each patch in reverse
if err := self.ApplyCustomPatch(true); err != nil {
if err := self.PatchBuilder.ApplyPatches(true); err != nil {
_ = self.rebase.AbortRebase()
return err
}
@@ -122,7 +72,7 @@ func (self *PatchCommands) MovePatchToSelectedCommit(commits []*models.Commit, s
}
// apply each patch forward
if err := self.ApplyCustomPatch(false); err != nil {
if err := self.PatchBuilder.ApplyPatches(false); err != nil {
// Don't abort the rebase here; this might cause conflicts, so give
// the user a chance to resolve them
return err
@@ -171,7 +121,7 @@ func (self *PatchCommands) MovePatchToSelectedCommit(commits []*models.Commit, s
}
// apply each patch in reverse
if err := self.ApplyCustomPatch(true); err != nil {
if err := self.PatchBuilder.ApplyPatches(true); err != nil {
_ = self.rebase.AbortRebase()
return err
}
@@ -194,7 +144,7 @@ func (self *PatchCommands) MovePatchToSelectedCommit(commits []*models.Commit, s
self.rebase.onSuccessfulContinue = func() error {
// now we should be up to the destination, so let's apply forward these patches to that.
// ideally we would ensure we're on the right commit but I'm not sure if that check is necessary
if err := self.ApplyPatch(patch, ApplyPatchOpts{Index: true, ThreeWay: true}); err != nil {
if err := self.rebase.workingTree.ApplyPatch(patch, "index", "3way"); err != nil {
// Don't abort the rebase here; this might cause conflicts, so give
// the user a chance to resolve them
return err
@@ -227,7 +177,7 @@ func (self *PatchCommands) MovePatchIntoIndex(commits []*models.Commit, commitId
return err
}
if err := self.ApplyCustomPatch(true); err != nil {
if err := self.PatchBuilder.ApplyPatches(true); err != nil {
if self.status.WorkingTreeState() == enums.REBASE_MODE_REBASING {
_ = self.rebase.AbortRebase()
}
@@ -251,7 +201,7 @@ func (self *PatchCommands) MovePatchIntoIndex(commits []*models.Commit, commitId
self.rebase.onSuccessfulContinue = func() error {
// add patches to index
if err := self.ApplyPatch(patch, ApplyPatchOpts{Index: true, ThreeWay: true}); err != nil {
if err := self.rebase.workingTree.ApplyPatch(patch, "index", "3way"); err != nil {
if self.status.WorkingTreeState() == enums.REBASE_MODE_REBASING {
_ = self.rebase.AbortRebase()
}
@@ -276,7 +226,7 @@ func (self *PatchCommands) PullPatchIntoNewCommit(commits []*models.Commit, comm
return err
}
if err := self.ApplyCustomPatch(true); err != nil {
if err := self.PatchBuilder.ApplyPatches(true); err != nil {
_ = self.rebase.AbortRebase()
return err
}
@@ -292,7 +242,7 @@ func (self *PatchCommands) PullPatchIntoNewCommit(commits []*models.Commit, comm
return err
}
if err := self.ApplyPatch(patch, ApplyPatchOpts{Index: true, ThreeWay: true}); err != nil {
if err := self.rebase.workingTree.ApplyPatch(patch, "index", "3way"); err != nil {
_ = self.rebase.AbortRebase()
return err
}
@@ -317,7 +267,5 @@ func (self *PatchCommands) PullPatchIntoNewCommit(commits []*models.Commit, comm
// only some lines of a range of adjacent added lines. To solve this, we
// get the diff of HEAD and the original commit and then apply that.
func (self *PatchCommands) diffHeadAgainstCommit(commit *models.Commit) (string, error) {
cmdStr := NewGitCmd("diff").Arg("HEAD.." + commit.Sha).ToString()
return self.cmd.New(cmdStr).RunWithOutput()
return self.cmd.New(fmt.Sprintf("git diff HEAD..%s", commit.Sha)).RunWithOutput()
}
-66
View File
@@ -1,66 +0,0 @@
package git_commands
import (
"fmt"
"os"
"regexp"
"testing"
"github.com/go-errors/errors"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/stretchr/testify/assert"
)
func TestWorkingTreeApplyPatch(t *testing.T) {
type scenario struct {
testName string
runner *oscommands.FakeCmdObjRunner
test func(error)
}
expectFn := func(regexStr string, errToReturn error) func(cmdObj oscommands.ICmdObj) (string, error) {
return func(cmdObj oscommands.ICmdObj) (string, error) {
re := regexp.MustCompile(regexStr)
cmdStr := cmdObj.ToString()
matches := re.FindStringSubmatch(cmdStr)
assert.Equal(t, 2, len(matches), fmt.Sprintf("unexpected command: %s", cmdStr))
filename := matches[1]
content, err := os.ReadFile(filename)
assert.NoError(t, err)
assert.Equal(t, "test", string(content))
return "", errToReturn
}
}
scenarios := []scenario{
{
testName: "valid case",
runner: oscommands.NewFakeRunner(t).
ExpectFunc(expectFn(`git apply --cached "(.*)"`, nil)),
test: func(err error) {
assert.NoError(t, err)
},
},
{
testName: "command returns error",
runner: oscommands.NewFakeRunner(t).
ExpectFunc(expectFn(`git apply --cached "(.*)"`, errors.New("error"))),
test: func(err error) {
assert.Error(t, err)
},
},
}
for _, s := range scenarios {
s := s
t.Run(s.testName, func(t *testing.T) {
instance := buildPatchCommands(commonDeps{runner: s.runner})
s.test(instance.ApplyPatch("test", ApplyPatchOpts{Cached: true}))
s.runner.CheckForMissingCalls()
})
}
}
+23 -23
View File
@@ -176,21 +176,23 @@ type PrepareInteractiveRebaseCommandOpts struct {
func (self *RebaseCommands) PrepareInteractiveRebaseCommand(opts PrepareInteractiveRebaseCommandOpts) oscommands.ICmdObj {
ex := oscommands.GetLazygitPath()
cmdStr := NewGitCmd("rebase").
Arg("--interactive").
Arg("--autostash").
Arg("--keep-empty").
ArgIf(!self.version.IsOlderThan(2, 26, 0), "--empty=keep").
Arg("--no-autosquash").
ArgIf(!self.version.IsOlderThan(2, 22, 0), "--rebase-merges").
Arg(opts.baseShaOrRoot).
ToString()
debug := "FALSE"
if self.Debug {
debug = "TRUE"
}
emptyArg := " --empty=keep"
if self.version.IsOlderThan(2, 26, 0) {
emptyArg = ""
}
rebaseMergesArg := " --rebase-merges"
if self.version.IsOlderThan(2, 22, 0) {
rebaseMergesArg = ""
}
cmdStr := fmt.Sprintf("git rebase --interactive --autostash --keep-empty%s --no-autosquash%s %s",
emptyArg, rebaseMergesArg, opts.baseShaOrRoot)
self.Log.WithField("command", cmdStr).Debug("RunCommand")
cmdObj := self.cmd.New(cmdStr)
@@ -226,8 +228,7 @@ func (self *RebaseCommands) AmendTo(commits []*models.Commit, commitIndex int) e
}
// Get the sha of the commit we just created
cmdStr := NewGitCmd("rev-parse").Arg("--verify", "HEAD").ToString()
fixupSha, err := self.cmd.New(cmdStr).RunWithOutput()
fixupSha, err := self.cmd.New("git rev-parse --verify HEAD").RunWithOutput()
if err != nil {
return err
}
@@ -264,11 +265,14 @@ func (self *RebaseCommands) SquashAllAboveFixupCommits(commit *models.Commit) er
shaOrRoot = "--root"
}
cmdStr := NewGitCmd("rebase").
Arg("--interactive", "--rebase-merges", "--autostash", "--autosquash", shaOrRoot).
ToString()
return self.runSkipEditorCommand(self.cmd.New(cmdStr))
return self.runSkipEditorCommand(
self.cmd.New(
fmt.Sprintf(
"git rebase --interactive --rebase-merges --autostash --autosquash %s",
shaOrRoot,
),
),
)
}
// BeginInteractiveRebaseForCommit starts an interactive rebase to edit the current
@@ -304,9 +308,7 @@ func (self *RebaseCommands) RebaseBranch(branchName string) error {
}
func (self *RebaseCommands) GenericMergeOrRebaseActionCmdObj(commandType string, command string) oscommands.ICmdObj {
cmdStr := NewGitCmd(commandType).Arg("--" + command).ToString()
return self.cmd.New(cmdStr)
return self.cmd.New("git " + commandType + " --" + command)
}
func (self *RebaseCommands) ContinueRebase() error {
@@ -363,9 +365,7 @@ func (self *RebaseCommands) DiscardOldFileChanges(commits []*models.Commit, comm
}
// check if file exists in previous commit (this command returns an error if the file doesn't exist)
cmdStr := NewGitCmd("cat-file").Arg("-e", "HEAD^:"+self.cmd.Quote(fileName)).ToString()
if err := self.cmd.New(cmdStr).Run(); err != nil {
if err := self.cmd.New("git cat-file -e HEAD^:" + self.cmd.Quote(fileName)).Run(); err != nil {
if err := self.os.Remove(fileName); err != nil {
return err
}
+22 -30
View File
@@ -15,52 +15,44 @@ func NewRemoteCommands(gitCommon *GitCommon) *RemoteCommands {
}
func (self *RemoteCommands) AddRemote(name string, url string) error {
cmdStr := NewGitCmd("remote").
Arg("add", self.cmd.Quote(name), self.cmd.Quote(url)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.
New(fmt.Sprintf("git remote add %s %s", self.cmd.Quote(name), self.cmd.Quote(url))).
Run()
}
func (self *RemoteCommands) RemoveRemote(name string) error {
cmdStr := NewGitCmd("remote").
Arg("remove", self.cmd.Quote(name)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.
New(fmt.Sprintf("git remote remove %s", self.cmd.Quote(name))).
Run()
}
func (self *RemoteCommands) RenameRemote(oldRemoteName string, newRemoteName string) error {
cmdStr := NewGitCmd("remote").
Arg("rename", self.cmd.Quote(oldRemoteName), self.cmd.Quote(newRemoteName)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.
New(fmt.Sprintf("git remote rename %s %s", self.cmd.Quote(oldRemoteName), self.cmd.Quote(newRemoteName))).
Run()
}
func (self *RemoteCommands) UpdateRemoteUrl(remoteName string, updatedUrl string) error {
cmdStr := NewGitCmd("remote").
Arg("set-url", self.cmd.Quote(remoteName), self.cmd.Quote(updatedUrl)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.
New(fmt.Sprintf("git remote set-url %s %s", self.cmd.Quote(remoteName), self.cmd.Quote(updatedUrl))).
Run()
}
func (self *RemoteCommands) DeleteRemoteBranch(remoteName string, branchName string) error {
cmdStr := NewGitCmd("push").
Arg(self.cmd.Quote(remoteName), "--delete", self.cmd.Quote(branchName)).
ToString()
return self.cmd.New(cmdStr).PromptOnCredentialRequest().WithMutex(self.syncMutex).Run()
command := fmt.Sprintf("git push %s --delete %s", self.cmd.Quote(remoteName), self.cmd.Quote(branchName))
return self.cmd.New(command).PromptOnCredentialRequest().WithMutex(self.syncMutex).Run()
}
// CheckRemoteBranchExists Returns remote branch
func (self *RemoteCommands) CheckRemoteBranchExists(branchName string) bool {
cmdStr := NewGitCmd("show-ref").
Arg("--verify", "--", fmt.Sprintf("refs/remotes/origin/%s", self.cmd.Quote(branchName))).
ToString()
_, err := self.cmd.New(cmdStr).DontLog().RunWithOutput()
_, err := self.cmd.
New(
fmt.Sprintf("git show-ref --verify -- refs/remotes/origin/%s",
self.cmd.Quote(branchName),
),
).
DontLog().
RunWithOutput()
return err == nil
}
+1 -2
View File
@@ -31,8 +31,7 @@ func NewRemoteLoader(
}
func (self *RemoteLoader) GetRemotes() ([]*models.Remote, error) {
cmdStr := NewGitCmd("branch").Arg("-r").ToString()
remoteBranchesStr, err := self.cmd.New(cmdStr).DontLog().RunWithOutput()
remoteBranchesStr, err := self.cmd.New("git branch -r").DontLog().RunWithOutput()
if err != nil {
return nil, err
}
+30 -68
View File
@@ -26,94 +26,68 @@ func NewStashCommands(
}
func (self *StashCommands) DropNewest() error {
cmdStr := NewGitCmd("stash").Arg("drop").ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git stash drop").Run()
}
func (self *StashCommands) Drop(index int) error {
cmdStr := NewGitCmd("stash").Arg("drop", fmt.Sprintf("stash@{%d}", index)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git stash drop stash@{%d}", index)).Run()
}
func (self *StashCommands) Pop(index int) error {
cmdStr := NewGitCmd("stash").Arg("pop", fmt.Sprintf("stash@{%d}", index)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git stash pop stash@{%d}", index)).Run()
}
func (self *StashCommands) Apply(index int) error {
cmdStr := NewGitCmd("stash").Arg("apply", fmt.Sprintf("stash@{%d}", index)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git stash apply stash@{%d}", index)).Run()
}
// Save save stash
func (self *StashCommands) Save(message string) error {
cmdStr := NewGitCmd("stash").Arg("save", self.cmd.Quote(message)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git stash save " + self.cmd.Quote(message)).Run()
}
func (self *StashCommands) Store(sha string, message string) error {
trimmedMessage := strings.Trim(message, " \t")
cmdStr := NewGitCmd("stash").Arg("store", self.cmd.Quote(sha)).
ArgIf(trimmedMessage != "", "-m", self.cmd.Quote(trimmedMessage)).
ToString()
return self.cmd.New(cmdStr).Run()
if len(trimmedMessage) > 0 {
return self.cmd.New(fmt.Sprintf("git stash store %s -m %s", self.cmd.Quote(sha), self.cmd.Quote(trimmedMessage))).Run()
}
return self.cmd.New(fmt.Sprintf("git stash store %s", self.cmd.Quote(sha))).Run()
}
func (self *StashCommands) Sha(index int) (string, error) {
cmdStr := NewGitCmd("rev-parse").
Arg(fmt.Sprintf("refs/stash@{%d}", index)).
ToString()
sha, _, err := self.cmd.New(cmdStr).DontLog().RunWithOutputs()
sha, _, err := self.cmd.New(fmt.Sprintf("git rev-parse refs/stash@{%d}", index)).DontLog().RunWithOutputs()
return strings.Trim(sha, "\r\n"), err
}
func (self *StashCommands) ShowStashEntryCmdObj(index int, ignoreWhitespace bool) oscommands.ICmdObj {
cmdStr := 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("stash@{%d}", index)).
ToString()
ignoreWhitespaceFlag := ""
if ignoreWhitespace {
ignoreWhitespaceFlag = " --ignore-all-space"
}
cmdStr := fmt.Sprintf(
"git stash show -p --stat --color=%s --unified=%d%s stash@{%d}",
self.UserConfig.Git.Paging.ColorArg,
self.UserConfig.Git.DiffContextSize,
ignoreWhitespaceFlag,
index,
)
return self.cmd.New(cmdStr).DontLog()
}
func (self *StashCommands) StashAndKeepIndex(message string) error {
cmdStr := NewGitCmd("stash").Arg("save", self.cmd.Quote(message), "--keep-index").
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git stash save %s --keep-index", self.cmd.Quote(message))).Run()
}
func (self *StashCommands) StashUnstagedChanges(message string) error {
if err := self.cmd.New(
NewGitCmd("commit").
Arg("--no-verify", "-m", self.cmd.Quote("[lazygit] stashing unstaged changes")).
ToString(),
).Run(); err != nil {
if err := self.cmd.New("git commit --no-verify -m \"[lazygit] stashing unstaged changes\"").Run(); err != nil {
return err
}
if err := self.Save(message); err != nil {
return err
}
if err := self.cmd.New(
NewGitCmd("reset").Arg("--soft", "HEAD^").ToString(),
).Run(); err != nil {
if err := self.cmd.New("git reset --soft HEAD^").Run(); err != nil {
return err
}
return nil
@@ -123,9 +97,7 @@ func (self *StashCommands) StashUnstagedChanges(message string) error {
// shoutouts to Joe on https://stackoverflow.com/questions/14759748/stashing-only-staged-changes-in-git-is-it-possible
func (self *StashCommands) SaveStagedChanges(message string) error {
// wrap in 'writing', which uses a mutex
if err := self.cmd.New(
NewGitCmd("stash").Arg("--keep-index").ToString(),
).Run(); err != nil {
if err := self.cmd.New("git stash --keep-index").Run(); err != nil {
return err
}
@@ -133,22 +105,15 @@ func (self *StashCommands) SaveStagedChanges(message string) error {
return err
}
if err := self.cmd.New(
NewGitCmd("stash").Arg("apply", "stash@{1}").ToString(),
).Run(); err != nil {
if err := self.cmd.New("git stash apply stash@{1}").Run(); err != nil {
return err
}
if err := self.os.PipeCommands(
NewGitCmd("stash").Arg("show", "-p").ToString(),
NewGitCmd("apply").Arg("-R").ToString(),
); err != nil {
if err := self.os.PipeCommands("git stash show -p", "git apply -R"); err != nil {
return err
}
if err := self.cmd.New(
NewGitCmd("stash").Arg("drop", "stash@{1}").ToString(),
).Run(); err != nil {
if err := self.cmd.New("git stash drop stash@{1}").Run(); err != nil {
return err
}
@@ -170,10 +135,7 @@ func (self *StashCommands) SaveStagedChanges(message string) error {
}
func (self *StashCommands) StashIncludeUntrackedChanges(message string) error {
return self.cmd.New(
NewGitCmd("stash").Arg("save", self.cmd.Quote(message), "--include-untracked").
ToString(),
).Run()
return self.cmd.New(fmt.Sprintf("git stash save %s --include-untracked", self.cmd.Quote(message))).Run()
}
func (self *StashCommands) Rename(index int, message string) error {
+2 -5
View File
@@ -32,8 +32,7 @@ func (self *StashLoader) GetStashEntries(filterPath string) []*models.StashEntry
return self.getUnfilteredStashEntries()
}
cmdStr := NewGitCmd("stash").Arg("list", "--name-only").ToString()
rawString, err := self.cmd.New(cmdStr).DontLog().RunWithOutput()
rawString, err := self.cmd.New("git stash list --name-only").DontLog().RunWithOutput()
if err != nil {
return self.getUnfilteredStashEntries()
}
@@ -66,9 +65,7 @@ outer:
}
func (self *StashLoader) getUnfilteredStashEntries() []*models.StashEntry {
cmdStr := NewGitCmd("stash").Arg("list", "-z", "--pretty='%gs'").ToString()
rawString, _ := self.cmd.New(cmdStr).DontLog().RunWithOutput()
rawString, _ := self.cmd.New("git stash list -z --pretty='%gs'").DontLog().RunWithOutput()
return slices.MapWithIndex(utils.SplitNul(rawString), func(line string, index int) *models.StashEntry {
return self.stashEntryFromLine(line, index)
})
+1 -3
View File
@@ -56,9 +56,7 @@ func (self *StatusCommands) IsBareRepo() (bool, error) {
}
func IsBareRepo(osCommand *oscommands.OSCommand) (bool, error) {
res, err := osCommand.Cmd.New(
NewGitCmd("rev-parse").Arg("--is-bare-repository").ToString(),
).DontLog().RunWithOutput()
res, err := osCommand.Cmd.New("git rev-parse --is-bare-repository").DontLog().RunWithOutput()
if err != nil {
return false, err
}
+32 -82
View File
@@ -2,6 +2,7 @@ package git_commands
import (
"bufio"
"fmt"
"os"
"path/filepath"
"regexp"
@@ -81,60 +82,38 @@ func (self *SubmoduleCommands) Stash(submodule *models.SubmoduleConfig) error {
return nil
}
cmdStr := NewGitCmd("stash").
RepoPath(self.cmd.Quote(submodule.Path)).
Arg("--include-untracked").
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git -C " + self.cmd.Quote(submodule.Path) + " stash --include-untracked").Run()
}
func (self *SubmoduleCommands) Reset(submodule *models.SubmoduleConfig) error {
cmdStr := NewGitCmd("submodule").
Arg("update", "--init", "--force", "--", self.cmd.Quote(submodule.Path)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git submodule update --init --force -- " + self.cmd.Quote(submodule.Path)).Run()
}
func (self *SubmoduleCommands) UpdateAll() error {
// not doing an --init here because the user probably doesn't want that
cmdStr := NewGitCmd("submodule").Arg("update", "--force").ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git submodule update --force").Run()
}
func (self *SubmoduleCommands) Delete(submodule *models.SubmoduleConfig) error {
// based on https://gist.github.com/myusuf3/7f645819ded92bda6677
if err := self.cmd.New(
NewGitCmd("submodule").
Arg("deinit", "--force", "--", self.cmd.Quote(submodule.Path)).ToString(),
).Run(); err != nil {
if !strings.Contains(err.Error(), "did not match any file(s) known to git") {
return err
}
if err := self.cmd.New("git submodule deinit --force -- " + self.cmd.Quote(submodule.Path)).Run(); err != nil {
if strings.Contains(err.Error(), "did not match any file(s) known to git") {
if err := self.cmd.New("git config --file .gitmodules --remove-section submodule." + self.cmd.Quote(submodule.Name)).Run(); err != nil {
return err
}
if err := self.cmd.New(
NewGitCmd("config").
Arg("--file", ".gitmodules", "--remove-section", "submodule."+self.cmd.Quote(submodule.Path)).
ToString(),
).Run(); err != nil {
return err
}
if err := self.cmd.New("git config --remove-section submodule." + self.cmd.Quote(submodule.Name)).Run(); err != nil {
return err
}
if err := self.cmd.New(
NewGitCmd("config").
Arg("--remove-section", "submodule."+self.cmd.Quote(submodule.Path)).
ToString(),
).Run(); err != nil {
// if there's an error here about it not existing then we'll just continue to do `git rm`
} else {
return err
}
}
if err := self.cmd.New(
NewGitCmd("rm").Arg("--force", "-r", submodule.Path).ToString(),
).Run(); err != nil {
if err := self.cmd.New("git rm --force -r " + submodule.Path).Run(); err != nil {
// if the directory isn't there then that's fine
self.Log.Error(err)
}
@@ -143,35 +122,24 @@ func (self *SubmoduleCommands) Delete(submodule *models.SubmoduleConfig) error {
}
func (self *SubmoduleCommands) Add(name string, path string, url string) error {
cmdStr := NewGitCmd("submodule").
Arg("add").
Arg("--force").
Arg("--name").
Arg(self.cmd.Quote(name)).
Arg("--").
Arg(self.cmd.Quote(url)).
Arg(self.cmd.Quote(path)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.
New(
fmt.Sprintf(
"git submodule add --force --name %s -- %s %s ",
self.cmd.Quote(name),
self.cmd.Quote(url),
self.cmd.Quote(path),
)).
Run()
}
func (self *SubmoduleCommands) UpdateUrl(name string, path string, newUrl string) error {
setUrlCmdStr := NewGitCmd("config").
Arg(
"--file", ".gitmodules", "submodule."+self.cmd.Quote(name)+".url", self.cmd.Quote(newUrl),
).
ToString()
// the set-url command is only for later git versions so we're doing it manually here
if err := self.cmd.New(setUrlCmdStr).Run(); err != nil {
if err := self.cmd.New("git config --file .gitmodules submodule." + self.cmd.Quote(name) + ".url " + self.cmd.Quote(newUrl)).Run(); err != nil {
return err
}
syncCmdStr := NewGitCmd("submodule").Arg("sync", "--", self.cmd.Quote(path)).
ToString()
if err := self.cmd.New(syncCmdStr).Run(); err != nil {
if err := self.cmd.New("git submodule sync -- " + self.cmd.Quote(path)).Run(); err != nil {
return err
}
@@ -179,45 +147,27 @@ func (self *SubmoduleCommands) UpdateUrl(name string, path string, newUrl string
}
func (self *SubmoduleCommands) Init(path string) error {
cmdStr := NewGitCmd("submodule").Arg("init", "--", self.cmd.Quote(path)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git submodule init -- " + self.cmd.Quote(path)).Run()
}
func (self *SubmoduleCommands) Update(path string) error {
cmdStr := NewGitCmd("submodule").Arg("update", "--init", "--", self.cmd.Quote(path)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git submodule update --init -- " + self.cmd.Quote(path)).Run()
}
func (self *SubmoduleCommands) BulkInitCmdObj() oscommands.ICmdObj {
cmdStr := NewGitCmd("submodule").Arg("init").
ToString()
return self.cmd.New(cmdStr)
return self.cmd.New("git submodule init")
}
func (self *SubmoduleCommands) BulkUpdateCmdObj() oscommands.ICmdObj {
cmdStr := NewGitCmd("submodule").Arg("update").
ToString()
return self.cmd.New(cmdStr)
return self.cmd.New("git submodule update")
}
func (self *SubmoduleCommands) ForceBulkUpdateCmdObj() oscommands.ICmdObj {
cmdStr := NewGitCmd("submodule").Arg("update", "--force").
ToString()
return self.cmd.New(cmdStr)
return self.cmd.New("git submodule update --force")
}
func (self *SubmoduleCommands) BulkDeinitCmdObj() oscommands.ICmdObj {
cmdStr := NewGitCmd("submodule").Arg("deinit", "--all", "--force").
ToString()
return self.cmd.New(cmdStr)
return self.cmd.New("git submodule deinit --all --force")
}
func (self *SubmoduleCommands) ResetSubmodules(submodules []*models.SubmoduleConfig) error {
+42 -27
View File
@@ -1,6 +1,8 @@
package git_commands
import (
"fmt"
"github.com/go-errors/errors"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
)
@@ -24,16 +26,26 @@ type PushOpts struct {
}
func (self *SyncCommands) PushCmdObj(opts PushOpts) (oscommands.ICmdObj, error) {
if opts.UpstreamBranch != "" && opts.UpstreamRemote == "" {
return nil, errors.New(self.Tr.MustSpecifyOriginError)
cmdStr := "git push"
if opts.Force {
cmdStr += " --force-with-lease"
}
cmdStr := NewGitCmd("push").
ArgIf(opts.Force, "--force-with-lease").
ArgIf(opts.SetUpstream, "--set-upstream").
ArgIf(opts.UpstreamRemote != "", self.cmd.Quote(opts.UpstreamRemote)).
ArgIf(opts.UpstreamBranch != "", self.cmd.Quote(opts.UpstreamBranch)).
ToString()
if opts.SetUpstream {
cmdStr += " --set-upstream"
}
if opts.UpstreamRemote != "" {
cmdStr += " " + self.cmd.Quote(opts.UpstreamRemote)
}
if opts.UpstreamBranch != "" {
if opts.UpstreamRemote == "" {
return nil, errors.New(self.Tr.MustSpecifyOriginError)
}
cmdStr += " " + self.cmd.Quote(opts.UpstreamBranch)
}
cmdObj := self.cmd.New(cmdStr).PromptOnCredentialRequest().WithMutex(self.syncMutex)
return cmdObj, nil
@@ -56,10 +68,14 @@ type FetchOptions struct {
// Fetch fetch git repo
func (self *SyncCommands) Fetch(opts FetchOptions) error {
cmdStr := NewGitCmd("fetch").
ArgIf(opts.RemoteName != "", self.cmd.Quote(opts.RemoteName)).
ArgIf(opts.BranchName != "", self.cmd.Quote(opts.BranchName)).
ToString()
cmdStr := "git fetch"
if opts.RemoteName != "" {
cmdStr = fmt.Sprintf("%s %s", cmdStr, self.cmd.Quote(opts.RemoteName))
}
if opts.BranchName != "" {
cmdStr = fmt.Sprintf("%s %s", cmdStr, self.cmd.Quote(opts.BranchName))
}
cmdObj := self.cmd.New(cmdStr)
if opts.Background {
@@ -77,12 +93,18 @@ type PullOptions struct {
}
func (self *SyncCommands) Pull(opts PullOptions) error {
cmdStr := NewGitCmd("pull").
Arg("--no-edit").
ArgIf(opts.FastForwardOnly, "--ff-only").
ArgIf(opts.RemoteName != "", self.cmd.Quote(opts.RemoteName)).
ArgIf(opts.BranchName != "", self.cmd.Quote(opts.BranchName)).
ToString()
cmdStr := "git pull --no-edit"
if opts.FastForwardOnly {
cmdStr += " --ff-only"
}
if opts.RemoteName != "" {
cmdStr = fmt.Sprintf("%s %s", cmdStr, self.cmd.Quote(opts.RemoteName))
}
if opts.BranchName != "" {
cmdStr = fmt.Sprintf("%s %s", cmdStr, self.cmd.Quote(opts.BranchName))
}
// setting GIT_SEQUENCE_EDITOR to ':' as a way of skipping it, in case the user
// has 'pull.rebase = interactive' configured.
@@ -90,18 +112,11 @@ func (self *SyncCommands) Pull(opts PullOptions) error {
}
func (self *SyncCommands) FastForward(branchName string, remoteName string, remoteBranchName string) error {
cmdStr := NewGitCmd("fetch").
Arg(self.cmd.Quote(remoteName)).
Arg(self.cmd.Quote(remoteBranchName) + ":" + self.cmd.Quote(branchName)).
ToString()
cmdStr := fmt.Sprintf("git fetch %s %s:%s", self.cmd.Quote(remoteName), self.cmd.Quote(remoteBranchName), self.cmd.Quote(branchName))
return self.cmd.New(cmdStr).PromptOnCredentialRequest().WithMutex(self.syncMutex).Run()
}
func (self *SyncCommands) FetchRemote(remoteName string) error {
cmdStr := NewGitCmd("fetch").
Arg(self.cmd.Quote(remoteName)).
ToString()
cmdStr := fmt.Sprintf("git fetch %s", self.cmd.Quote(remoteName))
return self.cmd.New(cmdStr).PromptOnCredentialRequest().WithMutex(self.syncMutex).Run()
}
+16 -19
View File
@@ -1,5 +1,9 @@
package git_commands
import (
"fmt"
)
type TagCommands struct {
*GitCommon
}
@@ -11,32 +15,25 @@ func NewTagCommands(gitCommon *GitCommon) *TagCommands {
}
func (self *TagCommands) CreateLightweight(tagName string, ref string) error {
cmdStr := NewGitCmd("tag").Arg("--", self.cmd.Quote(tagName)).
ArgIf(len(ref) > 0, self.cmd.Quote(ref)).
ToString()
return self.cmd.New(cmdStr).Run()
if len(ref) > 0 {
return self.cmd.New(fmt.Sprintf("git tag -- %s %s", self.cmd.Quote(tagName), self.cmd.Quote(ref))).Run()
} else {
return self.cmd.New(fmt.Sprintf("git tag -- %s", self.cmd.Quote(tagName))).Run()
}
}
func (self *TagCommands) CreateAnnotated(tagName, ref, msg string) error {
cmdStr := NewGitCmd("tag").Arg(self.cmd.Quote(tagName)).
ArgIf(len(ref) > 0, self.cmd.Quote(ref)).
Arg("-m", self.cmd.Quote(msg)).
ToString()
return self.cmd.New(cmdStr).Run()
if len(ref) > 0 {
return self.cmd.New(fmt.Sprintf("git tag %s %s -m %s", self.cmd.Quote(tagName), self.cmd.Quote(ref), self.cmd.Quote(msg))).Run()
} else {
return self.cmd.New(fmt.Sprintf("git tag %s -m %s", self.cmd.Quote(tagName), self.cmd.Quote(msg))).Run()
}
}
func (self *TagCommands) Delete(tagName string) error {
cmdStr := NewGitCmd("tag").Arg("-d", self.cmd.Quote(tagName)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git tag -d %s", self.cmd.Quote(tagName))).Run()
}
func (self *TagCommands) Push(remoteName string, tagName string) error {
cmdStr := NewGitCmd("push").Arg(self.cmd.Quote(remoteName), "tag", self.cmd.Quote(tagName)).
ToString()
return self.cmd.New(cmdStr).PromptOnCredentialRequest().WithMutex(self.syncMutex).Run()
return self.cmd.New(fmt.Sprintf("git push %s tag %s", self.cmd.Quote(remoteName), self.cmd.Quote(tagName))).PromptOnCredentialRequest().WithMutex(self.syncMutex).Run()
}
+1 -2
View File
@@ -28,8 +28,7 @@ func NewTagLoader(
func (self *TagLoader) GetTags() ([]*models.Tag, error) {
// get remote branches, sorted by creation date (descending)
// see: https://git-scm.com/docs/git-tag#Documentation/git-tag.txt---sortltkeygt
cmdStr := NewGitCmd("tag").Arg("--list", "-n", "--sort=-creatordate").ToString()
tagsOutput, err := self.cmd.New(cmdStr).DontLog().RunWithOutput()
tagsOutput, err := self.cmd.New(`git tag --list -n --sort=-creatordate`).DontLog().RunWithOutput()
if err != nil {
return nil, err
}
+1 -1
View File
@@ -15,7 +15,7 @@ type GitVersion struct {
}
func GetGitVersion(osCommand *oscommands.OSCommand) (*GitVersion, error) {
versionStr, _, err := osCommand.Cmd.New(NewGitCmd("--version").ToString()).RunWithOutputs()
versionStr, _, err := osCommand.Cmd.New("git --version").RunWithOutputs()
if err != nil {
return nil, err
}
+99 -94
View File
@@ -3,11 +3,15 @@ package git_commands
import (
"fmt"
"os"
"path/filepath"
"strings"
"time"
"github.com/go-errors/errors"
"github.com/jesseduffield/generics/slices"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/utils"
)
type WorkingTreeCommands struct {
@@ -29,7 +33,7 @@ func NewWorkingTreeCommands(
}
func (self *WorkingTreeCommands) OpenMergeToolCmdObj() oscommands.ICmdObj {
return self.cmd.New(NewGitCmd("mergetool").ToString())
return self.cmd.New("git mergetool")
}
func (self *WorkingTreeCommands) OpenMergeTool() error {
@@ -45,37 +49,30 @@ func (self *WorkingTreeCommands) StageFiles(paths []string) error {
quotedPaths := slices.Map(paths, func(path string) string {
return self.cmd.Quote(path)
})
cmdStr := NewGitCmd("add").Arg("--").Arg(quotedPaths...).ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git add -- %s", strings.Join(quotedPaths, " "))).Run()
}
// StageAll stages all files
func (self *WorkingTreeCommands) StageAll() error {
cmdStr := NewGitCmd("add").Arg("-A").ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git add -A").Run()
}
// UnstageAll unstages all files
func (self *WorkingTreeCommands) UnstageAll() error {
return self.cmd.New(NewGitCmd("reset").ToString()).Run()
return self.cmd.New("git reset").Run()
}
// 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 cmdStr string
if reset {
cmdStr = NewGitCmd("reset").Arg("HEAD", "--", self.cmd.Quote(name)).ToString()
} else {
cmdStr = NewGitCmd("rm").Arg("--cached", "--force", "--", self.cmd.Quote(name)).ToString()
}
command := "git rm --cached --force -- %s"
if reset {
command = "git reset HEAD -- %s"
}
err := self.cmd.New(cmdStr).Run()
for _, name := range fileNames {
err := self.cmd.New(fmt.Sprintf(command, self.cmd.Quote(name))).Run()
if err != nil {
return err
}
@@ -140,31 +137,22 @@ func (self *WorkingTreeCommands) DiscardAllFileChanges(file *models.File) error
quotedFileName := self.cmd.Quote(file.Name)
if file.ShortStatus == "AA" {
if err := self.cmd.New(
NewGitCmd("checkout").Arg("--ours", "--", quotedFileName).ToString(),
).Run(); err != nil {
if err := self.cmd.New("git checkout --ours -- " + quotedFileName).Run(); err != nil {
return err
}
if err := self.cmd.New(
NewGitCmd("add").Arg("--", quotedFileName).ToString(),
).Run(); err != nil {
if err := self.cmd.New("git add -- " + quotedFileName).Run(); err != nil {
return err
}
return nil
}
if file.ShortStatus == "DU" {
return self.cmd.New(
NewGitCmd("rm").Arg("rm", "--", quotedFileName).ToString(),
).Run()
return self.cmd.New("git rm -- " + quotedFileName).Run()
}
// if the file isn't tracked, we assume you want to delete it
if file.HasStagedChanges || file.HasMergeConflicts {
if err := self.cmd.New(
NewGitCmd("reset").Arg("--", quotedFileName).ToString(),
).Run(); err != nil {
if err := self.cmd.New("git reset -- " + quotedFileName).Run(); err != nil {
return err
}
}
@@ -196,8 +184,7 @@ func (self *WorkingTreeCommands) DiscardUnstagedDirChanges(node IFileNode) error
}
quotedPath := self.cmd.Quote(node.GetPath())
cmdStr := NewGitCmd("checkout").Arg("--", quotedPath).ToString()
if err := self.cmd.New(cmdStr).Run(); err != nil {
if err := self.cmd.New("git checkout -- " + quotedPath).Run(); err != nil {
return err
}
@@ -222,8 +209,7 @@ func (self *WorkingTreeCommands) RemoveUntrackedDirFiles(node IFileNode) error {
// DiscardUnstagedFileChanges directly
func (self *WorkingTreeCommands) DiscardUnstagedFileChanges(file *models.File) error {
quotedFileName := self.cmd.Quote(file.Name)
cmdStr := NewGitCmd("checkout").Arg("--", quotedFileName).ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git checkout -- " + quotedFileName).Run()
}
// Ignore adds a file to the gitignore for the repo
@@ -244,32 +230,61 @@ func (self *WorkingTreeCommands) WorktreeFileDiff(file *models.File, plain bool,
}
func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain bool, cached bool, ignoreWhitespace bool) oscommands.ICmdObj {
cachedArg := ""
trackedArg := "--"
colorArg := self.UserConfig.Git.Paging.ColorArg
quotedPath := self.cmd.Quote(node.GetPath())
quotedPrevPath := ""
ignoreWhitespaceArg := ""
contextSize := self.UserConfig.Git.DiffContextSize
if cached {
cachedArg = " --cached"
}
if !node.GetIsTracked() && !node.GetHasStagedChanges() && !cached && node.GetIsFile() {
trackedArg = "--no-index -- /dev/null"
}
if plain {
colorArg = "never"
}
if ignoreWhitespace {
ignoreWhitespaceArg = " --ignore-all-space"
}
if prevPath := node.GetPreviousPath(); prevPath != "" {
quotedPrevPath = " " + self.cmd.Quote(prevPath)
}
contextSize := self.UserConfig.Git.DiffContextSize
prevPath := node.GetPreviousPath()
noIndex := !node.GetIsTracked() && !node.GetHasStagedChanges() && !cached && node.GetIsFile()
cmdStr := NewGitCmd("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(cached, "--cached").
ArgIf(noIndex, "--no-index").
Arg("--").
ArgIf(noIndex, "/dev/null").
Arg(self.cmd.Quote(node.GetPath())).
ArgIf(prevPath != "", self.cmd.Quote(prevPath)).
ToString()
cmdStr := fmt.Sprintf("git diff --submodule --no-ext-diff --unified=%d --color=%s%s%s %s %s%s", contextSize, colorArg, ignoreWhitespaceArg, cachedArg, trackedArg, quotedPath, quotedPrevPath)
return self.cmd.New(cmdStr).DontLog()
}
func (self *WorkingTreeCommands) ApplyPatch(patch string, flags ...string) error {
filepath, err := self.SaveTemporaryPatch(patch)
if err != nil {
return err
}
return self.ApplyPatchFile(filepath, flags...)
}
func (self *WorkingTreeCommands) ApplyPatchFile(filepath string, flags ...string) error {
flagStr := ""
for _, flag := range flags {
flagStr += " --" + flag
}
return self.cmd.New(fmt.Sprintf("git apply%s %s", flagStr, self.cmd.Quote(filepath))).Run()
}
func (self *WorkingTreeCommands) SaveTemporaryPatch(patch string) (string, error) {
filepath := filepath.Join(self.os.GetTempDir(), utils.GetCurrentRepoName(), time.Now().Format("Jan _2 15.04.05.000000000")+".patch")
self.Log.Infof("saving temporary patch to %s", filepath)
if err := self.os.CreateFileWithContent(filepath, patch); err != nil {
return "", err
}
return filepath, nil
}
// 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,
@@ -281,59 +296,49 @@ func (self *WorkingTreeCommands) ShowFileDiff(from string, to string, reverse bo
func (self *WorkingTreeCommands) ShowFileDiffCmdObj(from string, to string, reverse bool, fileName string, plain bool,
ignoreWhitespace bool,
) oscommands.ICmdObj {
contextSize := self.UserConfig.Git.DiffContextSize
colorArg := self.UserConfig.Git.Paging.ColorArg
contextSize := self.UserConfig.Git.DiffContextSize
if plain {
colorArg = "never"
}
cmdStr := NewGitCmd("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").
Arg("--").
Arg(self.cmd.Quote(fileName)).
ToString()
reverseFlag := ""
if reverse {
reverseFlag = " -R"
}
return self.cmd.New(cmdStr).DontLog()
ignoreWhitespaceFlag := ""
if ignoreWhitespace {
ignoreWhitespaceFlag = " --ignore-all-space"
}
return self.cmd.
New(
fmt.Sprintf(
"git diff --submodule --no-ext-diff --unified=%d --no-renames --color=%s%s%s%s%s -- %s",
contextSize, colorArg, pad(from), pad(to), reverseFlag, ignoreWhitespaceFlag, self.cmd.Quote(fileName)),
).
DontLog()
}
// CheckoutFile checks out the file for the given commit
func (self *WorkingTreeCommands) CheckoutFile(commitSha, fileName string) error {
cmdStr := NewGitCmd("checkout").Arg(commitSha, "--", self.cmd.Quote(fileName)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New(fmt.Sprintf("git checkout %s -- %s", commitSha, self.cmd.Quote(fileName))).Run()
}
// DiscardAnyUnstagedFileChanges discards any unstaged file changes via `git checkout -- .`
// DiscardAnyUnstagedFileChanges discards any unstages file changes via `git checkout -- .`
func (self *WorkingTreeCommands) DiscardAnyUnstagedFileChanges() error {
cmdStr := NewGitCmd("checkout").Arg("--", ".").
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git checkout -- .").Run()
}
// RemoveTrackedFiles will delete the given file(s) even if they are currently tracked
func (self *WorkingTreeCommands) RemoveTrackedFiles(name string) error {
cmdStr := NewGitCmd("rm").Arg("-r", "--cached", "--", self.cmd.Quote(name)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git rm -r --cached -- " + self.cmd.Quote(name)).Run()
}
// RemoveUntrackedFiles runs `git clean -fd`
func (self *WorkingTreeCommands) RemoveUntrackedFiles() error {
cmdStr := NewGitCmd("clean").Arg("-fd").ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git clean -fd").Run()
}
// ResetAndClean removes all unstaged changes and removes all untracked files
@@ -358,23 +363,23 @@ func (self *WorkingTreeCommands) ResetAndClean() error {
// ResetHardHead runs `git reset --hard`
func (self *WorkingTreeCommands) ResetHard(ref string) error {
cmdStr := NewGitCmd("reset").Arg("--hard", self.cmd.Quote(ref)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git reset --hard " + self.cmd.Quote(ref)).Run()
}
// ResetSoft runs `git reset --soft HEAD`
func (self *WorkingTreeCommands) ResetSoft(ref string) error {
cmdStr := NewGitCmd("reset").Arg("--soft", self.cmd.Quote(ref)).
ToString()
return self.cmd.New(cmdStr).Run()
return self.cmd.New("git reset --soft " + self.cmd.Quote(ref)).Run()
}
func (self *WorkingTreeCommands) ResetMixed(ref string) error {
cmdStr := NewGitCmd("reset").Arg("--mixed", self.cmd.Quote(ref)).
ToString()
return self.cmd.New("git reset --mixed " + self.cmd.Quote(ref)).Run()
}
return self.cmd.New(cmdStr).Run()
// so that we don't have unnecessary space in our commands we use this helper function to prepend spaces to args so that in the format string we can go '%s%s%s' and if any args are missing we won't have gaps.
func pad(str string) string {
if str == "" {
return ""
}
return " " + str
}
@@ -2,6 +2,8 @@ package git_commands
import (
"fmt"
"os"
"regexp"
"testing"
"github.com/go-errors/errors"
@@ -428,6 +430,60 @@ func TestWorkingTreeCheckoutFile(t *testing.T) {
}
}
func TestWorkingTreeApplyPatch(t *testing.T) {
type scenario struct {
testName string
runner *oscommands.FakeCmdObjRunner
test func(error)
}
expectFn := func(regexStr string, errToReturn error) func(cmdObj oscommands.ICmdObj) (string, error) {
return func(cmdObj oscommands.ICmdObj) (string, error) {
re := regexp.MustCompile(regexStr)
cmdStr := cmdObj.ToString()
matches := re.FindStringSubmatch(cmdStr)
assert.Equal(t, 2, len(matches), fmt.Sprintf("unexpected command: %s", cmdStr))
filename := matches[1]
content, err := os.ReadFile(filename)
assert.NoError(t, err)
assert.Equal(t, "test", string(content))
return "", errToReturn
}
}
scenarios := []scenario{
{
testName: "valid case",
runner: oscommands.NewFakeRunner(t).
ExpectFunc(expectFn(`git apply --cached "(.*)"`, nil)),
test: func(err error) {
assert.NoError(t, err)
},
},
{
testName: "command returns error",
runner: oscommands.NewFakeRunner(t).
ExpectFunc(expectFn(`git apply --cached "(.*)"`, errors.New("error"))),
test: func(err error) {
assert.Error(t, err)
},
},
}
for _, s := range scenarios {
s := s
t.Run(s.testName, func(t *testing.T) {
instance := buildWorkingTreeCommands(commonDeps{runner: s.runner})
s.test(instance.ApplyPatch("test", "cached"))
s.runner.CheckForMissingCalls()
})
}
}
func TestWorkingTreeDiscardUnstagedFileChanges(t *testing.T) {
type scenario struct {
testName string
+24 -15
View File
@@ -29,6 +29,7 @@ type fileInfo struct {
}
type (
applyPatchFunc func(patch string, flags ...string) error
loadFileDiffFunc func(from string, to string, reverse bool, filename string, plain bool) (string, error)
)
@@ -46,14 +47,17 @@ type PatchBuilder struct {
// fileInfoMap starts empty but you add files to it as you go along
fileInfoMap map[string]*fileInfo
Log *logrus.Entry
applyPatch applyPatchFunc
// loadFileDiff loads the diff of a file, for a given to (typically a commit SHA)
loadFileDiff loadFileDiffFunc
}
func NewPatchBuilder(log *logrus.Entry, loadFileDiff loadFileDiffFunc) *PatchBuilder {
// NewPatchBuilder returns a new PatchBuilder
func NewPatchBuilder(log *logrus.Entry, applyPatch applyPatchFunc, loadFileDiff loadFileDiffFunc) *PatchBuilder {
return &PatchBuilder{
Log: log,
applyPatch: applyPatch,
loadFileDiff: loadFileDiff,
}
}
@@ -66,20 +70,6 @@ func (p *PatchBuilder) Start(from, to string, reverse bool, canRebase bool) {
p.fileInfoMap = map[string]*fileInfo{}
}
func (p *PatchBuilder) PatchToApply(reverse bool) string {
patch := ""
for filename, info := range p.fileInfoMap {
if info.mode == UNSELECTED {
continue
}
patch += p.RenderPatchForFile(filename, true, reverse)
}
return patch
}
func (p *PatchBuilder) addFileWhole(info *fileInfo) {
info.mode = WHOLE
lineCount := len(strings.Split(info.diff, "\n"))
@@ -244,6 +234,25 @@ func (p *PatchBuilder) GetFileIncLineIndices(filename string) ([]int, error) {
return info.includedLineIndices, nil
}
func (p *PatchBuilder) ApplyPatches(reverse bool) error {
patch := ""
applyFlags := []string{"index", "3way"}
if reverse {
applyFlags = append(applyFlags, "reverse")
}
for filename, info := range p.fileInfoMap {
if info.mode == UNSELECTED {
continue
}
patch += p.RenderPatchForFile(filename, true, reverse)
}
return p.applyPatch(patch, applyFlags...)
}
// clears the patch
func (p *PatchBuilder) Reset() {
p.To = ""
+40 -42
View File
@@ -27,34 +27,33 @@ type RefresherConfig struct {
}
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"`
SkipUnstageLineWarning bool `yaml:"skipUnstageLineWarning"`
SkipStashWarning bool `yaml:"skipStashWarning"`
SidePanelWidth float64 `yaml:"sidePanelWidth"`
ExpandFocusedSidePanel bool `yaml:"expandFocusedSidePanel"`
MainPanelSplitMode string `yaml:"mainPanelSplitMode"`
Language string `yaml:"language"`
TimeFormat string `yaml:"timeFormat"`
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"`
ExperimentalShowBranchHeads bool `yaml:"experimentalShowBranchHeads"`
CommandLogSize int `yaml:"commandLogSize"`
SplitDiff string `yaml:"splitDiff"`
SkipRewordInEditorWarning bool `yaml:"skipRewordInEditorWarning"`
WindowSize string `yaml:"windowSize"`
Border string `yaml:"border"`
ExperimentalMarkCommitsWhichChangedFile bool `yaml:"experimentalMarkCommitsWhichChangedFile"`
AuthorColors map[string]string `yaml:"authorColors"`
BranchColors map[string]string `yaml:"branchColors"`
ScrollHeight int `yaml:"scrollHeight"`
ScrollPastBottom bool `yaml:"scrollPastBottom"`
MouseEvents bool `yaml:"mouseEvents"`
SkipUnstageLineWarning bool `yaml:"skipUnstageLineWarning"`
SkipStashWarning bool `yaml:"skipStashWarning"`
SidePanelWidth float64 `yaml:"sidePanelWidth"`
ExpandFocusedSidePanel bool `yaml:"expandFocusedSidePanel"`
MainPanelSplitMode string `yaml:"mainPanelSplitMode"`
Language string `yaml:"language"`
TimeFormat string `yaml:"timeFormat"`
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"`
ExperimentalShowBranchHeads bool `yaml:"experimentalShowBranchHeads"`
CommandLogSize int `yaml:"commandLogSize"`
SplitDiff string `yaml:"splitDiff"`
SkipRewordInEditorWarning bool `yaml:"skipRewordInEditorWarning"`
WindowSize string `yaml:"windowSize"`
Border string `yaml:"border"`
}
type ThemeConfig struct {
@@ -411,20 +410,19 @@ func GetDefaultConfig() *UserConfig {
UnstagedChangesColor: []string{"red"},
DefaultFgColor: []string{"default"},
},
CommitLength: CommitLengthConfig{Show: true},
SkipNoStagedFilesWarning: false,
ShowListFooter: true,
ShowCommandLog: true,
ShowBottomLine: true,
ShowFileTree: true,
ShowRandomTip: true,
ShowIcons: false,
ExperimentalShowBranchHeads: false,
CommandLogSize: 8,
SplitDiff: "auto",
SkipRewordInEditorWarning: false,
Border: "single",
ExperimentalMarkCommitsWhichChangedFile: false,
CommitLength: CommitLengthConfig{Show: true},
SkipNoStagedFilesWarning: false,
ShowListFooter: true,
ShowCommandLog: true,
ShowBottomLine: true,
ShowFileTree: true,
ShowRandomTip: true,
ShowIcons: false,
ExperimentalShowBranchHeads: false,
CommandLogSize: 8,
SplitDiff: "auto",
SkipRewordInEditorWarning: false,
Border: "single",
},
Git: GitConfig{
Paging: PagingConfig{
+1 -1
View File
@@ -104,7 +104,7 @@ func (gui *Gui) getRandomTip() string {
),
fmt.Sprintf(
"to hard reset onto your current upstream branch, press '%s' in the files panel",
formattedKey(config.Commits.ViewResetOptions),
formattedKey(config.Files.ViewResetOptions),
),
fmt.Sprintf(
"To push a tag, navigate to the tag in the tags tab and press '%s'",
+1 -6
View File
@@ -13,8 +13,6 @@ type ListContextTrait struct {
c *ContextCommon
list types.IList
getDisplayStrings func(startIdx int, length int) [][]string
// alignment for each column. If nil, the default is left alignment
columnAlignments []utils.Alignment
}
func (self *ListContextTrait) IsListContext() {}
@@ -54,10 +52,7 @@ func (self *ListContextTrait) HandleFocusLost(opts types.OnFocusLostOpts) error
// OnFocus assumes that the content of the context has already been rendered to the view. OnRender is the function which actually renders the content to the view
func (self *ListContextTrait) HandleRender() error {
self.list.RefreshSelectedIdx()
content := utils.RenderDisplayStrings(
self.getDisplayStrings(0, self.list.Len()),
self.columnAlignments,
)
content := utils.RenderDisplayStrings(self.getDisplayStrings(0, self.list.Len()))
self.GetViewTrait().SetContent(content)
self.c.Render()
self.setFooter()
+10 -33
View File
@@ -3,7 +3,6 @@ package context
import (
"log"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/types/enums"
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
@@ -38,14 +37,20 @@ func NewLocalCommitsContext(c *ContextCommon) *LocalCommitsContext {
showYouAreHereLabel := c.Model().WorkingTreeStateAtLastCommitRefresh == enums.REBASE_MODE_REBASING
return getCommitsDisplayStrings(
c,
return presentation.GetCommitListDisplayStrings(
c.Common,
c.Model().Commits,
c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL,
c.Modes().CherryPicking.SelectedShaSet(),
c.Modes().Diffing.Ref,
c.UserConfig.Gui.TimeFormat,
c.UserConfig.Git.ParseEmoji,
selectedCommitSha,
startIdx,
length,
selectedCommitSha,
showYouAreHereLabel,
shouldShowGraph(c),
c.Model().BisectInfo,
showYouAreHereLabel,
)
}
@@ -154,31 +159,3 @@ func shouldShowGraph(c *ContextCommon) bool {
log.Fatalf("Unknown value for git.log.showGraph: %s. Expected one of: 'always', 'never', 'when-maximised'", value)
return false
}
func getCommitsDisplayStrings(
c *ContextCommon,
commits []*models.Commit,
startIdx int,
length int,
selectedCommitSha string,
showYouAreHereLabel bool,
bisectInfo *git_commands.BisectInfo,
) [][]string {
return presentation.GetCommitListDisplayStrings(
c.Common,
commits,
c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL,
c.Modes().CherryPicking.SelectedShaSet(),
c.Modes().Diffing.Ref,
c.UserConfig.Gui.TimeFormat,
c.UserConfig.Git.ParseEmoji,
selectedCommitSha,
startIdx,
length,
shouldShowGraph(c),
bisectInfo,
showYouAreHereLabel,
c.State().GetRepoState().GetRecentCommitsWhichChangedFile(),
c.UserConfig.Gui.ExperimentalMarkCommitsWhichChangedFile,
)
}
+4 -28
View File
@@ -5,13 +5,9 @@ import (
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
"github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
)
type MenuContext struct {
c *ContextCommon
*MenuViewModel
*ListContextTrait
}
@@ -21,10 +17,9 @@ var _ types.IListContext = (*MenuContext)(nil)
func NewMenuContext(
c *ContextCommon,
) *MenuContext {
viewModel := NewMenuViewModel(c)
viewModel := NewMenuViewModel()
return &MenuContext{
c: c,
MenuViewModel: viewModel,
ListContextTrait: &ListContextTrait{
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
@@ -38,7 +33,6 @@ func NewMenuContext(
getDisplayStrings: viewModel.GetDisplayStrings,
list: viewModel,
c: c,
columnAlignments: []utils.Alignment{utils.AlignRight, utils.AlignLeft},
},
}
}
@@ -54,15 +48,13 @@ func (self *MenuContext) GetSelectedItemId() string {
}
type MenuViewModel struct {
c *ContextCommon
menuItems []*types.MenuItem
*BasicViewModel[*types.MenuItem]
}
func NewMenuViewModel(c *ContextCommon) *MenuViewModel {
func NewMenuViewModel() *MenuViewModel {
self := &MenuViewModel{
menuItems: nil,
c: c,
}
self.BasicViewModel = NewBasicViewModel(func() []*types.MenuItem { return self.menuItems })
@@ -82,25 +74,9 @@ func (self *MenuViewModel) GetDisplayStrings(_startIdx int, _length int) [][]str
return slices.Map(self.menuItems, func(item *types.MenuItem) []string {
displayStrings := item.LabelColumns
if !showKeys {
return displayStrings
if showKeys {
displayStrings = slices.Prepend(displayStrings, style.FgCyan.Sprint(keybindings.LabelFromKey(item.Key)))
}
// These keys are used for general navigation so we'll strike them out to
// avoid confusion
reservedKeys := []string{
self.c.UserConfig.Keybinding.Universal.Confirm,
self.c.UserConfig.Keybinding.Universal.Select,
self.c.UserConfig.Keybinding.Universal.Return,
}
keyLabel := keybindings.LabelFromKey(item.Key)
keyStyle := style.FgCyan
if lo.Contains(reservedKeys, keyLabel) {
keyStyle = style.FgDefault.SetStrikethrough()
}
displayStrings = slices.Prepend(displayStrings, keyStyle.Sprint(keyLabel))
return displayStrings
})
}
+11 -4
View File
@@ -5,6 +5,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
)
@@ -39,14 +40,20 @@ func NewSubCommitsContext(
selectedCommitSha = selectedCommit.Sha
}
}
return getCommitsDisplayStrings(
c,
return presentation.GetCommitListDisplayStrings(
c.Common,
c.Model().SubCommits,
c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL,
c.Modes().CherryPicking.SelectedShaSet(),
c.Modes().Diffing.Ref,
c.UserConfig.Gui.TimeFormat,
c.UserConfig.Git.ParseEmoji,
selectedCommitSha,
startIdx,
length,
selectedCommitSha,
false,
shouldShowGraph(c),
git_commands.NewNullBisectInfo(),
false,
)
}
@@ -17,6 +17,6 @@ func (self *ViewportListContextTrait) FocusLine() {
startIdx, length := self.GetViewTrait().ViewPortYBounds()
displayStrings := self.ListContextTrait.getDisplayStrings(startIdx, length)
content := utils.RenderDisplayStrings(displayStrings, nil)
content := utils.RenderDisplayStrings(displayStrings)
self.GetViewTrait().SetViewPortContent(content)
}
@@ -199,7 +199,7 @@ func (self *CustomPatchOptionsMenuAction) handleApplyPatch(reverse bool) error {
action = "Apply patch in reverse"
}
self.c.LogAction(action)
if err := self.c.Git().Patch.ApplyCustomPatch(reverse); err != nil {
if err := self.c.Git().Patch.PatchBuilder.ApplyPatches(reverse); err != nil {
return self.c.Error(err)
}
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
-11
View File
@@ -9,7 +9,6 @@ import (
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
)
type FilesController struct {
@@ -193,16 +192,6 @@ func (self *FilesController) GetOnRenderToMain() func() error {
}
}
if self.c.UserConfig.Gui.ExperimentalMarkCommitsWhichChangedFile {
go utils.Safe(func() {
recentCommitsWhichChangedFile := self.c.Git().Commit.GetRecentCommitsWhichChangedFile(node.GetPath())
self.c.OnUIThread(func() error {
self.c.State().GetRepoState().SetRecentCommitsWhichChangedFile(recentCommitsWhichChangedFile)
return self.c.PostRefreshUpdate(self.c.Contexts().LocalCommits)
})
})
}
self.c.Helpers().MergeConflicts.ResetMergeState()
pair := self.c.MainViewPairs().Normal
-2
View File
@@ -21,8 +21,6 @@ func NewMenuController(
}
}
// NOTE: if you add a new keybinding here, you'll also need to add it to
// `reservedKeys` in `pkg/gui/context/menu_context.go`
func (self *MenuController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
bindings := []*types.Binding{
{
+14 -16
View File
@@ -4,7 +4,6 @@ import (
"strings"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/patch"
"github.com/jesseduffield/lazygit/pkg/gui/types"
)
@@ -214,14 +213,15 @@ func (self *StagingController) applySelection(reverse bool) error {
// apply the patch then refresh this panel
// create a new temp file with the patch, then call git apply with that patch
applyFlags := []string{}
if reverse {
applyFlags = append(applyFlags, "reverse")
}
if !reverse || self.staged {
applyFlags = append(applyFlags, "cached")
}
self.c.LogAction(self.c.Tr.Actions.ApplyPatch)
err := self.c.Git().Patch.ApplyPatch(
patchToApply,
git_commands.ApplyPatchOpts{
Reverse: reverse,
Cached: !reverse || self.staged,
},
)
err := self.c.Git().WorkingTree.ApplyPatch(patchToApply, applyFlags...)
if err != nil {
return self.c.Error(err)
}
@@ -262,7 +262,7 @@ func (self *StagingController) editHunk() error {
}).
FormatPlain()
patchFilepath, err := self.c.Git().Patch.SaveTemporaryPatch(patchText)
patchFilepath, err := self.c.Git().WorkingTree.SaveTemporaryPatch(patchText)
if err != nil {
return err
}
@@ -289,13 +289,11 @@ func (self *StagingController) editHunk() error {
}).
FormatPlain()
if err := self.c.Git().Patch.ApplyPatch(
newPatchText,
git_commands.ApplyPatchOpts{
Reverse: self.staged,
Cached: true,
},
); err != nil {
applyFlags := []string{"cached"}
if self.staged {
applyFlags = append(applyFlags, "reverse")
}
if err := self.c.Git().WorkingTree.ApplyPatch(newPatchText, applyFlags...); err != nil {
return self.c.Error(err)
}
-10
View File
@@ -220,8 +220,6 @@ type GuiRepoState struct {
ScreenMode types.WindowMaximisation
CurrentPopupOpts *types.CreatePopupPanelOpts
RecentCommitsWhichChangedFile []string
}
var _ types.IRepoStateAccessor = new(GuiRepoState)
@@ -270,14 +268,6 @@ func (self *GuiRepoState) GetSplitMainPanel() bool {
return self.SplitMainPanel
}
func (self *GuiRepoState) SetRecentCommitsWhichChangedFile(value []string) {
self.RecentCommitsWhichChangedFile = value
}
func (self *GuiRepoState) GetRecentCommitsWhichChangedFile() []string {
return self.RecentCommitsWhichChangedFile
}
type searchingState struct {
view *gocui.View
isSearching bool
+135 -66
View File
@@ -9,73 +9,142 @@ import (
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/constants"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/samber/lo"
)
var labelByKey = map[gocui.Key]string{
gocui.KeyF1: "<f1>",
gocui.KeyF2: "<f2>",
gocui.KeyF3: "<f3>",
gocui.KeyF4: "<f4>",
gocui.KeyF5: "<f5>",
gocui.KeyF6: "<f6>",
gocui.KeyF7: "<f7>",
gocui.KeyF8: "<f8>",
gocui.KeyF9: "<f9>",
gocui.KeyF10: "<f10>",
gocui.KeyF11: "<f11>",
gocui.KeyF12: "<f12>",
gocui.KeyInsert: "<insert>",
gocui.KeyDelete: "<delete>",
gocui.KeyHome: "<home>",
gocui.KeyEnd: "<end>",
gocui.KeyPgup: "<pgup>",
gocui.KeyPgdn: "<pgdown>",
gocui.KeyArrowUp: "<up>",
gocui.KeyArrowDown: "<down>",
gocui.KeyArrowLeft: "<left>",
gocui.KeyArrowRight: "<right>",
gocui.KeyTab: "<tab>", // <c-i>
gocui.KeyBacktab: "<backtab>",
gocui.KeyEnter: "<enter>", // <c-m>
gocui.KeyAltEnter: "<a-enter>",
gocui.KeyEsc: "<esc>", // <c-[>, <c-3>
gocui.KeyBackspace: "<backspace>", // <c-h>
gocui.KeyCtrlSpace: "<c-space>", // <c-~>, <c-2>
gocui.KeyCtrlSlash: "<c-/>", // <c-_>
gocui.KeySpace: "<space>",
gocui.KeyCtrlA: "<c-a>",
gocui.KeyCtrlB: "<c-b>",
gocui.KeyCtrlC: "<c-c>",
gocui.KeyCtrlD: "<c-d>",
gocui.KeyCtrlE: "<c-e>",
gocui.KeyCtrlF: "<c-f>",
gocui.KeyCtrlG: "<c-g>",
gocui.KeyCtrlJ: "<c-j>",
gocui.KeyCtrlK: "<c-k>",
gocui.KeyCtrlL: "<c-l>",
gocui.KeyCtrlN: "<c-n>",
gocui.KeyCtrlO: "<c-o>",
gocui.KeyCtrlP: "<c-p>",
gocui.KeyCtrlQ: "<c-q>",
gocui.KeyCtrlR: "<c-r>",
gocui.KeyCtrlS: "<c-s>",
gocui.KeyCtrlT: "<c-t>",
gocui.KeyCtrlU: "<c-u>",
gocui.KeyCtrlV: "<c-v>",
gocui.KeyCtrlW: "<c-w>",
gocui.KeyCtrlX: "<c-x>",
gocui.KeyCtrlY: "<c-y>",
gocui.KeyCtrlZ: "<c-z>",
gocui.KeyCtrl4: "<c-4>", // <c-\>
gocui.KeyCtrl5: "<c-5>", // <c-]>
gocui.KeyCtrl6: "<c-6>",
gocui.KeyCtrl8: "<c-8>",
gocui.MouseWheelUp: "mouse wheel up",
gocui.MouseWheelDown: "mouse wheel down",
var keyMapReversed = map[gocui.Key]string{
gocui.KeyF1: "f1",
gocui.KeyF2: "f2",
gocui.KeyF3: "f3",
gocui.KeyF4: "f4",
gocui.KeyF5: "f5",
gocui.KeyF6: "f6",
gocui.KeyF7: "f7",
gocui.KeyF8: "f8",
gocui.KeyF9: "f9",
gocui.KeyF10: "f10",
gocui.KeyF11: "f11",
gocui.KeyF12: "f12",
gocui.KeyInsert: "insert",
gocui.KeyDelete: "delete",
gocui.KeyHome: "home",
gocui.KeyEnd: "end",
gocui.KeyPgup: "pgup",
gocui.KeyPgdn: "pgdown",
gocui.KeyArrowUp: "▲",
gocui.KeyArrowDown: "▼",
gocui.KeyArrowLeft: "◀",
gocui.KeyArrowRight: "▶",
gocui.KeyTab: "tab", // ctrl+i
gocui.KeyBacktab: "shift+tab",
gocui.KeyEnter: "enter", // ctrl+m
gocui.KeyAltEnter: "alt+enter",
gocui.KeyEsc: "esc", // ctrl+[, ctrl+3
gocui.KeyBackspace: "backspace", // ctrl+h
gocui.KeyCtrlSpace: "ctrl+space", // ctrl+~, ctrl+2
gocui.KeyCtrlSlash: "ctrl+/", // ctrl+_
gocui.KeySpace: "space",
gocui.KeyCtrlA: "ctrl+a",
gocui.KeyCtrlB: "ctrl+b",
gocui.KeyCtrlC: "ctrl+c",
gocui.KeyCtrlD: "ctrl+d",
gocui.KeyCtrlE: "ctrl+e",
gocui.KeyCtrlF: "ctrl+f",
gocui.KeyCtrlG: "ctrl+g",
gocui.KeyCtrlJ: "ctrl+j",
gocui.KeyCtrlK: "ctrl+k",
gocui.KeyCtrlL: "ctrl+l",
gocui.KeyCtrlN: "ctrl+n",
gocui.KeyCtrlO: "ctrl+o",
gocui.KeyCtrlP: "ctrl+p",
gocui.KeyCtrlQ: "ctrl+q",
gocui.KeyCtrlR: "ctrl+r",
gocui.KeyCtrlS: "ctrl+s",
gocui.KeyCtrlT: "ctrl+t",
gocui.KeyCtrlU: "ctrl+u",
gocui.KeyCtrlV: "ctrl+v",
gocui.KeyCtrlW: "ctrl+w",
gocui.KeyCtrlX: "ctrl+x",
gocui.KeyCtrlY: "ctrl+y",
gocui.KeyCtrlZ: "ctrl+z",
gocui.KeyCtrl4: "ctrl+4", // ctrl+\
gocui.KeyCtrl5: "ctrl+5", // ctrl+]
gocui.KeyCtrl6: "ctrl+6",
gocui.KeyCtrl8: "ctrl+8",
gocui.MouseWheelUp: "mouse wheel ▲",
gocui.MouseWheelDown: "mouse wheel ▼",
}
var keyByLabel = lo.Invert(labelByKey)
var keyMap = map[string]types.Key{
"<c-a>": gocui.KeyCtrlA,
"<c-b>": gocui.KeyCtrlB,
"<c-c>": gocui.KeyCtrlC,
"<c-d>": gocui.KeyCtrlD,
"<c-e>": gocui.KeyCtrlE,
"<c-f>": gocui.KeyCtrlF,
"<c-g>": gocui.KeyCtrlG,
"<c-h>": gocui.KeyCtrlH,
"<c-i>": gocui.KeyCtrlI,
"<c-j>": gocui.KeyCtrlJ,
"<c-k>": gocui.KeyCtrlK,
"<c-l>": gocui.KeyCtrlL,
"<c-m>": gocui.KeyCtrlM,
"<c-n>": gocui.KeyCtrlN,
"<c-o>": gocui.KeyCtrlO,
"<c-p>": gocui.KeyCtrlP,
"<c-q>": gocui.KeyCtrlQ,
"<c-r>": gocui.KeyCtrlR,
"<c-s>": gocui.KeyCtrlS,
"<c-t>": gocui.KeyCtrlT,
"<c-u>": gocui.KeyCtrlU,
"<c-v>": gocui.KeyCtrlV,
"<c-w>": gocui.KeyCtrlW,
"<c-x>": gocui.KeyCtrlX,
"<c-y>": gocui.KeyCtrlY,
"<c-z>": gocui.KeyCtrlZ,
"<c-~>": gocui.KeyCtrlTilde,
"<c-2>": gocui.KeyCtrl2,
"<c-3>": gocui.KeyCtrl3,
"<c-4>": gocui.KeyCtrl4,
"<c-5>": gocui.KeyCtrl5,
"<c-6>": gocui.KeyCtrl6,
"<c-7>": gocui.KeyCtrl7,
"<c-8>": gocui.KeyCtrl8,
"<c-space>": gocui.KeyCtrlSpace,
"<c-\\>": gocui.KeyCtrlBackslash,
"<c-[>": gocui.KeyCtrlLsqBracket,
"<c-]>": gocui.KeyCtrlRsqBracket,
"<c-/>": gocui.KeyCtrlSlash,
"<c-_>": gocui.KeyCtrlUnderscore,
"<backspace>": gocui.KeyBackspace,
"<tab>": gocui.KeyTab,
"<backtab>": gocui.KeyBacktab,
"<enter>": gocui.KeyEnter,
"<a-enter>": gocui.KeyAltEnter,
"<esc>": gocui.KeyEsc,
"<space>": gocui.KeySpace,
"<f1>": gocui.KeyF1,
"<f2>": gocui.KeyF2,
"<f3>": gocui.KeyF3,
"<f4>": gocui.KeyF4,
"<f5>": gocui.KeyF5,
"<f6>": gocui.KeyF6,
"<f7>": gocui.KeyF7,
"<f8>": gocui.KeyF8,
"<f9>": gocui.KeyF9,
"<f10>": gocui.KeyF10,
"<f11>": gocui.KeyF11,
"<f12>": gocui.KeyF12,
"<insert>": gocui.KeyInsert,
"<delete>": gocui.KeyDelete,
"<home>": gocui.KeyHome,
"<end>": gocui.KeyEnd,
"<pgup>": gocui.KeyPgup,
"<pgdown>": gocui.KeyPgdn,
"<up>": gocui.KeyArrowUp,
"<down>": gocui.KeyArrowDown,
"<left>": gocui.KeyArrowLeft,
"<right>": gocui.KeyArrowRight,
}
func Label(name string) string {
return LabelFromKey(GetKey(name))
@@ -88,7 +157,7 @@ func LabelFromKey(key types.Key) string {
case rune:
keyInt = int(key)
case gocui.Key:
value, ok := labelByKey[key]
value, ok := keyMapReversed[key]
if ok {
return value
}
@@ -101,8 +170,8 @@ func LabelFromKey(key types.Key) string {
func GetKey(key string) types.Key {
runeCount := utf8.RuneCountInString(key)
if runeCount > 1 {
binding, ok := keyByLabel[strings.ToLower(key)]
if !ok {
binding := keyMap[strings.ToLower(key)]
if binding == nil {
log.Fatalf("Unrecognized key %s for keybinding. For permitted values see %s", strings.ToLower(key), constants.Links.Docs.CustomKeybindings)
} else {
return binding
+4
View File
@@ -60,6 +60,10 @@ func (self *OptionsMapMgr) globalOptions() []bindingInfo {
key: fmt.Sprintf("%s/%s", keybindings.Label(keybindingConfig.Universal.ScrollUpMain), keybindings.Label(keybindingConfig.Universal.ScrollDownMain)),
description: self.c.Tr.LcScroll,
},
{
key: fmt.Sprintf("%s %s %s %s", keybindings.Label(keybindingConfig.Universal.PrevBlock), keybindings.Label(keybindingConfig.Universal.NextBlock), keybindings.Label(keybindingConfig.Universal.PrevItem), keybindings.Label(keybindingConfig.Universal.NextItem)),
description: self.c.Tr.LcNavigate,
},
{
key: keybindings.Label(keybindingConfig.Universal.Return),
description: self.c.Tr.LcCancel,
+1 -1
View File
@@ -42,7 +42,7 @@ func LongAuthor(authorName string) string {
return value
}
paddedAuthorName := utils.WithPadding(authorName, 17, utils.AlignLeft)
paddedAuthorName := utils.WithPadding(authorName, 17)
truncatedName := utils.TruncateWithEllipsis(paddedAuthorName, 17)
value := AuthorStyle(authorName).Sprint(truncatedName)
authorNameCache[authorName] = value
+1 -1
View File
@@ -35,7 +35,7 @@ func getBranchDisplayStrings(b *models.Branch, fullDescription bool, diffed bool
}
coloredName := nameTextStyle.Sprint(displayName)
branchStatus := utils.WithPadding(ColoredBranchStatus(b, tr), 2, utils.AlignLeft)
branchStatus := utils.WithPadding(ColoredBranchStatus(b, tr), 2)
coloredName = fmt.Sprintf("%s %s", coloredName, branchStatus)
recencyColor := style.FgCyan
+1 -24
View File
@@ -16,7 +16,6 @@ import (
"github.com/jesseduffield/lazygit/pkg/theme"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/kyokomi/emoji/v2"
"github.com/samber/lo"
"github.com/sasha-s/go-deadlock"
)
@@ -49,8 +48,6 @@ func GetCommitListDisplayStrings(
showGraph bool,
bisectInfo *git_commands.BisectInfo,
showYouAreHereLabel bool,
recentCommitsWhichChangedFile []string,
markRecentFileChanges bool,
) [][]string {
mutex.Lock()
defer mutex.Unlock()
@@ -116,8 +113,6 @@ func GetCommitListDisplayStrings(
bisectStatus,
bisectInfo,
isYouAreHereCommit,
recentCommitsWhichChangedFile,
markRecentFileChanges,
))
}
return lines
@@ -264,8 +259,6 @@ func displayCommit(
bisectStatus BisectStatus,
bisectInfo *git_commands.BisectInfo,
isYouAreHereCommit bool,
recentCommitsWhichChangedFile []string,
markRecentFileChanges bool,
) []string {
shaColor := getShaColor(commit, diffName, cherryPickedCommitShaSet, bisectStatus, bisectInfo)
bisectString := getBisectStatusText(bisectStatus, bisectInfo)
@@ -306,23 +299,7 @@ func displayCommit(
cols := make([]string, 0, 7)
if icons.IsIconEnabled() {
if markRecentFileChanges && lo.SomeBy(recentCommitsWhichChangedFile, func(sha string) bool {
return utils.ShortSha(sha) == utils.ShortSha(commit.Sha)
}) {
cols = append(cols, style.FgDefault.Sprint(">"))
} else {
cols = append(cols, shaColor.Sprint(icons.IconForCommit(commit)))
}
} else {
if markRecentFileChanges {
if lo.SomeBy(recentCommitsWhichChangedFile, func(sha string) bool {
return utils.ShortSha(sha) == utils.ShortSha(commit.Sha)
}) {
cols = append(cols, style.FgDefault.Sprint(">"))
} else {
cols = append(cols, " ")
}
}
cols = append(cols, shaColor.Sprint(icons.IconForCommit(commit)))
}
cols = append(cols, shaColor.Sprint(commit.ShortSha()))
cols = append(cols, bisectString)
+1 -1
View File
@@ -283,7 +283,7 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
s.showYouAreHereLabel,
)
renderedResult := utils.RenderDisplayStrings(result, nil)
renderedResult := utils.RenderDisplayStrings(result)
t.Logf("\n%s", renderedResult)
assert.EqualValues(t, s.expected, renderedResult)
+1
View File
@@ -136,6 +136,7 @@ M file1
}
patchBuilder := patch.NewPatchBuilder(
utils.NewDummyLog(),
func(patch string, flags ...string) error { return nil },
func(from string, to string, reverse bool, filename string, plain bool) (string, error) {
return "", nil
},
+3 -16
View File
@@ -3,10 +3,9 @@ package style
import "github.com/gookit/color"
type Decoration struct {
bold bool
underline bool
reverse bool
strikethrough bool
bold bool
underline bool
reverse bool
}
func (d *Decoration) SetBold() {
@@ -21,10 +20,6 @@ func (d *Decoration) SetReverse() {
d.reverse = true
}
func (d *Decoration) SetStrikethrough() {
d.strikethrough = true
}
func (d Decoration) ToOpts() color.Opts {
opts := make([]color.Color, 0, 3)
@@ -40,10 +35,6 @@ func (d Decoration) ToOpts() color.Opts {
opts = append(opts, color.OpReverse)
}
if d.strikethrough {
opts = append(opts, color.OpStrikethrough)
}
return opts
}
@@ -60,9 +51,5 @@ func (d Decoration) Merge(other Decoration) Decoration {
d.reverse = true
}
if other.strikethrough {
d.strikethrough = true
}
return d
}
-6
View File
@@ -98,12 +98,6 @@ func (b TextStyle) SetReverse() TextStyle {
return b
}
func (b TextStyle) SetStrikethrough() TextStyle {
b.decoration.SetStrikethrough()
b.Style = b.deriveStyle()
return b
}
func (b TextStyle) SetBg(color Color) TextStyle {
b.bg = &color
b.Style = b.deriveStyle()
-2
View File
@@ -254,8 +254,6 @@ type IRepoStateAccessor interface {
IsSearching() bool
SetSplitMainPanel(bool)
GetSplitMainPanel() bool
SetRecentCommitsWhichChangedFile([]string)
GetRecentCommitsWhichChangedFile() []string
}
// startup stages so we don't need to load everything at once
-2
View File
@@ -368,7 +368,6 @@ type TranslationSet struct {
LcStartSearch string
Panel string
Keybindings string
KeybindingsLegend string
LcRenameBranch string
LcSetUnsetUpstream string
NewGitFlowBranchPrompt string
@@ -1040,7 +1039,6 @@ func EnglishTranslationSet() TranslationSet {
LcStartSearch: "start search",
Panel: "Panel",
Keybindings: "Keybindings",
KeybindingsLegend: "Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b",
LcRenameBranch: "rename branch",
LcSetUnsetUpstream: "set/unset upstream",
NewBranchNamePrompt: "Enter new branch name for branch",
-2
View File
@@ -17,8 +17,6 @@ func GetTextStyle(keys []string, background bool) style.TextStyle {
s = s.SetReverse()
case "underline":
s = s.SetUnderline()
case "strikethrough":
s = s.SetStrikethrough()
default:
value, present := style.ColorMap[key]
if present {
+9 -41
View File
@@ -8,52 +8,20 @@ import (
"github.com/samber/lo"
)
type Alignment int
const (
AlignLeft Alignment = iota
AlignRight
)
type ColumnConfig struct {
Width int
Alignment Alignment
}
// WithPadding pads a string as much as you want
func WithPadding(str string, padding int, alignment Alignment) string {
func WithPadding(str string, padding int) string {
uncoloredStr := Decolorise(str)
width := runewidth.StringWidth(uncoloredStr)
if padding < width {
return str
}
space := strings.Repeat(" ", padding-width)
if alignment == AlignLeft {
return str + space
} else {
return space + str
}
return str + strings.Repeat(" ", padding-width)
}
// defaults to left-aligning each column. If you want to set the alignment of
// each column, pass in a slice of Alignment values.
func RenderDisplayStrings(displayStringsArr [][]string, columnAlignments []Alignment) string {
func RenderDisplayStrings(displayStringsArr [][]string) string {
displayStringsArr = excludeBlankColumns(displayStringsArr)
padWidths := getPadWidths(displayStringsArr)
columnConfigs := make([]ColumnConfig, len(padWidths))
for i, padWidth := range padWidths {
// gracefully handle when columnAlignments is shorter than padWidths
alignment := AlignLeft
if len(columnAlignments) > i {
alignment = columnAlignments[i]
}
columnConfigs[i] = ColumnConfig{
Width: padWidth,
Alignment: alignment,
}
}
output := getPaddedDisplayStrings(displayStringsArr, columnConfigs)
output := getPaddedDisplayStrings(displayStringsArr, padWidths)
return output
}
@@ -91,23 +59,23 @@ outer:
return displayStringsArr
}
func getPaddedDisplayStrings(stringArrays [][]string, columnConfigs []ColumnConfig) string {
func getPaddedDisplayStrings(stringArrays [][]string, padWidths []int) string {
builder := strings.Builder{}
for i, stringArray := range stringArrays {
if len(stringArray) == 0 {
continue
}
for j, columnConfig := range columnConfigs {
for j, padWidth := range padWidths {
if len(stringArray)-1 < j {
continue
}
builder.WriteString(WithPadding(stringArray[j], columnConfig.Width, columnConfig.Alignment))
builder.WriteString(WithPadding(stringArray[j], padWidth))
builder.WriteString(" ")
}
if len(stringArray)-1 < len(columnConfigs) {
if len(stringArray)-1 < len(padWidths) {
continue
}
builder.WriteString(stringArray[len(columnConfigs)])
builder.WriteString(stringArray[len(padWidths)])
if i < len(stringArrays)-1 {
builder.WriteString("\n")
+29 -71
View File
@@ -6,49 +6,34 @@ import (
"github.com/stretchr/testify/assert"
)
// TestWithPadding is a function.
func TestWithPadding(t *testing.T) {
type scenario struct {
str string
padding int
alignment Alignment
expected string
str string
padding int
expected string
}
scenarios := []scenario{
{
str: "hello world !",
padding: 1,
alignment: AlignLeft,
expected: "hello world !",
"hello world !",
1,
"hello world !",
},
{
str: "hello world !",
padding: 14,
alignment: AlignLeft,
expected: "hello world ! ",
"hello world !",
14,
"hello world ! ",
},
{
str: "hello world !",
padding: 14,
alignment: AlignRight,
expected: " hello world !",
},
{
str: "Güçlü",
padding: 7,
alignment: AlignLeft,
expected: "Güçlü ",
},
{
str: "Güçlü",
padding: 7,
alignment: AlignRight,
expected: " Güçlü",
"Güçlü",
7,
"Güçlü ",
},
}
for _, s := range scenarios {
assert.EqualValues(t, s.expected, WithPadding(s.str, s.padding, s.alignment))
assert.EqualValues(t, s.expected, WithPadding(s.str, s.padding))
}
}
@@ -159,66 +144,39 @@ func TestTruncateWithEllipsis(t *testing.T) {
func TestRenderDisplayStrings(t *testing.T) {
type scenario struct {
input [][]string
columnAlignments []Alignment
expected string
input [][]string
expected string
}
tests := []scenario{
{
input: [][]string{{""}, {""}},
columnAlignments: nil,
expected: "",
[][]string{{""}, {""}},
"",
},
{
input: [][]string{{"a"}, {""}},
columnAlignments: nil,
expected: "a\n",
[][]string{{"a"}, {""}},
"a\n",
},
{
input: [][]string{{"a"}, {"b"}},
columnAlignments: nil,
expected: "a\nb",
[][]string{{"a"}, {"b"}},
"a\nb",
},
{
input: [][]string{{"a", "b"}, {"c", "d"}},
columnAlignments: nil,
expected: "a b\nc d",
[][]string{{"a", "b"}, {"c", "d"}},
"a b\nc d",
},
{
input: [][]string{{"a", "", "c"}, {"d", "", "f"}},
columnAlignments: nil,
expected: "a c\nd f",
[][]string{{"a", "", "c"}, {"d", "", "f"}},
"a c\nd f",
},
{
input: [][]string{{"a", "", "c", ""}, {"d", "", "f", ""}},
columnAlignments: nil,
expected: "a c\nd f",
},
{
input: [][]string{{"abc", "", "d", ""}, {"e", "", "f", ""}},
columnAlignments: nil,
expected: "abc d\ne f",
},
{
input: [][]string{{"abc", "", "d", ""}, {"e", "", "f", ""}},
columnAlignments: []Alignment{AlignLeft, AlignLeft}, // same as nil (default)
expected: "abc d\ne f",
},
{
input: [][]string{{"abc", "", "d", ""}, {"e", "", "f", ""}},
columnAlignments: []Alignment{AlignRight, AlignLeft},
expected: "abc d\n e f",
},
{
input: [][]string{{"abc", "", "d", ""}, {"e", "", "f", ""}},
columnAlignments: []Alignment{AlignRight}, // gracefully defaults unspecified columns to left-align
expected: "abc d\n e f",
[][]string{{"a", "", "c", ""}, {"d", "", "f", ""}},
"a c\nd f",
},
}
for _, test := range tests {
output := RenderDisplayStrings(test.input, test.columnAlignments)
output := RenderDisplayStrings(test.input)
if !assert.EqualValues(t, output, test.expected) {
t.Errorf("RenderDisplayStrings(%v) = %v, want %v", test.input, output, test.expected)
}