mcpField
D
datalad

datalad

github.com/k-dense-ai数据与数据库55.1k541 次安装2 天前更新
代码仓库

关于 datalad

DataLad 是构建在 Git 和 git-annex 之上的数据管理层,面向管理大型或分布式数据集的研究团队。它支持按需获取文件内容,并记录命令、输入和输出,便于检查和重跑分析。

主要功能

  1. 01使用 Git 和 git-annex 管理数据集
  2. 02按需获取大型文件
  3. 03嵌套数据集及独立历史
  4. 04记录命令和输出溯源
  5. 05重跑已记录的分析
  6. 06在容器中运行命令

适用场景

  1. 01管理不适合直接放入 Git 的大型数据集
  2. 02从远程数据集中按需获取文件
  3. 03记录并重跑研究分析
  4. 04与协作者共享数据和分析溯源

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/k-dense-ai/scientific-agent-skills --skill datalad

安装后在 Claude Code 中输入/datalad确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
data-access.md
provenance.md
publishing.md

详细介绍

DataLad

概述

DataLad 是构建在 Git 和 git-annex 之上的数据管理层。Git 跟踪数据集 结构、小型文本文件和历史记录。git-annex 跟踪大文件的内容,将每个文件存储为一个 key,并把字节数据保存在不一定 是本地仓库的地方。

普通的 clone 会获取 Git 历史和顶层文件列表,但不会拉取 annex 的字节数据。已安装的子数据集有各自的历史记录;clone 不会 自动填充它们。Clone 的成本取决于 Git 历史和文件数量,而不仅仅是 数据量。使用 datalad get 有选择地获取 annex 字节数据。

DataLad 增加的第二个能力是溯源。datalad run 执行一条命令,并将结果与 机器可读的记录一起提交,记录中包含该命令、其输入和输出。datalad rerun 读取该记录并重新执行它。这 将 "这张图是怎么生成的" 从考古难题变成了一条命令。

何时使用 DataLad 而不是普通 Git

在满足以下任一条件时使用 DataLad:

  • 文件太大,Git 难以轻松处理,或者总量超出每位 协作者希望在磁盘上保留的范围。
  • 数据存在于多个位置(实验室服务器、集群暂存盘、S3、超级计算机), 而你需要知道存在哪些副本。
  • 分析必须可重新执行,而普通的提交信息不足以作为证据。
  • 你正在使用来自 OpenNeuro、DANDI 或 datasets.datalad.org 的已发布数据集, 它们以 DataLad 数据集的形式分发。
  • 项目中嵌套了其他数据集,而你想让每个数据集保留各自 独立的历史记录。

当仓库仅包含代码和文本、所有内容都能轻松放入 Git,且没有人需要部分检出时,使用普通 Git。在小型纯代码仓库之上使用 DataLad 只会增加间接层,而没有任何收益。

安装

# git-annex is NOT written in Python but is available from PyPI if you already
# have git itself installed:
uv pip install git-annex
# You can also install it first from the system
# (Debian/Ubuntu: apt install git-annex; macOS: brew install git-annex;
#  conda-forge: conda install -c conda-forge git-annex)
uv pip install "datalad==1.6.5"
uv pip install "datalad-container==1.2.6"   # only for containers-run

datalad wtf --section dependencies   # confirm git-annex version is visible

PyPI 上的 git-annex 包提供平台特定的二进制文件。经过审核的 10.20260901.post1 wheel 覆盖 Linux glibc 2.34+(x86_64/ARM64)、macOS ARM64 14+ 和 x86_64 15+,以及 Windows x86_64。当没有匹配的 wheel 时,使用系统包。将其 环境保留在 PATH 上并验证可执行文件;该 wheel 不提供 Git 本身。 在创建或保存数据集之前,配置 Git 作者姓名/邮箱。

datalad wtf 打印解析后的环境,是行为看起来不可能时首先要运行的东西。过旧或缺失的 git-annex 是大量令人困惑错误的根源。

