从 Git 到 Fossil
摘要
作者解释了他们决定从 Git 切换到 Fossil 版本控制系统的原因,突出了 Fossil 的特点,如基于 C 的实现、简洁性和内置 Web 服务器。
暂无内容
查看缓存全文
缓存时间: 2026/09/13 02:35
# home/lucio.albenga.es - 从 Git 转向 Fossil
来源:https://lucio.albenga.es/web-en/posts/2025/from-git-to-fossil.html
## 从 Git 转向 Fossil
Git 社区的人们已经开始着手制定一项提案,试图强制推行 Rust 1 (https://lucio.albenga.es/web-en/posts/2025/from-git-to-fossil.html#fn.1) 编程语言。我不喜欢 Rust,更重要的是,我不喜欢它的社区里那群小群极端主义者,他们试图让每个人接受他们的主张,重写那些已经稳定运行了几十年的项目,在社交媒体上煽风点火,并且还有其他任何带有极权妄想的小团体才会干出的"精彩"勾当。因此,当我看到任何项目试图"强制"使用 Rust 或从 C 转向 Rust 时,我都会尽我所能逃离它,就像被《魔戒》里的炎魔挥舞着鞭子追杀一样。
我年纪够大,曾使用(或测试过)许多版本控制系统:RCS(修订控制系统)、CVS(并发版本系统)、SVN(Subversion)、HG(Mercurial)、BZR(Bazaar),以及前面提到的 Git,这意味着再次切换对我来说没有问题,于是我开始为我的个人项目寻找一个 Git 的替代品。
选择要么是回到一个已知的系统,要么是看看别的,这时我想起了 Fossil。我开始查阅它的源代码和阅读官方文档2 (https://lucio.albenga.es/web-en/posts/2025/from-git-to-fossil.html#fn.2),以了解它的特性、依赖项、如何安装和配置等。我注意到它有很多我喜欢的东西:
- **它用 C 编写**(虽然其 Web 功能使用了一些 js 和 tcl),是一个小巧高效的程序,硬件资源消耗很少。
- **它使用更简单,感觉更自然**(至少对于了解 Subversion 等其他系统的人来说),因为它不包含像暂存区那样过度的功能,这些功能在大型复杂项目(如 Linux 内核)中可能有用,但对我来说并无实际用处。
- **它允许你快速轻松地在自己的服务器上自托管**,因为它本身就为此做好了准备。事实上,它内置了 Web 服务器和包含版本控制视图、Wiki、问题跟踪等功能的 Web 界面。另一方面,使用 Git 你不得不依赖外部软件,如 GitLab、Gitea 或 Forgejo,而每一个至少都是一份额外的软件依赖。
- **提交信息不使用电子邮件地址**,而是使用用户名,因此如果你有一个公开的仓库,就无需担心垃圾邮件,也不需要为此专门注册一个电子邮箱地址。
- **它与 Git 兼容**,这意味着如果需要将仓库切换回 Git,你可以做到,并且它还支持 Fossil 仓库和 Git3 (https://lucio.albenga.es/web-en/posts/2025/from-git-to-fossil.html#fn.3) 仓库之间的双向同步(Fossil 和 Sqlite 项目就使用此功能来管理它们的 GitHub 镜像)。
考虑到所有这些,我决定安装 Fossil 并将我的项目从 Git 迁移过去。下面你将看到如何操作。
## 安装 Fossil
第一步是安装 Fossil,很可能你的操作系统软件包管理器里已经有了:
```
sudo apt install fossil # Devuan GNU+Linux
pkg install fossil # FreeBSD
```
当你的包管理器完成安装后,你可以用以下命令检查其可用性:
上述命令应该会返回类似下面的内容:
```
This is fossil version 2.21 [3c53b6364e] 2023-02-26 19:24:24 UTC
```
## 导入 Git 仓库
Fossil 的文档4 (https://lucio.albenga.es/web-en/posts/2025/from-git-to-fossil.html#fn.4) 中有以下示例,用于导出 Git 仓库并将其作为 Fossil 仓库导入:
```
cd repository
git fast-export --all | fossil import --git repository.fossil
```
我用了不同的方式,因为我希望调整一些东西,让导入的仓库"正确"。因为我有几个仓库,我创建了两个不同的文件夹,一个 *git-exported* 用于存储导出的仓库,另一个 *fossils* 用于存储新的 Fossil 仓库:
```
mkdir ~/git-exported
mkdir ~/fossils
```
现在你可以进入每个 Git 仓库文件夹并导出它:
```
cd repository
git fast-export --all > ~/git-exported/repository.export
```
一旦你导出了所有 Git 仓库,你应该进入 ~/fossils 文件夹,并使用以下命令逐个导入它们:
```
fossil import --git \
--rename-master trunk \
--attribute "[email protected] your_username" \
repository.fossil ~/git-exported/repository.export
```
选项 `--rename-master trunk` 会将你的 Git *master* 分支在新的 Fossil 仓库中重命名为 *trunk*。Fossil 和其他版本控制系统(如 Subversion)一样,使用 *trunk* 作为主分支的名称。如果你属于那些不幸地将主分支命名为 "main" 的人,这个选项不适用于你,如果你想重命名它,请查阅 Fossil 的文档。
选项 `--attribute "[email protected] your_username"` 会将 Git 提交中的电子邮件地址 "[email protected]" 在导入的 Fossil 提交中改为 "your_username"。在 Fossil 中,默认用户名与你当前在操作系统中使用的用户名相同。显然,给定的电子邮件地址必须存在于一个或多个提交信息中。
如果你想更改多个电子邮件地址,可以使用多个 `--attribute` 选项:
```
fossil import --git \
--rename-master trunk \
--attribute "[email protected] your_username" \
--attribute "[email protected] rms" \
--attribute "[email protected] torvalds" \
repository.fossil ~/git-exported/repository.export
```
导入命令的输出类似如下:
```
Rebuilding repository meta-data...
100.0% complete...
Vacuuming... ok
project-id: e64b112b40eb3db188060ddb8deeaa96a6ad3b71
server-id: bfbcd4bf8f0f64eaa2d832ddc3b4af00639624a6
admin-user: your_user (password is "XAxPVZcNQ6")
```
如果你仔细看,输出中给出了仓库管理员的用户名和密码。请保存它,因为你在仓库上执行某些操作时需要用到。
## 设置 Fossil 服务器
Fossil 内置了一个 Web 服务器,因此你可以利用它快速轻松地创建一个自托管服务器。以下方法适用于用户较少、位于无法从外部访问的私有网络的系统。设置 Fossil 服务器有多种方式,根据你的需求有些方式更好,因此我建议你查阅官方文档。
首先,你应该在服务器上创建一个文件夹来存储 Fossil 仓库:
```
mkdir /path/to/your/fossils
```
接下来,将你的 "fossils" 复制到服务器上的该文件夹:
```
scp *.fossil user@your_server:/path/to/your/fossils/
```
现在你可以使用以下命令启动服务器:
```
fossil server --port 8043 \
--cert /path/to/your_cert.pem \
--pkey /path/to/cert/key.pem \
--repolist /path/to/your/fossils/
```
如果你没有有效的证书,可以使用以下命令:
```
fossil server --port 8043 \
--cert unsafe-builtin
--repolist /path/to/your/fossils/
```
服务器运行后,如果你在浏览器中输入网址 `https://server_address_or_hostname:8043/`,你将访问一个包含仓库列表的网页。如果你点击列出的某个仓库,你将看到该仓库的网页。在导航菜单中,你应该能看到一个 "login"(登录)选项。点击它并使用仓库管理员的用户名和密码。现在你可以根据自己的喜好配置仓库了。请查阅 Fossil 的文档以了解更多信息。
如果你丢失了 Fossil 仓库管理员的密码,可以按照以下步骤恢复:
1. 进入服务器上的仓库文件夹。
2. 如果你没有安装 Sqlite,请按照你操作系统通常的方法安装它。
3. 用 Sqlite 打开 *repository.fossil*:`sqlite3 repository.fossil`
4. 进入 sqlite 后执行以下查询:`select login,pw from user;` 上述查询将返回类似这样的内容:`your_user|My3w2jRxt1 anonymous|57EBCBD1AAE663B4 nobody| developer| reader|` 密码是第二列的值(在此示例中是字符串 *My3w2jRxt1*)。
5. 使用以下命令退出 Sqlite
## 使用 Fossil
这里是一份关于如何开始使用 Fossil 的简要指南。本指南假设你了解如何在基础层面使用 Git,它只是一个起点,因此我建议你阅读 Fossil 的文档和 Fossil Book5 (https://lucio.albenga.es/web-en/posts/2025/from-git-to-fossil.html#fn.5)。
### 获取帮助
help 命令对于查看有哪些可用命令以及每个命令的用途和选项至关重要。help 命令的工作方式与 Git 类似:
```
fossil --help
fossil command_name --help
```
### 创建和克隆仓库
这些与 Git 的类似但有区别。在 Git 中,仓库通常与当前工作文件夹相对应。在 Fossil 中则不然,仓库(文件 *repository.fossil*)和工作(检出)文件夹 *repository_folder* 之间有明确的分离。
#### 创建仓库
你可以使用以下命令创建新仓库:
```
fossil init repository.fossil
```
此命令仅创建仓库,即 *repository.fossil* 文件。要开始使用它,你必须 "打开它"。创建一个文件夹,进入其中,然后打开仓库:
```
mkdir my_working_folder
cd my_working_folder
fossil open /path/to/repository.fossil
```
你也可以告诉 Fossil 工作文件夹的名称,如果它不存在,Fossil 会尝试创建它:
```
fossil open --workdir my_working_folder /path/to/repository.fossil
```
#### 克隆仓库
你可以使用命令 `fossil clone` 后跟仓库 url 来克隆仓库。url 可以是 web url、ssh url、文件路径等:
```
fossil clone https://host/repository
```
此命令会自动下载 *repository.fossil* 文件,并在同一级别创建工作文件夹 *repository_folder*。如果你不希望它创建工作文件夹,可以这样使用命令:
```
fossil clone --no-open https://host/repository
```
一旦仓库被克隆,如果你想将你的提交发送到远程仓库(并且你有权限这样做),你应该在工作文件夹内配置远程 fossil 仓库:
```
fossil remote https://user@host/repository
```
上述命令会询问你用户的密码,并询问你是否想将其保存以供将来使用。
**提示**:由于 Fossil 在仓库文件和另一方面工作文件夹之间有这种明确的分离,我将所有 \*.fossil 文件保存在我 /home 中名为 *fossils* 的文件夹里,而将工作文件夹放在每个案例中最合适的地方。
### 获取信息
关于获取工作文件夹和仓库状态信息,与 Git 相比有一些差异,特别是在命令的名称和用法上。
#### 查看时间线
在 Fossil 中,`fossil time` 和 `fossil timeline` 命令等效于 Git 的 *git log* 命令。以下是一些示例,从提供信息较少到信息较多:
```
fossil time --oneline # 类似 git log --oneline
fossil time
fossil time --medium
fossil time --verbose # 类似 git log
```
#### 查看工作文件夹中的更改
要查看工作文件夹相对于仓库的更改,有几个命令,每个命令都有不同的选项。
查看哪些文件和文件夹不在版本控制之下:
查看在版本控制下且已被修改的文件:
查看前两个命令的组合:
以更接近 Git 的 *git status* 命令输出的方式查看工作文件夹和仓库状态:
#### 查看差异
要查看工作文件夹中文件内容与仓库中内容的差异,Fossil 和 Git 一样,有一个 *diff* 命令:
查看特定提交与工作文件夹之间的差异:
```
fossil diff --from 2c26dd6b69 # 2c26dd6b69 是该提交的哈希值
```
查看两个特定提交之间的差异:
```
fossil diff --from 2c26dd6b69 --to cd086a1045
```
Fossil 的 *diff* 命令不显示彩色差异。如果你想看彩色差异,请查阅 Wiki6 (https://lucio.albenga.es/web-en/posts/2025/from-git-to-fossil.html#fn.6)。
### 获取更改
Fossil 有一个名为 *autosync* 的选项,默认启用。此选项保持你的本地仓库与远程仓库同步。如果你启用了 *autosync* 选项,你可以使用以下命令获取远程仓库的所有更改(如果有):
否则就更类似于 Git。你必须先执行 *pull* 来获取更改,然后执行 *update* 让这些更改出现在你的工作文件夹中:
```
fossil pull
fossil update
```
### 提交更改
由于 Fossil 没有 *暂存区*,其提交方式更类似于 Subversion 等版本控制系统,而不是 Git。
如果你想提交所有待处理的更改:
上述命令将打开一个编辑器让你输入提交信息,但你也可以将提交信息作为选项提供:
```
fossil commit -m "My commit message"
```
你可以提交特定文件:
```
fossil commit file1 file2
fossil commit file1 file2 -m "My commit message"
```
如果你启用了 *autosync* 选项,提交命令也会将你的更改发送到远程服务器(如果有)。否则,你将需要使用以下命令将更改发送到远程服务器:
### 添加和删除文件
当你需要将新文件置于版本控制下时,可以使用:
如果你想从版本控制中删除一个文件,可以使用:
```
fossil delete filename
fossil rm filename
```
默认情况下,*rm* 和 *delete* 命令不会从文件系统中物理删除文件,它们只是将文件标记为不再受版本控制。
还有一个命令 `fossil addremove`,它会将工作文件夹中所有未受版本控制的文件添加到仓库,并从仓库中移除那些在版本控制下但已不在工作文件夹中存在的文件。
### 忽略文件
配置是 Fossil 和 Git 之间存在几个重要差异的地方之一,因此我建议你查阅 Fossil 的文档。要忽略文件和文件夹,你必须在工作文件夹内创建文件 `.fossil-settings/ignore-glob`:
```
cd working_folder/
mkdir .fossil-settings
touch .fossil-settings/ignore-glob
```
然后使用 glob 模式编辑它7 (https://lucio.albenga.es/web-en/posts/2025/from-git-to-fossil.html#fn.7):
```
build/
3rdparty/
*.o
*/a.out
```
### 分支和标签
Git 的范式鼓励大量使用分支和标签,但 Fossil 的范式和特性不同,因此工作流程也不同。
由于我在个人项目中不太使用分支,为了让你对差异有一个概念,以便你能够将 Fossil 的特性适应你的工作流程,或者将你的工作流程适应 Fossil 的特性,我建议你阅读以下来自 Fossil Wiki 的链接:
- Fossil Check-Out Workflows (https://www.fossil-scm.org/home/doc/trunk/www/ckout-workflows.md)
- Fossil Branching, Forking, Merging, and Tagging (https://fossil-scm.org/home/doc/trunk/www/branching.wiki)
- Fossil Private Branches (https://fossil-scm.org/home/doc/trunk/www/private.wiki)
### 本地 Web 界面
我不想以这个简短的 Fossil
相似文章
Git之后是什么
这篇博客文章讨论了版本控制系统的演进,探讨了在现代软件开发中使用智能代理工具带来的挑战,并预览了East River Source Control构建下一代版本控制系统的方法,同时保持与Git的兼容性。
版本控制的复兴
作者回顾了版本控制系统的演变,从Git的兴起,到当前由AI代理驱动的转变,以及GitHub垄断地位可能的衰落。
Git在任何规模下(27分钟阅读)
本文解释了在大规模下托管Git仓库的困难,重点关注Git的packfile设计和分布式特性,并概述了潜在的解决方案。
@cursor_ai: 我们正在让Git托管变得更可靠、高性能和可扩展。这篇文章追溯了20年的Git基础设施,并……
Cursor AI 介绍了如何通过重新设计其Git存储系统 Origin,使其像数据库一样运作,来提升Git托管的可靠性、性能和可扩展性。
Git history 命令值得更多关注
文章重点介绍了新的 `git history` 命令及其 `fixup`、`reword` 和 `split` 子命令,这些命令提供了原子化且感知分支的提交历史编辑功能,带来了类似 jj 的益处,而无需切换版本控制系统。