git-annex 8.20210223 配置参数详解

git-annex 8.20210223 三层配置体系实测:git config annex.* 键、.gitattributes annex.largefiles 分流、numcopies 三层来源优先级实测、trust 信任级别与 group/wanted 分组、git-annex 元数据分支账本(numcopies.log/trust.log)与 .git/annex 目录结构。

git-annexgit-annexgit版本控制同步传输2026/10/30

git-annex 8.20210223 配置参数详解

实测环境:Ubuntu 22.04 LTS 服务器,git-annex 8.20210223(jammy apt 仓库),双机目录仓库(repo-a/repo-b)实测取值。实测日期:2026-10-30。安装过程见 《Ubuntu 22.04 安装 git-annex 8.20210223 指南》。

一、配置体系总览:三层配置源与生效优先级

git-annex 没有"一个主配置文件",它的配置分散在三个位置,按用途分工:

层载体管什么随仓库传播
git config 层仓库内 .git/config(或全局 ~/.gitconfig)仓库自身属性:UUID、版本、backend、SSH 行为等 annex.* 键否(.git/config 不被 clone 携带)
.gitattributes 层工作区 .gitattributes 文件文件分流规则(哪些文件进 annex/进 git)、按路径的 numcopies是(作为普通文件提交)
git-annex 分支层git-annex 元数据分支内的 log 文件全网络生效的状态:副本数下限(numcopies.log)、信任级别(trust.log)、仓库分组与偏好表达式是(随 sync 双向收敛)

前两层之外的第四个入口是命令行参数(如 --numcopies=N),优先级最高但一次性生效。

优先级实测(8.20210223,同一仓库同时存在多层配置时的实际生效情况):

先让两层配置同时存在——git config 层设 annex.numcopies=1,再用 git annex numcopies 2 命令写入分支层:

git config annex.numcopies 1
git annex numcopies 2
git show git-annex:numcopies.log
(recording state in git...)
1793341478.291006959s 2

对当前只有 2 份副本的文件执行 drop(drop 后剩 1 份):若 config 层的 1 生效则放行,若分支层的 2 生效则拒绝:

git annex drop big2.bin
drop big2.bin (unsafe) 
  Could only verify the existence of 1 out of 2 necessary copies

  Rather than dropping this file, try using: git annex move

  (Use --force to override this check, or adjust numcopies.)
failed
git-annex: drop: 1 failed

拒绝信息中的必要副本数是 2——8.20210223 实测:分支层 numcopies.log 覆盖 git config 层的 annex.numcopies。把 config 层改成 3 再次验证:

git config annex.numcopies 3
git annex drop big2.bin 2>&1 | grep verify
git annex numcopies
  Could only verify the existence of 1 out of 2 necessary copies
2

config=3 仍显示 "out of 2",且 git annex numcopies 查询命令读到的也是分支层的 2。只有命令行参数能即时压过它:

git annex drop big2.bin --numcopies=3 2>&1 | grep verify
  Could only verify the existence of 1 out of 3 necessary copies

结论(8.20210223 实测顺序):命令行 --numcopies > git-annex 分支 numcopies.log > git config annex.numcopies。因此生产上管理副本下限推荐统一走 git annex numcopies N 命令(写入分支层、随 sync 全网络传播),避免两层并存造成认知负担。

💡 技术拓展:为什么配置要放进 git 分支? numcopies、trust、group 这类状态本质是"全网络共识"——一台机器说了不算,所有仓库必须一致。git-annex 把它们记成 git-annex 分支里的 log 文件(时间戳 + 值),靠 git 的 push/pull 实现无中心的一致性收敛,这是把 git 分布式能力复用到配置上的典型设计。同类方案里,etcd/consul 需要独立集群达成共识,而 git-annex 直接"借住" git。

二、git config 层:annex.* 键实查

在已初始化的 repo-a 中实查全部 annex 相关键:

git config -l | grep -i annex

实测回显(该仓库配有一个 node-b remote 的状态):

