sapling/arcdiff.py
Wez Furlong 1aecce519b hgext: refactor last-diff code into diffprops.py
Summary:
I want to re-use this elsewhere, so robustify it a bit
and move it to phabricator.diffprops.

Test Plan: run-tests.py, also verified in my www repo.

Reviewers: #sourcecontrol, ttung

Reviewed By: ttung

Subscribers: mjpieters

Differential Revision: https://phabricator.intern.facebook.com/D3230147

Signature: t1:3230147:1463081787:799f232e2ce73395218db3a0fff37dec9a0b02e0
2016-05-12 13:11:08 -07:00

73 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.
from mercurial import cmdutil, commands, error, extensions, hg, scmutil, util
from mercurial.i18n import _
import json
import os
import re
import subprocess
from phabricator import (
arcconfig,
conduit,
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):
client = conduit.Client()
try:
client.apply_arcconfig(arcconfig.load_for_path(repo.root))
diffid = diffprops.getcurrentdiffidforrev(client, phabrev)
if diffid is None:
return None
localcommits = diffprops.getlocalcommitfordiffid(client, diffid)
return localcommits.get('commit', None) if localcommits else None
except conduit.ClientError as e:
ui.warn(_('Error calling conduit: %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 commit is not associated with a differential revision')
raise error.Abort(mess)
rev = _differentialhash(ui, repo, phabrev)
if rev is None:
mess = _('unable to determine previous commit hash')
raise error.Abort(mess)
rev = str(rev)
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(prev | curr)
return orig(ui, repo, *pats, **opts)