sapling/hgext/arcdiff.py
Phil Cohen 45c4a072f9 hgext: use relative imports wherever possible
Summary:
Port of D6798134 to fbsource. It eliminates module-import failures as well as errors like this:

```
mercurial.error.ForeignImportError: hgext.extlib.treedirstate: /home/phillco/.local/lib/python2.7/site-packages/hgext/extlib/treedirstate.so lives outside /..../hg
```

....that block other tests, like test-help.t

(Note: this ignores all push blocking failures!)

Reviewed By: quark-zju

Differential Revision: D6799259

fbshipit-source-id: b77d1b565dbf52165e0847002be498648658e064
2018-04-13 21:50:56 -07:00

72 lines
2.2 KiB
Python

# arcdiff.py - extension adding an option to the diff command to show changes
# since the last arcanist diff
#
# Copyright 2016 Facebook, Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
import os
from mercurial import commands, error, extensions
from mercurial.i18n import _
from .extlib.phabricator import (
arcconfig,
graphql,
diffprops,
)
def extsetup(ui):
entry = extensions.wrapcommand(commands.table, 'diff', _diff)
options = entry[1]
options.append(('', 'since-last-arc-diff', None,
_('show changes since last `arc diff`')))
def _differentialhash(ui, repo, phabrev):
timeout = repo.ui.configint('ssl', 'timeout', 5)
ca_certs = repo.ui.configpath('web', 'cacerts')
try:
client = graphql.Client(
repodir=repo.root, ca_bundle=ca_certs, repo=repo)
info = client.getrevisioninfo(timeout, [phabrev]).get(str(phabrev))
if not info:
return None
return info
except graphql.ClientError as e:
ui.warn(_('Error calling graphql: %s\n') % str(e))
return None
except arcconfig.ArcConfigError as e:
raise error.Abort(str(e))
def _diff(orig, ui, repo, *pats, **opts):
if not opts.get('since_last_arc_diff'):
return orig(ui, repo, *pats, **opts)
ctx = repo['.']
phabrev = diffprops.parserevfromcommitmsg(ctx.description())
if phabrev is None:
mess = _('local changeset is not associated with a differential '
'revision')
raise error.Abort(mess)
rev = _differentialhash(ui, repo, phabrev)
if rev is None or not isinstance(rev, dict) or "hash" not in rev:
mess = _('unable to determine previous changeset hash')
raise error.Abort(mess)
rev = str(rev['hash'])
opts['rev'] = [rev]
# if patterns aren't provided, restrict diff to files in both changesets
# this prevents performing a diff on rebased changes
if len(pats) == 0:
prev = set(repo.unfiltered()[rev].files())
curr = set(repo['.'].files())
pats = tuple(os.path.join(repo.root, p) for p in prev | curr)
return orig(ui, repo, *pats, **opts)