3

Is there a way that I can get the most recent commit on a remote repository using gitpython? I do not want to perform operations like a pull or merge on my local branch. I also do not want to depend on the master branch on my local to get this information. All I have is a valid repo out there, and I am using repo.remotes.origin.url to get the information.

With just the repo URL, can I get the most recent commit on that repository?

oyeesh
  • 551
  • 9
  • 21
  • How about `fetch`, would that be okay? – matt Jun 23 '20 at 00:48
  • @matt well, yeah that could work. I am wondering if I can somehow achieve this without having to deal with github token – oyeesh Jun 23 '20 at 01:08
  • @Shrav did my response below answer your question, or do you want to keep digging? I know it's not ideal, but such is life. – DV82XL Jun 23 '20 at 21:56
  • @DV82XL Thank you! It did answer my question. However, my use case is a little different as I have to do this on Buildkite without having to mount the ssh creds. I ended up creating a new plugin that sets up the repo before doing the git operations inside a docker container. – oyeesh Jun 25 '20 at 11:55

2 Answers2

6

Using gitpython, you can't do this without a local clone. Git is a distributed system, so it's designed for users to operate on their local repos. These answer gives some decent explanations and alternatives:

Using gitpython - requires local repo

You can do a shallow clone (for speed), get latest commit SHA using git rev-parse or git ls-remote, then delete the local repo.

import git
from pathlib import Path

repo_url = 'https://github.com/path/to/your/repo.git'
local_repo_dir = Path('/path/to/your/repo')

# delete the repo if it exists, perform shallow clone, get SHA, delete repo
local_repo_dir.unlink(missing_ok=True)
repo = git.Repo.clone_from(repo_url, local_repo_dir, depth=1)
sha = repo.rev_parse('origin/master')
local_repo_dir.unlink()
print(sha)

Using python subprocess - does not require local repo

This simpler solution uses git ls-remote, which does not require a local clone. The following uses subprocess to get the SHA-1 of the given branch from the remote repo without a local clone. Note that the SHA needs to be extracted from the output response by splitting at the first tab.

import subprocess
import re

repo_url = 'https://github.com/path/to/your/repo.git'
process = subprocess.Popen(["git", "ls-remote", repo_url], stdout=subprocess.PIPE)
stdout, stderr = process.communicate()
sha = re.split(r'\t+', stdout.decode('ascii'))[0]
print(sha)
DV82XL
  • 5,350
  • 5
  • 30
  • 59
  • 1
    `git ls-remote` doesn't require a local clone, you can give it a remote URL as an argument. I don't think `gitpython` can deal with it though. – hobbs Jun 23 '20 at 01:38
  • That's right. `git ls-remote` would have to be called using a subprocess call. – DV82XL Jun 23 '20 at 02:10
3

You can do it with gitpython without creating a local repository first:

remote_heads = git.cmd.Git().ls_remote(repo_url, heads=True)
Jan
  • 31
  • 2