git-annex 8.20210223 常用 CLI 命令详解

git-annex 8.20210223 核心命令族双机仓库实测:init/add/get/drop/move/copy/sync/whereis/list/find/info/fsck/metadata/unlock 等逐命令真实回显,含 numcopies 副本保护拒绝信息与 --force 数据丢失实录、命令速查表。

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

git-annex 8.20210223 常用 CLI 命令详解

实测环境:Ubuntu 22.04 LTS 服务器,git-annex 8.20210223(jammy apt 仓库),双机目录仓库(repo-a/node-a 与 repo-b/node-b)+ directory 型特殊仓库 usbdir。全部回显为真实命令输出。实测日期:2026-10-30。安装与双机链路搭建见 《Ubuntu 22.04 安装 git-annex 8.20210223 指南》。

一、命令体系概览

git-annex 的命令按职责分六族,全部以 git annex <命令> 形式调用:

族命令职责
仓库生命周期init、describe、version、fsck建仓、描述、版本与完整性
文件内容add、get、drop、move、copy、unlock、lock副本的增删搬调与编辑态切换
元数据metadata、find、whereis、list、status、info查账:内容在哪、谁持有、什么属性
同步sync、assistant、webappgit 账本与内容的收敛、自动同步
remote 管理initremote、enableremote、trust、semitrust、untrust、dead特殊仓库与信任体系
配置numcopies、group、wanted、vicfg副本下限、分组与偏好内容

配置体系(numcopies 三层来源、.gitattributes 分流、git-annex 分支账本)见 《git-annex 8.20210223 配置参数详解》,本篇专注命令操作本身。

二、仓库生命周期命令

2.1 git annex init:初始化并登记仓库

git init repo-a && cd repo-a
git annex init "node-a"

实测回显:

Initialized empty Git repository in /data/repo-a/.git/
init node-a (scanning for unlocked files...)
ok
(recording state in git...)

描述参数("node-a")会写进 uuid.log 并出现在所有 info/whereis 输出里;省略描述时仓库以 UUID 前几位显示。init 还会写入 filter.annex.* git 过滤器并创建 git-annex 元数据分支。在新 clone 的仓库里执行 init(见安装篇 2.3 节)时会先自动 merging origin/git-annex 收敛对端账本。

2.2 git annex version:版本与能力盘点

git annex version
git annex version --raw

实测回显(完整版含 build flags/backends/remote types 三张能力清单,逐行解读见安装篇 1.4 节;此处节选):

git-annex version: 8.20210223
build flags: Assistant Webapp Pairing Inotify DBus DesktopNotify TorrentParser MagicMime Feeds Testsuite S3 WebDAV
supported repository versions: 8
upgrade supported from repository versions: 0 1 2 3 4 5 6 7
8.20210223

--raw 只输出版本号,适合脚本判断。

2.3 git annex fsck:全量完整性校验

git annex fsck

实测回显(repo-b,3 个 annex key 逐一重算哈希):

fsck big2.bin (checksum...) ok
fsck bigfile.bin (checksum...) ok
fsck dataset-2026.tar (checksum...) ok
(recording state in git...)

fsck 按内容哈希逐 key 校验本地对象,发现损坏/缺失 key 时会修正 location log("fixing links")。定时任务里每周跑一次是备份场景的基本盘。附加参数 --fast(跳过哈希只查文件存在)、--numcopies=2(顺带校验副本数达标)。

三、文件内容命令:副本的增删搬调

dd if=/dev/urandom of=bigfile.bin bs=1M count=5 2>/dev/null
git annex add .

实测回显:

add bigfile.bin 
100%  5 MiB           306 MiB/s 0s                                    ok
(recording state in git...)

add 把文件内容搬进 .git/annex/objects/(哈希分桶),工作区原位替换为指向 key 的 symlink,并 stage 一个 mode 120000 的变更。配置了 annex.largefiles 后,小文件会明确走 git:

add small.log (non-large file; adding content to git repository) ok

3.2 git annex get:拉取内容

git annex get bigfile.bin

实测回显(repo-b,从 remote origin 拉取):

get bigfile.bin (from origin...) 
100%  5 MiB           329 MiB/s 0s                                    ok
(recording state in git...)

不指定来源时 git-annex 按 remote cost 自动选一个持有该 key 的 remote;显式指定用 --from:

git annex get dataset-2026.tar --from origin

实测回显:

get dataset-2026.tar (from origin...) 
100%  10 MiB          300 MiB/s 0s                                    ok
(recording state in git...)

常用参数:--from <remote> 指定来源;--all 拉取仓库历史里全部 key(不仅是当前工作区);-J4 并发 4 线程传输。

3.3 git annex drop:删除本地副本(带副本保护)

git annex drop bigfile.bin

实测回显(node-b 有另一份副本、numcopies=1 时放行):

drop bigfile.bin ok
(recording state in git...)

副本不足时拒绝删除是 git-annex 的核心安全特性,实测两种拒绝形态:

drop bigfile.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

