You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
3.1 KiB
142 lines
3.1 KiB
|
|
import sqlite3 |
|
import getopt |
|
import pygit2 |
|
import sys |
|
import time |
|
|
|
if len(sys.argv) != 5: |
|
print("usage: store_history.py -i repo_file -d database.db") |
|
sys.exit(1) |
|
|
|
optlist, args = getopt.getopt(sys.argv[1:], 'i:d:') |
|
repopath = "." |
|
dbpath = "example.db" |
|
|
|
|
|
for o, a in optlist: |
|
if o == '-i': |
|
repopath = a |
|
if o == '-d': |
|
dbpath = a |
|
|
|
|
|
print("repo path:", repopath) |
|
print("databse path:", dbpath) |
|
|
|
repo = pygit2.Repository(repopath) |
|
|
|
|
|
init_query = """ |
|
CREATE TABLE IF NOT EXISTS commits( |
|
sha TEXT PRIMARY KEY, author_name TEXT, author_email TEXT, |
|
commit_time INTEGER, |
|
message TEXT |
|
); |
|
|
|
""" |
|
|
|
init_query2 = """ |
|
CREATE TABLE IF NOT EXISTS deltas( |
|
id INTEGER PRIMARY KEY, |
|
from_sha TEXT, |
|
to_sha TEXT, |
|
new_file_name TEXT, |
|
addition_lines INTEGER, |
|
deletion_lines INTEGER, |
|
type TEXT, |
|
FOREIGN KEY (from_sha) REFERENCES commits(sha), |
|
FOREIGN KEY (to_sha) REFERENCES commits(sha) |
|
); |
|
""" |
|
|
|
init_query3 = """ |
|
CREATE VIEW IF NOT EXISTS full_deltas AS |
|
SELECT commits.*, deltas.* from commits, deltas where deltas.sha = |
|
commits.sha; |
|
""" |
|
|
|
|
|
insert_query = """ |
|
INSERT INTO commits(sha, author_name, author_email, commit_time, message) |
|
VALUES ( |
|
?, ?, ?, ?, ? |
|
); |
|
""" |
|
|
|
insert_delta_query = """ |
|
INSERT INTO deltas(from_sha, to_sha, new_file_name, addition_lines, deletion_lines, type) |
|
VALUES ( |
|
?, ?, ?, ?, ?, ? |
|
); |
|
""" |
|
|
|
|
|
|
|
con = sqlite3.connect(dbpath) |
|
cursor = con.cursor() |
|
cursor.execute(init_query) |
|
cursor.execute(init_query2) |
|
cursor.execute(init_query3) |
|
|
|
con.commit() |
|
|
|
data = [] |
|
deltas = [] |
|
|
|
last_commit = None |
|
first_time = None |
|
last_time = 0 |
|
for commit in repo.walk(repo.head.target, pygit2.GIT_SORT_TIME): |
|
time_t = commit.commit_time |
|
|
|
|
|
sha = str(commit.id) |
|
author_name = commit.author.name |
|
author_email = commit.author.email |
|
print("Found commit", sha, "for", time.asctime(time.gmtime(time_t))) |
|
|
|
if first_time is None: |
|
first_time = time_t |
|
|
|
# stop after one year |
|
if (abs(first_time - time_t) > 31536000): |
|
break |
|
|
|
message = commit.message |
|
data.append((sha, author_name, author_email, time_t, message)) |
|
|
|
if (abs(last_time - time_t) > 24 * 60 * 60): |
|
last_time = time_t |
|
if last_commit is not None: |
|
print("Finding deltas") |
|
diff = repo.diff(last_commit, commit) |
|
|
|
for patch in diff: |
|
file_name = str(patch.delta.new_file.path) |
|
status_char = patch.delta.status_char() |
|
_, additions, deletions = patch.line_stats |
|
deltas.append( |
|
(str(last_commit.id), sha, file_name, additions, deletions, status_char) |
|
) |
|
last_commit = commit |
|
|
|
if (last_commit is None): |
|
last_commit = commit |
|
|
|
if (len(data) + len(deltas) >= 1000): |
|
print("Storing", len(deltas) + len(data), "rows.") |
|
cursor.executemany(insert_query, data) |
|
cursor.executemany(insert_delta_query, deltas) |
|
con.commit() |
|
data = [] |
|
deltas = [] |
|
|
|
|
|
print("Storing", len(deltas) + len(data), "rows.") |
|
cursor.executemany(insert_delta_query, deltas) |
|
cursor.executemany(insert_query, data) |
|
con.commit() |
|
|
|
|
|
|
|
|