D122: phabricator: add --amend option to phabsend

2017-08-14 Thread quark (Jun Wu)
This revision was automatically updated to reflect the committed changes.
Closed by commit rHGfa3aa6c98bb7: phabricator: add --amend option to phabsend 
(authored by quark).

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D122?vs=838=873

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

AFFECTED FILES
  contrib/phabricator.py

CHANGE DETAILS

diff --git a/contrib/phabricator.py b/contrib/phabricator.py
--- a/contrib/phabricator.py
+++ b/contrib/phabricator.py
@@ -38,6 +38,8 @@
 from mercurial.node import bin, nullid
 from mercurial.i18n import _
 from mercurial import (
+cmdutil,
+context,
 encoding,
 error,
 mdiff,
@@ -315,7 +317,7 @@
 if not revision:
 raise error.Abort(_('cannot create revision for %s') % ctx)
 
-return revision
+return revision, diff
 
 def userphids(repo, names):
 """convert user names to PHIDs"""
@@ -333,6 +335,7 @@
 
 @command('phabsend',
  [('r', 'rev', [], _('revisions to send'), _('REV')),
+  ('', 'amend', False, _('update commit messages')),
   ('', 'reviewer', [], _('specify reviewers')),
   ('', 'confirm', None, _('ask for confirmation before sending'))],
  _('REV [OPTIONS]'))
@@ -348,18 +351,28 @@
 obsstore and tags information so it can figure out whether to update an
 existing Differential Revision, or create a new one.
 
+If --amend is set, update commit messages so they have the
+``Differential Revision`` URL, remove related tags. This is similar to what
+arcanist will do, and is more desired in author-push workflows. Otherwise,
+use local tags to record the ``Differential Revision`` association.
+
 The --confirm option lets you confirm changesets before sending them. You
 can also add following to your configuration file to make it default
 behaviour.
 
 [phabsend]
 confirm = true
+
+phabsend will check obsstore and the above association to decide whether to
+update an existing Differential Revision, or create a new one.
 """
 revs = list(revs) + opts.get('rev', [])
 revs = scmutil.revrange(repo, revs)
 
 if not revs:
 raise error.Abort(_('phabsend requires at least one changeset'))
+if opts.get('amend'):
+cmdutil.checkunfinished(repo)
 
 confirm = ui.configbool('phabsend', 'confirm')
 confirm |= bool(opts.get('confirm'))
@@ -377,6 +390,9 @@
 # {newnode: (oldnode, olddiff, olddrev}
 oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs])
 
+drevids = [] # [int]
+diffmap = {} # {newnode: diff}
+
 # Send patches one by one so we know their Differential Revision IDs and
 # can provide dependency relationship
 lastrevid = None
@@ -386,30 +402,69 @@
 
 # Get Differential Revision ID
 oldnode, olddiff, revid = oldmap.get(ctx.node(), (None, None, None))
-if oldnode != ctx.node():
+if oldnode != ctx.node() or opts.get('amend'):
 # Create or update Differential Revision
-revision = createdifferentialrevision(ctx, revid, lastrevid,
-  oldnode, olddiff, actions)
+revision, diff = createdifferentialrevision(
+ctx, revid, lastrevid, oldnode, olddiff, actions)
+diffmap[ctx.node()] = diff
 newrevid = int(revision[r'object'][r'id'])
 if revid:
 action = _('updated')
 else:
 action = _('created')
 
-# Create a local tag to note the association
-tagname = 'D%d' % newrevid
-tags.tag(repo, tagname, ctx.node(), message=None, user=None,
- date=None, local=True)
+# Create a local tag to note the association, if commit message
+# does not have it already
+m = _differentialrevisiondescre.search(ctx.description())
+if not m or int(m.group(1)) != newrevid:
+tagname = 'D%d' % newrevid
+tags.tag(repo, tagname, ctx.node(), message=None, user=None,
+ date=None, local=True)
 else:
 # Nothing changed. But still set "newrevid" so the next revision
 # could depend on this one.
 newrevid = revid
 action = _('skipped')
 
 ui.write(_('D%s: %s - %s: %s\n') % (newrevid, action, ctx,
 ctx.description().split('\n')[0]))
+drevids.append(newrevid)
 lastrevid = newrevid
 
+# Update commit messages and remove tags
+if opts.get('amend'):
+unfi = repo.unfiltered()
+drevs = callconduit(repo, 'differential.query', {'ids': drevids})
+with repo.wlock(), repo.lock(), repo.transaction('phabsend'):
+wnode = unfi['.'].node()
+mapping = {} # {oldnode: [newnode]}
+for i, rev in enumerate(revs):
+old 

D122: phabricator: add --amend option to phabsend

2017-08-12 Thread quark (Jun Wu)
quark updated this revision to Diff 838.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D122?vs=789=838

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

AFFECTED FILES
  contrib/phabricator.py

CHANGE DETAILS

diff --git a/contrib/phabricator.py b/contrib/phabricator.py
--- a/contrib/phabricator.py
+++ b/contrib/phabricator.py
@@ -38,6 +38,8 @@
 from mercurial.node import bin, nullid
 from mercurial.i18n import _
 from mercurial import (
+cmdutil,
+context,
 encoding,
 error,
 mdiff,
@@ -315,7 +317,7 @@
 if not revision:
 raise error.Abort(_('cannot create revision for %s') % ctx)
 
-return revision
+return revision, diff
 
 def userphids(repo, names):
 """convert user names to PHIDs"""
@@ -333,6 +335,7 @@
 
 @command('phabsend',
  [('r', 'rev', [], _('revisions to send'), _('REV')),
+  ('', 'amend', False, _('update commit messages')),
   ('', 'reviewer', [], _('specify reviewers')),
   ('', 'confirm', None, _('ask for confirmation before sending'))],
  _('REV [OPTIONS]'))
@@ -348,18 +351,28 @@
 obsstore and tags information so it can figure out whether to update an
 existing Differential Revision, or create a new one.
 
+If --amend is set, update commit messages so they have the
+``Differential Revision`` URL, remove related tags. This is similar to what
+arcanist will do, and is more desired in author-push workflows. Otherwise,
+use local tags to record the ``Differential Revision`` association.
+
 The --confirm option lets you confirm changesets before sending them. You
 can also add following to your configuration file to make it default
 behaviour.
 
 [phabsend]
 confirm = true
+
+phabsend will check obsstore and the above association to decide whether to
+update an existing Differential Revision, or create a new one.
 """
 revs = list(revs) + opts.get('rev', [])
 revs = scmutil.revrange(repo, revs)
 
 if not revs:
 raise error.Abort(_('phabsend requires at least one changeset'))
+if opts.get('amend'):
+cmdutil.checkunfinished(repo)
 
 confirm = ui.configbool('phabsend', 'confirm')
 confirm |= bool(opts.get('confirm'))
@@ -377,6 +390,9 @@
 # {newnode: (oldnode, olddiff, olddrev}
 oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs])
 
