예제 #1
0
def clone_repo_and_checkout_tag(localRepo, bookid, tagname, filename, dest_path):
    repo_home = pathof(localRepo)
    repo_home = repo_home.replace("/", os.sep)
    repo_path = os.path.join(repo_home, "epub_" + bookid)
    dest_path = dest_path.replace("/", os.sep)
    cdir = os.getcwd()
    # first verify both repo and tagname exist
    taglst = []
    if os.path.exists(repo_path):
        if not os.path.exists(dest_path): return ""
        os.chdir(repo_path)
        tags = porcelain.list_tags(repo='.')
        for atag in tags:
            taglst.append(unicode_str(atag))
        # use dest_path to clone into
        # clone current repo "s" into new repo "r"
        with open_repo_closing(".") as s:
            s.clone(dest_path, mkdir=False, bare=False, origin=b"origin", checkout=False)
            # cd out **before** the repo closes
            os.chdir(dest_path)
        with open_repo_closing(".") as r:
            if tagname not in taglist or tagname == "HEAD":
                tagkey = utf8_str("HEAD")
            else:
                tagkey = utf8_str("refs/tags/" + tagname)
            refkey = tagkey
            # if annotated tag get the commit id it pointed to instead
            if isinstance(r[tagkey], Tag):
                refkey = r[tagkey].object[1]
            r.reset_index(r[refkey].tree)
            r.refs.set_symbolic_ref(b"HEAD", tagkey)
            # cd out **before** the repo closes
            os.chdir(cdir)
    return "success"
예제 #2
0
 def __load_repo_metadata(self, repo_url):
     from dulwich import porcelain
     subdir = get_repo_subdir(repo_url)
     repo_dir = os.path.join(self.__beq_dir, subdir)
     commit_url = get_commit_url(repo_url)
     try:
         with porcelain.open_repo_closing(repo_dir) as local_repo:
             last_commit = local_repo[local_repo.head()]
             last_commit_time_utc = last_commit.commit_time
             last_commit_qdt = QDateTime()
             last_commit_qdt.setTime_t(last_commit_time_utc)
             self.lastCommitDate.setDateTime(last_commit_qdt)
             from datetime import datetime
             import calendar
             d = datetime.utcnow()
             now_utc = calendar.timegm(d.utctimetuple())
             days_since_commit = (now_utc - last_commit_time_utc) / 60 / 60 / 24
             warning_msg = ''
             if days_since_commit > 7.0:
                 warning_msg = f" was {round(days_since_commit)} days ago, press the button to update -->"
             commit_link = f"{commit_url}/{last_commit.id.decode('utf-8')}"
             self.infoLabel.setText(f"<a href=\"{commit_link}\">Last Commit</a>{warning_msg}")
             self.infoLabel.setTextFormat(Qt.RichText)
             self.infoLabel.setTextInteractionFlags(Qt.TextBrowserInteraction)
             self.infoLabel.setOpenExternalLinks(True)
             self.lastCommitMessage.setPlainText(
                 f"Author: {last_commit.author.decode('utf-8')}\n\n{last_commit.message.decode('utf-8')}")
     except:
         logger.exception(f"Unable to open git repo in {self.__beq_dir}")
         self.__beq_dir_not_exists(repo_url)
예제 #3
0
def get_tag_list(localRepo, bookid):
    repo_home = pathof(localRepo)
    repo_home = repo_home.replace("/", os.sep)
    repo_path = os.path.join(repo_home, "epub_" + bookid)
    cdir = os.getcwd()
    taglst = []
    if os.path.exists(repo_path):
        os.chdir(repo_path)
        with open_repo_closing(".") as r:
            tags = sorted(r.refs.as_dict(b"refs/tags"))
            for atag in tags:
                tagkey = b"refs/tags/" + atag
                obj = r[tagkey]
                tag_name = unicode_str(atag)
                tag_message = ""
                tag_date = ""
                if isinstance(obj,Tag):
                    time_tuple = time.gmtime(obj.tag_time + obj.tag_timezone)
                    time_str = time.strftime("%a %b %d %Y %H:%M:%S",time_tuple)
                    timezone_str = format_timezone(obj.tag_timezone).decode('ascii')
                    tag_date = time_str + " " + timezone_str
                    tag_message = unicode_str(obj.message)
                if isinstance(obj, Commit):
                    time_tuple = time.gmtime(obj.author_time + obj.author_timezone)
                    time_str = time.strftime("%a %b %d %Y %H:%M:%S",time_tuple)
                    timezone_str = format_timezone(obj.author_timezone).decode('ascii')
                    tag_date = time_str + " " + timezone_str
                    tag_message = unicode_str(obj.message)
                taglst.append(tag_name + "|" + tag_date + "|" + tag_message)
        os.chdir(cdir)
    return taglst
