13
13
14
14
15
15
def extract_repo_name (repo : Repo , remote : str = "origin" ) -> str :
16
+ """Extract the GitHub organization and repository name.
17
+
18
+ Assumes that the local repo has an appropriately configured remote named `origin`.
19
+ """
16
20
origin = repo .remote ("origin" )
17
21
parsed_url = urlparse (origin .url )
18
22
return parsed_url .path .rsplit (":" , 1 )[- 1 ].removesuffix (".git" )
19
23
20
24
21
25
def iter_blobs (item : Diff ) -> Generator [BlobDTO , None , None ]:
26
+ """Iterate through diff items and produce blobs."""
22
27
match (item .change_type ):
23
28
case "A" :
24
29
# File added
@@ -80,7 +85,17 @@ def iter_blobs(item: Diff) -> Generator[BlobDTO, None, None]:
80
85
81
86
82
87
def build_trees (blobs : list [BlobDTO ]) -> TreeDTO :
83
- """Build the tree structure from a list of blobs."""
88
+ """Build the tree structure from a list of blobs.
89
+
90
+ Technically, this function is not needed because the GitHub API supports
91
+ creating a nested tree in a single operation (and we use this feature).
92
+
93
+ However, this API detail was not obvious from documentation so the original
94
+ implementation created trees recursively and the DTOs still reflect this
95
+ possibility. Since these DTOs are more-or-less faithful to git's own object
96
+ model, removing the `Tree` structure would make the DTOs a bit less clear,
97
+ even if it removed a step.
98
+ """
84
99
trees : dict [Path , TreeDTO ] = {}
85
100
86
101
# Create the root tree
@@ -108,6 +123,7 @@ def build_trees(blobs: list[BlobDTO]) -> TreeDTO:
108
123
109
124
110
125
def find_parent (commit : Commit ) -> Commit :
126
+ """Find the parent of a commit."""
111
127
if not commit .parents :
112
128
raise ValueError ("Cannot create a repo's initial commit." )
113
129
@@ -118,17 +134,20 @@ def find_parent(commit: Commit) -> Commit:
118
134
119
135
120
136
def extract_message (commit : Commit ) -> str :
137
+ """Extract the commit message of a commit."""
121
138
if isinstance (commit .message , str ):
122
139
return commit .message
123
140
else :
124
141
return commit .message .decode ("utf-8" )
125
142
126
143
127
144
def read_repo (repo_path : Path ) -> Repo :
145
+ """Read a repo from a path."""
128
146
return Repo (repo_path )
129
147
130
148
131
149
def read_commit (repo : Repo , ref : str ) -> CommitDTO :
150
+ """Read a local commit into a DTO representaiton."""
132
151
# Find the commit at the given ref in the local repo.
133
152
commit = repo .commit (ref )
134
153
0 commit comments