@@ -493,6 +493,7 @@ class LayerDetailView(DetailView):
context['appends'] = layerbranch.bbappend_set.order_by('filename')
context['classes'] = layerbranch.bbclass_set.order_by('name')
context['updates'] = LayerUpdate.objects.filter(layer=layerbranch.layer, branch=layerbranch.branch).order_by('-started')
+ context['layerbranches'] = LayerBranch.objects.filter(layer=layer, branch__hidden=False, branch__comparison=False).select_related('layer', 'branch').order_by('branch__sort_priority')
context['url_branch'] = self.kwargs['branch']
context['this_url_name'] = resolve(self.request.path_info).url_name
if 'rrs' in settings.INSTALLED_APPS:
@@ -224,6 +224,7 @@
{% if updates.count > 0 %}
<li><a href="#updates" data-toggle="tab">Updates</a></li>
{% endif %}
+ <li><a href="#branches" data-toggle="tab">Branches</a></li>
</ul>
<div class="tab-content">
@@ -393,6 +394,28 @@
</table>
</div>
{% endif %}
+ <div class="tab-pane" id="branches">
+ <table class="table table-bordered">
+ <thead>
+ <tr>
+ <th>Branch</th>
+ <th>Git branch</th>
+ <th>Last commit</th>
+ <th>Updates</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for lb in layerbranches %}
+ <tr>
+ <td>{% if lb.branch.name == url_branch %}<b>{{ lb.branch.name }}</b>{% else %}<a href="{% url 'layer_item' lb.branch.name layeritem.name %}">{{ lb.branch.name }}</a>{% endif %}</td>
+ <td>{{ lb.get_checkout_branch }}</td>
+ <td>{% if lb.vcs_last_commit %}{{ lb.vcs_last_commit|date:"Y-m-d" }}{% else %}<span class="text-muted">not indexed</span>{% endif %}</td>
+ <td>{% with reason=lb.updates_disabled_reason %}{% if reason %}<span class="label label-default label-not-updated">not updated</span> <small class="text-muted">{{ reason }}</small>{% else %}updated{% endif %}{% endwith %}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
</div>
new file mode 100644
@@ -0,0 +1,45 @@
+# layerindex-web - test the table of a layer's branches on the layer page
+#
+# Licensed under the MIT license, see COPYING.MIT for details
+#
+# SPDX-License-Identifier: MIT
+
+import re
+from datetime import datetime
+
+import pytest
+from django.urls import reverse
+
+from layerindex.models import Branch, LayerBranch, LayerItem
+
+
+@pytest.mark.django_db
+def test_branch_table(client):
+ # [YOCTO #15380] like meta-qt6, where each branch tracks a different git branch
+ master, _ = Branch.objects.get_or_create(name='master', defaults={'bitbake_branch': 'master'})
+ master.sort_priority = 1
+ master.save()
+ scarthgap = Branch.objects.create(name='scarthgap', bitbake_branch='2.8', sort_priority=2)
+ kirkstone = Branch.objects.create(name='kirkstone', bitbake_branch='2.0', sort_priority=3,
+ updates_enabled=False)
+ hidden = Branch.objects.create(name='hiddenbranch', bitbake_branch='master', hidden=True)
+ layer = LayerItem.objects.create(name='meta-qt', status='P', layer_type='S', summary='qt',
+ description='qt', vcs_url='git://example.com/meta-qt.git')
+ LayerBranch.objects.create(layer=layer, branch=master, actual_branch='dev',
+ vcs_last_commit=datetime(2026, 11, 1))
+ LayerBranch.objects.create(layer=layer, branch=scarthgap, actual_branch='6.8')
+ LayerBranch.objects.create(layer=layer, branch=kirkstone, actual_branch='6.2')
+ LayerBranch.objects.create(layer=layer, branch=hidden)
+
+ page = client.get(reverse('layer_item', args=('master', 'meta-qt'))).content.decode()
+ table = page[page.index('id="branches"'):]
+ rows = [re.sub(r'<[^>]+>|\s+', ' ', r).split() for r in re.findall(r'<tr>(.*?)</tr>', table, re.S)[1:]]
+
+ assert [r[:2] for r in rows] == [['master', 'dev'], ['scarthgap', '6.8'], ['kirkstone', '6.2']]
+ assert rows[0][2:] == ['2026-11-01', 'updated']
+ assert rows[1][2:5] == ['not', 'indexed', 'updated']
+ assert 'Updates are disabled for the kirkstone branch' in table
+ assert 'hiddenbranch' not in table
+ # The current branch is not a link; the others are
+ assert reverse('layer_item', args=('scarthgap', 'meta-qt')) in table
+ assert reverse('layer_item', args=('master', 'meta-qt')) not in table
For a layer like meta-qt6, where each branch tracks a different git branch, the layer page only showed the branch being viewed. Add a Branches tab listing every branch of the layer, with the git branch it tracks (actual_branch), the date of its last commit, and whether it is still updated. [YOCTO #15380] AI-Generated: Claude Opus 5.5 Signed-off-by: Tim Orling <tim.orling@konsulko.com> --- This depends on "[PATCH v2] layerindex: show when a layer branch is no longer updated" (bug 14781) for the updates column, and applies on top of it and on master-next. Editing the branches, also asked for in the bug, would follow separately. On a test instance loaded with a copy of the layers.openembedded.org database, meta-qt6's table shows each branch's git branch (master: dev, scarthgap: lts-6.8, kirkstone: 6.5, ...) and that langdale is no longer updated. layerindex/views.py | 1 + templates/layerindex/detail.html | 23 ++++++++++++++++ tests/test_branch_table.py | 45 ++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 tests/test_branch_table.py base-commit: 08e58cdece30019a6f9e5d14af16ebe20afa6177 prerequisite-patch-id: d08807a0e95947278caa6b5f1c6c2e6e74dba0e5