在 GitHub 上编辑

diff

DVC 仓库 的两个提交之间,或在一个提交与工作区之间,显示被 DVC 跟踪的文件和目录的新增、修改或删除情况。

概要

usage: dvc diff [-h] [-q | -v]
                [--targets [<paths> [<paths> ...]]]
                [--json] [--show-hash] [--md]
                [a_rev] [b_rev]

positional arguments:
  a_rev      Old Git commit to compare (defaults to HEAD)
  b_rev      New Git commit to compare (defaults to current workspace)

描述

打印出 Git 提交 b_rev 相较于另一个 Git 提交 a_rev 所添加、修改、重命名或删除的文件和目录列表。参数 a_revb_rev 均可接受任意 Git 版本标识 —— 分支名、标签名、Git 提交哈希等。

请注意,对于重命名操作,dvc diff 仅能检测在两次 Git 提交之间被重命名但内容未发生更改的文件。

如果未指定参数 a_revb_rev,则默认比较当前工作区与最后一次提交(HEAD)。

可以使用选项 --json--show-hash 来调整此命令输出的格式。更多详细信息请参见下方的 选项示例 部分。

当仓库未由 Git 跟踪时(例如使用 dvc init 并指定 --no-scm 选项初始化),dvc diff 不会产生任何效果。

请注意,当前 dvc diff 的实现不会像 git diffGNU diff 那样显示各版本文件之间的逐行差异对比。这是因为 DVC 跟踪的数据可能有多种格式,例如结构化文本或二进制对象等。有关如何实现逐行文本文件对比的示例,请参考此 评论

选项

  • --targets <paths> - 指定要比较的特定 DVC 跟踪文件。

    当在 a_rev/b_rev 之前为 --targets 指定参数时,应在该选项参数后使用 --(适用于 POSIX 终端),例如:

    $ dvc diff --targets t1.json t2.yaml -- HEAD v1
  • --json - 以易于解析的 JSON 格式输出命令结果,而非人类可读的表格形式。

  • --md - 以 Markdown 表格格式输出命令结果。

  • --show-hash - 在输出文件和目录路径的同时打印其哈希值。对调试非常有用。

  • --hide-missing - 不列出在工作区和缓存中均缺失的数据(不在缓存中)。仅列出明确添加、修改或删除的文件和目录。此选项在比较两个 Git 提交时无效。

  • -h, --help - 打印使用说明/帮助信息,然后退出。

  • -q, --quiet - 不向标准输出写入任何内容。如果没有问题则以 0 退出,否则以 1 退出。

  • -v, --verbose - 显示详细的跟踪信息。

示例

在以下示例中,我们可以使用 入门指南 项目。

如果你还没有该项目,请先克隆我们的示例仓库:

$ git clone https://github.com/iterative/example-get-started
$ cd example-get-started

使用以下命令下载数据:

$ dvc fetch -T
Preparing to download data from 'https://remote.dvc.org/get-started'
...

使用 -T 选项时,dvc fetch 会确保我们获取仓库中所有现有 Git 标签对应的数据文件。你可以在此处查看示例仓库的可用标签 这里

示例:检查工作区变更

最简单的 dvc diff 用法是不带任何参数运行,默认比较 HEAD(最后一次 Git 提交)与当前 工作区(未提交的更改,如果有)之间的 DVC 跟踪文件:

$ dvc diff

示例:将工作区与任意提交进行比较

让我们切换到 2-track-data 标签,它对应 数据版本控制 入门章节,在我们使用 DVC 添加了 data.xml 文件之后的状态:

$ git checkout 2-track-data
$ dvc checkout

要查看项目上一个提交与工作区之间的差异,我们可以将 HEAD^ 用作 a_rev

$ dvc diff HEAD^
Added:
    data/data.xml

files summary: 1 added, 0 deleted, 0 modified

示例:比较标签或分支

我们的示例仓库包含 baseline-experimentbigrams-experiment 两个标签,它们分别指向两个不同的建模实验。

按照示例设置完成后,进入 example-get-started/ 目录。然后使用以下命令确保你拥有最新的代码和数据:

$ git checkout master
$ dvc checkout
$ dvc diff baseline-experiment bigrams-experiment
Modified:
    data/features/
    data/features/test.pkl
    data/features/train.pkl
    model.pkl
    prc.json
    scores.json

files summary: 0 added, 0 deleted, 5 modified

该命令的输出确认了标签 baseline-experimentbigrams-experiment 之间有 5 个文件存在差异。

示例:使用不同的输出格式

让我们使用与上面相同的命令,但以 JSON 格式输出并包含哈希值:

$ dvc diff --json --show-hash \
           baseline-experiment bigrams-experiment

输出结果为:

{
  "added": [],
  "deleted": [],
  "modified": [
    {
      "path": "data/features/",
      "hash": {
        "old": "3338d2c21bdb521cda0ba4add89e1cb0.dir",
        "new": "42c7025fc0edeb174069280d17add2d4.dir"
      }
    },
    ...
    {
      "path": "model.pkl",
      "hash": {
        "old": "43630cce66a2432dcecddc9dd006d0a7",
        "new": "662eb7f64216d9c2c1088d0a5e2c6951"
      }
    }
    ...
  ]
}

示例:重命名文件

完成前面示例的设置后,进入 example-get-started/ 目录。然后使用以下命令确保你拥有最新的代码和数据:

$ git checkout master
$ dvc checkout

dvc diff 仅能检测到被重命名但内容未修改的文件。如果一个文件被重命名的同时内容也被修改,dvc diff 将显示原始文件已被删除,而修改后的版本被视为新增文件。

让我们看看在工作区中重命名 data/data.xml 时会发生什么:

$ dvc move data/data.xml data/other_data.xml
$ dvc diff
Renamed:
    data/data.xml -> data/other_data.xml

files summary: 0 added, 0 deleted, 1 renamed, 0 modified, 0 not in cache

现在,我们修改 data/other_data.xml,然后再看一次结果:

$ echo "<row Id=\"12345678\" Body=\"New row\" />" >> data/other_data.xml
$ dvc diff
Added:
    data/other_data.xml

Deleted:
    data/data.xml

files summary: 1 added, 1 deleted, 0 renamed, 0 modified, 0 not in cache

在这种情况下,由于 data/other_data.xml 的文件内容已更改,dvc diff 不再能识别出它是原始文件 data/data.xml 的重命名版本。