def load_repository_packages( remote: git.Remote, prefix: str, host: str = "github.com") -> Dict[str, List[Tuple[str, str]]]: print("Loading repository packages...") remote.fetch() url = pathlib.Path(remote.url) raw_url = pathlib.Path(host) / url.parent.name / url.stem / "raw" branches: List[str] = ["any", "stubs"] for platform in ("Linux", "Darwin", "Windows"): for version in ("3.6", "3.7", "3.8"): branches.append(platform + "_" + version) if prefix: for idx in range(len(branches)): branches[idx] += "_" + prefix packages: Dict[str, List[Tuple[str, str]]] = {} for branch in branches: if branch in remote.refs: for t in remote.refs[branch].commit.tree.trees: for b in t.blobs: packages.setdefault(t.name, []) packages[t.name].append(( f"https://{raw_url}/{branch}/{t.name}/{b.name}", b.name, )) return packages
def get_last_commits(remote: git.Remote, branches: List[str]) -> Dict[str, str]: """Get last commit of each given branch for the given remote.""" last_commits = {} for branch in branches: fetch_info = remote.fetch(branch)[0] last_commits[branch] = fetch_info.commit.hexsha return last_commits
def is_same_commit(repo: Repo, remote: Remote) -> bool: local_commit = repo.commit() remote_commit = remote.fetch()[0].commit return local_commit.hexsha == remote_commit.hexsha
def clean_remote(remote: Remote): print_warning(f"Fetching {remote.name}, {remote.url}") remote.fetch() for branch in remote.refs: print(branch)
def git_check(wdir='.'): git_root = git_rootdir(wdir) if git_root == None: return 0 f = "{}/.git/FETCH_HEAD".format(os.path.abspath(git_root)) if os.path.isfile(f): ''' make sure this is not a freshly cloned repo with no FETCH_HEAD ''' last_fetch = int(os.stat(f).st_mtime) diff = int(time.time() - last_fetch) else: # if the repo is a fresh clone, there is no FETCH_HEAD # so set time diff to more than a minute to force a fetch diff = 61 repo = Repo(git_root) assert not repo.bare remote_names = [] # fetch at most once per minute for r in repo.remotes: remote_names.append(r.name) if diff > 60: remote = Remote(repo, r.name) remote.fetch() # check what branch we're on branch = repo.active_branch.name origin_branch = None for ref in repo.git.branch('-r').split('\n'): for rn in remote_names: if "{}/{}".format(rn, branch) in ref: origin_branch = ref.strip() break if origin_branch == None: # no remote branch to compare to return 0 # check if local branch is ahead and /or behind remote branch command = "git -C {} rev-list --left-right --count \"{}...{}\"".format( git_root, branch, origin_branch) #print command (ahead_behind, err, exitcode) = run(command, raise_exception_on_fail=True) ahead_behind = ahead_behind.strip().split("\t") ahead = int(ahead_behind[0]) behind = int(ahead_behind.pop()) if behind > 0: sys.stderr.write("") sys.stderr.write( "GIT ERROR: You are on branch {} and are behind the remote. Please git pull and/or merge before proceeding. Below is a git status:" .format(branch)) sys.stderr.write("") (status, err, exitcode) = run("git -C {} status ".format(git_root)) sys.stderr.write(status) sys.stderr.write("") return (-1) else: TB_GIT_DEFAULT_BRANCH = os.getenv('TB_GIT_DEFAULT_BRANCH', 'master') if branch != TB_GIT_DEFAULT_BRANCH: ''' in this case assume we're on a feature branch if the FB is behind master then issue a warning ''' command = "git -C {} branch -vv | grep {} ".format( git_root, TB_GIT_DEFAULT_BRANCH) (origin_master, err, exitcode) = run(command) if exitcode != 0: ''' In this case the git repo does not contain TB_GIT_DEFAULT_BRANCH, so I guess assume that we're on the default branch afterall and that we're up to date persuant to the above code ''' return 0 for line in origin_master.split("\n"): if line.strip().startswith(TB_GIT_DEFAULT_BRANCH): origin = line.strip().split('[')[1].split('/')[0] assert origin != None command = "git -C {} rev-list --left-right --count \"{}...{}/{}\"".format( git_root, branch, origin, TB_GIT_DEFAULT_BRANCH) (ahead_behind, err, exitcode) = run(command) ahead_behind = ahead_behind.strip().split("\t") ahead = int(ahead_behind[0]) behind = int(ahead_behind.pop()) command = "git -C {} rev-list --left-right --count \"{}...{}\"".format( git_root, branch, TB_GIT_DEFAULT_BRANCH) (ahead_behind, err, exitcode) = run(command) ahead_behind = ahead_behind.strip().split("\t") local_ahead = int(ahead_behind[0]) local_behind = int(ahead_behind.pop()) if behind > 0: sys.stderr.write("") sys.stderr.write( "GIT WARNING: Your branch, {}, is {} commit(s) behind {}/{}.\n" .format(branch, behind, origin, TB_GIT_DEFAULT_BRANCH)) sys.stderr.write( "This action may clobber new changes that have occurred in {} since your branch was made.\n" .format(TB_GIT_DEFAULT_BRANCH)) sys.stderr.write( "It is recommended that you stop now and merge or rebase from {}\n" .format(TB_GIT_DEFAULT_BRANCH)) sys.stderr.write("\n") if ahead != local_ahead or behind != local_behind: sys.stderr.write("") sys.stderr.write( "INFO: your local {} branch is not up to date with {}/{}\n" .format(TB_GIT_DEFAULT_BRANCH, origin, TB_GIT_DEFAULT_BRANCH)) sys.stderr.write("HINT:") sys.stderr.write( "git checkout {} ; git pull ; git checkout {}\n". format(TB_GIT_DEFAULT_BRANCH, branch)) sys.stderr.write("\n") answer = raw_input( "Do you want to continue anyway? [y/N]? ").lower() if answer != 'y': log("") log("Aborting due to user input") exit() return 0