Subject: bug#45187: git download defaults to origin/master

From: Kyle Meyer <[email-masked]>
Date: Fri, 11 Dec 2020 23:02:02 GMT

Ricardo Wurmus writes:

> Importing https://github.com/immunogenomics/scpost with the CRAN
> importer fails, because the git repository does not have an
> origin/master branch.  This repository only has a “main” branch.
>
> Arguably, this shouldn’t matter, but (guix git) has the “master” name
> set up as the default.  When cloning a repository it may be better to
> fetch everything and select the default branch — whichever name it may
> have.

One option may be to use the remote HEAD symref.  That's probably the
best indicator of what the primary branch is.  In a clone, it doesn't
necessarily match HEAD on the remote, because users may change it to
another branch they're interested in, but that isn't really relevant to
these behind-the-scenes checkouts.

Here's a quick and dirty demo that makes your reproducer work.  A real
patch in this direction would of course look very different.

diff --git a/guix/git.scm b/guix/git.scm
index ca77b9f54b..7320c0d6c8 100644
--- a/guix/git.scm
+++ b/guix/git.scm
@@ -207,6 +207,9 @@ (define (resolve-reference repository ref)
        (let ((oid (reference-target
                    (branch-lookup repository branch BRANCH-REMOTE))))
          (object-lookup repository oid)))
+      (('symref . symref)
+       (let ((oid (reference-name->oid repository symref)))
+         (object-lookup repository oid)))
       (('commit . commit)
        (let ((len (string-length commit)))
          ;; 'object-lookup-prefix' appeared in Guile-Git in Mar. 2018, so we
@@ -320,7 +323,7 @@ (define (reference-available? repository ref)
 
 (define* (update-cached-checkout url
                                  #:key
-                                 (ref '(branch . "master"))
+                                 (ref '(symref . "refs/remotes/origin/HEAD"))
                                  recursive?
                                  (check-out? #t)
                                  starting-commit
@@ -395,7 +398,7 @@ (define* (latest-repository-commit store url
                                    (log-port (%make-void-port "w"))
                                    (cache-directory
                                     (%repository-cache-directory))
-                                   (ref '(branch . "master")))
+                                   (ref '(symref . "refs/remotes/origin/HEAD")))
   "Return two values: the content of the git repository at URL copied into a
 store directory and the sha1 of the top level commit in this directory.  The
 reference to be checkout, once the repository is fetched, is specified by REF.