annex.uuid=da2dfc12-a5d2-4a5b-b7d0-7efc76ae9b07
annex.version=8
annex.numcopies=1
filter.annex.smudge=git-annex smudge -- %f
filter.annex.clean=git-annex smudge --clean -- %f
remote.node-b.annex-uuid=0be16052-5128-42f8-9ae7-1ab9a32dfc83

逐键说明:

  • annex.uuid:本仓库在 annex 网络中的全局唯一身份。git annex init 时生成,跨仓库追踪副本全靠它,不可手工改动;
  • annex.version:仓库格式版本,8.20210223 创建的是 v8 仓库(git annex version 的 supported repository versions: 8 一致对应);
  • annex.numcopies:本仓库视角的副本下限(受第一节的优先级实测约束,见 numcopies.log);
  • filter.annex.smudge / clean:git clean/smudge 过滤器定义,实现工作区 symlink 与 git 内容的转换。git annex init 自动写入,不要手工编辑;
  • remote.<name>.annex-uuid:把 remote 名字与对端仓库的 annex UUID 绑定,sync/whereis 用它定位对端。

其他常用可配置键(git annex version 实测的构建特性支持的范围内):

键作用实测/说明
annex.backends仓库默认 backend(内容哈希算法)默认 SHA256E;可用 git annex init --backend=SHA256E 或对该键设置
annex.sshcachingSSH 连接复用默认开启,多机同步减少握手开销
annex.largefiles全局兜底的文件分流表达式建议用 .gitattributes 按路径配置(第三节)
annex.autocommitassistant 是否自动 commitassistant 场景使用
annex.skipunknownremotesync 跳过不可达 remote多机场景容错

三、.gitattributes 层:annex.largefiles 分流规则

3.1 问题:默认行为把所有文件都 annex 化

8.20210223 默认 git annex add 把任何文件都转成 symlink(安装篇实测:12 字节的 notes.txt 也进了 annex 对象库)。生产仓库通常希望小文本文件直接进 git(享受 git diff/合并),大文件进 annex——这就是 annex.largefiles 属性的职责。

3.2 配置与分流实测

在 repo-a 配置"大于 1 MB 的文件才进 annex":

echo "* annex.largefiles=(largerthan=1mb)" > .gitattributes
git add .gitattributes
git commit -m "configure annex.largefiles 1mb threshold"
echo "small text" > small.log
dd if=/dev/zero of=big2.bin bs=1M count=2 2>/dev/null
git annex add small.log big2.bin
git annex list
ls -l small.log big2.bin | awk '{print $1, $9}'

实测回显:

add small.log (non-large file; adding content to git repository) ok
add big2.bin 
100%  2 MiB           281 MiB/s 0s                                    ok
(recording state in git...)
here
|node-b
||web
|||bittorrent
||||
X___ big2.bin
_X__ bigfile.bin
X___ dataset-2026.tar
____ notes.txt
lrwxrwxrwx big2.bin
-rw-r--r-- small.log

分流一目了然:11 字节的 small.log 被 add 时明确提示 (non-large file; adding content to git repository),落盘为普通文件 -rw-r--r--;2 MB 的 big2.bin 进 annex,落盘为 symlink。此后 addurl 拉取的小文件同样走 git(实测 addurl 下载 robots.txt 时提示 non-large file; adding content to git repository)。

3.3 largefiles 表达式语法

annex.largefiles 的值是一个匹配表达式,常用操作符(均可在实测环境验证):

表达式含义
largerthan=1mb / smallerthan=100kb按大小分流(单位 b/kb/mb/gb)
include=.mp4 / exclude=.c按 glob 路径匹配
mimetype(text/) / mimetype(image/)按 MIME 类型(需 build flags 含 MagicMime,jammy 包实测含)
anything / nothing全部/全不

多条件可用 and/or 组合,如 *.annex.largefiles=(largerthan=100mb or include=*.iso)(按路径前缀生效不同规则)。注意:该属性只影响此后 add 的文件,已 annex 化的文件要用 git annex migrate 转换 backend 或重新 add。

3.4 .gitattributes 里的 numcopies:按路径副本数

.gitattributes 还支持按路径设置副本下限,与分支层全局 numcopies 叠加生效(取更严格者):

