Mercurial > public > mercurial-scm > hg
comparison hgext/phabricator.py @ 44643:0437959de6f5
phabricator: record all local commits used to create a Differential revision
Arcanist records all of the commits that it squashes into a single review, and
that info will be helpful when adding similar functionality. This info is used
when submitting an updated review, so that the extension can recalculate the old
diff and see if a new one is necessary, or if it is just a property update. It
also shows on the `commits` tab in the `Revision Contents` section.
When submitting in the usual 1:1 commit to review mode, the wire protocol is
unchanged.
The content of `hg:meta` is a bit odd, but such is the problem when folding
several commits. The choice for the parent node is obvious, but the `node`
value uses the tip commit because that seems more natural, and is used elsewhere
to look up the previous diff when updating. The rest of the attributes follow
from there.
Differential Revision: https://phab.mercurial-scm.org/D8308
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Wed, 26 Feb 2020 13:13:49 -0500 |
parents | 022bf71515c9 |
children | dbe9182c90f5 |
comparison
equal
deleted
inserted
replaced
44642:da9b7f9635a2 | 44643:0437959de6f5 |
---|---|
966 msg = _(b'cannot create diff for %s') % ctx | 966 msg = _(b'cannot create diff for %s') % ctx |
967 raise error.Abort(msg) | 967 raise error.Abort(msg) |
968 return diff | 968 return diff |
969 | 969 |
970 | 970 |
971 def writediffproperties(ctx, diff): | 971 def writediffproperties(ctxs, diff): |
972 """write metadata to diff so patches could be applied losslessly""" | 972 """write metadata to diff so patches could be applied losslessly |
973 | |
974 ``ctxs`` is the list of commits that created the diff, in ascending order. | |
975 The list is generally a single commit, but may be several when using | |
976 ``phabsend --fold``. | |
977 """ | |
973 # creatediff returns with a diffid but query returns with an id | 978 # creatediff returns with a diffid but query returns with an id |
974 diffid = diff.get(b'diffid', diff.get(b'id')) | 979 diffid = diff.get(b'diffid', diff.get(b'id')) |
980 basectx = ctxs[0] | |
981 tipctx = ctxs[-1] | |
982 | |
975 params = { | 983 params = { |
976 b'diff_id': diffid, | 984 b'diff_id': diffid, |
977 b'name': b'hg:meta', | 985 b'name': b'hg:meta', |
978 b'data': templatefilters.json( | 986 b'data': templatefilters.json( |
979 { | 987 { |
980 b'user': ctx.user(), | 988 b'user': tipctx.user(), |
981 b'date': b'%d %d' % ctx.date(), | 989 b'date': b'%d %d' % tipctx.date(), |
982 b'branch': ctx.branch(), | 990 b'branch': tipctx.branch(), |
983 b'node': ctx.hex(), | 991 b'node': tipctx.hex(), |
984 b'parent': ctx.p1().hex(), | 992 b'parent': basectx.p1().hex(), |
985 } | 993 } |
986 ), | 994 ), |
987 } | 995 } |
988 callconduit(ctx.repo().ui, b'differential.setdiffproperty', params) | 996 callconduit(basectx.repo().ui, b'differential.setdiffproperty', params) |
989 | 997 |
998 commits = {} | |
999 for ctx in ctxs: | |
1000 commits[ctx.hex()] = { | |
1001 b'author': stringutil.person(ctx.user()), | |
1002 b'authorEmail': stringutil.email(ctx.user()), | |
1003 b'time': int(ctx.date()[0]), | |
1004 b'commit': ctx.hex(), | |
1005 b'parents': [ctx.p1().hex()], | |
1006 b'branch': ctx.branch(), | |
1007 } | |
990 params = { | 1008 params = { |
991 b'diff_id': diffid, | 1009 b'diff_id': diffid, |
992 b'name': b'local:commits', | 1010 b'name': b'local:commits', |
993 b'data': templatefilters.json( | 1011 b'data': templatefilters.json(commits), |
994 { | |
995 ctx.hex(): { | |
996 b'author': stringutil.person(ctx.user()), | |
997 b'authorEmail': stringutil.email(ctx.user()), | |
998 b'time': int(ctx.date()[0]), | |
999 b'commit': ctx.hex(), | |
1000 b'parents': [ctx.p1().hex()], | |
1001 b'branch': ctx.branch(), | |
1002 }, | |
1003 } | |
1004 ), | |
1005 } | 1012 } |
1006 callconduit(ctx.repo().ui, b'differential.setdiffproperty', params) | 1013 callconduit(basectx.repo().ui, b'differential.setdiffproperty', params) |
1007 | 1014 |
1008 | 1015 |
1009 def createdifferentialrevision( | 1016 def createdifferentialrevision( |
1010 ctx, | 1017 ctx, |
1011 revid=None, | 1018 revid=None, |
1047 # Even if we don't need to upload a new diff because the patch content | 1054 # Even if we don't need to upload a new diff because the patch content |
1048 # does not change. We might still need to update its metadata so | 1055 # does not change. We might still need to update its metadata so |
1049 # pushers could know the correct node metadata. | 1056 # pushers could know the correct node metadata. |
1050 assert olddiff | 1057 assert olddiff |
1051 diff = olddiff | 1058 diff = olddiff |
1052 writediffproperties(ctx, diff) | 1059 writediffproperties([ctx], diff) |
1053 | 1060 |
1054 # Set the parent Revision every time, so commit re-ordering is picked-up | 1061 # Set the parent Revision every time, so commit re-ordering is picked-up |
1055 if parentrevphid: | 1062 if parentrevphid: |
1056 transactions.append( | 1063 transactions.append( |
1057 {b'type': b'parents.set', b'value': [parentrevphid]} | 1064 {b'type': b'parents.set', b'value': [parentrevphid]} |
1287 mapping[old.node()] = [newnode] | 1294 mapping[old.node()] = [newnode] |
1288 # Update diff property | 1295 # Update diff property |
1289 # If it fails just warn and keep going, otherwise the DREV | 1296 # If it fails just warn and keep going, otherwise the DREV |
1290 # associations will be lost | 1297 # associations will be lost |
1291 try: | 1298 try: |
1292 writediffproperties(unfi[newnode], diffmap[old.node()]) | 1299 writediffproperties( |
1300 [unfi[newnode]], diffmap[old.node()] | |
1301 ) | |
1293 except util.urlerr.urlerror: | 1302 except util.urlerr.urlerror: |
1294 ui.warnnoi18n( | 1303 ui.warnnoi18n( |
1295 b'Failed to update metadata for D%d\n' % drevid | 1304 b'Failed to update metadata for D%d\n' % drevid |
1296 ) | 1305 ) |
1297 # Remove local tags since it's no longer necessary | 1306 # Remove local tags since it's no longer necessary |