Jujutsu 使用手册(附 Git 对比)
Jujutsu 使用手册(附 Git 对比)
- 官方文档: https://jj-vcs.github.io/jj/latest/tutorial/
- 官方 Git Comparison Table: https://jj-vcs.github.io/jj/latest/git-command-table/
理解 Jujutsu 的核心概念
Jujutsu 是一个与 Git 兼容的版本控制系统,旨在简化复杂工作流的同时保留 Git 的强大功能。其架构与 Git 在几个关键方面存在根本差异,使其在许多开发场景中更直观易用。
与 Git 的核心差异
Jujutsu 完全消除了暂存区的概念。工作目录中的所有更改都会自动跟踪为当前变更的一部分,无需使用 git add
命令。冲突被视为一等对象,可以提交、共享和协作解决,这与 Git 要求在提交前解决冲突的方式不同。
操作日志全面记录了每个命令的执行情况,提供了精确的撤销功能,超越了 Git 的 reflog 能力。历史操作更加灵活,允许更改自由重排、修改或合并,不受严格的线性约束。
Revset 符号参考
Jujutsu 使用功能性 revset 语言来选择提交。@ 表达式指代当前工作区中的工作副本提交。基本符号包括:
@
- 当前工作副本提交(相当于 Git 的 HEAD)@-
- 工作副本的父提交@+
- 工作副本的子提交::@
- 工作副本的所有祖先,包括 @ 本身@::
- 工作副本的所有后代,包括 @ 本身@..
- 除 @ 的祖先外的所有提交::
- 仓库中所有可见的提交~
- 集合补集(否定运算符)&
- 集合并集|
- 集合交集
仓库设置
克隆与初始化
对于 Git 后端仓库,使用 jj git clone <url>
创建新仓库。对于与现有 Git 仓库共存的模式,使用 jj git init --colocate
。
# Git 后端仓库
jj git clone https://github.com/user/repo
# 与现有 Git 仓库共存
git clone https://github.com/user/repo && cd repo && jj git init --colocate
# 初始化新的 Git 后端仓库
jj git init
基本工作流命令
仓库状态与历史
# 检查仓库状态
jj status # 或简写 jj st
# 查看提交历史
jj log
# 查看所有提交,包括隐藏的
jj log -r ::
创建和管理变更
jj commit 命令更新描述并在顶部创建新变更。变更会自动跟踪,无需显式暂存。
# Git 工作流
git add file.txt
git commit -m "更新文件"
# Jujutsu 工作流
jj commit -m "更新文件" # 自动包含所有变更
# 替代方案:仅描述当前变更而不创建新变更
jj describe -m "更新文件"
修改变更
# Git
git commit --amend
# Jujutsu - 将工作副本变更合并到父提交
jj squash
# 更新提交消息
jj describe -m "更新的消息"
书签管理
Jujutsu 使用"书签"(bookmarks)代替分支 - 它们是指向提交的轻量级指针。
# 从当前变更创建书签
jj bookmark create feature-name
# 从特定提交创建书签
jj bookmark create bugfix -r <commit-hash>
# 列出所有书签
jj bookmark list
# 删除书签
jj bookmark delete feature-name
在变更间导航
# 切换到特定书签或提交
jj edit <bookmark-name>
jj edit @- # 切换到父提交
# 从特定提交创建新变更
jj new <commit-hash> -m "新变更描述"
差异比较
# 当前工作副本的变更
jj diff
# 特定版本之间的差异
jj diff --from <rev1> --to <rev2>
# Git 风格的输出格式
jj diff --git
远程操作
获取和推送
使用 jj git fetch 从远程获取,使用 jj git push 并加上 --bookmark 推送特定书签。
# 从远程获取
jj git fetch
# 推送特定书签
jj git push --bookmark feature-name
# 推送到特定远程
jj git push --remote origin --bookmark feature-name
整合远程变更
# 获取并将当前变更变基到远程 main
jj git fetch
jj rebase -d main@origin
高级操作
撤销功能
jj undo 命令创建一个新操作,用于撤销先前的操作。使用 jj operation log 查看操作日志。
# 撤销上一个操作
jj undo
# 查看操作历史
jj operation log # 或简写 jj op log
# 恢复到特定操作
jj operation restore <operation-id>
变基操作
jj rebase 命令将修订移动到不同的父提交,同时保留变更。
# 将当前变更变基到 main
jj rebase -d main
# 变基特定修订
jj rebase -s <源> -d <目标>
# 变基多个修订,同时保留依赖关系
jj rebase -r <revset> -d <目标>
创建合并提交
# 创建具有多个父提交的合并提交
jj new main feature -m "将 feature 合并到 main"
冲突解决
Jujutsu 允许提交和共享冲突,支持协作解决。
# 查看有冲突的提交
jj log -r 'conflicts()'
# 手动解决冲突后,变更会自动整合
# 创建新变更以继续工作
jj new
文件操作和配置
文件历史和模式
# 查看修改特定文件的提交
jj log -r 'files("filename")'
# 设置用户配置
jj config set --user user.name "你的名字"
jj config set --user user.email "you@example.com"
高级 Revset 示例
Revsets 提供了强大的提交筛选功能。
# 不在任何远程书签上的提交
jj log -r 'remote_bookmarks()..'
# 特定作者的提交
jj log -r 'author("name@example.com")'
# 描述中包含特定文本的提交
jj log -r 'description("bug fix")'
# 合并提交
jj log -r 'merges()'
# 修改特定文件模式的提交
jj log -r 'files("src/**")'
关键行为差异
自动变更跟踪
与 Git 的暂存区方法不同,Jujutsu 自动将所有工作目录修改纳入当前变更,通过消除手动暂存步骤简化了开发工作流。
全面的操作日志
操作日志记录每个命令的执行,而不仅仅是引用更新,提供了比 Git 的 reflog 更精细的撤销能力。
冲突处理理念
Jujutsu 将冲突视为可提交、可共享的对象,支持分布式冲突解决工作流,这是 Git 的提交前解决要求无法实现的。
工作副本模型
工作副本与特定变更 ID 保持直接关联,修改会自动成为该变更的一部分,提供了工作目录状态和仓库历史之间的无缝集成。
这种方法消除了 Git 中工作目录、暂存区和仓库之间的概念复杂性,同时保持与 Git 仓库和工作流的完全兼容性。