汇总介绍几个Git相关项目,有客户端,也有SDK。
GitButler
Git, But Better的缩写,官网,现代化的开源(GitHub,20.2K Star,901 Fork)跨平台高颜值Git客户端,提供虚拟分支(Virtual Branches)概念,支持在同一个工作目录中同时处理多个功能开发,无需频繁切换分支。官方文档。

| 特性 | GitButler | SourceTree | GitKraken |
|---|---|---|---|
| 虚拟分支 | 原生支持 | 不支持 | 不支持 |
| AI辅助 | 内置 | 无 | 有限 |
| 跨平台 | 支持 | 仅桌面 | 支持 |
| 学习曲线 | 中等 | 低 | 低 |
| 价格 | 免费/付费 | 免费 | 付费 |
功能:
- 在同一个工作目录中维护多个虚拟分支:
- 每个虚拟分支对应一个独立变更集
- 文件更改可灵活分配到不同分支
- 随时可将任意分支推送到远程
- 虚拟分支只在本地存在
- 点击虚拟分支,推送到远端,自动转换为普通远程分支
- 点击同步,智能合并,冲突时提供可视化解决界面
- 智能差异分析:自动分析更改:
- 显示新增、删除、修改的文件
- 代码级差异对比
- 支持忽略空白字符等高级选项
- 内置AI功能:
- 自动生成提交信息:根据代码变更生成描述性提交信息
- 代码审查建议:识别潜在问题
- 变更解释:用自然语言描述复杂的代码改动
- 虚拟分支也会产生冲突:
- 可视化冲突标记
- 逐行选择保留哪个版本的代码
- 一键应用解决方案
- 部分提交,允许更细粒度的控制:
- 选择文件中的特定行进行提交
- 将一个大文件的不同部分分到不同分支
- 设置分支之间的依赖关系:
- 分支B依赖于分支A的更改
- 推送时自动确保顺序正确
- 自动维护操作历史
- 误删分支可以从历史恢复
- 更改分配错误可以撤销
Gitnuro
官网,一款基于JetBrains Compose和JGit构建的跨平台开源(GitHub,2.4K Star,122 Fork)Git客户端,旨在提供一个没有任何使用限制且不依赖Web技术的免费开源Git工具。

