Patchwork D9554: diff: add --from and --to flags as clearer alternative to -r -r

login
register
mail settings
Submitter phabricator
Date Dec. 10, 2020, 3:10 a.m.
Message ID <differential-rev-PHID-DREV-gl6iwvpkyab6aelnarhd-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/47852/
State Superseded
Headers show

Comments

phabricator - Dec. 10, 2020, 3:10 a.m.
martinvonz created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  I think it was mistake to let the `-r` flag accept two revisions in
  `hg diff` in 98633e60067c <https://phab.mercurial-scm.org/rHG98633e60067c7f0fe9ecff15e04d01accb695990> (Support for 0, 1, or 2 diff revs,
  2005-05-07). The command clearly acts on two revisions and having a
  single flag to indicate which those are is unclear. It got worse when
  it started accepting revsets as input.
  
  This patch introduces `--from` and `--to` flags, each taking a single
  revision and each defaulting to the working copy. That means that `hg
  diff --from .` behaves like `hg diff` and `hg diff --to .` behaves
  like `hg diff --reverse`.
  
  In addition to clarifying the direction, it also makes it so one won't
  make the mistake of thinking that `hg diff -r "date('yesterday')"`
  will show differences since (some commit) yesterday when it will
  actually depend on the how many commits were made yesterday (it works
  if exactly one commit was made). (Fun fact: `hg help diff -v` includes
  that broken case, incorrectly claiming that it shows changes "relative
  to the last change on some date".)
  
  I think `-r` should be deprecated, but I understand that it's used in
  way too much documentation and in people's muscle memory for that to
  be realistic.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D9554

AFFECTED FILES
  mercurial/commands.py
  tests/test-completion.t
  tests/test-diff-change.t
  tests/test-help.t

CHANGE DETAILS




To: martinvonz, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -662,6 +662,8 @@ 
   options ([+] can be repeated):
   
    -r --rev REV [+]         revision
+      --from REV            revision to diff from
+      --to REV              revision to diff to
    -c --change REV          change made by revision
    -a --text                treat all files as text
    -g --git                 use git extended diff format
diff --git a/tests/test-diff-change.t b/tests/test-diff-change.t
--- a/tests/test-diff-change.t
+++ b/tests/test-diff-change.t
@@ -1,4 +1,4 @@ 
-Testing diff --change
+Testing diff --change, --from, --to
 
   $ hg init a
   $ cd a
@@ -29,6 +29,59 @@ 
   -first
   +second
 
+Test --from and --to
+
+  $ hg diff --from . --rev .
+  abort: cannot specify both --from and --rev
+  [10]
+  $ hg diff --to . --rev .
+  abort: cannot specify both --to and --rev
+  [10]
+  $ hg diff --from . --change .
+  abort: cannot specify both --from and --change
+  [10]
+  $ hg diff --to . --change .
+  abort: cannot specify both --to and --change
+  [10]
+  $ echo dirty > file.txt
+  $ hg diff --from .
+  diff -r bf5ff72eb7e0 file.txt
+  --- a/file.txt	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/file.txt	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,1 +1,1 @@
+  -third
+  +dirty
+  $ hg diff --from . --reverse
+  diff -r bf5ff72eb7e0 file.txt
+  --- a/file.txt	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/file.txt	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,1 +1,1 @@
+  -dirty
+  +third
+  $ hg diff --to .
+  diff -r bf5ff72eb7e0 file.txt
+  --- a/file.txt	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/file.txt	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,1 +1,1 @@
+  -dirty
+  +third
+  $ hg diff --from 0 --to 2
+  diff -r 4bb65dda5db4 -r bf5ff72eb7e0 file.txt
+  --- a/file.txt	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/file.txt	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,1 +1,1 @@
+  -first
+  +third
+  $ hg diff --from 2 --to 0
+  diff -r bf5ff72eb7e0 -r 4bb65dda5db4 file.txt
+  --- a/file.txt	Thu Jan 01 00:00:00 1970 +0000
+  +++ b/file.txt	Thu Jan 01 00:00:00 1970 +0000
+  @@ -1,1 +1,1 @@
+  -third
+  +first
+  $ hg co -C .
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
   $ cd ..
 
 Test dumb revspecs: top-level "x:y", "x:", ":y" and ":" ranges should be handled
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -333,7 +333,7 @@ 
   debugwhyunstable: 
   debugwireargs: three, four, five, ssh, remotecmd, insecure
   debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
-  diff: rev, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
+  diff: rev, from, to, change, text, git, binary, nodates, noprefix, show-function, reverse, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, unified, stat, root, include, exclude, subrepos
   export: bookmark, output, switch-parent, rev, text, git, binary, nodates, template
   files: rev, print0, include, exclude, template, subrepos
   forget: interactive, include, exclude, dry-run
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2456,6 +2456,8 @@ 
     b'diff',
     [
         (b'r', b'rev', [], _(b'revision'), _(b'REV')),
+        (b'', b'from', b'', _(b'revision to diff from'), _(b'REV')),
+        (b'', b'to', b'', _(b'revision to diff to'), _(b'REV')),
         (b'c', b'change', b'', _(b'change made by revision'), _(b'REV')),
     ]
     + diffopts
@@ -2530,13 +2532,21 @@ 
     opts = pycompat.byteskwargs(opts)
     revs = opts.get(b'rev')
     change = opts.get(b'change')
+    from_rev = opts.get(b'from')
+    to_rev = opts.get(b'to')
     stat = opts.get(b'stat')
     reverse = opts.get(b'reverse')
 
+    cmdutil.check_incompatible_arguments(opts, b'from', [b'rev', b'change'])
+    cmdutil.check_incompatible_arguments(opts, b'to', [b'rev', b'change'])
     if change:
         repo = scmutil.unhidehashlikerevs(repo, [change], b'nowarn')
         ctx2 = scmutil.revsingle(repo, change, None)
         ctx1 = ctx2.p1()
+    elif from_rev or to_rev:
+        repo = scmutil.unhidehashlikerevs(repo, [from_rev] + [to_rev], b'nowarn')
+        ctx1 = scmutil.revsingle(repo, from_rev, None)
+        ctx2 = scmutil.revsingle(repo, to_rev, None)
     else:
         repo = scmutil.unhidehashlikerevs(repo, revs, b'nowarn')
         ctx1, ctx2 = scmutil.revpair(repo, revs)