+drevids = [] # [int]
+diffmap = {} # {newnode: diff}
+
 # Send patches one by one so we know their Differential Revision IDs and
 # can provide dependency relationship
 lastrevid = None
@@ -386,30 +402,69 @@
 
 # Get Differential Revision ID
 oldnode, olddiff, revid = oldmap.get(ctx.node(), (None, None, None))
-if oldnode != ctx.node():
+if oldnode != ctx.node() or opts.get('amend'):
 # Create or update Differential Revision
-revision = createdifferentialrevision(ctx, revid, lastrevid,
-  oldnode, olddiff, actions)
+revision, diff = createdifferentialrevision(
+ctx, revid, lastrevid, oldnode, olddiff, actions)
+diffmap[ctx.node()] = diff
 newrevid = int(revision[r'object'][r'id'])
 if revid:
 action = _('updated')
 else:
 action = _('created')
 
-# Create a local tag to note the association
-tagname = 'D%d' % newrevid
-tags.tag(repo, tagname, ctx.node(), message=None, user=None,
- date=None, local=True)
+# Create a local tag to note the association, if commit message
+# does not have it already
+m = _differentialrevisiondescre.search(ctx.description())
+if not m or int(m.group(1)) != newrevid:
+tagname = 'D%d' % newrevid
+tags.tag(repo, tagname, ctx.node(), message=None, user=None,
+ date=None, local=True)
 else:
 # Nothing changed. But still set "newrevid" so the next revision
 # could depend on this one.
 newrevid = revid
 action = _('skipped')
 
 ui.write(_('D%s: %s - %s: %s\n') % (newrevid, action, ctx,
 ctx.description().split('\n')[0]))
