home » zplus/clif.git
Author zPlus <zplus@peers.community> 2022-08-03 11:42:43
Committer zPlus <zplus@peers.community> 2022-08-03 11:42:43
Commit 3c8acc1 (patch)
Tree f09d22f
Parent(s)

Fix "ref not found" error when committing to empty repository. When new emails are sent to a newly created list repository, HEAD points to a non-existent reference refs/heads/master. It was thus impossible to commit with a non-existent parent commit. This has been fixed by committing the first commit with no parents.


commits diff: d184290..3c8acc1
1 file changed, 40 insertions, 30 deletionsdownload


Diffstat
-rwxr-xr-x emails.py 70

Diff options
View
Side
Whitespace
Context lines
Inter-hunk lines
+40/-30 M   emails.py
index 032b532..4a6de1a
old size: 11K - new size: 11K
@@ -16,8 +16,6 @@ import smtplib
16 16 import sys
17 17
18 18
19 -
20 -
21 19 ###############################################################################
22 20 # SETTINGS
23 21 ###############################################################################
@@ -99,7 +97,7 @@ repository_name = email_to[1].rsplit('@', 1)[0]
99 97 request_subscribe = repository_name.endswith('+subscribe')
100 98 request_unsubscribe = repository_name.endswith('+unsubscribe')
101 99
102 - # Remove leading command: from address
100 + # Remove command from address
103 101 if request_subscribe: repository_name = repository_name[:-10]
104 102 if request_unsubscribe: repository_name = repository_name[:-12]
105 103
@@ -127,8 +125,8 @@ except:
127 125 try:
128 126 head_tree = repo.revparse_single('HEAD').tree
129 127 except:
130 - logging.error('Could not find HEAD ref: {}'.format(repository_path))
131 - exit()
128 + logging.warning('Could not find HEAD ref: {}'.format(repository_path))
129 + head_tree = None
132 130
133 131 try:
134 132 subscribers = []
@@ -138,7 +136,7 @@ try:
138 136 subscribers.append(addr)
139 137 except:
140 138 subscribers = []
141 - logging.info('Subscribers file not found in {}'.format(repository_path))
139 + logging.info('Subscribers file not found or invalid: {}'.format(repository_path))
142 140
143 141
144 142
@@ -147,14 +145,16 @@ except:
147 145 # LISTS SUBSCRIPTION
148 146 ###############################################################################
149 147
150 - if request_subscribe \
151 - and email_from[1] in subscribers:
148 + if request_subscribe and (email_from[1] in subscribers):
152 149 # Already subscribed
150 +
151 + logging.info('Already subscribed to {}: {}'.format(repository_path, email_from))
153 152 exit()
154 153
155 - if request_unsubscribe \
156 - and email_from[1] not in subscribers:
157 - # No address to removed
154 + if request_unsubscribe and (email_from[1] not in subscribers):
155 + # No address to remove
156 +
157 + logging.info('Already unsubscribed from {}: {}'.format(repository_path, email_from))
158 158 exit()
159 159
160 160 if request_subscribe or request_unsubscribe:
@@ -170,19 +170,24 @@ if request_subscribe or request_unsubscribe:
170 170 oid = repo.create_blob('\n'.join(subscribers).encode('UTF-8'))
171 171
172 172 # Add the blob that we've just created to the HEAD tree
173 - head_tree_builder = repo.TreeBuilder(head_tree)
173 + head_tree_builder = repo.TreeBuilder(head_tree) if head_tree else repo.TreeBuilder()
174 174 head_tree_builder.insert('subscribers', oid, pygit2.GIT_FILEMODE_BLOB)
175 175 head_tree_oid = head_tree_builder.write()
176 176
177 177 repo.create_commit(
178 - repo.head.name, # reference name
178 + 'HEAD', # reference name
179 179 pygit2.Signature('CLIF', '-'), # author
180 180 pygit2.Signature('CLIF', '-'), # committer
181 181 commit_message, # message
182 182 head_tree_oid, # tree of this commit
183 - [ repo.head.target ] # parents commit
183 + [] if repo.is_empty else [ repo.head.target ] # parents commit
184 184 )
185 185
186 + if request_subscribe:
187 + logging.info('Subscribed to {}: {}'.format(repository_path, email_from))
188 + if request_unsubscribe:
189 + logging.info('Unsubscribed from {}: {}'.format(repository_path, email_from))
190 +
186 191 exit()
187 192
188 193
@@ -218,19 +223,24 @@ thread_title = '{} {} {}'.format(
218 223 )
219 224
220 225 if email_in_reply_to:
221 - # The hash of the email that is being replied to
222 - parent_message_hash = hashlib.sha256(email_in_reply_to.encode('utf-8')).hexdigest()[:8]
223 -
224 - # Find the thread (tree) containing the parent message
225 - for obj in head_tree:
226 - if obj.type_str == 'tree' and parent_message_hash + '.email' in obj:
227 - thread_tree = obj
228 - thread_title = obj.name
229 - break
230 -
231 - # We only accept emails in reply to existing messages
232 - if not thread_tree:
233 - logging.debug('In-Reply-To ID not found in repository: {}'.format(email_in_reply_to))
226 + try:
227 + assert head_tree
228 +
229 + # The hash of the email that is being replied to
230 + parent_message_hash = hashlib.sha256(email_in_reply_to.encode('utf-8')).hexdigest()[:8]
231 +
232 + # Find the thread (tree) containing the parent message
233 + for obj in head_tree:
234 + if obj.type_str == 'tree' and parent_message_hash + '.email' in obj:
235 + thread_tree = obj
236 + thread_title = obj.name
237 + break
238 +
239 + assert thread_tree
240 +
241 + except:
242 + # We only accept emails as reply to existing messages
243 + logging.debug('In-Reply-To message ID not found in repository: {}'.format(email_in_reply_to))
234 244 exit()
235 245
236 246 # Add the new email BLOB to the git store
@@ -242,17 +252,17 @@ thread_tree_builder.insert(email_id_hash + '.email', message_oid, pygit2.GIT_FIL
242 252 thread_tree_oid = thread_tree_builder.write()
243 253
244 254 # Add the thread tree to the HEAD tree
245 - head_tree_builder = repo.TreeBuilder(head_tree)
255 + head_tree_builder = repo.TreeBuilder(head_tree) if head_tree else repo.TreeBuilder()
246 256 head_tree_builder.insert(thread_title, thread_tree_oid, pygit2.GIT_FILEMODE_TREE)
247 257 head_tree_oid = head_tree_builder.write()
248 258
249 259 repo.create_commit(
250 - repo.head.name, # reference name
260 + 'HEAD', # reference name
251 261 pygit2.Signature('CLIF', '-'), # author
252 262 pygit2.Signature('CLIF', '-'), # committer
253 263 'New email.', # message
254 264 head_tree_oid, # tree of this commit
255 - [ repo.head.target ] # parents commit
265 + [] if repo.is_empty else [ repo.head.target ] # parents commit
256 266 )
257 267
258 268