예제 #4
0
def logsummary(repo=".", paths=None, outstream=sys.stdout, max_entries=None, reverse=False, stats=False):
    """Write commit logs with optional diff stat summaries
    Args:
      repo: Path to repository
      paths: Optional set of specific paths to print entries for
      outstream: Stream to write log output to
      reverse: Reverse order in which entries are printed
      max_entries: Optional maximum number of entries to display
      stats: Print diff stats
    """
    with open_repo_closing(repo) as r:
        walker = r.get_walker(max_entries=max_entries, paths=paths, reverse=reverse)
        for entry in walker:
            def decode(x):
                return commit_decode(entry.commit, x)
            print_commit(entry.commit, decode, outstream)
            if stats:
                commit = entry.commit
                if commit.parents:
                    parent_commit = r[commit.parents[0]]
                    base_tree = parent_commit.tree
                else:
                    base_tree = None
                adiff = b""
                with BytesIO() as diffstream:
                    write_tree_diff(
                        diffstream,
                        r.object_store, base_tree, commit.tree)
                    diffstream.seek(0)
                    adiff = diffstream.getvalue()
                dsum = diffstat(adiff.split(b'\n'))
                outstream.write(dsum.decode('utf-8'))
                outstream.write("\n\n")
예제 #5
0
def remote_add_or_update(repo, name, url):
    """
    Modified version of Dulwich's porcelain.remote_add(); adds a remote
    if it doesn't yet exist for the given repository, otherwise updates
    the URL and/or refspec if it's changed
    """

    if not isinstance(name, bytes):
        name = name.encode('utf-8')

    if not isinstance(url, bytes):
        url = url.encode('utf-8')

    with open_repo_closing(repo) as r:
        c = r.get_config()
        section = (b'remote', name)

        refspec = f'+refs/heads/*:refs/remotes/{name.decode()}/*'
        refspec = refspec.encode('utf-8')

        if c.has_section(section):
            if c.get(section, b'url') == url:
                try:
                    if c.get(section, b'fetch') == refspec:
                        return
                except KeyError:
                    # 'fetch' missing, set it in the following code
                    pass

        c.set(section, b'url', url)
        c.set(section, b'fetch', refspec)
        c.write_to_path()
예제 #6
0
 def __delete_legacy_dir(self):
     git_metadata_dir = os.path.abspath(os.path.join(
         self.__beq_dir, '.git'))
     move_it = False
     if os.path.exists(git_metadata_dir):
         from dulwich import porcelain
         with porcelain.open_repo_closing(self.__beq_dir) as local_repo:
             config = local_repo.get_config()
             remote_url = config.get(('remote', 'origin'), 'url').decode()
             if remote_url == BEQ_DEFAULT_REPO:
                 move_it = True
     if move_it is True:
         logger.info(
             f"Migrating legacy repo location from {self.__beq_dir}")
         target_dir = os.path.abspath(
             os.path.join(self.__beq_dir, 'bmiller_miniDSPBEQ'))
         os.mkdir(target_dir)
         for d in os.listdir(self.__beq_dir):
             if d != 'bmiller_miniDSPBEQ':
                 src = os.path.abspath(os.path.join(self.__beq_dir, d))
                 if os.path.isdir(src):
                     dst = os.path.abspath(os.path.join(target_dir, d))
                     logger.info(f"Migrating {src} to {dst}")
                     shutil.move(src, dst)
                 else:
                     logger.info(f"Migrating {src} to {target_dir}")
                     shutil.move(src, target_dir)
