Skip to content

Commit e6387bb

Browse files
committed
Fix archive DB connection not closing causing Windows file lock issue
1 parent 6881e8a commit e6387bb

2 files changed

Lines changed: 76 additions & 13 deletions

File tree

perceval/archive.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,12 @@ def __init__(self, archive_path):
9999
self._load_metadata()
100100

101101
def __del__(self):
102-
conn = getattr(self, '_db', None)
103-
if conn:
104-
conn.close()
102+
self.close()
103+
104+
def close(self):
105+
if hasattr(self, "_db") and self._db:
106+
self._db.close()
107+
self._db = None
105108

106109
def init_metadata(self, origin, backend_name, backend_version,
107110
category, backend_params):
@@ -258,6 +261,7 @@ def create(cls, archive_path):
258261

259262
logger.debug("Creating archive %s", archive_path)
260263
archive = cls(archive_path)
264+
archive.close()
261265
logger.debug("Achive %s was created", archive_path)
262266

263267
return archive

perceval/backends/core/git.py

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def __init__(self, uri, gitpath, tag=None, archive=None, ssl_verify=True):
8383
self.gitpath = gitpath
8484

8585
def fetch(self, category=CATEGORY_COMMIT, from_date=DEFAULT_DATETIME, to_date=DEFAULT_LAST_DATETIME,
86-
branches=None, latest_items=False, recovery_commit=None, no_update=False):
86+
branches=None, latest_items=False, recovery_commit=None, no_update=False, include_patch_id = False):
8787
"""Fetch commits.
8888
8989
The method retrieves from a Git repository or a log file
@@ -134,7 +134,8 @@ def fetch(self, category=CATEGORY_COMMIT, from_date=DEFAULT_DATETIME, to_date=DE
134134
'branches': branches,
135135
'latest_items': latest_items,
136136
'recovery_commit': recovery_commit,
137-
'no_update': no_update
137+
'no_update': no_update,
138+
'include_patch_id': include_patch_id
138139
}
139140
items = super().fetch(category, **kwargs)
140141

@@ -154,6 +155,7 @@ def fetch_items(self, category, **kwargs):
154155
latest_items = kwargs['latest_items']
155156
no_update = kwargs['no_update']
156157
recovery_commit = kwargs['recovery_commit']
158+
include_patch_id = kwargs.get('include_patch_id', False)
157159

158160
ncommits = 0
159161

@@ -164,7 +166,7 @@ def fetch_items(self, category, **kwargs):
164166
commits = self._fetch_from_log()
165167
else:
166168
commits = self._fetch_from_repo(from_date, to_date, branches,
167-
latest_items, no_update)
169+
latest_items, no_update, include_patch_id)
168170

169171
for commit in commits:
170172
yield commit
@@ -286,21 +288,21 @@ def _fetch_from_log(self):
286288
self.uri, self.gitpath)
287289
return self.parse_git_log_from_file(self.gitpath)
288290

289-
def _fetch_from_repo(self, from_date, to_date, branches, latest_items=False, no_update=False):
291+
def _fetch_from_repo(self, from_date, to_date, branches, latest_items=False, no_update=False, include_patch_id =False):
290292
# When no latest items are set or the repository has not
291293
# been cloned use the default mode
292294
default_mode = not latest_items or not os.path.exists(self.gitpath)
293295

294296
repo = self._create_git_repository()
295297

296298
if default_mode:
297-
commits = self._fetch_commits_from_repo(repo, from_date, to_date, branches, no_update)
299+
commits = self._fetch_commits_from_repo(repo, from_date, to_date, branches, no_update, include_patch_id)
298300
else:
299-
commits = self._fetch_newest_commits_from_repo(repo)
301+
commits = self._fetch_newest_commits_from_repo(repo, include_patch_id)
300302

301303
return commits
302304

303-
def _fetch_commits_from_repo(self, repo, from_date, to_date, branches, no_update):
305+
def _fetch_commits_from_repo(self, repo, from_date, to_date, branches, no_update, include_patch_id=False):
304306
if branches is None:
305307
branches_text = "all"
306308
elif len(branches) == 0:
@@ -327,9 +329,48 @@ def _fetch_commits_from_repo(self, repo, from_date, to_date, branches, no_update
327329
repo.update()
328330

329331
gitlog = repo.log(from_date, to_date, branches)
330-
return self.parse_git_log_from_iter(gitlog)
331332

332-
def _fetch_newest_commits_from_repo(self, repo):
333+
commits = list(self.parse_git_log_from_iter(gitlog))
334+
if include_patch_id:
335+
import subprocess
336+
import gc
337+
import time
338+
339+
for commit in commits:
340+
try:
341+
commit_hash = commit['data']['commit']
342+
343+
show_result = subprocess.run(
344+
["git", "show", commit_hash],
345+
cwd=repo.path,
346+
text=True,
347+
capture_output=True,
348+
check=True
349+
)
350+
351+
patch_result = subprocess.run(
352+
["git", "patch-id"],
353+
input=show_result.stdout,
354+
cwd=repo.path,
355+
text=True,
356+
capture_output=True,
357+
check=True
358+
)
359+
360+
patch_id = patch_result.stdout.split()[0] if patch_result.stdout else None
361+
362+
363+
# IMPORTANT: DO NOT TOUCH core data
364+
commit['patch_id'] = patch_id
365+
366+
except Exception:
367+
commit['patch_id'] = None
368+
gc.collect()
369+
time.sleep(0.1)
370+
371+
return commits
372+
373+
def _fetch_newest_commits_from_repo(self, repo, include_patch_id=False):
333374
logger.info("Fetching latest commits: '%s' git repository",
334375
self.uri)
335376

@@ -338,7 +379,25 @@ def _fetch_newest_commits_from_repo(self, repo):
338379
return []
339380

340381
gitshow = repo.show(hashes)
341-
return self.parse_git_log_from_iter(gitshow)
382+
383+
commits = list(self.parse_git_log_from_iter(gitshow))
384+
385+
if include_patch_id:
386+
import subprocess
387+
for commit in commits:
388+
try:
389+
commit_hash = commit['data']['commit']
390+
result = subprocess.check_output(
391+
f"git show {commit_hash} | git patch-id",
392+
shell=True,
393+
cwd=repo.path
394+
)
395+
patch_id = result.decode().split()[0]
396+
commit['data']['patch_id'] = patch_id
397+
except Exception:
398+
commit['data']['patch_id'] = None
399+
400+
return commits
342401

343402
def __fetch_from_packs(self, repo, packs, from_commit):
344403
"""Retrieve commits from packfiles starting with the pack containing from_commit"""

0 commit comments

Comments
 (0)