+drevids.append(newrevid)
 lastrevid = newrevid
 
+# Update commit messages and remove tags
+if opts.get('amend'):
+unfi = repo.unfiltered()
+drevs = callconduit(repo, 'differential.query', {'ids': drevids})
+with repo.wlock(), repo.lock(), repo.transaction('phabsend'):
+wnode = unfi['.'].node()
+mapping = {} # {oldnode: [newnode]}
+for i, rev in enumerate(revs):
+old = unfi[rev]
+drevid = drevids[i]
+drev = [d for d in drevs if int(d[r'id']) == drevid][0]
+   

D122: phabricator: add --amend option to phabsend

2017-08-11 Thread quark (Jun Wu)
quark updated this revision to Diff 789.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D122?vs=568=789

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

AFFECTED FILES
  contrib/phabricator.py

CHANGE DETAILS

diff --git a/contrib/phabricator.py b/contrib/phabricator.py
--- a/contrib/phabricator.py
+++ b/contrib/phabricator.py
@@ -38,6 +38,8 @@
 from mercurial.node import bin, nullid
 from mercurial.i18n import _
 from mercurial import (
+cmdutil,
+context,
 encoding,
 error,
 mdiff,
@@ -316,7 +318,7 @@
 if not revision:
 raise error.Abort(_('cannot create revision for %s') % ctx)
 
-return revision
+return revision, diff
 
 def userphids(repo, names):
 """convert user names to PHIDs"""
@@ -334,6 +336,7 @@
 
 @command('phabsend',
  [('r', 'rev', [], _('revisions to send'), _('REV')),
+  ('', 'amend', False, _('update commit messages')),
   ('', 'reviewer', [], _('specify reviewers')),
   ('', 'confirm', None, _('ask for confirmation before sending'))],
  _('REV [OPTIONS]'))
@@ -349,18 +352,28 @@
 obsstore and tags information so it can figure out whether to update an
 existing Differential Revision, or create a new one.
 
+If --amend is set, update commit messages so they have the
+``Differential Revision`` URL, remove related tags. This is similar to what
+arcanist will do, and is more desired in author-push workflows. Otherwise,
+use local tags to record the ``Differential Revision`` association.
+
 The --confirm option lets you confirm changesets before sending them. You
 can also add following to your configuration file to make it default
 behaviour.
 
 [phabsend]
 confirm = true
+
+phabsend will check obsstore and the above association to decide whether to
+update an existing Differential Revision, or create a new one.
 """
 revs = list(revs) + opts.get('rev', [])
 revs = scmutil.revrange(repo, revs)
 
 if not revs:
 raise error.Abort(_('phabsend requires at least one changeset'))
+if opts.get('amend'):
+cmdutil.checkunfinished(repo)
 
 confirm = ui.configbool('phabsend', 'confirm')
 confirm |= bool(opts.get('confirm'))
@@ -378,6 +391,9 @@
 # {newnode: (oldnode, olddiff, olddrev}
 oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs])
 
+drevids = [] # [int]
+diffmap = {} # {newnode: diff}
+
 # Send patches one by one so we know their Differential Revision IDs and
 # can provide dependency relationship
 lastrevid = None
@@ -387,30 +403,69 @@
 
 # Get Differential Revision ID
 oldnode, olddiff, revid = oldmap.get(ctx.node(), (None, None, None))
-if oldnode != ctx.node():
+if oldnode != ctx.node() or opts.get('amend'):
 # Create or update Differential Revision
-revision = createdifferentialrevision(ctx, revid, lastrevid,
-  oldnode, olddiff, actions)
+revision, diff = createdifferentialrevision(
+ctx, revid, lastrevid, oldnode, olddiff, actions)
+diffmap[ctx.node()] = diff
 newrevid = int(revision[r'object'][r'id'])
 if revid:
 action = _('updated')
 else:
 action = _('created')
 
-# Create a local tag to note the association
-tagname = 'D%d' % newrevid
-tags.tag(repo, tagname, ctx.node(), message=None, user=None,
- date=None, local=True)
+# Create a local tag to note the association, if commit message
+# does not have it already
+m = _differentialrevisiondescre.search(ctx.description())
+if not m or int(m.group(1)) != newrevid:
+tagname = 'D%d' % newrevid
+tags.tag(repo, tagname, ctx.node(), message=None, user=None,
+ date=None, local=True)
 else:
 # Nothing changed. But still set "newrevid" so the next revision
 # could depend on this one.
 newrevid = revid
 action = _('skipped')
 
 ui.write(_('D%s: %s - %s: %s\n') % (newrevid, action, ctx,
 ctx.description().split('\n')[0]))
+drevids.append(newrevid)
 lastrevid = newrevid
 
+# Update commit messages and remove tags
+if opts.get('amend'):
+unfi = repo.unfiltered()
+drevs = callconduit(repo, 'differential.query', {'ids': drevids})
+with repo.wlock(), repo.lock(), repo.transaction('phabsend'):
+wnode = unfi['.'].node()
+mapping = {} # {oldnode: [newnode]}
+for i, rev in enumerate(revs):
+old = unfi[rev]
+drevid = drevids[i]
+drev = [d for d in drevs if int(d[r'id']) == drevid][0]
+   

D122: phabricator: add --amend option to phabsend

2017-08-04 Thread quark (Jun Wu)
quark updated this revision to Diff 568.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D122?vs=553=568

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

AFFECTED FILES
  contrib/phabricator.py

CHANGE DETAILS

diff --git a/contrib/phabricator.py b/contrib/phabricator.py
--- a/contrib/phabricator.py
+++ b/contrib/phabricator.py
@@ -38,6 +38,8 @@
 from mercurial.node import bin, nullid
 from mercurial.i18n import _
 from mercurial import (
+cmdutil,
+context,
 encoding,
 error,
 mdiff,
@@ -316,7 +318,7 @@
 if not revision:
 raise error.Abort(_('cannot create revision for %s') % ctx)
 
-return revision
+return revision, diff
 
 def userphids(repo, names):
 """convert user names to PHIDs"""
@@ -334,6 +336,7 @@
 
 @command('phabsend',
  [('r', 'rev', [], _('revisions to send'), _('REV')),
+  ('', 'amend', False, _('update commit messages')),
   ('', 'reviewer', [], _('specify reviewers')),
   ('', 'confirm', None, _('ask for confirmation before sending'))],
  _('REV [OPTIONS]'))
@@ -349,18 +352,28 @@
 obsstore and tags information so it can figure out whether to update an
 existing Differential Revision, or create a new one.
 
+If --amend is set, update commit messages so they have the
+``Differential Revision`` URL, remove related tags. This is similar to what
+arcanist will do, and is more desired in author-push workflows. Otherwise,
+use local tags to record the ``Differential Revision`` association.
+
 The --confirm option lets you confirm changesets before sending them. You
 can also add following to your configuration file to make it default
 behaviour.
 
 [phabsend]
 confirm = true
+
+phabsend will check obsstore and the above association to decide whether to
+update an existing Differential Revision, or create a new one.
 """
 revs = list(revs) + opts.get('rev', [])
 revs = scmutil.revrange(repo, revs)
 
 if not revs:
 raise error.Abort(_('phabsend requires at least one changeset'))
+if opts.get('amend'):
+cmdutil.checkunfinished(repo)
 
 confirm = ui.configbool('phabsend', 'confirm')
 confirm |= bool(opts.get('confirm'))
@@ -378,6 +391,9 @@
 # {newnode: (oldnode, olddiff, olddrev}
 oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs])
 