DataLad 采用 MIT 许可证;git-annex 有单独的 AGPL 许可证。重新分发任一工具时,请查阅上游 许可证。

最先让人栽跟头的故障:指针不是数据

执行 datalad clone 之后, annexed 文件以符号链接的形式存在于 .git/annex/objects/ 中(在无法使用符号链接的场景下,例如 Windows 或功能受限的文件系统上,则表现为小型的指针文件)。此时内容尚未被下载。

这是一个说明性的远程数据示例;请检查所选修订版本中的确切路径,并在 Python 读取之前安装 NiBabel。该刷新测试在没有下载影像数据的情况下验证了等效的本地指针/get 行为。

datalad clone https://github.com/OpenNeuroDatasets/ds000001.git
cd ds000001
ls sub-01/anat/            # the file is listed
python -c "import nibabel; nibabel.load('sub-01/anat/sub-01_T1w.nii.gz')"   # fails
datalad get sub-01/anat/sub-01_T1w.nii.gz                                   # now it works

需要识别的故障模式:某个工具报告文件为空、被截断、已损坏、“不是 gzip 文件”,或者是损坏的符号链接,而磁盘上的文件大小只有几百字节。这些症状可能表明存在未获取的 annex 指针;在诊断损坏之前,请先用 annex status 进行确认。在读取数据之前先运行 datalad get,并将“文件存在”视为不足以证明其内容已存在的证据。

在分析触及某个目录之前,请显式地获取它:

datalad get sub-01/                  # everything under a path
datalad get -r .                     # everything, including subdatasets
datalad get -n -r .                  # subdataset structure only, no file content

datalad status --annex availability 检查哪些内容已在本地存在,而 git annex whereis <path> 报告哪些仓库持有某个给定文件。whereis 读取的是已记录的状态,不会联系远程仓库,因此它告诉你的是 git-annex 上次获知的情况,而不是当前真实的情况。

关于查找数据集、子数据集行为、安全地丢弃内容以及修复数据集,请参见 data-access.md。

使用 datalad run 记录溯源信息

datalad run 是在方法学语境下选择 DataLad 的理由。它将命令与其效果一起保存在同一个提交中:

这是一个说明性的 FSL 示例(需要 bet 以及一个已存在的 derivatives/ 目录):

datalad run -m "extract brain and mask" \
  --input "sub-01/anat/sub-01_T1w.nii.gz" \
  --output "derivatives/sub-01_brain.nii.gz" \
  --output "derivatives/sub-01_brain_mask.nii.gz" \
  "bet {inputs[0]} {outputs[0]} -m"

每个部分的作用,以及为何跳过它会带来麻烦:

  • --input 在运行前获取内容,因此命令不会因指针而失败。它还会记录依赖关系,这正是 rerun 能够在另一台机器上获取相同输入的原因。
  • --output 会先解锁或移除目标,这样 git-annex 就不会拒绝覆盖它正在保护的内容。如果没有它,第二次运行同一命令通常会因为对一个看似只读的 annexed 文件的权限错误而失败。
  • {inputs} 和 {outputs} 会展开为这些值。{pwd}、{dspath} 和 {tmpdir} 也可用,而 {inputs[0]} 可以索引各个条目。
  • 提交消息在 === Do not change lines below === 和 ^^^ Do not change lines above ^^^ 之间携带一条 JSON 运行记录。不要手动编辑该区块;rerun 会解析它。

当数据集存在未保存的修改时,datalad run 会拒绝启动,因为不干净的起始状态会使记录不可靠。请先保存或丢弃,或者传入 --explicit 以仅保存已声明的输出。这不会捕获未保存的输入更改;在声称该运行可复现之前,请保存所有依赖项。在正式执行某个命令之前,可以用 --dry-run basic 或 --dry-run command 检查它。

没有任何更改的运行不会产生提交,与 datalad save 的行为完全一样。

