unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Andy Wingo <wingo@pobox.com>
Subject: [PATCH 1/7] guix: git: Support shallow git clones if a tag is available
Date: Tue, 18 Aug 2015 10:03:06 +0200	[thread overview]
Message-ID: <1439892848.733703.3774@rusty> (raw)

* guix/build/git.scm (git-fetch): Instead of cloning the remote repo, use the
  lower-level "init" / "fetch" / "checkout" operations.  This lets us make a
  shallow checkout if we are checking out a tag.

* guix/git-download.scm (<git-reference>): Add tag field.
  (git-fetch): Support git references with tags but no commits.
---
 guix/build/git.scm    | 58 ++++++++++++++++++++++++++++++++++-----------------
 guix/git-download.scm | 10 +++++++--
 2 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/guix/build/git.scm b/guix/build/git.scm
index 121f07a..1af547f 100644
--- a/guix/build/git.scm
+++ b/guix/build/git.scm
@@ -28,32 +28,52 @@
 ;;; Code:
 
 (define* (git-fetch url commit directory
-                    #:key (git-command "git") recursive?)
+                    #:key tag (git-command "git") recursive?)
   "Fetch COMMIT from URL into DIRECTORY.  COMMIT must be a valid Git commit
 identifier.  When RECURSIVE? is true, all the sub-modules of URL are fetched,
 recursively.  Return #t on success, #f otherwise."
-
   ;; Disable TLS certificate verification.  The hash of the checkout is known
   ;; in advance anyway.
   (setenv "GIT_SSL_NO_VERIFY" "true")
 
-  (let ((args `("clone" ,@(if recursive? '("--recursive") '())
-                ,url ,directory)))
-    (and (zero? (apply system* git-command args))
-         (with-directory-excursion directory
-           (system* git-command "tag" "-l")
-           (and (zero? (system* git-command "checkout" commit))
-                (begin
-                  ;; The contents of '.git' vary as a function of the current
-                  ;; status of the Git repo.  Since we want a fixed output, this
-                  ;; directory needs to be taken out.
-                  (delete-file-recursively ".git")
+  (mkdir directory)
+  (with-directory-excursion directory
+    (and (zero? (system* git-command "init"))
+         (zero? (system* git-command "remote" "add" "origin" url))
+         (cond
+          ;; If there's a tag, do a shallow fetch.  Otherwise we do a full
+          ;; fetch.
+          (tag
+           (and (zero? (system* git-command "fetch" "--depth=1" "origin" tag))
+                ;; Either there is no commit specified, in which case we are
+                ;; good, or there is a commit and it is the same as the tag,
+                ;; in which case we're still good, or there's a commit and
+                ;; it's under the tag so we have to unshallow the checkout and
+                ;; try again.
+                (if commit
+                    (or (zero? (system* git-command "checkout" commit))
+                        (and (zero? (system* git-command "fetch" "--unshallow"))
+                             (zero? (system* git-command "checkout" commit))))
+                    (zero? (system* git-command "checkout" "FETCH_HEAD")))))
+          (else
+           ;; Fall back to a full fetch.  In that case print available tags.
+           (and (zero? (system* git-command "fetch" "origin"))
+                (zero? (system* git-command "tag" "-l"))
+                (zero? (system* git-command "checkout" commit)))))
+         (or (not recursive?)
+             (zero? (system* git-command
+                             "submodule" "update" "--init" "--recursive")))
+         (begin
+           ;; The contents of '.git' vary as a function of the current
+           ;; status of the Git repo.  Since we want a fixed output, this
+           ;; directory needs to be taken out.
+           (delete-file-recursively ".git")
 
-                  (when recursive?
-                    ;; In sub-modules, '.git' is a flat file, not a directory,
-                    ;; so we can use 'find-files' here.
-                    (for-each delete-file-recursively
-                              (find-files directory "^\\.git$")))
-                  #t))))))
+           (when recursive?
+             ;; In sub-modules, '.git' is a flat file, not a directory,
+             ;; so we can use 'find-files' here.
+             (for-each delete-file-recursively
+                       (find-files directory "^\\.git$")))
+           #t))))
 
 ;;; git.scm ends here
diff --git a/guix/git-download.scm b/guix/git-download.scm
index 0f2218c..43bc466 100644
--- a/guix/git-download.scm
+++ b/guix/git-download.scm
@@ -28,6 +28,7 @@
             git-reference?
             git-reference-url
             git-reference-commit
+            git-reference-tag
             git-reference-recursive?
 
             git-fetch))
@@ -44,7 +45,8 @@
   git-reference make-git-reference
   git-reference?
   (url        git-reference-url)
-  (commit     git-reference-commit)
+  (commit     git-reference-commit (default #f))
+  (tag        git-reference-tag (default #f))
   (recursive? git-reference-recursive?   ; whether to recurse into sub-modules
               (default #f)))
 
@@ -81,8 +83,12 @@ HASH-ALGO (a symbol).  Use NAME as the file name, or a generic name if #f."
                                           dirs)))
 
         (git-fetch '#$(git-reference-url ref)
-                   '#$(git-reference-commit ref)
+                   (or '#$(git-reference-commit ref)
+                       '#$(git-reference-tag ref))
                    #$output
+                   ;; FIXME: Pass #:tag when fixed daemons are widely
+                   ;; deployed.
+                   ;; #:tag '#$(git-reference-tag ref)
                    #:recursive? '#$(git-reference-recursive? ref)
                    #:git-command (string-append #+git "/bin/git"))))
 
-- 
2.4.3

             reply	other threads:[~2015-08-18 10:14 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-18  8:03 Andy Wingo [this message]
  -- strict thread matches above, loose matches on Subject: below --
2015-08-18  8:03 [PATCH 1/7] guix: git: Support shallow git clones if a tag is available Andy Wingo
2015-08-25 14:02 ` Ludovic Courtès
2015-10-20 15:20   ` Christopher Allan Webber
2015-10-25 21:30     ` Ludovic Courtès
2015-10-26  7:46       ` Andy Wingo
2017-02-02 20:33   ` ng0
2015-08-18  8:03 Andy Wingo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1439892848.733703.3774@rusty \
    --to=wingo@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).