Lazygit: 从0到熟练使用,你需要的都在这里

488 阅读14分钟

lazygit:拥有 68K star,终端里的全能Git可视化工具

以前最常用sourceTree,后来用了一段时间fork,直到接触 lazygit,才发现这是最好的git客户端

  • 本文已经非常全面,从接触到熟练掌握,所需要的所有细节都在这里。
  • 虽然文章内容有点多,但只有2种内容:
    • 【2Panels窗格】介绍了5个panel下常用的快捷键;
    • 【3场景实例】包含了多个场景演示,都是很简单的内容,只需要简单几步即可完成一个操作。很多步骤都是重复的,全部看完实践一遍就可以掌握。
  • 包含了以前不了解的worktree操作。近期靠AI对用到的一个开源软件提交贡献恰好也用到了这部分内容,操作起来非常方便。

标准流程示例:简单几个按键即可实现暂存、提交、拉取、推送

按键说明
2进入Files文件 窗格
a暂存所有文件; 或选择单个文件,按Space暂存 或选则单个文件,按Enter后,按a,按块或者行暂存
c提交,输入commit信息
p拉取
Shift+p推送

窗口示例: image.png

在命令行执行 lazygit 启用。 推荐 git-bash,或者vscode等 IDE 中 不推荐cmd/powershell,存在中文输入问题

0. Windows下通过scoop 安装lazygit

在github 官方仓库 github.com/jesseduffie… releases 中下载. 目前最新0.56.0 :windows下载: github.com/jesseduffie…

由于我是通过scoop安装的lazygit,本文所有内容也都是在这一环境下测试的。不清楚上面的版本是否会有不同。

配置lazygit

常见问题与配置建议

  • 配色不可读:cmd/bash中,底部可用操作项默认黑底蓝字,难以辨认。见下方推荐配置:改为白色字体。
  • 自动 fetch 导致command log被刷屏:见下方推荐配置:关闭自动fetch。
  • 中文输入框不显示:在 cmd/PowerShell 下候选框不可见,建议改用 git-bash 或 VS Code(Cursor)集成终端运行 lazygit。

[!tip] 配置文件路径 编辑 C:\Users\Administrator\AppData\Local\lazygit\config.yml

[!example] 推荐配置(提高底部提示可读性并避免 fetch 刷屏)

gui:
  theme:
    optionsTextColor:
      - white
git:
  autoFetch: false

运行lazygit

在目标仓库目录下执行 lazygit 即可

1. 通用快捷键

一切都要基于英文输入法 区分大小写

在任何操作场合基本都共用的按键:

按键功能详情
1..5快速切换Panel左侧5个Panel,通过数字键1..5切换;
lazygit最基本的概念、按键
?查看更多快捷键绑定每个Panel中都可以查看当前可用的快捷键。
常用按键会在底部显示;
j下一行
k上一行
[左移tabPanel 可能有多个tab,向左切换
]右移tab在同一Panel中左右切换
Enter确认
进入Local branch,查看commits
进入commit,查看差异files
进入file,查看差异
C+o复制branchname/commithash/filaname
/过滤
esc退出/取消当前操作
+循环放大窗格
q退出lazygit
:调用终端执行常规命令操作比如代码commit后,需要执行 mvn clean package, 则按 : (即Shift+;)在弹出窗口中输入 mvn clean package

2. Panels窗格

1-5:左侧5个Panel,可通过数字直接激活。 底部会显示激活窗格对应的可用快捷键与对应功能

1.Status Panel 状态

按键次级按键功能
1激活Status Panel
Enterlazygit打开过的最近仓库,选择一条切换
j/k下/上一行
/过滤

2.Files Panel 文件

文件、工作区、子模块 通过 [ ] 左右切换至 Worktrees Submodules(不讨论)

Files文件