run 记录命令和数据集状态;它不会冻结任意由主机安装的软件或外部服务。将环境锁文件和脚本作为已声明的输入进行版本控制,或者使用通过 containers-run 跟踪的容器镜像。记录随机种子和相关的运行时设置,然后在声称计算可复现之前,从全新环境中测试 rerun。

重新执行
datalad rerun                       # redo the run recorded at HEAD
datalad rerun --report              # show what would be done, change nothing
datalad rerun --script recompute.sh # extract the commands instead of running them
datalad rerun --since <commit> -b check <revision>   # replay a range onto a new branch

--report 只检查计划;它不会执行或验证结果。分支(-b)会保留原始提交,但使用同一个工作树。关于在首次运行之前开始的 --since/--onto 重放,请参见参考文档,并比较 annex 键或内容校验和以及科学输出。

容器

借助 datalad-container 扩展,只需注册一次镜像,之后每次运行都会记录产出结果的是哪个镜像:

使用先前构建的本地 SIF 镜像的容器工作流示例(本次刷新中并未实际执行;运行时和镜像必须可用):

datalad containers-add fsl --url /path/to/fsl.sif \
  --call-fmt 'apptainer exec {img} {cmd}'
datalad containers-run -n fsl -m "brain and mask in container" \
  --input "sub-01/anat/sub-01_T1w.nii.gz" \
  --output "derivatives/sub-01_brain.nii.gz" \
  --output "derivatives/sub-01_brain_mask.nii.gz" \
  "bet {inputs[0]} {outputs[0]} -m"

镜像本身被跟踪在数据集中,因此软件环境随数据以及溯源记录一同传递,而不是留在某人的 shell 历史里。当只配置了一个容器时,-n 可以省略。

关于 STAMPED 原则和 YODA 项目布局、运行记录格式、--explicit 与 --assume-ready 的语义,以及将溯源导出为 W3C PROV,请参阅 provenance.md。

保存与检查变更

datalad status                 # what changed, including subdataset state
datalad save -m "add QC report" path/to/file
datalad save -m "checkpoint" -r                 # recurse into subdatasets
datalad save -m "small text file" --to-git notes.md

datalad save 会依据数据集的 .gitattributes,逐个文件决定内容是进入 Git 还是进入 git-annex。用 --to-git 强制将文件放入 Git,对于应当保持可直接阅读的代码和小型文本文件来说这是正确的选择。yoda 过程(datalad create -c yoda)会自动为 code/、README.md 和 CHANGELOG.md 完成这一设置。

创建数据集

datalad create my_dataset               # plain dataset
datalad create -c yoda my_analysis      # analysis layout (code/ tracked in Git,
                                        # README.md and CHANGELOG.md preconfigured)
datalad create -d . inputs/raw          # register a new subdataset under an existing one

-c yoda 会应用 provenance.md 中描述的分析项目布局。-d . 的作用是将新数据集注册为父数据集的子数据集,而不是在父数据集内留下一个互不相关的仓库。

发布

一个 DataLad 数据集通常同时发布到两个位置:用于存放历史的 Git 托管服务,以及用于存放 annex 内容的存储远程。

带身份验证的发布示例(会创建远程资源;需要 GitHub token 和 S3 凭证)。myorg/mydataset 仅用于组织命名空间。

datalad create-sibling-github mydataset
git annex initremote store type=S3 bucket=my-bucket protocol=https \
  encryption=none autoenable=true
datalad siblings configure -s github --publish-depends store
datalad push --to github

Git sibling 和存储 sibling 是由不同工具刻意分别创建的。Git sibling 是一个 Git 远程,而 datalad create-sibling-* 处理面向托管服务的那些。S3 存储桶(或 WebDAV,或 SSH 目录)是 git-annex 特殊远程,不是 Git 远程,因此要用 git annex initremote 创建。datalad siblings 之后会识别出该特殊远程,并像对待其他远程一样对待它。在这里使用 datalad siblings add --url s3://... 正是本节所要防止的错误:--url 是 Git 远程 URL,而 S3 不是,于是下面的 push --to github 会在 --publish-depends 这一跳上失败。

