Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/tools/tools/repohooks/rh/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 7 kB image not shown  

Quelle  git.py

  Sprache: Python
 

# Copyright 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Git helper functions."""

import os
from pathlib import Path
import re
import sys


THIS_FILE = Path(__file__).resolve()
THIS_DIR = THIS_FILE.parent
sys.path.insert(0, str(THIS_DIR.parent))

# pylint: disable=wrong-import-position
import rh.utils


def get_upstream_remote():
    """Returns the current upstream remote name."""
    # First get the current branch name.
    cmd = ["git""rev-parse""--abbrev-ref""HEAD"]
    result = rh.utils.run(cmd, capture_output=True)
    branch = result.stdout.strip()

    # Then get the remote associated with this branch.
    cmd = ["git""config", f"branch.{branch}.remote"]
    result = rh.utils.run(cmd, capture_output=True)
    return result.stdout.strip()


def get_upstream_branch():
    """Returns the upstream tracking branch of the current branch.

    Raises:
      Error if there is no tracking branch
    """
    cmd = ["git""symbolic-ref""HEAD"]
    result = rh.utils.run(cmd, capture_output=True)
    current_branch = result.stdout.strip().replace("refs/heads/""")
    if not current_branch:
        raise ValueError("Need to be on a tracking branch")

    cfg_option = "branch." + current_branch + "."
    cmd = ["git""config", cfg_option + "merge"]
    result = rh.utils.run(cmd, capture_output=True)
    full_upstream = result.stdout.strip()
    # If remote is not fully qualified, add an implicit namespace.
    if "/" not in full_upstream:
        full_upstream = f"refs/heads/{full_upstream}"
    cmd = ["git""config", cfg_option + "remote"]
    result = rh.utils.run(cmd, capture_output=True)
    remote = result.stdout.strip()
    if not remote or not full_upstream:
        raise ValueError("Need to be on a tracking branch")

    return full_upstream.replace("heads""remotes/" + remote)


def get_commit_for_ref(ref):
    """Returns the latest commit for this ref."""
    cmd = ["git""rev-parse", ref]
    result = rh.utils.run(cmd, capture_output=True)
    return result.stdout.strip()


def get_remote_revision(ref, remote):
    """Returns the remote revision for this ref."""
    prefix = f"refs/remotes/{remote}/"
    if ref.startswith(prefix):
        return ref[len(prefix) :]
    return ref


def get_patch(commit):
    """Returns the patch for this commit."""
    cmd = ["git""format-patch""--stdout""-1", commit]
    return rh.utils.run(cmd, capture_output=True).stdout


def get_file_content(commit, path):
    """Returns the content of a file at a specific commit.

    We can't rely on the file as it exists in the filesystem as people might be
    uploading a series of changes which modifies the file multiple times.

    Note: The "content" of a symlink is just the target.  So if you're expecting
    a full file, you should check that first.  One way to detect is that the
    content will not have any newlines.
    """
    cmd = ["git""show", f"{commit}:{path}"]
    return rh.utils.run(cmd, capture_output=True).stdout


class RawDiffEntry(object):
    """Representation of a line from raw formatted git diff output."""

    # pylint: disable=redefined-builtin
    def __init__(
        self,
        src_mode=0,
        dst_mode=0,
        src_sha=None,
        dst_sha=None,
        status=None,
        score=None,
        src_file=None,
        dst_file=None,
        file=None,
    ):
        self.src_mode = src_mode
        self.dst_mode = dst_mode
        self.src_sha = src_sha
        self.dst_sha = dst_sha
        self.status = status
        self.score = score
        self.src_file = src_file
        self.dst_file = dst_file
        self.file = file


# This regular expression pulls apart a line of raw formatted git diff output.
DIFF_RE = re.compile(
    r":(?P<src_mode>[0-7]*) (?P<dst_mode>[0-7]*) "
    r"(?P<src_sha>[0-9a-f]*)(\.)* (?P<dst_sha>[0-9a-f]*)(\.)* "
    r"(?P<status>[ACDMRTUX])(?P<score>[0-9]+)?\t"
    r"(?P<src_file>[^\t]+)\t?(?P<dst_file>[^\t]+)?"
)


def raw_diff(path, target):
    """Return the parsed raw format diff of target

    Args:
      path: Path to the git repository to diff in.
      target: The target to diff.

    Returns:
      A list of RawDiffEntry's.
    """
    entries = []

    cmd = ["git""diff""--no-ext-diff""-M""--raw", target]
    diff = rh.utils.run(cmd, cwd=path, capture_output=True).stdout
    diff_lines = diff.strip().splitlines()
    for line in diff_lines:
        match = DIFF_RE.match(line)
        if not match:
            raise ValueError(f"Failed to parse diff output: {line}")
        rawdiff = RawDiffEntry(**match.groupdict())
        rawdiff.src_mode = int(rawdiff.src_mode)
        rawdiff.dst_mode = int(rawdiff.dst_mode)
        rawdiff.file = (
            rawdiff.dst_file if rawdiff.dst_file else rawdiff.src_file
        )
        entries.append(rawdiff)

    return entries


def get_affected_files(commit):
    """Returns list of file paths that were modified/added.

    Returns:
      A list of modified/added (and perhaps deleted) files
    """
    return raw_diff(os.getcwd(), f"{commit}^-")


def get_commits(ignore_merged_commits=False):
    """Returns a list of commits for this review."""
    cmd = ["git""rev-list", f"{get_upstream_branch()}.."]
    if ignore_merged_commits:
        cmd.append("--first-parent")
    return rh.utils.run(cmd, capture_output=True).stdout.split()


def get_commit_desc(commit):
    """Returns the full commit message of a commit."""
    cmd = ["git""diff-tree""-s""--always""--format=%B", commit]
    return rh.utils.run(cmd, capture_output=True).stdout


def find_repo_root(path=None, outer=False):
    """Locate the top level of this repo checkout starting at |path|.

    Args:
      outer: Whether to find the outermost manifest, or the sub-manifest.
    """
    if path is None:
        path = os.getcwd()
    orig_path = path

    path = os.path.abspath(path)

    # If we are working on a superproject instead of a repo client, use the
    # result from git directly.  For regular repo client, this would return
    # empty string.
    cmd = ["git""rev-parse""--show-superproject-working-tree"]
    git_worktree_path = rh.utils.run(
        cmd, cwd=path, capture_output=True
    ).stdout.strip()
    if git_worktree_path:
        return git_worktree_path

    while not os.path.exists(os.path.join(path, ".repo")):
        path = os.path.dirname(path)
        if path == "/":
            raise ValueError(f"Could not locate .repo in {orig_path}")

    root = path
    if not outer and os.path.isdir(os.path.join(root, ".repo""submanifests")):
        # If there are submanifests, walk backward from path until we find the
        # corresponding submanifest root.
        abs_orig_path = os.path.abspath(orig_path)
        parts = os.path.relpath(abs_orig_path, root).split(os.path.sep)
        while parts and not os.path.isdir(
            os.path.join(root, ".repo""submanifests", *parts, "manifests")
        ):
            parts.pop()
        path = os.path.join(root, *parts)

    return path


def is_git_repository(path):
    """Returns True if the path is a valid git repository."""
    cmd = ["git""rev-parse""--resolve-git-dir", os.path.join(path, ".git")]
    result = rh.utils.run(cmd, capture_output=True, check=False)
    return result.returncode == 0

Messung V0.5 in Prozent
C=88 H=79 G=83

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet am  2026-06-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.