예제 #7
0
 def __pull_beq(repo, local_dir):
     ''' pulls the git repo but does not use dulwich pull as it has file lock issues on windows '''
     from dulwich import porcelain, index
     with porcelain.open_repo_closing(local_dir) as local_repo:
         remote_refs = porcelain.fetch(local_repo, repo)
         local_repo[b"HEAD"] = remote_refs[b"refs/heads/master"]
         index_file = local_repo.index_path()
         tree = local_repo[b"HEAD"].tree
         index.build_index_from_tree(local_repo.path, index_file, local_repo.object_store, tree)
예제 #8
0
def add(content_repo, custom_content_repo, paths):
    """Add files to the custom content repo and stage them."""
    for p in paths:
        dst = os.path.join(custom_content_repo.path, p)
        src = os.path.join(content_repo.path, p)
        os.makedirs(os.path.dirname(dst), exist_ok=True)
        copyfile(src, dst)

    with open_repo_closing(custom_content_repo) as r:
        r.stage(paths)
예제 #9
0
def checkout_head(repo_path):
    result = True
    cdir = os.getcwd()
    result = cleanWorkingDir(repo_path)
    if not result:
        return result
    os.chdir(repo_path)
    with open_repo_closing(".") as r:
        r.reset_index(r[b"HEAD"].tree)
        # cd out **before** the repo closes
        os.chdir(cdir)
    os.chdir(cdir)
    return result
예제 #10
0
def checkout_tag(repo_path, tagname):
    result = True
    cdir = os.getcwd()
    result = cleanWorkingDir(repo_path)
    if not result: return result
    os.chdir(repo_path)
    with open_repo_closing(".") as r:
        tagkey = utf8_str("refs/tags/" + tagname)
        refkey = tagkey
        # if annotated tag get the commit it pointed to
        if isinstance(r[tagkey], Tag):
            refkey = r[tagkey].object[1]
        r.reset_index(r[refkey].tree)
        # use this to reset HEAD to this tag (ie. revert)
        # r.refs.set_symbolic_ref(b"HEAD", tagkey)
        # cd out **before** the repo closes
        os.chdir(cdir)
    os.chdir(cdir)
    return result
예제 #11
0
 def _from_path(self, path):
     # We already know that the path is a (symlink to a) directory
     # If it is a symlink, it is a local repository, even if the other end
     # is a git repo
     if path.is_symlink():
         return Repository(path.stem, 'local', path.resolve())
     # Now we know we have a path to a directory that is not a symlink
     # To have type 'git', it must be a git repo with a remote called 'origin'
     # The remote URL is what we return as path
     try:
         with porcelain.open_repo_closing(path) as r:
             # Let the KeyError get caught be the outer try
             origin = r.get_config().get((b"remote", b"origin"), b"url")
         return Repository(path.stem, 'git', origin.decode())
     except Exception:
         # Ignore errors
         pass
     # If it is not a git repo with an origin, treat it as a regular directory
     return Repository(path.stem, 'local', path.resolve())
예제 #12
0
def generate_diff_from_checkpoints(localRepo, bookid, leftchkpoint, rightchkpoint):
    repo_home = pathof(localRepo)
    repo_home = repo_home.replace("/", os.sep)
    repo_path = os.path.join(repo_home, "epub_" + bookid)
    success = True
    if os.path.exists(repo_path):
        os.chdir(repo_path)
        with open_repo_closing(".") as r:
            tags = r.refs.as_dict(b"refs/tags")
            commit1 = r[r[tags[utf8_str(leftchkpoint)]].object[1]]
            commit2 = r[r[tags[utf8_str(rightchkpoint)]].object[1]]
            output = io.BytesIO()
            try:
                write_tree_diff(output, r.object_store, commit1.tree, commit2.tree)
            except Exception as e:
                print("diff failed in python")
                print(str(e))
                success = False
                pass
        if success:
            return output.getvalue()
        return ''
예제 #13
0
파일: api.py 프로젝트: gruns/gitauthors
def getRepositoryAuthorsByNumberOfCommits(path):
    authors = {}  # email -> (name, numCommits, latestCommitDate).

    with porcelain.open_repo_closing(path) as repo:
        for entry in repo.get_walker():
            commit = entry.commit
            author = utf8(commit.author)

            date = gmtime(commit.author_time)
            name, email = [s.strip(' <>') for s in author.rsplit(' ', 1)]

            _, numCommits, _ = authors.get(email, ('ignored', 0, 'ignored'))
            numCommits += 1

            authors[email] = (name, numCommits, date)

    items = [(email, name, numCommits, date)
             for email, (name, numCommits, date) in authors.items()]
    authorsByNumCommits = sorted(items, key=lambda author: author[2])[::-1]

    # List of (email, name, numCommits, latestCommitDate) tuples.
    return authorsByNumCommits
