Create fake revisions for every commit in the base of a linked package

This is a rather complex operation, but whenever a package changes in
Factory, the inherited package gets a shadow revision consisting of the
3-way merge. If this happens due to a request being accepted, this is
actually in most cases also commited by 'buildservice-autocommit',
so we're making sure this is always happening (and are actually
duplicating revisions in cases that we filter out later as empty
commits).

To differenciate the fake revisions from the real revisions, I add
a fraction part
This commit is contained in:
Stephan Kulow
2022-10-24 20:21:53 +02:00
parent d17e60a608
commit 2784171f75
8 changed files with 24958 additions and 18353 deletions

View File

@@ -2,6 +2,8 @@ import functools
import logging
import xml.etree.ElementTree as ET
import psycopg2
from lib.binary import is_binary_or_large
from lib.db import DB
from lib.db_revision import DBRevision
@@ -165,6 +167,18 @@ class Importer:
(rev.dbid, linked_rev.dbid),
)
def calculate_file_hashes(self, db):
cur = db.cursor()
cur.execute(
"SELECT * from revisions where files_hash IS NULL AND broken is FALSE"
)
for row in cur.fetchall():
rev = DBRevision(row)
md5 = rev.calculate_files_hash(db)
cur.execute(
"UPDATE revisions SET files_hash=%s WHERE id=%s", (md5, rev.dbid)
)
def fetch_all_linked_packages(self, db, project, package):
cur = db.cursor()
cur.execute(
@@ -176,19 +190,86 @@ class Importer:
(lproject, lpackage) = row
self.update_db_package(db, lproject, lpackage)
def find_fake_revisions(self, db):
cur = db.cursor()
cur.execute(
"""SELECT * from revisions WHERE
id in (SELECT revision_id from linked_revs WHERE considered=FALSE) AND
id not in (SELECT revision_id FROM fake_revs) ORDER by project,package,rev"""
)
for row in cur.fetchall():
rev = DBRevision(row)
prev = rev.previous_commit(db)
if not prev:
cur.execute(
"UPDATE linked_revs SET considered=TRUE where revision_id=%s",
(rev.dbid,),
)
continue
cur2 = db.cursor()
cur2.execute(
"""SELECT * from revisions where id in
(SELECT revision_id from linked_revs WHERE linked_id=%s)
AND commit_time <= %s ORDER BY commit_time""",
(prev.dbid, rev.commit_time),
)
last_linked = None
for linked in cur2.fetchall():
linked = DBRevision(linked)
nextrev = linked.next_commit(db)
if nextrev and nextrev.commit_time < rev.commit_time:
continue
last_linked = linked
cur.execute(
"UPDATE linked_revs SET considered=TRUE where revision_id=%s",
(rev.dbid,),
)
if last_linked:
linked = last_linked
cur2.execute(
"SELECT 1 FROM fake_revs where revision_id=%s AND linked_id=%s",
(rev.dbid, linked.dbid),
)
if cur2.fetchone():
cur.execute(
"UPDATE linked_revs SET considered=TRUE where revision_id=%s",
(rev.dbid,),
)
continue
fake_rev = linked.rev + rev.rev / 1000.0
comment = f"Updating link to change in {rev.project}/{rev.package} revision {rev.rev}"
cur2.execute(
"""INSERT INTO revisions (project,package,rev,unexpanded_srcmd5,
commit_time, userid, comment) VALUES(%s,%s,%s,%s,%s,%s,%s) RETURNING id""",
(
linked.project,
linked.package,
fake_rev,
linked.unexpanded_srcmd5,
rev.commit_time,
"buildservice-autocommit",
comment,
),
)
new_id = cur2.fetchone()[0]
cur2.execute(
"""INSERT INTO linked_revs (revision_id, linked_id) VALUES (%s,%s)""",
(new_id, rev.dbid),
)
cur2.execute(
"""INSERT INTO fake_revs (revision_id, linked_id) VALUES (%s,%s)""",
(rev.dbid, linked.dbid),
)
def import_into_db(self):
db = DB()
for project, _, api_url in self.projects:
self.obs.change_url(api_url)
self.update_db_package(db, project, self.package)
with db.cursor() as cur:
cur.execute(
"SELECT DISTINCT l.project, l.package from links l join revisions r on r.id=l.revision_id WHERE r.project=%s AND r.package=%s",
(project, self.package),
)
for row in cur.fetchall():
(lproject, lpackage) = row
self.update_db_package(db, lproject, lpackage)
self.fetch_all_linked_packages(db, project, self.package)
# all remaining, no filtering here
self.find_linked_revs(db)
self.find_fake_revisions(db)
missing_users = User.missing_users(db)
for userid in missing_users:
@@ -203,7 +284,7 @@ class Importer:
with db.cursor() as cur:
cur.execute(
"""SELECT unexpanded_srcmd5 from revisions WHERE
id=(SELECT linked_id FROM linked_revs WHERE revision_id=%s""",
id=(SELECT linked_id FROM linked_revs WHERE revision_id=%s)""",
(rev.dbid,),
)
linked_rev = cur.fetchone()
@@ -217,8 +298,8 @@ class Importer:
else:
rev.set_broken(db)
for number in DBRevision.requests_to_fetch(db, project, self.package):
self.obs.request(number).import_into_db(db)
for number in DBRevision.requests_to_fetch(db, project, self.package):
self.obs.request(number).import_into_db(db)
db.conn.commit()
TreeBuilder(db).build(self.package)