Is there a Mercurial revset for "working directory"?

238 views Asked by At

I'm trying to script hg diff and want to accept an argument that will be passed to the -r option, and if no argument is given, to default to the working directory. However, it appears there is no value that can be passed to -r to indicate "working directory", and instead the option must be omitted entirely, which leads to the following logic in my script:

if [ -z "${to_rev}" ]; then
  to_rev_args=""
else
  to_rev_args="-r ${to_rev}"
fi

hg diff ... ${to_rev_args}

Am I correct in believing this is the only way? We can assume that making the script accept a -r argument and passing the whole thing on to Mercurial is not an option; the arguments must conform to a style used by a suite of tools.

1

There are 1 answers

2
Reimer Behrends On BEST ANSWER

The following Mercurial extension should do what you need, by allowing you to specify the working directory as a pseudo revision named "=".

"""wdir diff

Allows specifying the working directory as a pseudo revision.
"""

testedwith = "3.5"
wdir_pseudo_rev = "="

from mercurial import commands, extensions

def wrap_diff(original_cmd, ui, repo, *pats, **opts):
  revargs = opts["rev"]
  if len(revargs) == 1:
    if revargs[0] == wdir_pseudo_rev:
      return
  elif len(revargs) == 2:
    if revargs[0] == wdir_pseudo_rev:
      if revargs[1] == wdir_pseudo_rev:
        return
      else:
        revargs.remove(wdir_pseudo_rev)
    elif revargs[1] == wdir_pseudo_rev:
      revargs.remove(wdir_pseudo_rev)
      opts["reverse"] = not opts["reverse"]
  return original_cmd(ui, repo, *pats, **opts)

def uisetup(ui):
  extensions.wrapcommand(commands.table, "diff", wrap_diff)

The same logic can also fairly easily be encoded in a script or other program code if you don't want the hassle of dealing with an extension, you just have to distinguish between four different cases:

Assume that you want to diff REV1 and REV2, where either revision may be the working directory:

  1. If both REV1 and REV2 represent the working directory, do nothing.
  2. If REV1 represents the working directory, and REV2 is an actual revision, use hg diff -r REV2.
  3. If REV1 is an actual revision, and REV2 represents the working directory, use hg diff --reverse -r REV1.
  4. If both REV1 and REV2 are actual revisions, use hg diff -r REV1 -r REV2.