Skip to content

Commit ab91b26

Browse files
committed
initbare and mktemplate
1 parent b63e4d5 commit ab91b26

3 files changed

Lines changed: 78 additions & 48 deletions

File tree

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ incrypt-plugin.so: git/incrypt-plugin.so
2828
cp $< $@
2929

3030
git/incrypt-plugin.so: git/incrypt-plugin.c git/config.mak
31-
$(MAKE) -C $(@D) DEVELOPER:=1 $(@F)
31+
$(MAKE) -C $(@D) prefix:=/usr DEVELOPER:=1 $(@F)
3232

3333
git/%.c: %.c
3434
cp $< $@
@@ -38,7 +38,7 @@ man1/%.1: git/Documentation/%.1
3838
cp $< $@
3939

4040
git/Documentation/%.1: git/Documentation/%.adoc git/config.mak
41-
$(MAKE) -C $(@D) DEVELOPER:=1 $(@F)
41+
$(MAKE) -C $(@D) prefix:=/usr DEVELOPER:=1 $(@F)
4242

4343
git/Documentation/%.adoc: %.adoc
4444
cp $< $@

git-incrypt

Lines changed: 47 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,15 @@ plugin.set_option.argtypes = [ctypes.c_char_p, ctypes.c_size_t,
4848
plugin.geturl.restype = ctypes.c_char_p
4949
plugin.getprefix.restype = ctypes.c_char_p
5050
plugin.hashdata.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
51-
plugin.hashdatahex.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_char_p]
51+
plugin.hashdatahex.argtypes = [ctypes.c_void_p, ctypes.c_size_t,
52+
ctypes.c_char_p]
5253
plugin.hashdatahex.restype = ctypes.c_char_p
53-
plugin.globalinit.argtypes = [ctypes.c_char_p]
54+
plugin.globalinit.argtypes = [ctypes.c_char_p, ctypes.c_char_p]
55+
plugin.initbare.argtypes = [ctypes.c_char_p]
56+
plugin.mktemplate.argtypes = [ctypes.c_char_p, ctypes.c_char_p,
57+
ctypes.c_char_p, ctypes.c_char_p,
58+
ctypes.c_char_p]
59+
plugin.mktemplate.restype = ctypes.c_char_p
5460

5561
if not hasattr(pygit2.enums, 'FileMode'):
5662
class FileMode(enum.IntFlag):
@@ -157,44 +163,30 @@ class CryptRepo:
157163

158164
def __init__(self, clearname, url, init=None, forcetrust=False):
159165
assert clearname, 'This does not work yet outside a git repository'
160-
plugin.globalinit(url.encode('utf-8'))
166+
plugin.globalinit(clearname.encode('utf-8'), url.encode('utf-8'))
161167
if init:
162-
self.repo = pygit2.init_repository(clearname, bare=True)
163-
template = self._mktemplate(init.name, init.email,
164-
init.date, init.m)
168+
plugin.initbare(clearname.encode('utf-8'))
169+
output = ctypes.create_string_buffer(41)
170+
poutput = ctypes.c_char_p(ctypes.addressof(output))
171+
plugin.mktemplate(
172+
init.name.encode('utf-8') if init.name else None,
173+
init.email.encode('utf-8') if init.email else None,
174+
init.date.encode('utf-8') if init.date else None,
175+
'\n\n'.join(init.m).encode('utf-8') if init.m else None,
176+
poutput)
177+
self.repo = pygit2.Repository('.')
178+
template = self.repo.get(
179+
output.value.decode('utf-8')).read_raw().split(b'\n', 1)[1]
165180
self.meta = MetaData(self.repo).init(
166181
init.keys, template, 'refs/heads/master')
167182
self.trust(force=True, sign=True)
168183
else:
169-
self.repo = pygit2.Repository(clearname)
184+
self.repo = pygit2.Repository('.')
170185
self._fetch('_')
171186
self.meta = MetaData(self.repo).read()
172187
if forcetrust:
173188
self.trust(force=forcetrust)
174189

