diff: add support for specifying a target

This commit is contained in:
Mr. Outis
2020-01-25 11:00:36 -06:00
parent 576a27667f
commit 07abd1b41b
2 changed files with 44 additions and 13 deletions
+5 -2
View File
@@ -40,8 +40,9 @@ def diff(self, a_ref="HEAD", b_ref=None, *, target=None):
By default, it compares the working tree with the last commit's tree.
When a `target` path is given, it only shows that file's comparison.
It will silently fail when `target` is not found in any of the trees.
This implementation differs from `git diff`, since DVC doesn't have
This implementation differs from `git diff` since DVC doesn't have
the concept of `index`, `dvc diff` would be the same as `dvc diff HEAD`.
"""
outs = {}
@@ -52,11 +53,13 @@ def diff(self, a_ref="HEAD", b_ref=None, *, target=None):
for stage in self.stages
for out in stage.outs
)
old = outs[a_ref]
new = outs[b_ref or "working tree"]
delta = old ^ new
if target:
delta = set(x for x in delta if x.filename == target)
if not delta:
return
+39 -11
View File
@@ -1,4 +1,9 @@
import pytest
import hashlib
def _checksum(text):
return hashlib.md5(bytes(text, "utf-8")).hexdigest()
def test_no_scm(tmp_dir, dvc):
@@ -13,7 +18,7 @@ def test_added(tmp_dir, scm, dvc):
result = {
"file": {
"old": {},
"new": {"checksum": "1cb251ec0d568de6a929b520c4aed8d1", "size": 4},
"new": {"checksum": _checksum("text"), "size": 4},
"diff": {"status": "added", "size": 4},
}
}
@@ -27,7 +32,7 @@ def test_deleted(tmp_dir, scm, dvc):
result = {
"file": {
"old": {"checksum": "1cb251ec0d568de6a929b520c4aed8d1", "size": 4},
"old": {"checksum": _checksum("text"), "size": 4},
"new": {},
"diff": {"status": "deleted", "size": 4},
}
@@ -42,8 +47,8 @@ def test_modified(tmp_dir, scm, dvc):
result = {
"file": {
"old": {"checksum": "8b04d5e3775d298e78455efc5ca404d5", "size": 6},
"new": {"checksum": "a9f0e61a137d86aa9db53465e0801612", "size": 6},
"old": {"checksum": _checksum("first"), "size": 6},
"new": {"checksum": _checksum("second"), "size": 6},
"diff": {"status": "modified", "size": 0},
}
}
@@ -56,10 +61,27 @@ def test_refs(tmp_dir, scm, dvc):
tmp_dir.dvc_gen("file", "second", commit="second version")
tmp_dir.dvc_gen("file", "third", commit="third version")
# dvc.diff("HEAD~1") --> (third, second)
# dvc.diff("HEAD~1", "HEAD~2") --> (second, first)
# dvc.diff("missing") --> error
pytest.skip("TODO: define output structure")
HEAD_2 = _checksum("first")
HEAD_1 = _checksum("second")
HEAD = _checksum("third")
assert dvc.diff("HEAD~1") == {
"file": {
"old": {"checksum": HEAD_1, "size": 5},
"new": {"checksum": HEAD, "size": 5},
"diff": {"status": "modified", "size": 0},
}
}
assert dvc.diff("HEAD~1", "HEAD~2") == {
"file": {
"old": {"checksum": HEAD_2, "size": 5},
"new": {"checksum": HEAD_1, "size": 5},
"diff": {"status": "modified", "size": 0},
}
}
pytest.skip('TODO: test dvc.diff("missing")')
def test_target(tmp_dir, scm, dvc):
@@ -73,9 +95,15 @@ def test_target(tmp_dir, scm, dvc):
scm.add(["foo.dvc", "bar.dvc"])
scm.commit("uppercase")
# dvc.diff("HEAD~1", target="foo")
# dvc.diff("HEAD~1", target="missing") --> error
pytest.skip("TODO: define output structure")
assert dvc.diff("HEAD~1", target="foo") == {
"foo": {
"old": {"checksum": _checksum("foo"), "size": 3},
"new": {"checksum": _checksum("FOO"), "size": 3},
"diff": {"status": "modified", "size": 0},
}
}
assert not dvc.diff("HEAD~1", target="missing")
def test_directories(tmp_dir, scm, dvc):