Merge lp:~cjwatson/launchpad/git-mp-commits into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 18046
Proposed branch: lp:~cjwatson/launchpad/git-mp-commits
Merge into: lp:launchpad
Prerequisite: lp:~cjwatson/launchpad/git-commits-link-mps
Diff against target: 524 lines (+213/-73)
11 files modified
lib/lp/code/browser/branchmergeproposal.py (+16/-4)
lib/lp/code/browser/tests/test_branchmergeproposal.py (+42/-7)
lib/lp/code/interfaces/branchmergeproposal.py (+4/-1)
lib/lp/code/model/branchmergeproposal.py (+54/-40)
lib/lp/code/stories/branches/xx-code-review-comments.txt (+50/-0)
lib/lp/code/templates/branchmergeproposal-index.pt (+8/-0)
lib/lp/code/templates/branchmergeproposal-resubmit.pt (+21/-11)
lib/lp/code/templates/codereviewcomment-reply.pt (+2/-2)
lib/lp/code/templates/codereviewnewrevisions-footer.pt (+13/-5)
lib/lp/code/templates/codereviewnewrevisions-header.pt (+1/-1)
lib/lp/code/templates/git-macros.pt (+2/-2)
To merge this branch: bzr merge lp:~cjwatson/launchpad/git-mp-commits
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+294671@code.launchpad.net

Commit message

Show unmerged and conversation-relevant Git commits in merge proposal views.

Description of the change

Show unmerged and conversation-relevant Git commits in merge proposal views.

