--- a/mercurial/hgweb/webutil.py Mon Feb 26 20:44:01 2018 +0800
+++ b/mercurial/hgweb/webutil.py Mon Feb 26 20:44:21 2018 +0800
@@ -28,6 +28,7 @@
error,
match,
mdiff,
+ obsutil,
patch,
pathutil,
pycompat,
@@ -362,6 +363,18 @@
# teach templater succsandmarkers is switched to (context, mapping) API
succsandmarkers._requires = {'repo', 'ctx', 'templ'}
+def whyunstable(context, mapping):
+ repo = context.resource(mapping, 'repo')
+ ctx = context.resource(mapping, 'ctx')
+
+ entries = obsutil.whyunstable(repo, ctx)
+ for entry in entries:
+ if entry.get('divergentnodes'):
+ entry['divergentnodes'] = _siblings(entry['divergentnodes'])
+ yield entry
+
+whyunstable._requires = {'repo', 'ctx', 'templ'}
+
def commonentry(repo, ctx):
node = ctx.node()
return {
@@ -380,6 +393,7 @@
'obsolete': ctx.obsolete(),
'succsandmarkers': succsandmarkers,
'instabilities': [{"instability": i} for i in ctx.instabilities()],
+ 'whyunstable': whyunstable,
'branch': nodebranchnodefault(ctx),
'inbranch': nodeinbranch(repo, ctx),
'branches': nodebranchdict(repo, ctx),
--- a/mercurial/templates/paper/changeset.tmpl Mon Feb 26 20:44:01 2018 +0800
+++ b/mercurial/templates/paper/changeset.tmpl Mon Feb 26 20:44:21 2018 +0800
@@ -53,6 +53,10 @@
<th>obsolete</th>
<td>{join(succsandmarkers%obsfateentry, '<br>\n')}</td>
</tr>')}
+{if(instabilities, '<tr>
+ <th>unstable</th>
+ <td>{join(whyunstable%whyunstableentry, '<br>\n')}</td>
+</tr>')}
<tr>
<th class="author">parents</th>
<td class="author">{ifeq(count(parent), '2', parent%changesetparentdiff, parent%changesetparent)}</td>
--- a/mercurial/templates/paper/map Mon Feb 26 20:44:01 2018 +0800
+++ b/mercurial/templates/paper/map Mon Feb 26 20:44:21 2018 +0800
@@ -216,6 +216,9 @@
obsfateusers = '{if(obsfateusers(markers), ' by {join(obsfateusers(markers)%'{user|obfuscate}', ', ')}')}'
obsfatedate = '{if(obsfatedate(markers), ' {ifeq(min(obsfatedate(markers)), max(obsfatedate(markers)), '<span class="age">{min(obsfatedate(markers))|rfc822date}</span>', 'between <span class="age">{min(obsfatedate(markers))|rfc822date}</span> and <span class="age">{max(obsfatedate(markers))|rfc822date}</span>')}')}'
obsfateentry = '{obsfateverb}{obsfateoperations}{obsfatesuccessors}{obsfateusers}{obsfatedate}'
+instabilitychangesetlink = '<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
+divergentnode = '{instabilitychangesetlink} ({phase})'
+whyunstableentry = '{instability}: {if(divergentnodes, divergentnodes%divergentnode)} {reason} {instabilitychangesetlink}'
filediffparent = '
<tr>
--- a/tests/test-hgweb-commands.t Mon Feb 26 20:44:01 2018 +0800
+++ b/tests/test-hgweb-commands.t Mon Feb 26 20:44:21 2018 +0800
@@ -903,6 +903,7 @@
<td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
</tr>
+
<tr>
<th class="author">parents</th>
<td class="author"></td>
--- a/tests/test-hgweb-diffs.t Mon Feb 26 20:44:01 2018 +0800
+++ b/tests/test-hgweb-diffs.t Mon Feb 26 20:44:21 2018 +0800
@@ -104,6 +104,7 @@
<td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
</tr>
+
<tr>
<th class="author">parents</th>
<td class="author"></td>
@@ -400,6 +401,7 @@
<td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
</tr>
+
<tr>
<th class="author">parents</th>
<td class="author"></td>
--- a/tests/test-hgweb-removed.t Mon Feb 26 20:44:01 2018 +0800
+++ b/tests/test-hgweb-removed.t Mon Feb 26 20:44:21 2018 +0800
@@ -85,6 +85,7 @@
<td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
</tr>
+
<tr>
<th class="author">parents</th>
<td class="author"><a href="/rev/cb9a9f314b8b">cb9a9f314b8b</a> </td>
--- a/tests/test-obsolete-divergent.t Mon Feb 26 20:44:01 2018 +0800
+++ b/tests/test-obsolete-divergent.t Mon Feb 26 20:44:21 2018 +0800
@@ -720,3 +720,19 @@
$ hg debugwhyunstable 1a2a9b5b0030
content-divergent: 70d5a63ca112acb3764bc1d7320ca90ea688d671 (draft) predecessor a178212c3433c4e77b573f6011e29affb8aefa33
+
+#if serve
+
+ $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
+ $ cat hg.pid >> $DAEMON_PIDS
+
+check explanation for a content-divergent changeset
+
+ $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=paper' | grep divergent:
+ <td>content-divergent: <a href="/rev/70d5a63ca112?style=paper">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=paper">a178212c3433</a></td>
+ $ get-with-headers.py localhost:$HGPORT 'rev/1a2a9b5b0030?style=coal' | grep divergent:
+ <td>content-divergent: <a href="/rev/70d5a63ca112?style=coal">70d5a63ca112</a> (draft) predecessor <a href="/rev/a178212c3433?style=coal">a178212c3433</a></td>
+
+ $ killdaemons.py
+
+#endif
--- a/tests/test-obsolete.t Mon Feb 26 20:44:01 2018 +0800
+++ b/tests/test-obsolete.t Mon Feb 26 20:44:21 2018 +0800
@@ -1072,9 +1072,19 @@
<th class="instabilities">instabilities:</th>
<td class="instabilities">orphan phase-divergent </td>
+check explanation for an orphan and phase-divergent changeset
+
+ $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=paper' | egrep '(orphan|phase-divergent):'
+ <td>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=paper">3de5eca88c00</a><br>
+ phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=paper">245bde4270cd</a></td>
+ $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=coal' | egrep '(orphan|phase-divergent):'
+ <td>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=coal">3de5eca88c00</a><br>
+ phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=coal">245bde4270cd</a></td>
+
$ killdaemons.py
$ rm hg.pid access.log errors.log
+
#endif
Test incoming/outcoming with changesets obsoleted remotely, known locally