--publish-depends 正是用来阻止那种常见的发布故障:一个 Git 仓库,其历史引用了从未上传过的内容,于是协作者克隆成功,随后发现每次 datalad get 都失败。声明该依赖可确保存储 sibling 每次都先发布。

datalad push 会同时发送 Git 历史,以及默认情况下(--data auto-if-wanted)由目标 wanted 设置所选择的 annex 内容;若没有 wanted 设置,则传输所有选定的当前内容。--data anything 会绕过首选内容过滤,但不会恢复本地缺失的字节,也不会归档每一个历史版本。

关于 RIA 存储、特殊远程、凭证处理,以及配置哪个 sibling 存放什么内容,请参阅 publishing.md。

释放磁盘空间

git annex whereis sub-01/                 # inspect recorded locations first
datalad drop sub-01/                      # remove local content, keep the pointer

datalad drop 默认会检查所需副本和可用性。--nocheck 已弃用,取而代之的是 --reckless availability,后者会禁用这些保护。--if-dirty 已弃用并被忽略;它不是可用性检查选项。--what 用于在 filecontent(默认)、allkeys、datasets 和 all 之间进行选择。

值得了解的故障模式

症状原因修复方法
文件读取为空、被截断,或是一个损坏的符号链接内容未被获取;仅存在指针datalad get <path>
写入已有输出时提示 "Permission denied"git-annex 对已归档内容写保护使用 --output 声明它,或执行 datalad unlock <path>
datalad run 拒绝启动数据集有未保存的更改先执行 datalad save,或传入 --explicit
datalad drop 拒绝执行没有内容经过验证的第二份副本推送到可访问的 sibling,然后重试安全检查
协作者克隆成功,但每次 get 都失败发布历史时未包含内容发布存储 sibling,并设置 --publish-depends
克隆成功,但子数据集目录为空子数据集默认不会被安装执行 datalad get -n -r .,然后 get 你需要的路径
命令行为异常git-annex 缺失或版本过旧执行 datalad wtf --section dependencies

详细参考

  • data-access.md:查找已发布的数据集 (registry.datalad.org、OpenNeuro、DANDI、datasets.datalad.org 以及 /// 快捷方式)、clone 和 get 选项、子数据集处理、annex 内容状态、drop 和 remove,以及 fsck 修复。
  • provenance.md:STAMPED 原则和 YODA 布局、 run 记录格式、run 和 rerun 的完整选项、containers-run,以及 将 DataLad 溯源信息导出为 W3C PROV 的当前进展。
  • publishing.md:sibling 及其操作、 create-sibling-* 变体、RIA 存储、特殊远程、push 语义,以及 凭据处理。

相关技能

bids 技能涵盖脑成像数据结构(Brain Imaging Data Structure),通过 DataLad 分发的 大多数神经影像数据集都按此结构组织。典型工作流是:用 DataLad 克隆一个 BIDS 数据集,用 BIDS 工具对其进行验证,然后在 datalad containers-run 下运行一个 BIDS-App,使衍生结果携带溯源信息。

验证范围

已于 2026-09-30 对照 DataLad 1.6.5 和 datalad-container 1.2.6 源码及 当前官方手册进行审查。小型本地测试覆盖 clone/get/drop、解锁状态下的保存、 子数据集安装、run/rerun、默认 push 选择,以及 RIA publish/clone/get。 远程托管、凭据、FSL 和容器执行示例仅作说明用途; 未执行经过身份验证的远程发布,也未下载科学数据。

主要来源

致谢

本技能的主题范围部分参考了 @bcmcpher 以 MIT 许可证发布的 datalad-cli 插件(十九个按命令划分的斜杠命令技能)。此处文本为 独立撰写,并以上游 DataLad 文档为依据;由于两者都涵盖 DataLad,重叠不可避免, 但结构、风格和具体技术主张有所不同。

评论

支持 Markdown