def git_supports_spatial_filter(git_supports_filter_extensions): if not git_supports_filter_extensions: return False with tempfile.TemporaryDirectory() as td: subprocess.run( ["git", "-C", td, "init", "--quiet", "."], env=tool_environment(), check=True, ) p = subprocess.run( [ "git", "rev-list", "HEAD", "--objects", "--max-count=1", "--filter=extension:spatial=1,2,3,4", ], env=tool_environment(), stderr=subprocess.PIPE, text=True, ) err = p.stderr.strip() if err == "fatal: No filter extension found with name spatial": return False elif "No spatial index found" in err or p.returncode == 0: return True else: raise ValueError( "git_supports_spatial_filter: unexpected output {p.returncode}: {err}" )
def git_supports_filter_extensions(): with tempfile.TemporaryDirectory() as td: subprocess.run( ["git", "-C", td, "init", "--quiet", "."], env=tool_environment(), check=True, ) p = subprocess.run( ["git", "-C", td, "rev-list", "--filter=extension:z", "--objects"], env=tool_environment(), stderr=subprocess.PIPE, text=True, ) if p.returncode == 0: raise ValueError( f"git_supports_filter_extensions: unexpected return code {p.returncode}" ) err = p.stderr.strip() if err == "fatal: invalid filter-spec 'extension:z'": return False elif err == "fatal: No filter extension found with name z": return True else: raise ValueError( "git_supports_filter_extensions: unexpected output: {err}")
def iter_feature_blobs(repo, start_commits, stop_commits): cmd = [*_revlist_command(repo), *start_commits, "--not", *stop_commits] try: p = subprocess.Popen( cmd, stdout=subprocess.PIPE, encoding="utf8", env=tool_environment(), ) yield from _parse_revlist_output(repo, p.stdout, r"feature/.+") except subprocess.CalledProcessError as e: raise SubprocessError( f"There was a problem with git rev-list: {e}", called_process_error=e )
def test_cli_tool_environment(): env_exec = tool_environment() assert len(env_exec) assert env_exec is not os.environ if platform.system() == "Linux": env_in = { "LD_LIBRARY_PATH": "bob", "LD_LIBRARY_PATH_ORIG": "alex", "my": "me" } env_exec = tool_environment(env_in) assert env_exec is not env_in assert env_exec["LD_LIBRARY_PATH"] == "alex" assert env_exec["my"] == "me" env_in = {"LD_LIBRARY_PATH": "bob", "my": "me"} env_exec = tool_environment(env_in) assert "LD_LIBRARY_PATH" not in env_exec else: env_in = {"my": "me"} env_exec = tool_environment(env_in) assert env_exec is not env_in assert env_exec == env_in
def _all_commits(self): cmd = [ "git", "-C", self.repo.path, "rev-list", *self.start_stop_spec, ] try: commits = subprocess.check_output( cmd, encoding="utf8", env=tool_environment(), ) except subprocess.CalledProcessError as e: raise SubprocessError( f"There was a problem with git rev-list: {e}", called_process_error=e ) return commits.splitlines()
def _minimal_description_of_commit_set(repo, commits): """ Returns the minimal set of commit IDs that have the same set of ancestors as the given set of commit IDs. Stated differently - returns the given commits except for those which are reachable by following ancestors of commits in the given set. """ cmd = ["git", "-C", repo.path, "merge-base", "--independent"] + list(commits) try: r = subprocess.run( cmd, encoding="utf8", check=True, capture_output=True, env=tool_environment(), ) except subprocess.CalledProcessError as e: raise SubprocessError( f"There was a problem with git merge-base: {e}", called_process_error=e ) return set(r.stdout.splitlines())
def resolve_all_commit_refs(repo): """Returns the set of all branch heads, refs, HEAD, as commit SHAs.""" cmd = ["git", "-C", repo.path, "show-ref", "--hash", "--head"] try: r = subprocess.run( cmd, encoding="utf8", check=True, capture_output=True, env=tool_environment(), ) except subprocess.CalledProcessError as e: raise SubprocessError( f"There was a problem with git show-ref: {e}", called_process_error=e ) result = set() for c in r.stdout.splitlines(): try: if repo[c].type_str == "commit": result.add(c) except KeyError: pass return result
def reset_worktree_index(repo, reset_index_paths): """ Creates a file <GIT-DIR>/worktree-index that is an index of that part of the contents of the workdir that is contained within the given update_index_paths (which can be files or folders). """ worktree_index_file = repo.gitdir_file("worktree-index") # NOTE - we could also use pygit2.Index to do this, but this has been easier to get working so far. env = tool_environment() env["GIT_INDEX_FILE"] = str(worktree_index_file) # TODO - this may be inefficient - it might be possible to reuse some or all of the existing index, # rather than regenerating it from scratch. if worktree_index_file.exists(): worktree_index_file.unlink() for path in reset_index_paths: try: args = ["git", "add", path] subprocess.check_call( args, env=env, cwd=repo.workdir_path, stdout=subprocess.DEVNULL ) except subprocess.CalledProcessError as e: sys.exit(translate_subprocess_exit_code(e.returncode))