X-Git-Url: https://git.ralfj.de/git-mirror.git/blobdiff_plain/9e8ef5ff99e70c7cc97445acbd91abaf539fd536..2b00eaa147818ccfd68a1466d28c41995accef7d:/git_mirror.py?ds=sidebyside diff --git a/git_mirror.py b/git_mirror.py index a3b7fe9..12075bf 100644 --- a/git_mirror.py +++ b/git_mirror.py @@ -27,6 +27,7 @@ import hmac, hashlib import email.mime.text, email.utils, smtplib mail_sender = "null@localhost" +config_file = os.path.join(os.path.dirname(__file__), 'git-mirror.conf') class GitCommand: def __getattr__(self, name): @@ -53,10 +54,10 @@ def git_is_forced_update(oldsha, newsha): assert code in (0, 1) return False if code == 0 else True # if oldsha is an ancestor of newsha, then this was a "good" (non-forced) update -def read_config(fname, defSection = 'DEFAULT'): +def read_config(defSection = 'DEFAULT'): '''Reads a config file that may have options outside of any section.''' config = configparser.ConfigParser() - with open(fname) as file: + with open(config_file) as file: stream = itertools.chain(("["+defSection+"]\n",), file) config.read_file(stream) return config @@ -83,7 +84,7 @@ class Repo: self.name = name self.local = conf['local'] self.owner = conf['owner'] # email address to notify in case of problems - self.hmac_secret = conf['hmac-secret'].encode('utf-8') + self.hmac_secret = conf['hmac-secret'].encode('utf-8') if 'hmac-secret' in conf else None self.deploy_key = conf['deploy-key'] # the SSH ky used for authenticating against remote hosts self.mirrors = {} # maps mirrors to their URLs mirror_prefix = 'mirror-' @@ -96,6 +97,7 @@ class Repo: send_mail("git-mirror {}".format(self.name), msg, recipients = [self.owner], sender = mail_sender) def compute_hmac(self, data): + assert self.hmac_secret is not None h = hmac.new(self.hmac_secret, digestmod = hashlib.sha1) h.update(data) return h.hexdigest() @@ -153,7 +155,8 @@ class Repo: if len(local_state): raise Exception("Something went wrong getting the local state of {}.".format(ref)) local_sha = git_nullsha - assert local_sha in (oldsha, newsha), "Someone lied about the old SHA." + # some sanity checking, but deal gracefully with new branches appearing + assert local_sha in (git_nullsha, oldsha, newsha), "Someone lied about the old SHA: Local ({}) is neither old ({}) nor new ({})".format(local_sha, oldsha, newsha) # if we are already at newsha locally, we also ran the local hooks, so we do not have to do anything if local_sha == newsha: return "Local repository is already up-to-date." @@ -174,7 +177,7 @@ class Repo: # Now run the post-receive hooks. This will *also* push the changes to all mirrors, as we # are one of these hooks! os.putenv("GIT_MIRROR_SOURCE", mirror) # tell ourselves which repo we do *not* have to update - with subprocess.Popen(['/bin/sh', 'hooks/post-receive'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as p: + with subprocess.Popen(['hooks/post-receive'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as p: (stdout, stderr) = p.communicate("{} {} {}\n".format(oldsha, newsha, ref).encode('utf-8')) stdout = stdout.decode('utf-8') if p.returncode: @@ -189,8 +192,7 @@ def find_repo_by_directory(repos, dir): def load_repos(): global mail_sender - conffile = os.path.join(os.path.dirname(__file__), 'git-mirror.conf') - conf = read_config(conffile) + conf = read_config() mail_sender = conf['DEFAULT']['mail-sender'] repos = {}