summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--guix/channels.scm20
-rw-r--r--guix/git.scm16
-rw-r--r--guix/tests/git.scm4
-rw-r--r--tests/git.scm72
4 files changed, 101 insertions, 11 deletions
diff --git a/guix/channels.scm b/guix/channels.scm
index 662fc7bae22..ac9303c5fa0 100644
--- a/guix/channels.scm
+++ b/guix/channels.scm
@@ -5,6 +5,7 @@
5;;; Copyright © 2021 Brice Waegeneire <brice@waegenei.re> 5;;; Copyright © 2021 Brice Waegeneire <brice@waegenei.re>
6;;; Copyright © 2024 Julien Lepiller <julien@lepiller.eu> 6;;; Copyright © 2024 Julien Lepiller <julien@lepiller.eu>
7;;; Copyright © 2024 Rostislav Svoboda <Rostislav.Svoboda@gmail.com> 7;;; Copyright © 2024 Rostislav Svoboda <Rostislav.Svoboda@gmail.com>
8;;; Copyright © 2026 Simon Tournier <zimon.toutoune@gmail.com>
8;;; 9;;;
9;;; This file is part of GNU Guix. 10;;; This file is part of GNU Guix.
10;;; 11;;;
@@ -245,13 +246,18 @@ could be found at DIRECTORY or one of its ancestors."
245(define (channel-reference channel) 246(define (channel-reference channel)
246 "Return the \"reference\" for CHANNEL, an sexp suitable for 247 "Return the \"reference\" for CHANNEL, an sexp suitable for
247'latest-repository-commit'." 248'latest-repository-commit'."
248 (match (channel-commit channel) 249 (let* ((commit (channel-commit channel))
249 (#f (let ((branch (channel-branch channel))) 250 (branch (channel-branch channel))
250 (if (and (string? branch) 251 (refs? (and branch
251 (string-prefix? "refs/" branch)) 252 (string? branch)
252 `(symref . ,branch) 253 (string-prefix? "refs/" branch))))
253 `(branch . ,branch)))) 254 (if commit
254 (commit `(tag-or-commit . ,(channel-commit channel))))) 255 (if refs?
256 `(symref . (,branch . ,commit))
257 `(tag-or-commit . ,commit))
258 (if refs?
259 `(symref . ,branch)
260 `(branch . ,branch)))))
255 261
256(define sexp->channel-introduction 262(define sexp->channel-introduction
257 (match-lambda 263 (match-lambda
diff --git a/guix/git.scm b/guix/git.scm
index f6fab9fc914..4107acd4867 100644
--- a/guix/git.scm
+++ b/guix/git.scm
@@ -5,7 +5,7 @@
5;;; Copyright © 2021 Marius Bakke <marius@gnu.org> 5;;; Copyright © 2021 Marius Bakke <marius@gnu.org>
6;;; Copyright © 2022 Maxime Devos <maximedevos@telenet.be> 6;;; Copyright © 2022 Maxime Devos <maximedevos@telenet.be>
7;;; Copyright © 2023 Tobias Geerinckx-Rice <me@tobias.gr> 7;;; Copyright © 2023 Tobias Geerinckx-Rice <me@tobias.gr>
8;;; Copyright © 2023, 2025 Simon Tournier <zimon.toutoune@gmail.com> 8;;; Copyright © 2023, 2025, 2026 Simon Tournier <zimon.toutoune@gmail.com>
9;;; 9;;;
10;;; This file is part of GNU Guix. 10;;; This file is part of GNU Guix.
11;;; 11;;;
@@ -273,9 +273,14 @@ corresponding Git object."
273 (let ((oid (reference-target 273 (let ((oid (reference-target
274 (branch-lookup repository branch BRANCH-REMOTE)))) 274 (branch-lookup repository branch BRANCH-REMOTE))))
275 (object-lookup repository oid))) 275 (object-lookup repository oid)))
276 (('symref . symref) 276 (('symref . (? string? symref))
277 (let ((oid (reference-name->oid repository symref))) 277 (let ((oid (reference-name->oid repository symref)))
278 (object-lookup repository oid))) 278 (object-lookup repository oid)))
279 (('symref . (_ . commit))
280 ;; It handles channel files automatically generated by Cuirass, where
281 ;; the branch follows Pull-Request Git namespace as refs/pull/1/head,
282 ;; and one commit is specifically pinned on that symref branch.
283 (resolve `(commit . ,commit)))
279 (('commit . commit) 284 (('commit . commit)
280 (let ((len (string-length commit))) 285 (let ((len (string-length commit)))
281 ;; 'object-lookup-prefix' appeared in Guile-Git in Mar. 2018, so we 286 ;; 'object-lookup-prefix' appeared in Guile-Git in Mar. 2018, so we
@@ -437,6 +442,8 @@ definitely available in REPOSITORY, false otherwise."
437 ('tag-or-commit . str)) 442 ('tag-or-commit . str))
438 (false-if-git-not-found 443 (false-if-git-not-found
439 (->bool (resolve-reference repository ref)))) 444 (->bool (resolve-reference repository ref))))
445 (('symref . (_ . (? commit-id? commit)))
446 (reference-available? repository `(commit . ,commit)))
440 (_ 447 (_
441 ;; For the others REF as branch or symref, the REF cannot be available 448 ;; For the others REF as branch or symref, the REF cannot be available
442 #f))) 449 #f)))
@@ -588,7 +595,8 @@ current settings unchanged."
588 595
589 (define ref->refspecs 596 (define ref->refspecs
590 (match-lambda 597 (match-lambda
591 (('symref . symref) 598 ((or ('symref . (? string? symref))
599 ('symref . (symref . _)))
592 (list (string-append "+" symref ":" symref))) 600 (list (string-append "+" symref ":" symref)))
593 (_ '()))) 601 (_ '())))
594 602
diff --git a/guix/tests/git.scm b/guix/tests/git.scm
index a649c1fa6e8..35a41470eb1 100644
--- a/guix/tests/git.scm
+++ b/guix/tests/git.scm
@@ -1,6 +1,7 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz> 3;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
4;;; Copyright © 2026 Simon Tournier <zimon.toutoune@gmail.com>
4;;; 5;;;
5;;; This file is part of GNU Guix. 6;;; This file is part of GNU Guix.
6;;; 7;;;
@@ -120,6 +121,9 @@ Return DIRECTORY on success."
120 (loop rest)) 121 (loop rest))
121 ((('reset to) rest ...) 122 ((('reset to) rest ...)
122 (git "reset" "--hard" to) 123 (git "reset" "--hard" to)
124 (loop rest))
125 ((('symbolic-ref name ref) rest ...)
126 (git "symbolic-ref" name ref)
123 (loop rest))))) 127 (loop rest)))))
124 128
125(define (call-with-temporary-git-repository directives proc) 129(define (call-with-temporary-git-repository directives proc)
diff --git a/tests/git.scm b/tests/git.scm
index 9ccd04f0cdf..712b12c7fc4 100644
--- a/tests/git.scm
+++ b/tests/git.scm
@@ -1,6 +1,7 @@
1;;; GNU Guix --- Functional package management for GNU 1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2019-2020, 2022, 2024 Ludovic Courtès <ludo@gnu.org> 2;;; Copyright © 2019-2020, 2022, 2024 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz 3;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz
4;;; Copyright © 2026 Simon Tournier <zimon.toutoune@gmail.com>
4;;; 5;;;
5;;; This file is part of GNU Guix. 6;;; This file is part of GNU Guix.
6;;; 7;;;
@@ -279,4 +280,75 @@
279 (not (file-exists? 280 (not (file-exists?
280 (in-vicinity cache "stale-untracked-file"))))))))) 281 (in-vicinity cache "stale-untracked-file")))))))))
281 282
283(test-assert "update-cached-checkout, symref tag"
284 (call-with-temporary-directory
285 (lambda (cache)
286 (with-temporary-git-repository directory
287 '((add "a.txt" "A")
288 (commit "First commit")
289 (tag "v1.0" "release-1.0")
290 (branch "develop")
291 (checkout "develop")
292 (add "b.txt" "B")
293 (commit "Second commit")
294 (tag "v1.1" "release-1.1")
295 (checkout "master"))
296 (let* ((tag-directory (let* ((pipe (open-pipe* OPEN_READ (git-command)
297 "-C" directory
298 "rev-parse" "v1.1"))
299 (str (get-string-all pipe)))
300 (close-pipe pipe)
301 (string-trim-right str)))
302 (cached-directory commit relation
303 (update-cached-checkout directory
304 #:ref '(symref . "refs/tags/v1.1")
305 #:cache-directory cache))
306 (head-cached (let* ((pipe (open-pipe* OPEN_READ (git-command)
307 "-C" cached-directory
308 ;; switch-to-ref doesn't dereference the Git object,
309 ;; thus it points to a Git tag object.
310 ;; And HEAD points to a Git commit object.
311 ;; Hence, the check is against Git tag objects.
312 ;; For the difference see:
313 ;; git show-ref --dereference v1.1
314 "rev-parse" "v1.1"))
315 (str (get-string-all pipe)))
316 (close-pipe pipe)
317 (string-trim-right str))))
318 (and (string=? commit head-cached)
319 (string=? tag-directory head-cached)))))))
320
321(test-assert "update-cached-checkout, symref pull-request"
322 (call-with-temporary-directory
323 (lambda (cache)
324 (with-temporary-git-repository directory
325 '((add "a.txt" "A")
326 (commit "First commit")
327 (tag "v1.0" "release-1.0")
328 (branch "develop")
329 (checkout "develop")
330 (add "b.txt" "B")
331 (commit "Second commit")
332 (tag "v1.1" "release-1.1")
333 (symbolic-ref "refs/pull/1/head" "refs/heads/develop")
334 (checkout "master"))
335 (let* ((head-directory (let* ((pipe (open-pipe* OPEN_READ (git-command)
336 "-C" directory
337 "rev-parse" "refs/pull/1/head"))
338 (str (get-string-all pipe)))
339 (close-pipe pipe)
340 (string-trim-right str)))
341 (cached-directory commit relation
342 (update-cached-checkout directory
343 #:ref '(symref . "refs/pull/1/head")
344 #:cache-directory cache))
345 (head-cached (let* ((pipe (open-pipe* OPEN_READ (git-command)
346 "-C" cached-directory
347 "rev-parse" "HEAD"))
348 (str (get-string-all pipe)))
349 (close-pipe pipe)
350 (string-trim-right str))))
351 (and (string=? commit head-directory)
352 (string=? head-cached head-directory)))))))
353
282(test-end "git") 354(test-end "git")