jelmer / dulwich

Pure-Python Git implementation
https://www.dulwich.io/
Other
2.06k stars 395 forks source link

ls_remote: Support --symref from git's ls-remote #863

Open MCOfficer opened 3 years ago

MCOfficer commented 3 years ago

I need to find a remote repo's default branch. In git that's

git ls-remote --symref <url> HEAD

However, this doesn't seem possible with dulwich, as ls_remote doesn't accept any such arguments. And unlike -h or -t (which are merely filters), this information can't be inferred from ls_remote's default output.

Would it be possible to support this?

MCOfficer commented 3 years ago

I dug a bit deeper, and this information is in fact known in client.read_pkt_refs, as part of server_capabilities:

https://github.com/dulwich/dulwich/blob/76dd8356f9d8870f44226e4232c24fbc1e573e93/dulwich/client.py#L228

However, it's discarded by TraditionalGitClient.get_refs:

https://github.com/dulwich/dulwich/blob/76dd8356f9d8870f44226e4232c24fbc1e573e93/dulwich/client.py#L1061

I could probably monkeypatch that, but considering that this seem like an API change, I feel very much unqualified.

Edit: example server_capabilities set, search for "symref":

[b'multi_ack', b'thin-pack', b'side-band', b'side-band-64k', b'ofs-delta', b'shallow', b'deepen-since', b'deepen-not', b'deepen-relative', b'no-progress', b'include-tag', b'multi_ack_detailed', b'allow-tip-sha1-in-want', b'allow-reachable-sha1-in-want', b'no-done', b'symref=HEAD:refs/heads/master', b'filter', b'object-format=sha1', b'agent=git/github-g48472559e5d2']
jelmer commented 3 years ago

On Fri, Apr 09, 2021 at 07:41:27AM -0700, MCOfficer wrote:

I need to find a remote repo's master branch. In git that's

git ls-remote --symref <url> HEAD

However, this doesn't seem possible with dulwich, as ls_remote doesn't accept any such arguments. And unlike -h or -t, this information can't be inferred from ls_remote's default output.

Would it be possible to support this? Yeah, we should relatively easily be able to do this.

We can do something similar as we did for fetch/push, where we returned a new object that implements most of dict() for backwards compatibility (and that triggers a DeprecationWarning).

Jelmer