第 14 章:Git 集成
第 14 章:Git 集成
14.1 Magit 简介
Magit 被广泛认为是 最好的 Git 客户端,没有之一。它将 Git 的所有操作通过简洁的键盘界面暴露出来,比任何 GUI 工具都快。
“Using Magit for a week made me better at Git. Using it for a month made me love Git.” — 社区用户反馈
安装
(use-package magit
:bind ("C-x g" . magit-status)
:config
(setq magit-display-buffer-function 'magit-display-buffer-same-window-except-diff-v1
magit-save-repository-buffers 'dontask))
14.2 Magit 基本操作
打开 Magit
| 快捷键 | 命令 | 说明 |
|---|---|---|
C-x g | magit-status | 打开 Magit 状态界面 |
C-x M-g | magit-dispatch | 打开 Magit 命令菜单 |
Magit 状态界面
Head: main Add new feature
Merge: origin/main
Tag: v1.0 (25)
Untracked files (2)
new-file.txt
docs/notes.md
Unstaged changes (3)
modified src/main.py
modified src/utils.py
deleted old-config.json
Staged changes (1)
new file src/helpers.py
Recent commits
abc1234 Add new feature
def5678 Fix typo in README
ghi9012 Initial commit
状态界面按键
| 按键 | 说明 |
|---|---|
s | 暂存(stage)当前文件/区域 |
u | 取消暂存 |
S | 暂存所有 |
U | 取消所有暂存 |
c c | 提交(输入提交信息后 C-c C-c) |
c a | 修改上次提交(amend) |
P p | 推送(push) |
F p | 拉取(pull) |
b b | 切换分支 |
b c | 创建分支 |
l l | 查看日志 |
d d | 查看差异 |
z z | 暂存(stash) |
! | 执行 shell 命令 |
q | 退出 Magit |
g | 刷新 |
14.3 Magit 提交流程
典型提交流程:
1. C-x g → 打开 Magit 状态
2. s s s → 逐个暂存文件
或 S → 暂存所有文件
3. c c → 开始提交
4. 输入提交信息 → "feat: add user authentication"
5. C-c C-c → 确认提交
6. P p → 推送到远程
修改上次提交:
1. c a → amend 模式
2. 修改提交信息或暂存更多文件
3. C-c C-c → 确认
提交信息编辑器
在提交信息编辑缓冲区中:
C-c C-c → 确认提交
C-c C-k → 取消提交
C-c C-a → 切换 --author
C-c C-s → 添加 Signed-off-by
;; 配置提交模板
(setq git-commit-summary-max-length 50
git-commit-style-convention-checks '(overlong-summary-line non-empty-second-line))
14.4 Magit Diff
;; 在 Magit 状态界面:
;; d d → 查看工作区差异
;; d s → 查看已暂存差异
;; d r → 查看与指定版本的差异
;; Diff 操作:
;; TAB → 展开/折叠文件
;; SPC → 向下翻页
;; n / p → 下/上一个差异块
;; s → 暂存当前差异块
;; u → 取消暂存当前差异块
;; k → 丢弃当前差异块
;; E → 编辑差异(直接编辑补丁)
;; a → 将差异块应用到工作区
交互式暂存
Magit 的杀手级功能:交互式暂存(Interactive Staging)
场景:一个文件中有 3 处修改,但你只想提交第 1 和第 3 处
1. 在 Magit 状态界面,定位到 modified 文件
2. 按 TAB 展开文件,看到每个差异块(hunk)
3. 对第一个差异块按 s → 暂存
4. 跳过第二个差异块
5. 对第三个差异块按 s → 暂存
6. c c → 提交(只包含第 1 和第 3 处修改)
这比任何 Git GUI 工具都快!
14.5 Magit 日志
l l → 查看当前分支日志
l L → 查看所有分支日志
l a → 查看所有分支
日志操作:
RET → 查看提交详情
a → cherry-pick 当前提交
v → revert 当前提交
x → reset 到当前提交
e → 编辑(interactive rebase)
14.6 分支管理
b b → 切换分支
b c → 创建分支
b B → 创建并切换
b d → 删除分支
b r → 重命名分支
b m → 合并分支
b e → rebase
b i → 初始化(git init)
Stash 操作:
z z → 创建 stash
z p → 弹出 stash
z a → 应用 stash(不删除)
z d → 删除 stash
z v → 查看 stash 内容
z k → 清除所有 stash
14.7 Forge(代码平台集成)
Forge 让你在 Magit 中直接操作 GitHub/GitLab 的 Issue、PR、Discussion。
安装配置
(use-package forge
:after magit)
设置 API Token
# 在 ~/.authinfo 中添加:
machine api.github.com login YOUR_USERNAME^forge password YOUR_TOKEN
# 生成 Token:
# GitHub: Settings → Developer settings → Personal access tokens
# 勾选 repo, read:org 权限
Forge 操作
在 Magit 状态界面:
@ i → 列出 Issues
@ p → 列出 Pull Requests
@ m → 创建新 Issue
@ n → 创建新 PR
在 Issue/PR 列表中:
RET → 查看详情
c → 评论
e → 编辑
a → 添加标签
14.8 代码审查(Code Review)
;; 使用 code-review 包进行 PR 审查
(use-package code-review
:after forge
:bind (:map forge-topic-mode-map
("r" . code-review-forge-pr-at-point)))
;; 工作流:
;; 1. @ p → 列出 PR
;; 2. 定位到要审查的 PR
;; 3. 按 r 进入代码审查模式
;; 4. 逐个文件审查:
;; n / p → 下/上一个文件
;; TAB → 展开差异
;; C-c C-r → 添加评论
;; C-c C-c → 提交审查
14.9 Git Gutter(行级差异标记)
;; 在行号区域显示 Git 变更标记
(use-package diff-hl
:hook ((prog-mode . diff-hl-mode)
(org-mode . diff-hl-mode)
(dired-mode . diff-hl-dired-mode))
:config
(setq diff-hl-side 'left)
;; 实时更新
(diff-hl-flydiff-mode 1)
;; Magit 集成
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh))
;; 标记说明:
;; | 绿色 + → 新增的行
;; | 红色 - → 删除的行
;; | 黄色 ~ → 修改的行
14.10 Timemachine(文件历史浏览)
;; 浏览 Git 文件的修改历史
(use-package git-timemachine
:bind ("C-x v t" . git-timemachine))
;; 操作:
;; p → 上一个版本
;; n → 下一个版本
;; w → 复制当前版本的哈希
;; q → 退出
;; c → 显示当前版本的 commit 信息
;; W → 切换到工作区版本
14.11 Git 命令行集成
在 Emacs 中运行 Git 命令
;; Eshell 中的 Git
;; 在 Eshell 中直接运行 git 命令
;; $ git status
;; $ git log --oneline
;; Magit 中运行 shell 命令
;; 在 Magit 状态中按 ! 可以运行任意 Git 命令
完整的 Git 配置
;; 完整的 Git 集成配置
(use-package magit
:bind ("C-x g" . magit-status)
:config
(setq magit-display-buffer-function 'magit-display-buffer-same-window-except-diff-v1
magit-save-repository-buffers 'dontask
magit-revision-show-gravatars t))
(use-package forge
:after magit)
(use-package diff-hl
:hook ((prog-mode . diff-hl-mode)
(magit-post-refresh . diff-hl-magit-post-refresh))
:config
(diff-hl-flydiff-mode 1))
(use-package git-timemachine
:bind ("C-x v t" . git-timemachine))
(use-package git-modes
:mode ("/\\.gitignore\\'" . gitignore-mode)
:mode ("/\\.gitattributes\\'" . gitattributes-mode))
14.12 本章小结
| 功能 | 工具 | 核心操作 |
|---|---|---|
| Git 操作 | Magit | C-x g 状态、s 暂存、c c 提交 |
| Diff | Magit | d d 差异、s/u 暂存块 |
| 日志 | Magit | l l 日志、RET 查看详情 |
| 分支 | Magit | b b/c/d 切换/创建/删除 |
| PR/Issue | Forge | @ p/i 列出 PR/Issue |
| 代码审查 | code-review | r 审查 PR |
| 行级差异 | diff-hl | 侧边栏显示修改标记 |
| 文件历史 | git-timemachine | C-x v t 浏览历史 |
14.13 扩展阅读
← 上一章 第 13 章:补全系统 | 下一章 → 第 15 章:终端模拟