echo "* annex.numcopies=2" >> .gitattributes
git add .gitattributes && git commit -m "require 2 copies for all annexed files"

上面这行让全仓库 annex 文件至少 2 副本;写成 datasets/** annex.numcopies=3 则只对 datasets 目录强制 3 副本。

四、副本管理配置:numcopies 全参数实测

4.1 设置与查询命令

git annex numcopies 2     # 写入分支层 numcopies.log(全网络生效)
git annex numcopies       # 查询当前生效值

实测回显:

(recording state in git...)
2

4.2 drop 的副本校验语义(实测)

numcopies=N 的准确语义是:drop 本地副本后,全网络剩余副本数必须 ≥ N。安装篇与第一节实测的拒绝信息反复印证:

  • 2 份副本、numcopies=2:Could only verify the existence of 1 out of 2 necessary copies(除本地外剩 1 份 < 2,拒绝);
  • 位置记录未同步时:Could only verify the existence of 0 out of 2 necessary copies——先 git annex sync 让 location log 收敛再 drop;
  • numcopies=1、另一仓库有副本:正常放行。

git-annex 还有一个更强的 required content 机制(对特定仓库强制"必须/不得"持有内容表达式,违反时 drop 直接报错),由 git annex required <remote> <expression> 管理。注意 8.x 的 required 命令第一个参数必须是仓库名,实测传数字会报错:

git annex required 1
git-annex: there is no available git remote named "1"
git-annex: Specify a repository.

五、信任级别与仓库分组

5.1 三级信任与特殊 UUID

git annex info 实测展示的信任体系:

trusted repositories: 0
semitrusted repositories: 4
	00000000-0000-0000-0000-000000000001 -- web
 	00000000-0000-0000-0000-000000000002 -- bittorrent
 	0be16052-5128-42f8-9ae7-1ab9a32dfc83 -- [node-b]
 	da2dfc12-a5d2-4a5b-b7d0-7efc76ae9b07 -- node-a [here]
untrusted repositories: 0
  • trusted:无条件相信其持有声明,副本计数必算;
  • semitrusted(默认):副本计数算入,但单独存在不阻止数据被判定"安全";
  • untrusted:副本计数忽略(网络盘/不可靠存储适合);
  • web 与 bittorrent 是两个保留 UUID(全 0 特殊值),代表"从 URL 直接可取"的虚拟 remote。

信任级别变更写入分支层 trust.log,实测内容(semitrusted 记为 ?):

git show git-annex:trust.log
0be16052-5128-42f8-9ae7-1ab9a32dfc83 ? timestamp=1793341363.120228306s

5.2 trust 命令的防呆设计(实测)

把仓库标记为 trusted 需要 --force——8.20210223 明确拒绝轻率信任:

git annex trust node-b
git-annex: Trusting a repository can lead to data loss. If you're sure you know what you're doing, use --force to make this take effect. If you choose to do so, bear in mind that any time you drop content from node-b, you will risk losing data.
failed
git-annex: trust: 1 failed

恢复默认用 git annex semitrust node-b(实测回显 (recording state in git...),info 显示回到 semitrusted);标记不可靠存储用 git annex untrust(实测后 info 显示 trust: untrusted);退役仓库用 git annex dead——实测 dead usbdir 后 whereis 的副本列表立即排除该仓库。

5.3 分组与偏好内容:describe / group / wanted

为 remote 写描述、归组、设偏好内容表达式:

git annex describe node-b "second backup node"
git annex group node-b backup
git annex wanted node-b standard
git annex info node-b

实测回显(info 头部):

uuid: 0be16052-5128-42f8-9ae7-1ab9a32dfc83
description: second backup node [node-b]
trust: semitrusted
remote: node-b
cost: 100.0
type: git
repository location: /work/repo-b
last synced: 2026-10-30 06:20:49 UTC
remote annex keys: 2
remote annex size: 15.73 megabytes
  • group 预置语义组:backup(尽量多拿内容)、client(只留最近用过的)、archive(只进不出)等。git annex wanted <remote> standard 启用该组的内置偏好表达式;
  • cost:remote 传输代价,默认本地 git remote 100,数值越小越优先作为 get 的来源;
  • wanted 接受偏好表达式(与 largefiles 语法同源),如 git annex wanted node-b "include=datasets/**" 让 node-b 只收数据集。

批量交互编辑这些配置用 git annex vicfg(按 tab 分列列出 group/wanted/trust,保存即写入分支层)。

六、git-annex 元数据分支:仓库的"账本"

git-annex 分支是 git-annex 的全部状态账本,普通 git 命令即可审阅:

git log git-annex --oneline

实测回显:

ada9d52 update
bd0db40 update
268b843 update
67e58ef update
53839b2 update

每次 annex 操作产生一个 update 提交。分支内的关键 log 文件(均实测可 git show git-annex:<文件> 查看):

文件内容实测样例
numcopies.log全局副本下限(时间戳 + 值)1793341478.291006959s 2
trust.log仓库信任级别(T/S/?/U/D)0be16052-... ? timestamp=1793341363.120228306s
uuid.logUUID → 描述映射describe/group/wanted 写入处
log(location log)key → 持有仓库(时间戳 + UUID + # Present)whereis/list 的数据源

运维要点:账本即 git 历史,任何状态变更可审计、可回滚(git checkout 到旧提交对照);两仓库只要 git 能互通,账本就能收敛——这就是"无中心、无数据库"的配置体系。

七、数据目录结构:.git/annex/ 实查

repo-a 的 annex 数据目录实测结构:

ls .git/annex/
gitqueue.lck
index
index.lck
journal
journal.lck
keysdb
keysdb.cache
keysdb.lck
mergedrefs
move.lck
move.log
objects
othertmp.lck
sentinal
sentinal.cache
smudge.lck
tmp
transfer
目录/文件用途
objects/内容对象库:两级哈希分桶(实测 objects/G8/4G/<key>/<key> 形态),同名 key 内容唯一
journal/未提交到 git-annex 分支的状态变更日志(崩溃恢复依据)
transfer/进行中的内容传输暂存(assistant/copy 断点)
tmp/下载中对象的临时文件
keysdb/SQLite 的 key 数据库缓存(加速 find/whereis)
*.lck并发锁文件(多命令并发安全)
indexgit-annex 分支的工作索引

目录级 remote(如 directory 型 usbdir)的落盘形态同样是分桶:实测 /work/annex-dir/ 下直接是 7de/、tmp/ 等目录。

八、特殊 remote 配置:initremote / enableremote

除 git remote 外,git-annex 用 initremote 创建带独立配置的特殊仓库(云存储、目录、rsync 等),配置保存在分支层 uuid.log:

git annex initremote usbdir type=directory directory=/data/annex-dir encryption=none

实测回显:

initremote usbdir ok
(recording state in git...)

随后可对其 copy/get(实测 copy --to usbdir 后 whereis 显示 3 copies:node-b + usbdir + here)。两个实测踩坑点:

  1. 目标目录必须先存在,否则报错 git-annex: Directory does not exist: /data/annex-dir 且 initremote 整体 failed;
  2. 仓库退役不要直接删 remote,用 git annex dead <name> 标记死亡(whereis 立即排除其副本),确认无副本依赖后再清理存储。

启用已存在但未激活的 remote 用 git annex enableremote <name>(如换机器后重新指向 S3 bucket)。加密场景 encryption=none 换成 encryption=shared(对称密钥)或 encryption=<keyid>(gpg 公钥),密钥配置同样落在 uuid.log。

九、配置自查命令速查

目的命令
看仓库身份/版本git config annex.uuid、git config annex.version
看当前副本下限git annex numcopies
看某 remote 全量属性git annex info <remote>
看分流规则cat .gitattributes
看信任/分组账本git show git-annex:trust.log、git show git-annex:uuid.log
交互式改配置git annex vicfg
全仓库健康检查git annex fsck(逐 key 校验哈希,实测 3 个 key 全 ok)

命令族的完整用法(get/drop/move/copy/sync 等的参数与回显)见 《git-annex 8.20210223 常用 CLI 命令详解》。