123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- # -*- coding: utf-8 -*-
- import collections
- import datetime
- import tempfile
- import subprocess
- import re
- import tarfile
- GitRef = collections.namedtuple('VersionRef', [
- 'name',
- 'commit',
- 'source',
- 'is_remote',
- 'refname',
- 'creatordate',
- ])
- def get_all_refs(gitroot):
- cmd = ("git", "for-each-ref", "--format",
- "%(objectname)\t%(refname)\t%(creatordate:iso)", "refs")
- output = subprocess.check_output(cmd, cwd=gitroot).decode()
- for line in output.splitlines():
- is_remote = False
- fields = line.strip().split("\t")
- if len(fields) != 3:
- continue
- commit = fields[0]
- refname = fields[1]
- creatordate = datetime.datetime.strptime(fields[2], "%Y-%m-%d %H:%M:%S %z")
- # Parse refname
- matchobj = re.match(r"^refs/(heads|tags|remotes/[^/]+)/(\S+)$", refname)
- if not matchobj:
- continue
- source = matchobj.group(1)
- name = matchobj.group(2)
- if source.startswith('remotes/'):
- is_remote = True
- yield GitRef(name, commit, source, is_remote, refname, creatordate)
- def get_refs(gitroot, tag_whitelist, branch_whitelist, remote_whitelist):
- for ref in get_all_refs(gitroot):
- if ref.source == 'tags':
- if tag_whitelist is None or not re.match(tag_whitelist, ref.name):
- continue
- elif ref.source == 'heads':
- if branch_whitelist is None or not re.match(branch_whitelist, ref.name):
- continue
- elif ref.is_remote and remote_whitelist is not None:
- remote_name = ref.source.partition('/')[2]
- if not re.match(remote_whitelist, remote_name):
- continue
- if branch_whitelist is None or not re.match(branch_whitelist, ref.name):
- continue
- else:
- continue
- yield ref
- def copy_tree(src, dst, reference, sourcepath='.'):
- with tempfile.SpooledTemporaryFile() as fp:
- cmd = ("git", "archive", "--format", "tar", reference.commit, "--", sourcepath)
- subprocess.check_call(cmd, stdout=fp)
- fp.seek(0)
- with tarfile.TarFile(fileobj=fp) as tarfp:
- tarfp.extractall(dst)
|