The only significant oddity here is that we're using Git's idea of commit dates rather than when the commit was pushed. This will make sense from an author's point of view, but it will potentially mean that a reviewer sees commits pop up before their review comment. It arguably makes about as much sense as the approach we take with Bazaar, but it's certainly different. However, we can't emulate the Bazaar approach unless we start doing a full branch scanner and creating Revision rows for Git, which we wanted to avoid unless we had no choice, so let's go with this approach.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/code/browser/branchmergeproposal.py'
--- lib/lp/code/browser/branchmergeproposal.py 2016-05-07 00:40:18 +0000
+++ lib/lp/code/browser/branchmergeproposal.py 2016-05-18 22:37:48 +0000
@@ -534,9 +534,15 @@
534 particular time.534 particular time.
535 """535 """
536536
537 def __init__(self, revisions, date, branch, diff):537 def __init__(self, revisions, date, source, diff):
538 self.revisions = revisions538 self.revisions = revisions
539 self.branch = branch539 self.source = source
540 if IBranch.providedBy(source):
541 self.branch = source
542 self.git_ref = None
543 else:
544 self.branch = None
545 self.git_ref = source
540 self.has_body = False546 self.has_body = False
541 self.has_footer = True547 self.has_footer = True
542 # The date attribute is used to sort the comments in the conversation.548 # The date attribute is used to sort the comments in the conversation.
@@ -613,7 +619,9 @@
613 if IBranch.providedBy(source):619 if IBranch.providedBy(source):
614 source = DecoratedBranch(source)620 source = DecoratedBranch(source)
615 comments = []621 comments = []
616 if getFeatureFlag('code.incremental_diffs.enabled'):622 if (getFeatureFlag('code.incremental_diffs.enabled') and
623 merge_proposal.source_branch is not None):
624 # XXX cjwatson 2016-05-09: Implement for Git.
617 ranges = [625 ranges = [
618 (revisions[0].revision.getLefthandParent(),626 (revisions[0].revision.getLefthandParent(),
619 revisions[-1].revision)627 revisions[-1].revision)
@@ -622,8 +630,12 @@
622 else:630 else:
623 diffs = [None] * len(groups)631 diffs = [None] * len(groups)
624 for revisions, diff in zip(groups, diffs):632 for revisions, diff in zip(groups, diffs):
633 if merge_proposal.source_branch is not None:
634 last_date_created = revisions[-1].revision.date_created
635 else:
636 last_date_created = revisions[-1]["author_date"]
625 newrevs = CodeReviewNewRevisions(637 newrevs = CodeReviewNewRevisions(
626 revisions, revisions[-1].revision.date_created, source, diff)638 revisions, last_date_created, source, diff)
627 comments.append(newrevs)639 comments.append(newrevs)
628 while merge_proposal is not None:640 while merge_proposal is not None:
629 from_superseded = merge_proposal != self.context641 from_superseded = merge_proposal != self.context
630642
=== modified file 'lib/lp/code/browser/tests/test_branchmergeproposal.py'
--- lib/lp/code/browser/tests/test_branchmergeproposal.py 2016-05-18 12:15:05 +0000
+++ lib/lp/code/browser/tests/test_branchmergeproposal.py 2016-05-18 22:37:48 +0000
@@ -11,6 +11,7 @@
11 timedelta,11 timedelta,
12 )12 )
13from difflib import unified_diff13from difflib import unified_diff
14import hashlib
14import re15import re
1516
16from lazr.lifecycle.event import ObjectModifiedEvent17from lazr.lifecycle.event import ObjectModifiedEvent
@@ -1031,9 +1032,12 @@
10311032
10321033
1033class TestBranchMergeProposalRequestReviewViewGit(1034class TestBranchMergeProposalRequestReviewViewGit(
1034 TestBranchMergeProposalRequestReviewViewMixin, BrowserTestCase):1035 TestBranchMergeProposalRequestReviewViewMixin, GitHostingClientMixin,
1036 BrowserTestCase):
1035 """Test `BranchMergeProposalRequestReviewView` for Git."""1037 """Test `BranchMergeProposalRequestReviewView` for Git."""
10361038
1039 layer = LaunchpadFunctionalLayer
1040
1037 def makeBranchMergeProposal(self):1041 def makeBranchMergeProposal(self):
1038 return self.factory.makeBranchMergeProposalForGit()1042 return self.factory.makeBranchMergeProposalForGit()
10391043
@@ -1261,10 +1265,10 @@
1261 self.assertEqual('flibble', bmp.superseded_by.description)1265 self.assertEqual('flibble', bmp.superseded_by.description)
12621266
12631267
1264class TestResubmitBrowserGit(BrowserTestCase):1268class TestResubmitBrowserGit(GitHostingClientMixin, BrowserTestCase):
1265 """Browser tests for resubmitting branch merge proposals for Git."""1269 """Browser tests for resubmitting branch merge proposals for Git."""
12661270
1267 layer = DatabaseFunctionalLayer1271 layer = LaunchpadFunctionalLayer
12681272
1269 def test_resubmit_text(self):1273 def test_resubmit_text(self):
1270 """The text of the resubmit page is as expected."""1274 """The text of the resubmit page is as expected."""
@@ -1441,7 +1445,7 @@
1441 [diff],1445 [diff],
1442 [comment.diff for comment in comments])1446 [comment.diff for comment in comments])
14431447
1444 def test_CodeReviewNewRevisions_implements_ICodeReviewNewRevisions(self):1448 def test_CodeReviewNewRevisions_implements_interface_bzr(self):
1445 # The browser helper class implements its interface.1449 # The browser helper class implements its interface.
1446 review_date = datetime(2009, 9, 10, tzinfo=pytz.UTC)1450 review_date = datetime(2009, 9, 10, tzinfo=pytz.UTC)
1447 revision_date = review_date + timedelta(days=1)1451 revision_date = review_date + timedelta(days=1)
@@ -1454,6 +1458,36 @@
14541458
1455 self.assertTrue(verifyObject(ICodeReviewNewRevisions, new_revisions))1459 self.assertTrue(verifyObject(ICodeReviewNewRevisions, new_revisions))
14561460
1461 def test_CodeReviewNewRevisions_implements_interface_git(self):
1462 # The browser helper class implements its interface.
1463 review_date = datetime(2009, 9, 10, tzinfo=pytz.UTC)
1464 author = self.factory.makePerson()
1465 with person_logged_in(author):
1466 author_email = author.preferredemail.email
1467 epoch = datetime.fromtimestamp(0, tz=pytz.UTC)
1468 review_date = self.factory.getUniqueDate()
1469 commit_date = self.factory.getUniqueDate()
1470 bmp = self.factory.makeBranchMergeProposalForGit(
1471 date_created=review_date)
1472 hosting_client = FakeMethod()
1473 hosting_client.getLog = FakeMethod(result=[
1474 {
1475 u'sha1': unicode(hashlib.sha1(b'0').hexdigest()),
1476 u'message': u'0',
1477 u'author': {
1478 u'name': author.display_name,
1479 u'email': author_email,
1480 u'time': int((commit_date - epoch).total_seconds()),
1481 },
1482 }
1483 ])
1484 self.useFixture(ZopeUtilityFixture(hosting_client, IGitHostingClient))
1485
1486 view = create_initialized_view(bmp, '+index')
1487 new_commits = view.conversation.comments[0]
1488
1489 self.assertTrue(verifyObject(ICodeReviewNewRevisions, new_commits))
1490
1457 def test_include_superseded_comments(self):1491 def test_include_superseded_comments(self):
1458 for x, time in zip(range(3), time_counter()):1492 for x, time in zip(range(3), time_counter()):
1459 if x != 0:1493 if x != 0:
@@ -1527,9 +1561,10 @@
1527 self.assertThat(browser.contents, HTMLContains(expected_meta))1561 self.assertThat(browser.contents, HTMLContains(expected_meta))
15281562
15291563
1530class TestBranchMergeProposalBrowserView(BrowserTestCase):1564class TestBranchMergeProposalBrowserView(
1565 GitHostingClientMixin, BrowserTestCase):
15311566
1532 layer = DatabaseFunctionalLayer1567 layer = LaunchpadFunctionalLayer
15331568
1534 def test_prerequisite_bzr(self):1569 def test_prerequisite_bzr(self):
1535 # A prerequisite branch is rendered in the Bazaar case.1570 # A prerequisite branch is rendered in the Bazaar case.
@@ -1727,7 +1762,7 @@
1727 self.assertEqual('Eric on 2008-09-10', view.status_title)1762 self.assertEqual('Eric on 2008-09-10', view.status_title)
17281763
17291764
1730class TestBranchMergeProposal(BrowserTestCase):1765class TestBranchMergeProposal(GitHostingClientMixin, BrowserTestCase):
17311766
1732 layer = LaunchpadFunctionalLayer1767 layer = LaunchpadFunctionalLayer
17331768
17341769
=== modified file 'lib/lp/code/interfaces/branchmergeproposal.py'
--- lib/lp/code/interfaces/branchmergeproposal.py 2015-10-19 10:56:16 +0000
+++ lib/lp/code/interfaces/branchmergeproposal.py 2016-05-18 22:37:48 +0000
@@ -1,4 +1,4 @@
1# Copyright 2009-2015 Canonical Ltd. This software is licensed under the1# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4"""The interface for branch merge proposals."""4"""The interface for branch merge proposals."""
@@ -429,6 +429,9 @@
429 source branch that are not in the revision history of the target429 source branch that are not in the revision history of the target
430 branch. These are the revisions that have been committed to the430 branch. These are the revisions that have been committed to the
431 source branch since it branched off the target branch.431 source branch since it branched off the target branch.
432
433 For Bazaar, this returns a sequence of `BranchRevision` objects.
434 For Git, this returns a sequence of commit information dicts.
432 """435 """
433436
434 def getUsersVoteReference(user):437 def getUsersVoteReference(user):
435438
=== modified file 'lib/lp/code/model/branchmergeproposal.py'
--- lib/lp/code/model/branchmergeproposal.py 2015-10-13 17:24:59 +0000
+++ lib/lp/code/model/branchmergeproposal.py 2016-05-18 22:37:48 +0000
@@ -1,7 +1,7 @@
1# Copyright 2009-2015 Canonical Ltd. This software is licensed under the1# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4"""Database class for branch merge prosals."""4"""Database class for branch merge proposals."""
55
6__metaclass__ = type6__metaclass__ = type
7__all__ = [7__all__ = [
@@ -36,10 +36,7 @@
36 Int,36 Int,
37 Reference,37 Reference,
38 )38 )
39from storm.store import (39from storm.store import Store
40 EmptyResultSet,
41 Store,
42 )
43from zope.component import getUtility40from zope.component import getUtility
44from zope.event import notify41from zope.event import notify
45from zope.interface import implementer42from zope.interface import implementer
@@ -70,8 +67,8 @@
70 IBranchMergeProposal,67 IBranchMergeProposal,
71 IBranchMergeProposalGetter,68 IBranchMergeProposalGetter,
72 )69 )
73from lp.code.interfaces.branchrevision import IBranchRevision
74from lp.code.interfaces.branchtarget import IHasBranchTarget70from lp.code.interfaces.branchtarget import IHasBranchTarget
71from lp.code.interfaces.codereviewcomment import ICodeReviewComment
75from lp.code.interfaces.codereviewinlinecomment import (72from lp.code.interfaces.codereviewinlinecomment import (
76 ICodeReviewInlineCommentSet,73 ICodeReviewInlineCommentSet,
77 )74 )
@@ -785,26 +782,38 @@
785782
786 def getUnlandedSourceBranchRevisions(self):783 def getUnlandedSourceBranchRevisions(self):
787 """See `IBranchMergeProposal`."""784 """See `IBranchMergeProposal`."""
788 if self.source_branch is None:785 if self.source_branch is not None:
789 # XXX cjwatson 2015-04-16: Implement for Git somehow, perhaps by786 store = Store.of(self)
790 # calling turnip via memcached.787 source = SQL("""
791 return []788 source AS (
792 store = Store.of(self)789 SELECT
793 source = SQL("""source AS (SELECT BranchRevision.branch,790 BranchRevision.branch, BranchRevision.revision,
794 BranchRevision.revision, Branchrevision.sequence FROM791 Branchrevision.sequence
795 BranchRevision WHERE BranchRevision.branch = %s and792 FROM BranchRevision
796 BranchRevision.sequence IS NOT NULL ORDER BY BranchRevision.branch793 WHERE
797 DESC, BranchRevision.sequence DESC794 BranchRevision.branch = %s
798 LIMIT 10)""" % self.source_branch.id)795 AND BranchRevision.sequence IS NOT NULL
799 where = SQL("""BranchRevision.revision NOT IN (SELECT revision from796 ORDER BY
800 BranchRevision AS target where target.branch = %s and797 BranchRevision.branch DESC,
801 BranchRevision.revision = target.revision)""" %798 BranchRevision.sequence DESC
802 self.target_branch.id)799 LIMIT 10)""" % self.source_branch.id)
803 using = SQL("""source as BranchRevision""")800 where = SQL("""
804 revisions = store.with_(source).using(using).find(801 BranchRevision.revision NOT IN (
805 BranchRevision, where)802 SELECT revision
806 return list(revisions.order_by(803 FROM BranchRevision AS target
807 Desc(BranchRevision.sequence)).config(limit=10))804 WHERE
805 target.branch = %s
806 AND BranchRevision.revision = target.revision)""" %
807 self.target_branch.id)
808 using = SQL("""source AS BranchRevision""")
809 revisions = store.with_(source).using(using).find(
810 BranchRevision, where)
811 return list(revisions.order_by(
812 Desc(BranchRevision.sequence)).config(limit=10))
813 else:
814 return self.source_git_ref.getCommits(
815 self.source_git_commit_sha1, limit=10,
816 stop=self.target_git_commit_sha1)
808817
809 def createComment(self, owner, subject, content=None, vote=None,818 def createComment(self, owner, subject, content=None, vote=None,
810 review_type=None, parent=None, _date_created=DEFAULT,819 review_type=None, parent=None, _date_created=DEFAULT,
@@ -1031,34 +1040,39 @@
1031 return None1040 return None
10321041
1033 def _getNewerRevisions(self):1042 def _getNewerRevisions(self):
1034 if self.source_branch is None:
1035 # XXX cjwatson 2015-04-16: Implement for Git.
1036 return EmptyResultSet()
1037 start_date = self.date_review_requested1043 start_date = self.date_review_requested
1038 if start_date is None:1044 if start_date is None:
1039 start_date = self.date_created1045 start_date = self.date_created
1040 return self.source_branch.getMainlineBranchRevisions(1046 if self.source_branch is not None:
1041 start_date, self.revision_end_date, oldest_first=True)1047 revisions = self.source_branch.getMainlineBranchRevisions(
1048 start_date, self.revision_end_date, oldest_first=True)
1049 return [
1050 ((revision.date_created, branch_revision.sequence),
1051 branch_revision)
1052 for branch_revision, revision in revisions]
1053 else:
1054 commits = reversed(self.source_git_ref.getCommits(
1055 self.source_git_commit_sha1, stop=self.target_git_commit_sha1,
1056 start_date=start_date, end_date=self.revision_end_date))
1057 return [
1058 ((commit["author_date"], count), commit)
1059 for count, commit in enumerate(commits)]
10421060
1043 def getRevisionsSinceReviewStart(self):1061 def getRevisionsSinceReviewStart(self):
1044 """Get the grouped revisions since the review started."""1062 """Get the grouped revisions since the review started."""
1045 entries = [1063 entries = [
1046 ((comment.date_created, -1), comment) for comment1064 ((comment.date_created, -1), comment) for comment
1047 in self.all_comments]1065 in self.all_comments]
1048 revisions = self._getNewerRevisions()1066 entries.extend(self._getNewerRevisions())
1049 entries.extend(
1050 ((revision.date_created, branch_revision.sequence),
1051 branch_revision)
1052 for branch_revision, revision in revisions)
1053 entries.sort()1067 entries.sort()
1054 current_group = []1068 current_group = []
1055 for sortkey, entry in entries:1069 for sortkey, entry in entries:
1056 if IBranchRevision.providedBy(entry):1070 if ICodeReviewComment.providedBy(entry):
1057 current_group.append(entry)
1058 else:
1059 if current_group != []:1071 if current_group != []:
1060 yield current_group1072 yield current_group
1061 current_group = []1073 current_group = []
1074 else:
1075 current_group.append(entry)
1062 if current_group != []:1076 if current_group != []:
1063 yield current_group1077 yield current_group
10641078
10651079
=== modified file 'lib/lp/code/stories/branches/xx-code-review-comments.txt'
--- lib/lp/code/stories/branches/xx-code-review-comments.txt 2015-10-06 06:48:01 +0000
+++ lib/lp/code/stories/branches/xx-code-review-comments.txt 2016-05-18 22:37:48 +0000
@@ -188,6 +188,56 @@
188 4. By ... on 2009-09-12188 4. By ... on 2009-09-12
189 and it works!189 and it works!
190190
191The same thing works for Git. Note that the hosting client returns newest
192log entries first.
193
194 >>> from lp.code.interfaces.githosting import IGitHostingClient
195 >>> from lp.testing.fakemethod import FakeMethod
196 >>> from lp.testing.fixture import ZopeUtilityFixture
197
198 >>> login('admin@canonical.com')
199 >>> bmp = factory.makeBranchMergeProposalForGit()
200 >>> bmp.requestReview(review_date)
201 >>> epoch = datetime.fromtimestamp(0, tz=pytz.UTC)
202 >>> commit_date = review_date + timedelta(days=1)
203 >>> hosting_client = FakeMethod()
204 >>> hosting_client.getLog = FakeMethod(result=[])
205 >>> for i in range(2):
206 ... hosting_client.getLog.result.insert(0, {
207 ... u'sha1': unicode(i * 2) * 40,
208 ... u'message': u'Testing commits in conversation',
209 ... u'author': {
210 ... u'name': bmp.registrant.display_name,
211 ... u'email': bmp.registrant.preferredemail.email,
212 ... u'time': int((commit_date - epoch).total_seconds()),
213 ... },
214 ... })
215 ... hosting_client.getLog.result.insert(0, {
216 ... u'sha1': unicode(i * 2 + 1) * 40,
217 ... u'message': u'and it works!',
218 ... u'author': {
219 ... u'name': bmp.registrant.display_name,
220 ... u'email': bmp.registrant.preferredemail.email,
221 ... u'time': int((commit_date - epoch).total_seconds()),
222 ... },
223 ... })
224 ... commit_date += timedelta(days=1)
225 >>> url = canonical_url(bmp)
226 >>> logout()
227
228 >>> with ZopeUtilityFixture(hosting_client, IGitHostingClient):
229 ... browser.open(url)
230 >>> print_tag_with_id(browser.contents, 'conversation')
231 ~.../+git/...:... updated on 2009-09-12 ...
232 0000000... by ... on 2009-09-11
233 Testing commits in conversation
234 1111111... by ... on 2009-09-11
235 and it works!
236 2222222... by ... on 2009-09-12
237 Testing commits in conversation
238 3333333... by ... on 2009-09-12
239 and it works!
240
191241
192Inline Comments242Inline Comments
193---------------243---------------
194244
=== modified file 'lib/lp/code/templates/branchmergeproposal-index.pt'
--- lib/lp/code/templates/branchmergeproposal-index.pt 2015-04-22 16:11:40 +0000
+++ lib/lp/code/templates/branchmergeproposal-index.pt 2016-05-18 22:37:48 +0000
@@ -170,6 +170,14 @@
170 <p>Recent revisions are not available due to the source branch being remote.</p>170 <p>Recent revisions are not available due to the source branch being remote.</p>
171 </tal:remote-branch>171 </tal:remote-branch>
172 </tal:bzr-revisions>172 </tal:bzr-revisions>
173 <tal:git-revisions condition="context/source_git_ref">
174 <tal:history-available condition="context/source_git_ref/has_commits"
175 define="ref context/source_git_ref;
176 commit_infos view/unlanded_revisions">
177 <h2>Unmerged commits</h2>
178 <metal:commits use-macro="ref/@@+macros/ref-commits"/>
179 </tal:history-available>
180 </tal:git-revisions>
173 </div>181 </div>
174 </div>182 </div>
175183
176184
=== modified file 'lib/lp/code/templates/branchmergeproposal-resubmit.pt'
--- lib/lp/code/templates/branchmergeproposal-resubmit.pt 2015-04-28 16:39:15 +0000
+++ lib/lp/code/templates/branchmergeproposal-resubmit.pt 2016-05-18 22:37:48 +0000
@@ -24,18 +24,28 @@
24 </div>24 </div>
25 </div>25 </div>
2626
27 <div id="source-revisions" tal:condition="context/source_branch">27 <div id="source-revisions">
28 <tal:history-available condition="context/source_branch/revision_count"28 <tal:bzr-revisions condition="context/source_branch">
29 define="branch context/source_branch;29 <tal:history-available condition="context/source_branch/revision_count"
30 revisions view/unlanded_revisions">30 define="branch context/source_branch;
31 <h2>Unmerged revisions</h2>31 revisions view/unlanded_revisions">
32 <metal:landing-target use-macro="branch/@@+macros/branch-revisions"/>32 <h2>Unmerged revisions</h2>
33 </tal:history-available>33 <metal:landing-target use-macro="branch/@@+macros/branch-revisions"/>
34 </tal:history-available>
3435
35 <tal:remote-branch condition="context/source_branch/branch_type/enumvalue:REMOTE">36 <tal:remote-branch condition="context/source_branch/branch_type/enumvalue:REMOTE">
36 <h2>Unmerged revisions</h2>37 <h2>Unmerged revisions</h2>
37 <p>Recent revisions are not available due to the source branch being remote.</p>38 <p>Recent revisions are not available due to the source branch being remote.</p>
38 </tal:remote-branch>39 </tal:remote-branch>
40 </tal:bzr-revisions>
41 <tal:git-revisions condition="context/source_git_ref">
42 <tal:history-available condition="context/source_git_ref/has_commits"
43 define="ref context/source_git_ref;
44 commit_infos view/unlanded_revisions">
45 <h2>Unmerged commits</h2>
46 <metal:commits use-macro="ref/@@+macros/ref-commits"/>
47 </tal:history-available>
48 </tal:git-revisions>
39 </div>49 </div>
4050
41</div>51</div>
4252
=== modified file 'lib/lp/code/templates/codereviewcomment-reply.pt'
--- lib/lp/code/templates/codereviewcomment-reply.pt 2016-01-21 03:23:01 +0000
+++ lib/lp/code/templates/codereviewcomment-reply.pt 2016-05-18 22:37:48 +0000
@@ -8,8 +8,8 @@
88
9 <body>9 <body>
10 <h1 metal:fill-slot="heading"10 <h1 metal:fill-slot="heading"
11 tal:define="branch view/branch_merge_proposal/merge_source">11 tal:define="source view/branch_merge_proposal/merge_source">
12 Code review comment for <tal:source content="branch/identity"/>12 Code review comment for <tal:source content="source/identity"/>
13 </h1>13 </h1>
1414
15 <div metal:fill-slot="main">15 <div metal:fill-slot="main">
1616
=== modified file 'lib/lp/code/templates/codereviewnewrevisions-footer.pt'
--- lib/lp/code/templates/codereviewnewrevisions-footer.pt 2015-06-23 17:30:39 +0000
+++ lib/lp/code/templates/codereviewnewrevisions-footer.pt 2016-05-18 22:37:48 +0000
@@ -3,11 +3,19 @@
3 xmlns:metal="http://xml.zope.org/namespaces/metal"3 xmlns:metal="http://xml.zope.org/namespaces/metal"
4 omit-tag="">4 omit-tag="">
55
6 <tal:revisions define="branch context/branch;6 <tal:bzr-revisions condition="context/branch">
7 revisions context/revisions;7 <tal:revisions define="branch context/branch;
8 show_diff_expander python:True;">8 revisions context/revisions;
9 <metal:landing-target use-macro="branch/@@+macros/branch-revisions"/>9 show_diff_expander python:True;">
10 </tal:revisions>10 <metal:revisions use-macro="branch/@@+macros/branch-revisions"/>
11 </tal:revisions>
12 </tal:bzr-revisions>
13 <tal:git-revisions condition="context/git_ref">
14 <tal:revisions define="ref context/git_ref;
15 commit_infos context/revisions;">
16 <metal:commits use-macro="ref/@@+macros/ref-commits"/>
17 </tal:revisions>
18 </tal:git-revisions>
11 <tal:has-diff condition="context/diff">19 <tal:has-diff condition="context/diff">
12 <tal:diff condition="not: request/ss|nothing"20 <tal:diff condition="not: request/ss|nothing"
13 replace="structure context/diff/text/fmt:diff" />21 replace="structure context/diff/text/fmt:diff" />
1422
=== modified file 'lib/lp/code/templates/codereviewnewrevisions-header.pt'
--- lib/lp/code/templates/codereviewnewrevisions-header.pt 2009-12-10 01:33:59 +0000
+++ lib/lp/code/templates/codereviewnewrevisions-header.pt 2016-05-18 22:37:48 +0000
@@ -3,7 +3,7 @@
3 xmlns:metal="http://xml.zope.org/namespaces/metal"3 xmlns:metal="http://xml.zope.org/namespaces/metal"
4 omit-tag="">4 omit-tag="">
55
6 <tal:branch replace="structure context/branch/fmt:link"/>6 <tal:source replace="structure context/source/fmt:link"/>
7 updated7 updated
8 <tal:date replace="context/date/fmt:displaydate" />8 <tal:date replace="context/date/fmt:displaydate" />
99
1010
=== modified file 'lib/lp/code/templates/git-macros.pt'
--- lib/lp/code/templates/git-macros.pt 2016-05-18 11:49:31 +0000
+++ lib/lp/code/templates/git-macros.pt 2016-05-18 22:37:48 +0000
@@ -135,7 +135,7 @@
135 sha1 python:commit_info['sha1'];135 sha1 python:commit_info['sha1'];
136 author python:commit_info['author'];136 author python:commit_info['author'];
137 author_date python:commit_info['author_date']">137 author_date python:commit_info['author_date']">
138 <a tal:attributes="href python: context.getCodebrowseUrlForRevision(sha1)"138 <a tal:attributes="href python: ref.getCodebrowseUrlForRevision(sha1)"
139 tal:content="sha1/fmt:shorten/10" />139 tal:content="sha1/fmt:shorten/10" />
140 by140 by
141 <tal:known-person condition="author/person">141 <tal:known-person condition="author/person">
@@ -153,7 +153,7 @@
153 replace="structure commit_message/fmt:obfuscate-email/fmt:text-to-html" />153 replace="structure commit_message/fmt:obfuscate-email/fmt:text-to-html" />
154 </dd>154 </dd>
155155
156 <div tal:define="merge_proposal python:commit_info['merge_proposal']"156 <div tal:define="merge_proposal python:commit_info.get('merge_proposal')"
157 tal:condition="merge_proposal">157 tal:condition="merge_proposal">
158 <dd class="subordinate commit-comment"158 <dd class="subordinate commit-comment"
159 tal:define="committer_date merge_proposal/merge_source/committer_date|nothing">159 tal:define="committer_date merge_proposal/merge_source/committer_date|nothing">