예제 #14
0
def commit(root, indexfile, message=None):
    with porcelain.open_repo_closing(root) as repo:
        porcelain.add(repo, indexfile)
        if message is None:
            message = "update %s" % (os.path.basename(indexfile))
        porcelain.commit(repo, message=message, author=_AUTHOR, committer=_COMMITTER)
예제 #15
0
import sys

import semver

from dulwich import porcelain
from dulwich.client import get_transport_and_path
from dulwich.objectspec import parse_reftuples

with porcelain.open_repo_closing(".") as repo:
    latest_version = None
    latest_version_ref = None

    for ref in repo.refs.as_dict(b"refs/tags"):
        if ref.startswith(b"v"):
            sv_part = ref[1:].decode('ascii')
            if latest_version is None:
                latest_version = sv_part
                latest_version_ref = repo.refs[b"refs/tags/" + ref]
            elif semver.compare(sv_part, latest_version) > 0:
                latest_version = sv_part
                latest_version_ref = repo.refs[b"refs/tags/" + ref]

    client, host_path = get_transport_and_path("git://github.com/godfoder/dulwitch_selfref")

    remote_refs = client.fetch(host_path.encode('utf-8'), repo, progress=sys.stderr.write)
    # print(remote_refs)

    # print(repo.refs)

    dirty = False
    for ref in remote_refs:
예제 #16
0
def check_update():
    data = {}
    repo = Repo('.')
    local_ref = repo.head().decode('utf-8')
    print('Versão local: ', local_ref)
    remote_commit = porcelain.ls_remote(REMOTE_REPO)[b"HEAD"].decode('utf-8')
    print('\nVersão remota: ', remote_commit)

    with porcelain.open_repo_closing(repo) as r:
        walker = r.get_walker(max_entries=1)
        for entry in walker:
            message = str(entry.commit.message)[2:-3]
            author = str(entry.commit.author)
            if message.startswith('Merge'):
                continue

    stamp = datetime.utcfromtimestamp(entry.commit.commit_time)
    delta = timedelta(hours=3)
    last_update = (stamp - delta).strftime('%d/%m/%Y' + ' ás ' + '%H:%M:%S')
    data['local'] = local_ref
    data['remote'] = remote_commit
    data['last_update'] = last_update
    #print(data)

    # tag_labels = tag_list(repo)
    # print(tag_labels)
    # for i in ref.get_walker(include=[local_ref]):
    # print(i)
    # import git
    # repo = git.Repo(".")
    # tree = repo.tree()
    # for blob in tree:
    # commit = next(repo.iter_commits(paths=blob.path, max_count=1))
    # print(blob.path, commit.author, commit.committed_date)

    # path = sys.argv[0].encode('utf-8')

    # w = ref.get_walker(paths=[path], c = next(iter(w)).commit)
    # try:
    # c = next(iter(w)).commit
    # except StopIteration:
    # print("No file %s anywhere in history." % sys.argv[0])
    # else:
    # print("%s was last changed by %s at %s (commit %s)" % (
    # sys.argv[1], c.author, time.ctime(c.author_time), c.id))

    # log = porcelain.log('.', max_entries=1)
    # print(log)
    # log = porcelain.log(LOCAL_REPO)
    # print(log)
    # changes = porcelain.get_tree_changes(LOCAL_REPO)
    # print(changes)
    # status = porcelain.status(LOCAL_REPO)
    # print(status)
    # r = porcelain.fetch(LOCAL_REPO,REMOTE_REPO)
    # print(r)
    # for i in r:
    # print(i)
    if local_ref != remote_commit:
        pass
        # print('\nNOVA VERSÃO DISPONÍVEL,INSTALANDO...\n')
        # update()
    else:
        pass
        # print('\nVC JÁ ESTÁ COM A ÚLTIMA VERSÃO INSTALADA.')

    return data