1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
import os, time
from pygit2 import Repository, Signature
from binascii import b2a_hex
class Fit:
def __init__(self, path):
self.repo = Repository(path)
def _insert_node(self, node_oid, path, root_oid):
filename = os.path.basename(path)
if root_oid:
root = self.repo.TreeBuilder(root_oid)
current_node = self.repo[root_oid]
else:
root = self.repo.TreeBuilder()
current_node = root.write()
entries = path.split('/')[:-1]
entries.reverse()
# search for existing nodes in path
tree_path = [('/', root)]
while len(entries) > 0:
if entries[-1] not in current_node:
break
entry = entries.pop()
current_node = self.repo[current_node[entry].oid]
tree_path.append((
entry, self.repo.TreeBuilder(current_node.oid)
))
# create node
if len(entries) > 0:
tmp = self.repo.TreeBuilder()
elif len(tree_path) > 0:
tmp = tree_path[-1][1]
else:
tmp = root
tmp.insert(filename, node_oid, 0100644)
current = tmp.write()
# create new nodes bottom-up for our node
size = len(entries)
for i, entry in enumerate(entries):
if i < (size - 1):
tmp = self.repo.TreeBuilder()
tmp.insert(entry, current, 040000)
current = tmp.write()
else:
tree_path.append((entry, None))
# connect existing nodes with created nodes
pre = tree_path.pop()[0]
tree_path.reverse()
for name, builder in tree_path:
builder.insert(pre, current, 040000)
current = builder.write()
pre = name
return current
def _get_last_commit(self):
head = self.repo.lookup_reference('HEAD').resolve()
return self.repo[head.oid]
def add_file(self, data, git_path, tags):
try:
commit = self._get_last_commit()
parents = [commit.oid]
root = commit.tree.oid
except:
parents = []
root = None
blob_oid = self.repo.create_blob(data)
root = self._insert_node(blob_oid, git_path, root)
filename = os.path.basename(git_path)
for tag in tags:
name = 'tags/%s/%s' % (tag, filename)
root = self._insert_node(blob_oid, name, root)
author = committer = Signature('Fit', 'Fit@fit.de', int(time.time()), 120)
commit = self.repo.create_commit(
'HEAD',
author,
committer,
'added %s' % git_path,
root,
parents
)
return b2a_hex(commit).decode('ascii')
def get_all_files(self):
try:
commit = self._get_last_commit()
files = commit.tree['files'].to_object()
return ((x.name, x.hex) for x in files)
except:
return []
def get_file(self, oid):
return self.repo[oid].data
def get_all_tags(self):
try:
commit = self._get_last_commit()
tags = commit.tree['tags'].to_object()
return ((x.name, x.hex) for x in tags)
except:
return []
def get_files_for_tags(self, tags):
try:
commit = self._get_last_commit()
tree = commit.tree['tags'].to_object()
entries = [ tree[x.encode('ascii')].to_object() for x in tags]
add = lambda x,y: x+y
return reduce(add,
map(lambda entry: [ (x.name, x.hex) for x in entry ],entries)
)
except:
return []
def get_file_with_tags(self, oid):
tags = []
for name, tag_oid in fit.get_all_tags():
for entry in self.repo[tag_oid]:
if entry.oid == oid:
tags.append((name, tag_oid))
return tags
#fit = Fit('tmp/fit')
#fit.add_file('main.c', 'files/main.c', ['alp2', '2007'])
#
#print("All files")
#for name, oid in fit.get_all_files():
# tags = ','.join(map(lambda x: x[0], fit.get_file_with_tags(oid)))
# print("* %s (%s)" % (name, tags))
# #print(fit.get_file(oid) + "\n")
#
#print("\nAll tags")
#for name, oid in fit.get_all_tags():
# files = ','.join(map(lambda x: x[0], fit.get_files_for_tags([name])))
# print("* %s (%s)" % (name, files))
|