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
|
# Git wrapper for repo/tree/index manipulation
#
# Copyright 2016, 2018—2022 Andrej Shadura <andrew@shadura.me>
#
# This software may be used and distributed according to the terms of
# the GNU General Public License, incorporated herein by reference.
#
# SPDX-License-Identifier: GPL-2.0-or-later
from __future__ import annotations
import os
import sys
from pathlib import Path
from . import util
INDEX_FILENAME = "index"
ObjectHash = str
class GitTree:
def __init__(self, tree):
self._tree = tree
def __repr__(self):
return "%s(%r)" % (self.__class__.__name__, self._tree)
def read(self):
util.system(['git', 'read-tree', '--reset',
self._tree], onerr=RuntimeError)
class GitIndex:
def __init__(self, filename):
self._filename = filename
self.indextree = None
def __repr__(self):
return "%s(%r, %r)" % (self.__class__.__name__, self._filename, self.indextree)
def commit(self) -> ObjectHash:
return util.systemcall(
['git', 'write-tree'],
onerr=RuntimeError,
encoding="ascii",
).rstrip('\n')
def write(self):
GitTree(self.indextree).read()
def backup_tree(self) -> ObjectHash:
try:
self.indextree = self.commit()
except RuntimeError as inst:
raise util.Abort('failed to read the index: %s' % inst)
return self.indextree
class GitRepo:
def __init__(self, path: os.PathLike | str | None):
try:
self.path = Path(util.systemcall(
['git', 'rev-parse', '--show-toplevel'],
dir=path,
encoding="fs",
onerr=util.Abort
).rstrip('\n'))
self._controldir = Path(util.systemcall(
['git', 'rev-parse', '--git-dir'],
dir=path,
encoding="fs",
).rstrip('\n'))
if not self._controldir.is_dir():
raise util.Abort
except util.Abort:
sys.exit(1)
def __repr__(self):
return "%s(%s)" % (self.__class__.__name__, self.path)
@property
def controldir(self) -> Path:
return self._controldir.resolve()
@property
def index_path(self) -> Path:
return self.controldir / INDEX_FILENAME
def open_index(self) -> GitIndex:
return GitIndex(self.index_path)
def head(self) -> ObjectHash:
return util.systemcall(
['git', 'rev-parse', '--verify', '-q', 'HEAD'],
encoding="ascii",
).rstrip('\n')
|