以及位置记录未同步时的 Could only verify the existence of 0 out of 2 necessary copies——先 git annex sync 收敛账本再 drop。危险参数 --force 会绕过保护,第七节有它造成数据丢失的完整实录。

3.4 git annex copy:复制副本(不删本地)

git annex copy dataset-2026.tar --to node-b

实测回显:

copy dataset-2026.tar (to node-b...) 
100%  10 MiB          311 MiB/s 0s                                    ok
(recording state in git...)

批量把本地全部内容推给备份仓库:git annex copy --to node-b .(配合 --not --in node-b 只传对端没有的)。--from 方向同理拉取。

3.5 git annex move:复制后删除本地(腾空间)

git annex move notes.txt --to node-b

实测回显:

move notes.txt (to node-b...) 
100%  12 B              3 KiB/s 0s                                     ok
(recording state in git...)

move 等价 copy + drop(且 drop 不受 numcopies 拒绝——副本仍在网络中)。验证:move 后 git annex whereis notes.txt 显示 1 copy,唯一副本在对端:

whereis notes.txt (1 copy) 
  	0be16052-5128-42f8-9ae7-1ab9a32dfc83 -- [node-b]
ok

3.6 git annex unlock / lock:编辑态切换

annex 化的文件是只读 symlink,要修改内容先解锁:

git annex unlock dataset-2026.tar
ls -l dataset-2026.tar | awk '{print $1}'
echo "appended" >> dataset-2026.tar
git annex add dataset-2026.tar
git commit -m "modify dataset"

实测回显:

unlock dataset-2026.tar ok
(recording state in git...)
-rw-r--r--
add dataset-2026.tar 
100%  10 MiB          353 MiB/s 0s                                    ok
(recording state in git...)

unlock 把 symlink 替换成普通文件(-rw-r--r--),改完重新 add 会生成新 key(内容变了,key 也变,旧 key 位置记录保留)。不改动则用 lock 收回(实测 lock 后 ls -l 回到 lrwxrwxrwx)。assistant 开启的仓库文件常态为 unlocked(annex.addunlocked 配置),行为一致。

四、元数据与查询命令:随时知道内容在哪

4.1 git annex whereis:key 的全网络副本分布

git annex whereis dataset-2026.tar

实测回显(3 份副本形态,含 directory 型 remote):

whereis dataset-2026.tar (3 copies) 
  	0be16052-5128-42f8-9ae7-1ab9a32dfc83 -- second backup node [node-b]
   	3a52abc3-41f5-4d75-b6b1-9b5ffc614e0f -- [usbdir]
   	da2dfc12-a5d2-4a5b-b7d0-7efc76ae9b07 -- node-a [here]
ok

副本数不足时命令直接失败(0 copies 报 whereis: 1 failed),适合当健康检查用。

4.2 git annex list:副本矩阵

git annex list

实测回显:

here
|node-b
||web
|||bittorrent
||||
XX__ bigfile.bin
X___ dataset-2026.tar
_X_ notes.txt

列头自上而下读:here、node-b、web、bittorrent;行内 X 表示对应仓库持有内容,_ 表示没有,- 表示该仓库副本已被 untrust/dead 排除。一屏看清全库副本水位。

4.3 git annex find:按条件筛文件

git annex find "--include=*.bin"
git annex find --not --in here

实测回显:

big2.bin
bigfile.bin
bigfile.bin
notes.txt

第一组按路径模式筛;第二组列出"本地没有内容"的文件(断链清单,get 的输入)。常用匹配器与 largefiles 同源:--in <remote>、--not --in <remote>、--copies=N、--largerthan=1gb。

4.4 git annex status / info:两个粒度的"状态"

git annex status 是 git status 的 annex 增强(标注 annex 属性变化):

A big2.bin
A small.log

git annex info 是仓库整体水位(repo-a 实测节选):

available local disk space: 216.69 gigabytes (+1 megabyte reserved)
local annex keys: 3
local annex size: 15.73 megabytes
annexed files in working tree: 3
size of annexed files in working tree: 15.73 megabytes
bloom filter size: 32 mebibytes (0% full)
backend usage: 
	SHA256E: 3

git annex info <remote> 则给出对端属性(type/cost/最近同步时间/持有 key 数与体积),remote 排障先看它。

4.5 git annex metadata:给文件打标签

git annex metadata dataset-2026.tar -t projectA -s year=2026
git annex metadata dataset-2026.tar

实测回显:

metadata dataset-2026.tar 
  lastchanged=2026-10-30@06-21-50
  tag=projectA
  tag-lastchanged=2026-10-30@06-21-50
  year=2026
  year-lastchanged=2026-10-30@06-21-50
ok

标签与字段值记录在 git-annex 分支,可用 git annex find --tag=projectA 检索——不搬文件、不改路径就能给数据集分类。

五、同步命令

5.1 git annex sync:账本收敛(可携带内容)

git annex sync

实测回显(repo-a 首次同步 node-b):

(merging node-b/git-annex into git-annex...)
push node-b 
To /work/repo-b
 * [new branch]      git-annex -> synced/git-annex
 * [new branch]      master -> synced/master