实战
支持多种安装方式:
- Windows:GitHub Release下载
- Linux:
flatpak install com.jetpackduba.Gitnuro,依赖于JRE 17 - macOS:
brew install jetpackduba/apps/gitnuro
核心功能:
- 查看文本文件的差异对比
- 浏览历史记录和所有分支
- 添加(暂存)和重置(取消暂存)文件
- 暂存和取消暂存代码块(hunks)
- 检出文件(恢复未提交文件的更改)
- 克隆仓库
- 提交更改
- 重置提交
- 撤销提交
- 修改上一次提交
- 合并分支
- 变基操作
高级功能:
- 创建和删除本地分支
- 创建和删除本地标签
- 查看远程分支
- 拉取和推送更改
- 储藏
stash和弹出储藏 - 检出特定提交(分离HEAD)
- 查看图片差异(并排对比)
- 强制推送
- 从远程删除分支
- 管理远程仓库
- 创建新的本地仓库
- 按提交信息/作者/提交ID搜索
- 交互式变基
- 文件
blame功能 - 查看文件历史
- 主题支持
- 文本文件并排差异对比
- 暂存/取消暂存特定行
- 子模块支持
- 更改特定分支的跟踪分支
支持自定义主题,通过JSON配置文件
json
{
"primary": "FF456b00",
"primaryVariant": "FF456b00",
"onPrimary": "FFFFFFFFF",
"secondary": "FF9c27b0",
"onBackground": "FF141f00",
"onBackgroundSecondary": "FF595858",
"error": "FFc93838",
"onError": "FFFFFFFF",
"background": "FFe7f2d3",
"backgroundSelected": "C0cee1f2",
"surface": "FFc5f078",
"secondarySurface": "FFedeef2",
"tertiarySurface": "FFF4F6FA",
"addFile": "FF32A852",
"deletedFile": "FFc93838",
"modifiedFile": "FF0070D8",
"conflictingFile": "FFFFB638",
"dialogOverlay": "AA000000",
"normalScrollbar": "FFCCCCCC",
"hoverScrollbar": "FF0070D8",
"diffLineAdded": "FF0070D8",
"diffLineRemoved": "FF0070D8",
"isLight": true
}
通过.gitconfig文件指定完整路径,来支持Git凭据管理器:
[credential]
helper = /usr/share/git-credential-manager-core/git-credential-manager-core
JGit
项目地址,Eclipse基金会开源(GitHub,373 Star,102 Fork)轻量级、纯Java实现的Git版本控制系统库,包含仓库访问流程、网络协议和核心版本控制算法。
概念
通过Maven将JGit集成到项目:
xml
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>4.6.0.201612231935-r</version>
</dependency>
JGit提供两级API:
- Porcelain API:面向用户的高级操作,类似Git命令行工具
- Plumbing API:直接操作底层仓库对象
java
# 创建新仓库
Git git = Git.init().setDirectory("D://code//jgit").call();
# 克隆现有仓库
Git git = Git.cloneRepository()
.setURI("https://github.com/eclipse-jgit/jgit.git")
.setDirectory("/path/to/repo")
.call();
Git对象包含四种类型:
blob:存储文件数据tree:目录结构,引用其他tree和blobcommit:指向单个treetag:标记特殊commit,通常用于版本发布
Git中所有对象通过SHA-1 ID标识,JGit中用AnyObjectId和ObjectId表示。
java
// 解析对象
ObjectId head = repository.resolve("HEAD");
// Ref是持有单个对象ID的变量,可指向任何Git对象。如获取master分支引用:
Ref HEAD = repository.getRef("refs/heads/master");
// RevWalk用于遍历提交图并按序生成提交:
RevWalk walk = new RevWalk(repository);
// RevCommit表示Git中的提交对象。使用RevWalk解析:
RevWalk walk = new RevWalk(repository);
RevCommit commit = walk.parseCommit(objectIdOfCommit);
// RevTag表示Git中的标签对象。解析方式:
RevWalk walk = new RevWalk(repository);
RevTag tag = walk.parseTag(objectIdOfTag);
// RevTree表示Git中的树对象。解析方式:
RevWalk walk = new RevWalk(repository);
RevTree tree = walk.parseTree(objectIdOfTree);
Porcelain API
JGit在org.eclipse.jgit.api包中提供模拟Git命令的高级API。
AddCommand,即git add,通过addFilepattern()添加文件到暂存区:
java
Git git = new Git(db);
AddCommand add = git.add();
add.addFilepattern("someDirectory").call();
CommitCommand,即git commit,提交代码支持以下选项:
setAuthor()setCommitter()setAll()
示例:
java
Git git = new Git(db);
CommitCommand commit = git.commit();
commit.setMessage("initial commit").call();
TagCommand,即git tag,标签操作支持:
setName()setMessage()setTagger()setObjectId()setForceUpdate()setSigned()
示例:
java
Git git = new Git(db);
RevCommit commit = git.commit().setMessage("initial commit").call();
RevTag tag = git.tag().setName("tag").call();
LogCommand,即git log,遍历提交图:
add(AnyObjectId start)addRange(AnyObjectId since, AnyObjectId until)
获取提交日志:
java
Git git = new Git(db);
Iterable<RevCommit> log = git.log().call();
Ant任务
JGit在org.eclipse.jgit.ant包中提供常用Ant任务。
配置任务:
xml
<taskdef resource="org/eclipse/jgit/ant/ant-tasks.properties">
<classpath>
<pathelement location="path/to/org.eclipse.jgit.ant-VERSION.jar"/>
<pathelement location="path/to/org.eclipse.jgit-VERSION.jar"/>
<pathelement location="path/to/jsch-0.1.44-1.jar"/>
</classpath>
</taskdef>
支持git-clone、git-init和git-checkout任务。
git-clone
xml
<git-clone uri="http://egit.eclipse.org/jgit.git" />
必需属性:
uri:克隆源地址
可选属性:
dest:目标路径,默认基于URI生成目录名bare:是否创建裸仓库,默认falsebranch:初始检出分支,默认HEAD
git-init
xml
<git-init />
可选属性:
dest:仓库初始化路径,默认当前目录bare:是否创建裸仓库,默认false
git-checkout
xml
<git-checkout src="path/to/repo" branch="origin/newbranch" />
必需属性:
src:仓库路径branch:检出分支名称
可选属性:
createbranch:分支不存在时是否创建,默认falseforce:是否强制覆盖现有分支,默认false