+drevids = [] # [int]
+diffmap = {} # {newnode: diff}
+
 # Send patches one by one so we know their Differential Revision IDs and
 # can provide dependency relationship
 lastrevid = None
@@ -389,28 +405,67 @@
 oldnode, olddiff, revid = oldmap.get(ctx.node(), (None, None, None))
 if oldnode != ctx.node():
 # Create or update Differential Revision
-revision = createdifferentialrevision(ctx, revid, lastrevid,
-  oldnode, olddiff, actions)
+revision, diff = createdifferentialrevision(
+ctx, revid, lastrevid, oldnode, olddiff, actions)
+diffmap[ctx.node()] = diff
 newrevid = int(revision[r'object'][r'id'])
 if revid:
 action = _('updated')
 else:
 action = _('created')
 
-# Create a local tag to note the association
-tagname = 'D%d' % newrevid
-tags.tag(repo, tagname, ctx.node(), message=None, user=None,
- date=None, local=True)
+# Create a local tag to note the association, if commit message
+# does not have it already
+m = _differentialrevisiondescre.search(ctx.description())
+if not m or int(m.group(1)) != newrevid:
+tagname = 'D%d' % newrevid
+tags.tag(repo, tagname, ctx.node(), message=None, user=None,
+ date=None, local=True)
 else:
 # Nothing changed. But still set "newrevid" so the next revision
 # could depend on this one.
 newrevid = revid
 action = _('skipped')
 
 ui.write(_('D%s: %s - %s: %s\n') % (newrevid, action, ctx,
 ctx.description().split('\n')[0]))
