The tracking of branches has turned out to be more involved than I thought. Many functions are already branch-aware and return / do the right thing. Tonight, I tried my recent idea of using head to get the slave ports for a given master port on a branch. So far, that works. The hard part now is dealing with a slave port on a branch which had not yet had any commits on that branch.
First, FreshPorts takes action only upon recent of a commit. If a file has been created by a repo copy, then FreshPorts knows nothing about it.
That’s bad news for branches, which are similar to a repo-copy in concept.
Compare these two URLs:
- https://svnweb.freebsd.org/ports/head/sysutils/bacula-server/Makefile
- https://svnweb.freebsd.org/ports/branches/2016Q2/sysutils/bacula-server/Makefile
You will see revision 412349 on both pages.
Ideally, FreshPorts would do it’s own internal equivalent of a repocopy when it sees the 2016Q2 branch created, but in the current database design, that would duplicate the content of head for each branch, four times a year. That’s not a good approach.
The current system of adding new elements (each file in a commit is an element, e.g. /ports/branches/2016Q2/sysutils/bacula-server/Makefile) is based upon processing a commit. Each commit has an associated revision number. Thus, when adding a new element, we add a reference to that revision name. This won’t work for the situation we have under consideration.
I think the new approach needs a function such as: $port->CreatePortOnBranch($category_name, $port_name, $CommitBranch); which will take all the elements until a given point in head and duplicate them on a branch. This seems to be the easiest solution so far. I think I can easier create a store procedure which pulls back all children under a given point in the tree.
Using the recursion query I created a few days ago as a starting point, it only took me a few minute to create this query:
WITH RECURSIVE all_descendents AS ( SELECT id, name, parent_id, directory_file_flag, status FROM element WHERE id = (select pathname_id('/ports/head/sysutils/bacula-server/')) UNION SELECT E.id, E.name, E.parent_id, E.directory_file_flag, E.status FROM element E JOIN all_descendents AD ON (E.parent_id = AD.id) ) SELECT id, name, parent_id, directory_file_flag, status, element_pathname(id) AS pathname FROM all_descendents WHERE status = 'A' ORDER BY pathname; id | name | parent_id | directory_file_flag | status | pathname --------+---------------------------------+-----------+---------------------+--------+-------------------------------------------------------------------------- 205194 | bacula-server | 218 | D | A | /ports/head/sysutils/bacula-server 205195 | Makefile | 205194 | F | A | /ports/head/sysutils/bacula-server/Makefile 475011 | Makefile.common | 205194 | F | A | /ports/head/sysutils/bacula-server/Makefile.common 212250 | distinfo | 205194 | F | A | /ports/head/sysutils/bacula-server/distinfo 212251 | files | 205194 | D | A | /ports/head/sysutils/bacula-server/files 240895 | bacula-dir.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/bacula-dir.in 240896 | bacula-fd.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/bacula-fd.in 240897 | bacula-sd.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/bacula-sd.in 212252 | chio-bacula | 212251 | F | A | /ports/head/sysutils/bacula-server/files/chio-bacula 682189 | patch-src_console_Makefile.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/patch-src_console_Makefile.in 682190 | patch-src_dird_Makefile.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/patch-src_dird_Makefile.in 682191 | patch-src_filed_Makefile.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/patch-src_filed_Makefile.in 682192 | patch-src_qt-console_bat.pro.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/patch-src_qt-console_bat.pro.in 682193 | patch-src_stored_Makefile.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/patch-src_stored_Makefile.in 682194 | patch-src_tools_Makefile.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/patch-src_tools_Makefile.in 352748 | pkg-deinstall.client.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/pkg-deinstall.client.in 352749 | pkg-deinstall.server.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/pkg-deinstall.server.in 352750 | pkg-install.client.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/pkg-install.client.in 352751 | pkg-install.server.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/pkg-install.server.in 262399 | pkg-message.client.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/pkg-message.client.in 262400 | pkg-message.server.in | 212251 | F | A | /ports/head/sysutils/bacula-server/files/pkg-message.server.in 205198 | pkg-plist | 205194 | F | A | /ports/head/sysutils/bacula-server/pkg-plist 205199 | pkg-plist.client | 205194 | F | A | /ports/head/sysutils/bacula-server/pkg-plist.client (23 rows)
Comparing this to a find in the ports tree:
$ find . | sort . ./Makefile ./Makefile.common ./distinfo ./files ./files/bacula-barcodes ./files/bacula-dir.in ./files/bacula-fd.in ./files/bacula-sd.in ./files/chio-bacula ./files/patch-src_console_Makefile.in ./files/patch-src_dird_Makefile.in ./files/patch-src_filed_Makefile.in ./files/patch-src_qt-console_bat.pro.in ./files/patch-src_stored_Makefile.in ./files/patch-src_tools_Makefile.in ./files/pkg-deinstall.client.in ./files/pkg-deinstall.server.in ./files/pkg-install.client.in ./files/pkg-install.server.in ./files/pkg-message.client.in ./files/pkg-message.server.in ./pkg-descr ./pkg-plist ./pkg-plist.client
That’s close enough.
I think the pseudo code for creating the port on the branch will be:
ListOfFiles = GetFilesFor('/ports/head/sysutils/bacula-server'); for file in ${Files} do NewFile = replace('^/ports/head/', '/ports/branches/2016Q2/', ${file}); AddToElementTable(${NewFile}); done NewPort(''/ports/branches/2016Q2/sysutils/bacula-server');
Again, I’ll think on it. I’m too tired to even review what I wrote above…
That pseudo code, although cute, was close but not exactly what was implemented.