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}")
Exemple #3
0
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
        )
Exemple #4
0
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
Exemple #5
0
 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()
Exemple #6
0
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())
Exemple #7
0
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
Exemple #8
0
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))