ok

默认只同步 git 元数据(账本 + 工作分支);加 --content 连内容一起按 wanted 表达式搬运:

git annex sync --content

实测回显(推送对端后双向收敛):

push node-b 
To /work/repo-b
   14aa159..9ea9224  git-annex -> synced/git-annex
ok

5.2 git annex assistant:自动同步守护进程

git annex assistant --help

实测回显:

git-annex assistant - automatically sync changes

Usage: git-annex assistant [--foreground] [--stop] [--autostart] 
                           [--startdelay NUMBER] [--autostop]

jammy 包 build flags 含 Assistant。前台调试用 --foreground,开机自启用 --autostart(配合 git annex webapp 或手工把仓库加入 autostart 清单),停止用 --stop。

5.3 git annex webapp:网页控制台(有桌面的场景)

build flags 含 Webapp,但 headless 服务器实测 git annex webapp 无可用图形环境不产出可访问界面——服务器场景以 CLI 为准,webapp 属于桌面用户辅助形态。

六、remote 管理命令

6.1 initremote:创建特殊仓库

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

实测回显(目录不存在时的报错与修复后成功):

initremote usbdir 
git-annex: Directory does not exist: /data/annex-dir
failed
git-annex: initremote: 1 failed
initremote usbdir ok
(recording state in git...)

创建成功后即可像普通 remote 一样 copy/get(实测 git annex copy dataset-2026.tar --to usbdir 成功,落盘为分桶目录结构)。S3/WebDAV/rsync 等类型在 initremote 时传入各自的配置参数(bucket、url、keyid 等),配置全部落在 git-annex 分支。

6.2 trust / semitrust / untrust / dead:信任体系

实测(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

trust 需要 --force 确认(防呆);semitrust/untrust/dead 无需 force。dead 标记仓库退役,实测后 whereis 副本列表立即排除该仓库(3 copies 变 2 copies)。恢复用 semitrust。

七、副本与安全:numcopies 与 --force 数据丢失实录

7.1 numcopies 命令

git annex numcopies 2
git annex numcopies

实测回显:

(recording state in git...)
2

写入分支层全网络生效;查询显示当前生效值。三层来源的优先级实测(命令行 --numcopies > 分支层 > git config 层)见 《git-annex 8.20210223 配置参数详解》 第一节。

7.2 实录:--force drop 如何丢掉一份数据

复现一次完整的事故链(测试文件 notes.txt,唯一副本在 node-b):

cd /data/repo-b
git annex drop --force notes.txt
drop notes.txt ok
(recording state in git...)

--force 绕过了 numcopies 保护(当时它是最后一副本)。此后所有仓库的账本都显示该 key 0 copies,内容在网络上不复存在:

git annex whereis notes.txt
whereis notes.txt (0 copies) failed
git-annex: whereis: 1 failed

工作区残留断链 symlink,cat 报 No such file or directory;git annex find --not --in here 把它列入"本地缺失"清单但已无处可 get。恢复手段只剩重新生成内容(本例 re-echo 原文后重新 git annex add)。三条防线记牢:drop 永远不带 --force;numcopies 按数据价值设 2–3;发现 0 copies 立即用 whereis 定位源头补救。

7.3 unused:孤儿内容清理

git annex unused

实测回显(无孤儿时):

unused . (checking for unused data...) ok

有孤儿时列出编号,git annex dropunused all 统一清理。孤儿通常产生于 add 后回滚、rename 后遗忘等场景,定期检查避免对象库膨胀。

八、其他高频命令

  • git annex addurl:把 URL 资源收进仓库(实测 git annex addurl https://www.quzuo.net/robots.txt,受 largefiles 规则分流,web 虚拟 remote 记录来源,断链时可 --from web 重取);
  • git annex describe/group/wanted:remote 描述、分组与偏好内容,配置语义见配置篇第五节;
  • git annex vicfg:交互式批量编辑 trust/group/wanted/numcopies;
  • git annex migrate:转换文件到新 backend(如 SHA256E → BLAKE2B512E),配合 backend 升级。

九、命令速查表

命令一句话高频参数
init初始化 annex 仓库<描述>
add文件入库(symlink 化).、--force large
get拉内容到本地--from、--all、-J4
drop删本地副本(校验 numcopies)--force(危险)
copy复制副本不删本地--to/--from、--not --in
movecopy + drop 腾空间--to/--from
unlock/lock编辑态/受管态切换<文件>
sync账本收敛--content、-J4
whereis查副本分布<文件>、--all
list副本矩阵一屏览无
find条件筛文件--include/--in/--copies
info仓库/对端水位<remote>
fsck完整性校验--fast、--numcopies
metadata打标签-t、-s key=value
initremote建特殊仓库type= directory=/ encryption=
trust 系信任级别管理semitrust/untrust/dead
numcopies全局副本下限N(写)/无参(查)
unused孤儿内容盘点dropunused all
version版本与能力--raw
assistant自动同步守护--autostart/--stop