From e6164b2c5dde2cdc920abe15c68022f02c9b916a Mon Sep 17 00:00:00 2001 From: Andrew Olsen Date: Thu, 7 Jul 2022 15:58:29 +1200 Subject: [PATCH] Support `kart diff COMMIT1 COMMIT2` [#666] --- CHANGELOG.md | 1 + kart/diff.py | 19 +++++++++++++++++-- tests/test_diff.py | 10 ++++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bb8e0973..dbae01a3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ _When adding new entries to the changelog, please include issue/PR numbers where - Changed format of feature IDs in GeoJSON output to be more informative and consistent. [#135](https://github.com/koordinates/kart/issues/135) - Fixed primary key issues for shapefile import - now generates an `auto_pk` by default, but uses an existing field if specified (doesn't use the FID). [#646](https://github.com/koordinates/kart/pull/646) - Add `--with-dataset-types` option to `kart meta get` which is informative now that there is more than one type of dataset. [#649](https://github.com/koordinates/kart/pull/649) +- Support `kart diff COMMIT1 COMMIT2` as an alternative to typing `kart diff COMMIT1...COMMIT2` [#666](https://github.com/koordinates/kart/issues/666) ## 0.11.3 diff --git a/kart/diff.py b/kart/diff.py index 57aa236e4..098c523e8 100644 --- a/kart/diff.py +++ b/kart/diff.py @@ -5,8 +5,10 @@ from . import diff_estimation from .cli_util import OutputFormatType, parse_output_format from .crs_util import CoordinateReferenceString +from .exceptions import NotFound from .output_util import dump_json_output from .repo import KartRepoState +from .structs import CommitWithReference def feature_count_diff( @@ -140,10 +142,12 @@ def diff( - if supplied with the form: commit-A...commit-B - diffs between commit-A and commit-B. + - supplying two seperate refs: commit-A commit-B - also diffs between commit-A and commit-B + - if supplied with the form: commit-A..commit-B - diffs between (the common ancestor of commit-A and commit-B) and (commit-B). - To list only particular conflicts, supply one or more FILTERS of the form [DATASET[:PRIMARY_KEY]] + To list only particular changes, supply one or more FILTERS of the form [DATASET[:PRIMARY_KEY]] """ output_type, fmt = parse_output_format(output_format, json_style) @@ -158,9 +162,20 @@ def diff( only_feature_count, ) + repo = ctx.obj.get_repo(allowed_states=KartRepoState.ALL_STATES) + + # Handle the `commit-A commit-B` format: + if commit_spec and ".." not in commit_spec and filters: + try: + if CommitWithReference.resolve(repo, filters[0]): + filters = list(filters) + extra_commit_spec = filters.pop(0) + commit_spec = f"{commit_spec}...{extra_commit_spec}" + except NotFound: + pass + from .base_diff_writer import BaseDiffWriter - repo = ctx.obj.get_repo(allowed_states=KartRepoState.ALL_STATES) diff_writer_class = BaseDiffWriter.get_diff_writer_class(output_type) diff_writer = diff_writer_class( repo, diff --git a/tests/test_diff.py b/tests/test_diff.py index 72df7d50f..dac21f980 100644 --- a/tests/test_diff.py +++ b/tests/test_diff.py @@ -1092,12 +1092,14 @@ def test_diff_rev_rev(head_sha, head1_sha, data_archive_readonly, cli_runner): f"{head1_sha}...{head_sha}", f"{head1_sha}...", "HEAD^1...HEAD", + ["HEAD^1", "HEAD"], ) R_SPECS = ( f"{head_sha}...{head1_sha}", f"...{head1_sha}", "HEAD...HEAD^1", + ["HEAD", "HEAD^1"], ) CHANGE_IDS = { @@ -1111,7 +1113,9 @@ def test_diff_rev_rev(head_sha, head1_sha, data_archive_readonly, cli_runner): with data_archive_readonly("points"): for spec in F_SPECS: print(f"fwd: {spec}") - r = cli_runner.invoke(["diff", "--exit-code", "-o", "json", spec]) + if isinstance(spec, str): + spec = [spec] + r = cli_runner.invoke(["diff", "--exit-code", "-o", "json", *spec]) assert r.exit_code == 1, r odata = json.loads(r.stdout)["kart.diff/v1+hexwkb"] assert len(odata[H.POINTS.LAYER]["feature"]) == 5 @@ -1134,7 +1138,9 @@ def test_diff_rev_rev(head_sha, head1_sha, data_archive_readonly, cli_runner): for spec in R_SPECS: print(f"rev: {spec}") - r = cli_runner.invoke(["diff", "--exit-code", "-o", "json", spec]) + if isinstance(spec, str): + spec = [spec] + r = cli_runner.invoke(["diff", "--exit-code", "-o", "json", *spec]) assert r.exit_code == 1, r odata = json.loads(r.stdout)["kart.diff/v1+hexwkb"] assert len(odata[H.POINTS.LAYER]["feature"]) == 5