175-
def _mktemplate(self, name, email, date, messages):
176-
'create a template commit'
177-
if not messages:
178-
messages = ['Encrypted by git-incrypt.',
179-
'https://github.com/schiele/git-incrypt']
180-
env = os.environ.copy()
181-
if name:
182-
env['GIT_AUTHOR_NAME'] = name
183-
env['GIT_COMMITTER_NAME'] = name
184-
if email:
185-
env['GIT_AUTHOR_EMAIL'] = email
186-
env['GIT_COMMITTER_EMAIL'] = email
187-
if date:
188-
env['GIT_AUTHOR_DATE'] = date
189-
env['GIT_COMMITTER_DATE'] = date
190-
templateid = subprocess.check_output(
191-
['git', 'commit-tree'] +
192-
[x for m in messages for x in ('-m', m)] +
193-
['4b825dc642cb6eb9a060e54bf8d69288fbee4904'],
194-
cwd=self.repo.path, env=env).decode('utf-8').strip()
195-
template = self.repo.get(templateid).read_raw().split(b'\n', 1)[1]
196-
return template
197-
198190
def _progress_for(self, what, iterable, function):
199191
'iterate over iterable and show progress'
200192
def update():
@@ -244,7 +236,8 @@ class CryptRepo:
244236
CryptRepo.verbosityflags[plugin.getverbosity()],
245237
'--progress' if plugin.getprogress() else '--no-progress',
246238
'--no-write-fetch-head', '-p', plugin.geturl().decode('utf-8'),
247-
f'+refs/heads/{pattern}:{plugin.getprefix().decode("utf-8")}1/{pattern}'],
239+
f'+refs/heads/{pattern}:{
240+
plugin.getprefix().decode("utf-8")}1/{pattern}'],
248241
cwd=self.repo.path, check=True, stdout=sys.stderr)
249242

