diff options
| -rw-r--r-- | guix/channels.scm | 20 | ||||
| -rw-r--r-- | guix/git.scm | 16 | ||||
| -rw-r--r-- | guix/tests/git.scm | 4 | ||||
| -rw-r--r-- | tests/git.scm | 72 |
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") |