功能按键次级按键详情
激活2激活Files Panel
stage/unstagea暂存所有
Space单个目录/文件:暂存/取消暂存
Enter选中文件,按Enter后可以按行暂存
aEnter后,按a,选择行
vEnter后,按v,进入多行选择模式
←→↑↓Enter后,可以在hunk(块)之间选择
discardd丢弃,不可恢复,谨慎操作
D重置
ignorei忽略文件、目录
i添加到 .gitignore
在团队中共享该忽略
e添加到 .git/info/exclude
只在本地忽略,不会被提交
commitc提交
C(大写)在外部编辑器编辑提交信息
fetchf
pullp拉取:针对当前检出的分支。
总是使用rebase,只能修改git配置:
git config --global pull.rebase true
pushP(大写)推送:针对当前检出的分支。
edite编辑
o使用默认编辑器编辑
stashs贮藏
S(大写)更多贮藏选项
?查看按键绑定

Worktrees 工作区

工作树是更准确的翻译

git worktree 是一个非常有用的 Git 功能,它允许你同时签出同一个仓库的多个分支到不同的目录

示例场景
  1. 我正在 rebuilld分支进行重构,工作区处于如此混乱的状态(有新的、被移动的、被删除的文件)。此时需要在 master分支上修复线上bug,那么我只需要基于 master分支创建一个工作区:路径(../hotfix、新分支 hotfix 。就会多一个 hotfix 的同级文件夹,在里面进行开发验证。
  2. 开源软件在我本地有自己的版本。今天优化了一个功能commitA,想提交PR给原作者。我不需要清理在用的工作目录,只需要基于原作者upstream分支创建一个工作区,应用commitA,然后推送提交就可以了。
原始git流程
# 1. 查看当前工作区
git worktree list

# 2. 为紧急修复创建新工作区:基于master分支创建hotfix分支,目录在../hotfix
$ git worktree add -b hotfix ../hotfix master

# 3. 切换到新工作区
cd ../hotfix

# 4. 进行修复并提交
git add .
git commit -m "紧急修复"

# 5. 返回主工作区,继续之前的工作
cd ../main-project

# 6. 完成后移除工作区
git worktree remove ../hotfix
lazygit操作
按键次级按键/输入说明
3进入本地分支
j/k移动至目标分支,这里是master
w创建工作区
../hotfix目标路径
hotfix新建分支名称
则本地分支已经变成hotfix
2-工作区下当前为hotfix

3.Local branches Panel 本地分支

通过 [ ] 左右切换至 Remotes Tags

功能按键次级按键详情
激活3
fetchf获取远程最新信息,是否有代码需要pull
pullp拉取:针对当前检出的分支
pushShift+p推送:针对当前检出的分支
checkoutSpace检出
newn创建分支
deleted删除分支
mergeM合并到当前检出的分支
rebaser变基
sSimple rebase onto main(简单变基到main)
更多按键?查看按键绑定
filter/在本地分支中过滤,Enter选择
searchc在本地、远程分支中搜索
worktreew在选定分支上创建工作区

4.Commits Panel

当前检出分支的commits记录

功能按键次级按键详情
激活4
CheckoutSpace检出当前commit
Rechanger修改提交信息
TagT任意commit上添加tag
AmendA将当前暂存的文件合并到选择的commit中
1,按2,进入Files中暂存文件
2,按4,选择任何commit
3,按Shift+a
查看变更文件Enter查看变更文件
Ctrl+w忽略空白、tab、换行。等价于 git diff -w
ccheckout,检出选定文件当前commit版本,并暂存
eedit,编辑选定文件,为最新版本,而非当前commit
d从当前commit中删除该文件,会引发rebase
Deleted删除提交
Revertt选择某个commit,回滚提交
Squashs1,选择单个或Shift+↓/↑选择多个
2,按s,合并到下方的提交
Fixupf将选择的提交合并到下方的提交,本次提交信息会丢失
Rebaserrebase变基
interactive rebaseistart an interactive rebase.
更多按键?查看按键绑定
,移动到当前页第一项
或者上一页
.移动到下一页
/搜索
Ctrl+s过滤,可以根据作者过滤:先移动到该作者提交的commit,再执行过滤。
+放大窗格

5.Stash Panel

按键说明
5激活
Space应用
g应用并删除
d删除

3. 场景实例

按表格中按键顺序依次按下

标准流程:暂存、提交、拉取、推送

按键说明
2进入Files文件
a暂存所有文件;
或选择单个文件,按Space暂存
或选则单个文件,按Enter后,按a,按块或者行暂存
c提交,输入commit信息
p拉取
Shift+p推送

从远程创建本地分支并追踪

按键次级按键说明
3进入本地分支
c搜索远程分支名,选中目标(如 origin/feature-x)
Enter检出并创建同名本地跟踪分支
EnterNew Local branch

暂存/丢弃 块/行

按键次级按键说明
2进入 Files
j/k移动到目标文件
Enter进入文件
j/k移动至目标块
a单行/块 选择模式
v进入、退出多行选择模式
j/k上下移动至目标行
Space/dSpace 暂存选中行
d 丢弃选中行(不可逆,谨慎操作)
Esc返回Files

忽略文件

思路:在 Files 窗格,对选择的文件,按 i 进行 ignore

按键次级按键说明
2进入Files文件
i忽略
i添加到 .gitignore 需要提交,团队共享
e添加到 .git/info/exclude 不需要提交,个人

合并其他分支到当前分支

按键功能
3进入Local branches
j/k移动,选择要合并的分支
Shift+m合并
m常规合并

根据author搜索提交记录

思路:按4,进入commits 方法1:选择目标作者提交的任一条commit,按Ctrl+s搜索,选择第一项 方法2:任一提交记录上按Ctrl+s搜索,选择第三项:输入作者搜索,在弹框中输入或者选择作者

方法1示例

按键次级按键说明
4进入commits
j/k移动,选则目标作者提交的任一条记录
Ctrl+s搜索
Enter第一项 Filter by 'author <email>'按Enter确认

cherry-pick 复制其他分支commits到当前检出分支

场景:当前检出分支为A,想将分支B上的commitA 复制到当前分支A 思路:按3进入 local branches,通过j/k定位到分支B,按 Enter 进入,按 j/k 到目标commitA,按 Shift+c 复制提交(可以通过j/k在多个commit上复制),按 4 进入当前检出分支的commits,按 Shift+v 粘贴

按键说明
3进入Local branches
j/k移动,选择目标分支
Enter进入目标分支
j/k移动至目标commit
Shift+c复制提交;
可以多次移动复制
4进入Commits (当前检出分支的commits)
Shift+v粘贴到当前检出分支

Rebase 变基

最基本的Rebase

场景:

  1. 从 main 分支 checkout dev 分支: main ->dev
  2. 在 dev 分支依次提交了 dev.1 dev.2: main->dev.1->dev.2
  3. 此时 main 分支提交了 main.1: main->main.1
  4. 此时,想将 mian 分支同步到 dev 分支,可以在dev分支执行 git rebase main,此时dev分支的提交记录变为 main->main.1->dev.1->dev.2

对应lazygit操作:

按键次级按键说明
前提:检出分支为dev分支
3进入Local branches
j/k选择master
rrebase
sSimple rebase onto main(简单变基到main)

Rebase from marked base commit

场景解释:从master分支创建新分支dev,并提交dev.1 从dev分支创建新分支feature,并提交 feature.1, feature.2。 此时的提交记录为 master->dev.1->feature.1->feature.2 然后你想将feature上的2次提交,改为从master上 提交记录为 master->feature.1->feature.2

按键次级按键说明
当前位于feature分支
4进入commits
j移动至 feature分支前的 commit,这里是 dev.1
Shift+b标记从这里开始变基
3进入本地分支
j/k移动到master
r变基
sSimple rebase onto main(简单变基到main)

interactive rebase演示:将commitA合并到commitB

按键次级按键说明
4进入commits
istart an interactive rebase;按下后commit前会显示pick标记
Ctrl+jmove down;Shift+↓多选;
Ctrl+kmove up
f标记当前commit为 fixup
rebase后将合并下面标记为 pick 的提交,提交信息也将合并
s标记当前commit为 squash
rebase后将合并到下面标记为 pick 的提交,提交信息将丢弃
ddrop
eedit
m完成标记后,按m,选择continue,完成变基

思路: 选择commitA,按 i start an interactive rebase,向下移动至commitB上方,标记commitA为fixup,按 m 查看rebase选项,选择 continue 完成rebase。

按键次级按键说明
4进入Commits
j/k移动至目标commitA
irebase
Ctrl+j向下移动至commitB上方
f标记commitA为 fixup
丢弃commitA信息
m查看rebase选项
Enter默认continue,确认,完成

改写历史

将本次变更(未提交)合并到历史中某次commitB

或修正上一次提交 适用于未推送,或允许强制推送 思路: 执行 Amend

按键次级按键说明
2进入Files文件
Space暂存文件
4进入Commits
j向下移动,至目标CommitB
/也可以搜索,输入提交信息中关键字
按Enter,定位到第一个匹配Commit
Shift+aAmend到目标commitB
r需要时改写提交信息

将某文件恢复至某次提交

按键次级按键说明
4进入commits
j/k选中目标提交
Enter进入提交,查看变更文件
j/k移动至目标文件
ccheckout,检出选定文件当前版本

将当前分支重置到某次提交(Reset)

按键说明
4进入 Commits
j/k选中目标提交
g打开菜单
选择默认:mixed reset
Mixed:默认,保留工作区;=git reset commitId
Soft:仅移动 HEAD;
Hard:丢失工作区;=git reset --h commitId

回退(revert)指定提交

按键说明
4进入 Commits
j/k选中目标提交
tRevert 生成反向提交

生成补丁文件

按键次级按键说明
4进入 Commits 提交
j/k选择一个提交
Enter进入 Diff files
a选中变更文件
Ctrl+p打开选项菜单
yCopy patch to clipboard(复制补丁到剪贴板)
将剪贴板内容粘贴为 xxx.patch 即为补丁文件

Rebase Magic

从某次历史提交中删除一行注释 最好删除的行不要与后续的提交在同一块中(如删除最后一行,后续又在最后添加代码),则位于同一块中。 此时需要查看冲突,选择冲突文件,Enter进入,e编辑文件:删除注释行后保存关闭,Space选择位于下面的块,此时所有的冲突都解决。

处理冲突,本质就是用Space来选择上面的原变更块(hunk),还是下面的新变更。 也可能需要先 e 编辑目标块,再 Space 选择它。如上一段所述。

按键次级按键次级按键说明
4进入 Commits 提交
j/k选择一个提交
Enter进入 Diff files
j/k选择一个文件
Enter进入文件
a进入逐行模式
j/k选择要删除的目标行
Space将选中行加入自定义补丁
Esc退出文件
Ctrl+p打开patch菜单
d从原来的提交中删除补丁
Enter如果出现了冲突,查看冲突
Enter选择冲突文件后,进入文件
e编辑文件,删除上一次提交中要删除的行
Space暂存下面的块,完成冲突处理
Esc返回Commits

Undo

删除commit后 按 z 恢复回来。 可以执行多次

差异

当前分支以CommitA为基准,比较后面的分支相比CommitA的变更

按键次级按键说明
4进入commits提交
j/k移动到CommitA
Shift+w
Enter选择第一条 差异 CommitA
k依次比较后面的相比A的变更

当前分支相比BranchB分支的变更

按键次级按键说明
4进入commits提交
Shift+w
j选择第2条 输入 ref 以 diff
Enter
输入其他BranchB
Tab选中
Enter进入
j查看当前分支早期提交相比BranchB差异

打标签并推送

按键说明
4进入 Commits
j/k选中要打标签的提交
Shift+t打标签

4. 其他

rebase操作报错

warning: could not read '.git/rebase-merge/head-name': No such file or directory: git rebase --quit

Cursor、vscode中 打开lazygit

Alt+F12 激活命令行,输入 lazygit 打开。