2020
2121# Committing to git and obtaining timestamps
2222
23- import datetime
23+ from datetime import datetime , timezone
2424import logging as _logging
25+ from pathlib import Path
2526import subprocess
2627import sys
2728import threading
@@ -53,12 +54,15 @@ def cross_timestamp(repo, branch, server):
5354 % (branch , server ))
5455
5556
56- def has_changes (repo ):
57+ def has_user_changes (repo ):
5758 """Check whether there are uncommitted changes, i.e., whether
58- `git status -z` has any output."""
59+ `git status -z` has any output. A modification of only `pgp-timestamp.sig`
60+ is ignored, as it is neither necessary nor desirable to trigger on it:
61+ (a) our own timestamp is not really needed on it and
62+ (b) it would cause an unnecessary second timestamp per idle force period."""
5963 ret = subprocess .run (['git' , 'status' , '-z' ],
6064 cwd = repo , capture_output = True , check = True )
61- return len (ret .stdout ) > 0
65+ return len (ret .stdout ) > 0 and ret . stdout != b' M pgp-timestamp.sig \0 '
6266
6367
6468def pending_merge (repo ):
@@ -69,7 +73,7 @@ def pending_merge(repo):
6973def commit_current_state (repo ):
7074 """Force a commit; will be called only if a commit has to be made.
7175 I.e., if there really are changes or the force duration has expired."""
72- now = datetime .datetime . now (datetime . timezone .utc )
76+ now = datetime .now (timezone .utc )
7377 nowstr = now .strftime ('%Y-%m-%d %H:%M:%S UTC' )
7478 subprocess .run (['git' , 'add' , '.' ],
7579 cwd = repo , check = True )
@@ -85,9 +89,9 @@ def head_older_than(repo, duration):
8589 r = git .Repository (repo )
8690 if r .head_is_unborn :
8791 return False
88- now = datetime .datetime . utcnow ()
89- if datetime .datetime . utcfromtimestamp (r . head . peel (). commit_time ) + duration < now :
90- return True
92+ now = datetime .utcnow ()
93+ return datetime .utcfromtimestamp (
94+ r . head . peel (). commit_time ) + duration < now
9195
9296
9397def do_commit ():
@@ -108,18 +112,18 @@ def do_commit():
108112 # Allow 5% of an interval tolerance, such that small timing differences
109113 # will not lead to lengthening the duration by one commit_interval
110114 force_interval = (autoblockchainify .config .arg .commit_interval
111- * (autoblockchainify .config .arg .force_after_intervals - 0.05 ))
115+ * (autoblockchainify .config .arg .force_after_intervals - 0.05 ))
112116 try :
113117 repo = autoblockchainify .config .arg .repository
114118 # If a merge (a manual process on the repository) is detected,
115119 # try to not interfere with the manual process and wait for the
116120 # next forced update
117- if ((has_changes (repo ) and not pending_merge (repo ))
121+ if ((has_user_changes (repo ) and not pending_merge (repo ))
118122 or head_older_than (repo , force_interval )):
119123 # 1. Commit
120124 commit_current_state (repo )
121125
122- # 2. Timestamp using Zeitgitter
126+ # 2. Timestamp (synchronously) using Zeitgitter
123127 repositories = autoblockchainify .config .arg .push_repository
124128 branches = autoblockchainify .config .arg .push_branch
125129 for r in autoblockchainify .config .arg .zeitgitter_servers :
@@ -132,15 +136,14 @@ def do_commit():
132136 logging .info ("Pushing upstream to %s" % r )
133137 push_upstream (repo , r , branches )
134138
135- # 4. Timestamp by mail (asynchronous )
139+ # 4. Timestamp by mail (asynchronously )
136140 if autoblockchainify .config .arg .stamper_own_address :
137- logging .info ("cross-timestamping by mail" )
138- autoblockchainify .mail .async_email_timestamp ()
141+ autoblockchainify .mail .async_email_timestamp (wait = force_interval )
139142
140- logging .info ("do_commit done" )
143+ logging .info ("do_commit done" )
141144 except Exception as e :
142145 logging .error ("Unhandled exception in do_commit() thread: %s: %s" %
143- (e , '' .join (traceback .format_tb (sys .exc_info ()[2 ]))))
146+ (e , '' .join (traceback .format_tb (sys .exc_info ()[2 ]))))
144147
145148
146149def loop ():
0 commit comments