libgit2 / pygit2

Python bindings for libgit2
https://www.pygit2.org/
Other
1.61k stars 385 forks source link

Need help with checking out gerrit review #1318

Closed srikanthpailla closed 3 hours ago

srikanthpailla commented 3 hours ago

Hi,

I am struggling to get the code working for checking out gerrit review.

` class Git: """Git class to interact with a git repo."""

def __init__(self, url: str, authcb: str, committer: str, workdir: Optional[str] = None) -> None:
    if not workdir:
        temp_git_dir = tempfile.mkdtemp(prefix="artcis_ci_lib_")
        dirname = hashlib.sha256(url.encode("utf-8")).hexdigest()
        self._workdir = os.path.join(temp_git_dir, dirname)
    else:
        self._workdir = workdir

    self._authentication_callback = authcb
    self._committer = committer

    logger.info("Checking out %s to %s...", url, self._workdir)

    self._repo = init_repository(self._workdir)
    self._remote = self._repo.remotes.create("origin", url)  # type: ignore

    logger.debug("TODO: install sig handler that removes %s on exit", self._workdir)

@property
def workdir(self) -> str:
    """Returns the workdir of the git repo.

    Returns:
    -------
        str: The workdir of the git repo

    """
    return self._workdir

def fetch_and_checkout(self, remote_ref: str, retries: int = 8) -> TransferProgress:
    """Fetch and checkout the remote ref.

    Args:
    ----
        remote_ref (str): The remote ref to fetch and checkout
        retries (int): The number of retries to perform

    Returns:
    -------
       TransferProgress: The fetch progress

    """
    for i in range(1, retries + 1):
        try:
            progress = self._remote.fetch([remote_ref], callbacks=self._authentication_callback)  # type: ignore
            for _ in range(1800):
                sleep(0.1)
                if progress.received_objects == progress.total_objects:
                    break
            if progress.received_objects != progress.total_objects:
                raise TimeoutError("Timeout while recieving objects")
            break
        except (TimeoutError, GitError) as err:
            if i >= retries:
                raise err
            backoff_time = 2**i
            logger.error("Failed to fetch repository, retrying in %s seconds...", backoff_time)
            time.sleep(backoff_time)
            continue

    self._repo.checkout("FETCH_HEAD") 
    return progress  # type: ignore

`

This is working fine with branches, but when trying out with merged commit revision or commit revision from gerrit review, this code isn't working.

i get below error when trying to checkout gerrit review with revision or any revision which is already merged into master: _pygit2.GitError: cannot fetch a specific object from the remote repository

Could you please help to solve this issue.

srikanthpailla commented 3 hours ago

I realized that I opened issue instead of starting the discussion. will close this and start the discussion. Started the discussion here: https://github.com/libgit2/pygit2/discussions/1319