250243
def trust(self, force=False, sign=False):
@@ -289,8 +282,10 @@ class CryptRepo:
289282
refs = [[r[0], plugin.getprefix().decode('utf-8') + '0/' + r[0],
290283
self.repo.revparse_single(r[1])]
291284
for r in [[decryptrefname(r, self.meta.key), r] for r in
292-
filter(lambda r: len(r) > len(plugin.getprefix().decode('utf-8'))+3 and
293-
r.startswith(plugin.getprefix().decode('utf-8') + '1/'),
285+
filter(lambda r: len(r) >
286+
len(plugin.getprefix().decode('utf-8'))+3 and
287+
r.startswith(plugin.getprefix().
288+
decode('utf-8') + '1/'),
294289
self.repo.references)]]
295290
cryptmap = self.meta.readmap(reverse=True)
296291
self._progress_for(
@@ -307,8 +302,9 @@ class CryptRepo:
307302
for r in self.repo.references:
308303
if r.startswith(plugin.getprefix().decode('utf-8') + '0/'):
309304
if r in expected:
310-
result.append([r[len(plugin.getprefix().decode('utf-8'))+2:],
311-
self.repo.lookup_reference(r).target])
305+
result.append(
306+
[r[len(plugin.getprefix().decode('utf-8'))+2:],
307+
self.repo.lookup_reference(r).target])
312308
else:
313309
self.repo.references.delete(r)
314310
return result
@@ -353,7 +349,8 @@ class CryptRepo:
353349
else [cryptmap[str(obj.target)]])
354350

355351
xrefs = [[r[0], r[1], r[3], ('+' if r[2] else '') +
356-
(plugin.getprefix().decode('utf-8') + '1/' + r[3] if r[0] else '') +
352+
(plugin.getprefix().decode('utf-8') + '1/' +
353+
r[3] if r[0] else '') +
357354
':refs/heads/' + r[3],
358355
self.repo.revparse_single(r[0]) if r[0] else None]
359356
for r in [[r[0], r[1], r[2],
@@ -372,11 +369,12 @@ class CryptRepo:
372369
for r in xrefs:
373370
if r[4]:
374371
self.repo.create_reference(
375-
plugin.getprefix().decode('utf-8') + '1/' + r[2], cryptmap[str(r[4].id)],
376-
force=True)
372+
plugin.getprefix().decode('utf-8') + '1/' + r[2],
373+
cryptmap[str(r[4].id)], force=True)
377374
else:
378375
try:
379-
self.repo.references.delete(plugin.getprefix().decode('utf-8') + '1/' + r[2])
376+
self.repo.references.delete(
377+
plugin.getprefix().decode('utf-8') + '1/' + r[2])
380378
except KeyError:
381379
pass
382380
resdict = {}
@@ -388,7 +386,8 @@ class CryptRepo:
388386
else '--no-progress', '--porcelain'] +
389387
(['--atomic'] if plugin.getatomic() else []) +
390388
[plugin.geturl().decode('utf-8'), '+' +
391-
plugin.getprefix().decode('utf-8') + '1/_:' + MetaData.REFNAME] +
389+
plugin.getprefix().decode('utf-8') + '1/_:' +
390+
MetaData.REFNAME] +
392391
[r[3] for r in xrefs],
393392
cwd=self.repo.path, check=False, text=True,
394393
stdout=subprocess.PIPE,
@@ -512,7 +511,8 @@ class MetaData:
512511
def read(self):
513512
'read the metadata'
514513
self.files = {}
515-
tree = self.repo.revparse_single(plugin.getprefix().decode('utf-8') + '1/_').tree
514+
tree = self.repo.revparse_single(
515+
plugin.getprefix().decode('utf-8') + '1/_').tree
516516
obj = tree['ver']
517517
self.files['ver'] = obj.id
518518
data = obj.read_raw()
@@ -604,16 +604,19 @@ class MetaData:
604604
mapfile = self.repo.create_blob(encryptdata(
605605
sha1(rawdata) + rawdata, self.key))
606606
collector.insert('map', mapfile, pygit2.enums.FileMode.BLOB)
607-
readmefile = self.repo.create_blob(ctypes.c_char_p.in_dll(plugin, 'CRYPTREADME').value)
607+
readmefile = self.repo.create_blob(
608+
ctypes.c_char_p.in_dll(plugin, 'CRYPTREADME').value)
608609
collector.insert('README.md', readmefile, pygit2.enums.FileMode.BLOB)
609610
colid = collector.write()
610611
commit = self.secretcommit(colid, [])
611-
self.repo.create_reference(plugin.getprefix().decode('utf-8') + '1/_', commit, force=True)
612+
self.repo.create_reference(
613+
plugin.getprefix().decode('utf-8') + '1/_', commit, force=True)
612614
return self
613615

614616
def readmap(self, reverse=False):
615617
'read the mapping table'
616-
tree = self.repo.revparse_single(plugin.getprefix().decode('utf-8') + '1/_').tree
618+
tree = self.repo.revparse_single(
619+
plugin.getprefix().decode('utf-8') + '1/_').tree
617620
o = 20 if reverse else 0
618621
processed = {}
619622
rawdata = decryptdata(tree['map'].read_raw(), self.key)

incrypt-plugin.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
#include "git-compat-util.h"
1212
#include "hash.h"
1313
#include "hex.h"
14+
#include "setup.h"
15+
#include "ident.h"
1416

15-
void globalinit(const char* url_arg);
17+
void globalinit(const char* dir, const char* url_arg);
1618
int set_option(const char *name, size_t namelen, const char *value);
1719
int getverbosity(void);
1820
int getprogress(void);
@@ -30,6 +32,8 @@ unsigned char* hashdata(const unsigned char* input, size_t inputlen,
3032
unsigned char* output);
3133
char* hashdatahex(const unsigned char* input, size_t inputlen,
3234
char* output);
35+
void initbare(const char* dir);
36+
char* mktemplate(const char* name, const char* email, const char* date, const char* msg, char* output);
3337

3438
/*static*/ const char* CRYPTREADME = "# 401 Unauthorized\n\n"
3539
"This is an encrypted git repository. You can clone it, but you will not be\n"
@@ -47,8 +51,9 @@ static struct options options;
4751
static char* url = NULL;
4852
static char prefix[] = "refs/incrypt/......................................../";
4953

50-
void globalinit(const char* url_arg) {
54+
void globalinit(const char* dir, const char* url_arg) {
5155
size_t urllen = strlen(url_arg);
56+
chdir(dir);
5257
options.verbosity = 1;
5358
options.progress = !!isatty(2);
5459
options.atomic = 0;
@@ -320,6 +325,28 @@ char* hashdatahex(const unsigned char* input, size_t inputlen, char* output) {
320325
return hash_to_hex_algop_r(output, hash, &hash_algos[GIT_HASH_SHA1]);
321326
}
322327

328+
void initbare(const char* dir) {
329+
init_db(dir, NULL, NULL, GIT_HASH_UNKNOWN, REF_STORAGE_FORMAT_UNKNOWN, NULL, -1, 0);
330+
}
331+
332+
char* mktemplate(const char* name, const char* email, const char* date, const char* msg, char* output) {
333+
struct object_id ret;
334+
int res;
335+
if (!msg)
336+
msg = "Encrypted by git-incrypt.\n\n"
337+
"https://github.com/schiele/git-incrypt\n";
338+
res = commit_tree_extended(msg, strlen(msg),
339+
hash_algos[GIT_HASH_SHA1].empty_tree,
340+
NULL, &ret,
341+
fmt_ident(name?name:getenv("GIT_AUTHOR_NAME"), email?email:getenv("GIT_AUTHOR_EMAIL"), WANT_AUTHOR_IDENT, date?date:getenv("GIT_AUTHOR_DATE"), 0),
342+
fmt_ident(name?name:getenv("GIT_COMMITTER_NAME"), email?email:getenv("GIT_COMMITTER_EMAIL"), WANT_COMMITTER_IDENT, date?date:getenv("GIT_COMMITTER_DATE"), 0),
343+
NULL, NULL);
344+
if (res != 0)
345+
return NULL;
346+
memcpy(output, oid_to_hex(&ret), 41);
347+
return output;
348+
}
349+
323350
int cmd_main(int argc, const char** argv) {
324351
(void)argv;
325352
(void)argc;

0 commit comments

Comments
 (0)