+drevids.append(newrevid)
 lastrevid = newrevid
 
+# Update commit messages and remove tags
+if opts.get('amend'):
+unfi = repo.unfiltered()
+drevs = callconduit(repo, 'differential.query', {'ids': drevids})
+with repo.wlock(), repo.lock(), repo.transaction('phabsend'):
+wnode = unfi['.'].node()
+mapping = {} # {oldnode: [newnode]}
+for i, rev in enumerate(revs):
+old = unfi[rev]
+drevid = drevids[i]
+drev = [d for d in drevs if int(d[r'id']) == drevid][0]
+newdesc = getdescfromdrev(drev)
+# Make sure commit message contain 

D122: phabricator: add --amend option to phabsend

2017-08-04 Thread quark (Jun Wu)
quark updated this revision to Diff 553.
quark edited the test plan for this revision.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D122?vs=485=553

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

AFFECTED FILES
  contrib/phabricator.py

CHANGE DETAILS

diff --git a/contrib/phabricator.py b/contrib/phabricator.py
--- a/contrib/phabricator.py
+++ b/contrib/phabricator.py
@@ -38,6 +38,8 @@
 from mercurial.node import bin, nullid
 from mercurial.i18n import _
 from mercurial import (
+cmdutil,
+context,
 encoding,
 error,
 mdiff,
@@ -316,7 +318,7 @@
 if not revision:
 raise error.Abort(_('cannot create revision for %s') % ctx)
 
-return revision
+return revision, diff
 
 def userphids(repo, names):
 """convert user names to PHIDs"""
@@ -334,6 +336,7 @@
 
 @command('phabsend',
  [('r', 'rev', [], _('revisions to send'), _('REV')),
+  ('', 'amend', False, _('update commit messages')),
   ('', 'reviewer', [], _('specify reviewers'))],
  _('REV [OPTIONS]'))
 def phabsend(ui, repo, *revs, **opts):
@@ -343,16 +346,21 @@
 with a linear dependencies relationship using the order specified by the
 revset.
 
-For the first time uploading changesets, local tags will be created to
-maintain the association. After the first time, phabsend will check
-obsstore and tags information so it can figure out whether to update an
-existing Differential Revision, or create a new one.
+If --amend is set, update commit messages so they have the
+``Differential Revision`` URL, remove related tags. This is similar to what
+arcanist will do, and is more desired in author-push workflows. Otherwise,
+use local tags to record the ``Differential Revision`` association.
+
+phabsend will check obsstore and the above association to decide whether to
+update an existing Differential Revision, or create a new one.
 """
 revs = list(revs) + opts.get('rev', [])
 revs = scmutil.revrange(repo, revs)
 
 if not revs:
 raise error.Abort(_('phabsend requires at least one changeset'))
+if opts.get('amend'):
+cmdutil.checkunfinished(repo)
 
 actions = []
 reviewers = opts.get('reviewer', [])
@@ -363,6 +371,9 @@
 # {newnode: (oldnode, olddiff, olddrev}
 oldmap = getoldnodedrevmap(repo, [repo[r].node() for r in revs])
 
+drevids = [] # [int]
+diffmap = {} # {newnode: diff}
+
 # Send patches one by one so we know their Differential Revision IDs and
 # can provide dependency relationship
 lastrevid = None
@@ -374,28 +385,67 @@
 oldnode, olddiff, revid = oldmap.get(ctx.node(), (None, None, None))
 if oldnode != ctx.node():
 # Create or update Differential Revision
-revision = createdifferentialrevision(ctx, revid, lastrevid,
-  oldnode, olddiff, actions)
+revision, diff = createdifferentialrevision(
+ctx, revid, lastrevid, oldnode, olddiff, actions)
+diffmap[ctx.node()] = diff
 newrevid = int(revision[r'object'][r'id'])
 if revid:
 action = _('updated')
 else:
 action = _('created')
 
-# Create a local tag to note the association
-tagname = 'D%d' % newrevid
-tags.tag(repo, tagname, ctx.node(), message=None, user=None,
- date=None, local=True)
+# Create a local tag to note the association, if commit message
+# does not have it already
+m = _differentialrevisiondescre.search(ctx.description())
+if not m or int(m.group(1)) != newrevid:
+tagname = 'D%d' % newrevid
+tags.tag(repo, tagname, ctx.node(), message=None, user=None,
+ date=None, local=True)
 else:
 # Nothing changed. But still set "newrevid" so the next revision
 # could depend on this one.
 newrevid = revid
 action = _('skipped')
 
 ui.write(_('D%s: %s - %s: %s\n') % (newrevid, action, ctx,
 ctx.description().split('\n')[0]))
+drevids.append(newrevid)
 lastrevid = newrevid
 
+# Update commit messages and remove tags
+if opts.get('amend'):
+unfi = repo.unfiltered()
+drevs = callconduit(repo, 'differential.query', {'ids': drevids})
+with repo.wlock(), repo.lock(), repo.transaction('phabsend'):
+wnode = unfi['.'].node()
+mapping = {} # {oldnode: [newnode]}
+for i, rev in enumerate(revs):
+old = unfi[rev]
+drevid = drevids[i]
+drev = [d for d in drevs if int(d[r'id']) == drevid][0]
+newdesc = getdescfromdrev(drev)
+# Make sure commit message contain 

D122: phabricator: add --amend option to phabsend

2017-08-01 Thread quark (Jun Wu)
quark updated this revision to Diff 485.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D122?vs=233=485

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

AFFECTED FILES
  contrib/phabricator.py

CHANGE DETAILS

diff --git a/contrib/phabricator.py b/contrib/phabricator.py
--- a/contrib/phabricator.py
+++ b/contrib/phabricator.py
@@ -38,6 +38,8 @@
 from mercurial.node import bin, nullid
 from mercurial.i18n import _
 from mercurial import (
+cmdutil,
+context,
 encoding,
 error,
 mdiff,
@@ -324,6 +326,7 @@
 
 @command('phabsend',
  [('r', 'rev', [], _('revisions to send'), _('REV')),
+  ('', 'amend', False, _('update commit messages')),
   ('', 'reviewer', [], _('specify reviewers'))],
  _('REV [OPTIONS]'))
 def phabsend(ui, repo, *revs, **opts):
@@ -333,16 +336,21 @@
 with a linear dependencies relationship using the order specified by the
 revset.
 
-For the first time uploading changesets, local tags will be created to
-maintain the association. After the first time, phabsend will check
-obsstore and tags information so it can figure out whether to update an
-existing Differential Revision, or create a new one.
+If --amend is set, update commit messages so they have the
+``Differential Revision`` URL, remove related tags. This is similar to what
+arcanist will do, and is more desired in author-push workflows. Otherwise,
+use local tags to record the ``Differential Revision`` association.
+
+phabsend will check obsstore and the above association to decide whether to
+update an existing Differential Revision, or create a new one.
 """
 revs = list(revs) + opts.get('rev', [])
 revs = scmutil.revrange(repo, revs)
 
 if not revs:
 raise error.Abort(_('phabsend requires at least one changeset'))
+if opts.get('amend'):
+cmdutil.checkunfinished(repo)
 
 actions = []
 reviewers = opts.get('reviewer', [])
@@ -354,6 +362,7 @@
 
 # Send patches one by one so we know their Differential Revision IDs and
 # can provide dependency relationship
+drevids = []
 lastrevid = None
 for rev in revs:
 ui.debug('sending rev %d\n' % rev)
@@ -371,20 +380,55 @@
 else:
 action = _('created')
 
-# Create a local tag to note the association
-tagname = 'D%d' % newrevid
-tags.tag(repo, tagname, ctx.node(), message=None, user=None,
- date=None, local=True)
+# Create a local tag to note the association, if commit message
+# does not have it already
+m = _differentialrevisiondescre.search(ctx.description())
+if not m or int(m.group(1)) != newrevid:
+tagname = 'D%d' % newrevid
+tags.tag(repo, tagname, ctx.node(), message=None, user=None,
+ date=None, local=True)
 else:
 # Nothing changed. But still set "newrevid" so the next revision
 # could depend on this one.
 newrevid = revid
 action = _('skipped')
 
 ui.write(_('D%s: %s - %s: %s\n') % (newrevid, action, ctx,
 ctx.description().split('\n')[0]))
+drevids.append(newrevid)
 lastrevid = newrevid
 
+# Update commit messages and remove tags
+if opts.get('amend'):
+unfi = repo.unfiltered()
+drevs = callconduit(repo, 'differential.query', {'ids': drevids})
+with repo.wlock(), repo.lock(), repo.transaction('phabsend'):
+wnode = unfi['.'].node()
+mapping = {} # {oldnode: newnode}
+for i, rev in enumerate(revs):
+old = unfi[rev]
+drevid = drevids[i]
+drev = [d for d in drevs if int(d[r'id']) == drevid][0]
+newdesc = getdescfromdrev(drev)
+# Make sure commit message contain "Differential Revision"
+if old.description() != newdesc:
+parents = [
+mapping.get(old.p1().node(), (old.p1(),))[0],
+mapping.get(old.p2().node(), (old.p2(),))[0],
+]
+new = context.metadataonlyctx(
+repo, old, parents=parents, text=newdesc,
+user=old.user(), date=old.date(), extra=old.extra())
+mapping[old.node()] = [new.commit()]
+# Remove local tags since it's no longer necessary
+tagname = 'D%d' % drevid
+if tagname in repo.tags():
+tags.tag(repo, tagname, nullid, message=None, user=None,
+ date=None, local=True)
+scmutil.cleanupnodes(repo, mapping, 'phabsend')
+if wnode in mapping:
+unfi.setparents(mapping[wnode][0])
+
 # Map from 

Re: D122: phabricator: add --amend option to phabsend

2017-07-18 Thread quark (Jun Wu)
quark added inline comments.

INLINE COMMENTS

> mitrandir wrote in phabricator.py:413
> I think it would be better to use differential.getcommitmessage for this. For 
> example "reviewed by" field is a really nice thing to have in the commit 
> message.

I was trying to make it behave closer to `hg email`. IIRC reviewers have some 
other plans to show "who accepts" information (that works for both Phabricator 
and email submits) on hgweb, so I didn't pay too much attention on "Reviewed 
By" here.

REPOSITORY
  rHG Mercurial

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

EMAIL PREFERENCES
  https://phab.mercurial-scm.org/settings/panel/emailpreferences/

To: quark, #hg-reviewers, mitrandir
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


Re: D122: phabricator: add --amend option to phabsend

2017-07-18 Thread mitrandir (Mateusz Jakub Kwapich)
mitrandir accepted this revision.
mitrandir added inline comments.

INLINE COMMENTS

> phabricator.py:413
> +drev = [d for d in drevs if int(d[r'id']) == drevid][0]
> +newdesc = getdescfromdrev(drev)
> +# Make sure commit message contain "Differential Revision"

I think it would be better to use differential.getcommitmessage for this. For 
example "reviewed by" field is a really nice thing to have in the commit 
message.

REPOSITORY
  rHG Mercurial

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

EMAIL PREFERENCES
  https://phab.mercurial-scm.org/settings/panel/emailpreferences/

To: quark, #hg-reviewers, mitrandir
Cc: mercurial-devel
___
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel