GNU bug report logs - #75975
[PATCH (WIP) 0/4] Add 'guix fork'.

Previous Next

Package: guix-patches;

Reported by: 45mg <45mg.writes <at> gmail.com>

Date: Fri, 31 Jan 2025 18:30:02 UTC

Severity: normal

Tags: patch

Done: 45mg <45mg.writes <at> gmail.com>

To reply to this bug, email your comments to 75975 AT debbugs.gnu.org.
There is no need to reopen the bug first.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to ludo <at> gnu.org, maxim.cournoyer <at> gmail.com, guix-patches <at> gnu.org:
bug#75975; Package guix-patches. (Fri, 31 Jan 2025 18:30:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to 45mg <45mg.writes <at> gmail.com>:
New bug report received and forwarded. Copy sent to ludo <at> gnu.org, maxim.cournoyer <at> gmail.com, guix-patches <at> gnu.org. (Fri, 31 Jan 2025 18:30:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: 45mg <45mg.writes <at> gmail.com>
To: guix-patches <at> gnu.org
Cc: Nicolas Graves <ngraves <at> ngraves.fr>, Tomas Volf <~@wolfsden.cz>,
 45mg <45mg.writes <at> gmail.com>,
 Liliana Marie Prikler <liliana.prikler <at> gmail.com>,
 Ricardo Wurmus <rekado <at> elephly.net>, Attila Lendvai <attila <at> lendvai.name>
Subject: [PATCH (WIP) 0/4] Add 'guix fork'.
Date: Fri, 31 Jan 2025 23:58:44 +0530
Hello Guix,

This patch series aims to enable and automate the creation and management of
authenticated local forks of Guix. The purpose of this work is to allow
contributors to use their own patches before they're applied to
upstream Guix, so that their own use of Guix is not hindered by the slow and
erratic pace of patch review.

This is a solution to bug #75552 [1], in whose discussion thread the design
was conceived and refined. Credit goes to Tomas for being the first person (to
my knowledge) to share their solution to this problem [2], which provided a
blueprint for 'guix fork create'; to Liliana for the idea behind the way 'guix
fork update' works [3]; and to Ricardo for the idea behind 'guix fork
identify' [4]. I've also CC'ed Attila and Nicolas since they replied in the
original thread (apologies in advance if I shouldn't have).

As I mentioned in the original thread [5], this solution aims to satisfy four
conditions which are not met by any existing method to my knowledge:

1. Allows authenticating both upstream and fork commits.
2. Does not require bumping the channel introduction (as distributing channel
introductions is sensitive)
3. Keeps fork history intact (to avoid force pulls).
4. Keeps upstream history intact (to avoid confusion).

Despite the '(WIP)' subject prefix, this patch series should be perfectly
usable in its current state. The easiest way to try it out would be as follows:

1. Apply it to your local clone of Guix (eg. in a branch) and build it.
2. 'cp -r' your local clone to another location.
3. Run the following command:
./pre-inst-env guix fork create <fingerprint-of-your-key> path/to/copy/of/local/clone --use-existing

Now you have the setup needed for an authenticated local fork. From here, you
can create and 'guix pull' (with authentication) from branches starting from
the initial fork commit. You can authenticate both fork and upstream using
'guix fork authenticate', even if the key used to create your fork is not
authorized upstream. You can update your fork with new commits from upstream
using 'guix fork update'.

The documentation (additions to doc/guix.texi and doc/contributing.texi)
should provide a proper overview of these commands and their usage. Easiest
way to view it could be to run 'make doc/guix.html' and then open it in a
browser.

The '(WIP)' subject prefix is there because the following things are yet to be
implemented:
1. The 'guix fork identify' command.
2. Tests, along the lines of tests/guix-git-authenticate.sh.

The code here adapts certain procedures from Tomas Volf's original 'fork-guix'
script [6]; namely: '-->', 'invoke/c', 'create-keyring-branch', 'git-C', and
'git-C/c'. That script is licensed under AGPL, so my understanding is that it,
or the procedures I used from it, would need to be relicensed under GPLv3 to
be included into Guix. Tomas - could you confirm here that you're willing to
do so, as we discussed earlier? (Note that I didn't ask you about the last two
of the five procedures above, since I hadn't used them yet at the time.)

Regards,
45mg

P.S For some reason, if I `guix pull` from a local clone with these patches
applied, Guix tries to build stuff from (gnu packages commencement) from
source, even though I applied them to a commit for which CI has already built
substitutes [7]. It's been stuck on that for hours, so I don't even know the
extent of the rebuild it's trying to do. I am unable to figure out why this is
happening. Any ideas are welcome, since I'd like to start daily-driving this
patch series as soon as possible.

[1] https://issues.guix.gnu.org/75552
[2] https://lists.gnu.org/archive/html/help-guix/2023-09/msg00078.html
[3] https://lists.nongnu.org/archive/html/bug-guix/2025-01/msg00139.html
[4] https://lists.nongnu.org/archive/html/bug-guix/2025-01/msg00130.html
[5] https://lists.nongnu.org/archive/html/bug-guix/2025-01/msg00135.html
[6] https://git.wolfsden.cz/guix/tree/etc/fork-guix
[7] https://ci.guix.gnu.org/eval/2036099


45mg (4):
  Add 'guix fork create'.
  Add 'guix fork authenticate'.
  Add 'guix fork update'.
  Document 'guix fork'.

 Makefile.am                        |   4 +
 doc/contributing.texi              |  50 +++++
 doc/guix.texi                      | 149 +++++++++++++
 guix/build/utils.scm               |  20 ++
 guix/channels.scm                  |  13 ++
 guix/git-authenticate.scm          |  17 ++
 guix/git.scm                       |  10 +
 guix/scripts/fork.scm              |  71 +++++++
 guix/scripts/fork/authenticate.scm | 330 +++++++++++++++++++++++++++++
 guix/scripts/fork/create.scm       | 253 ++++++++++++++++++++++
 guix/scripts/fork/update.scm       | 181 ++++++++++++++++
 guix/scripts/git/authenticate.scm  |  45 +---
 guix/utils.scm                     |  33 +++
 13 files changed, 1135 insertions(+), 41 deletions(-)
 create mode 100644 guix/scripts/fork.scm
 create mode 100644 guix/scripts/fork/authenticate.scm
 create mode 100644 guix/scripts/fork/create.scm
 create mode 100644 guix/scripts/fork/update.scm


base-commit: b85d20e853192a92093cd8d6a5756ec80e94c658
-- 
2.47.1





Information forwarded to andreas <at> enge.fr, guix <at> cbaines.net, janneke <at> gnu.org, dev <at> jpoiret.xyz, ludo <at> gnu.org, othacehe <at> gnu.org, zimon.toutoune <at> gmail.com, me <at> tobias.gr, guix-patches <at> gnu.org:
bug#75975; Package guix-patches. (Fri, 31 Jan 2025 18:35:02 GMT) Full text and rfc822 format available.

Message #8 received at 75975 <at> debbugs.gnu.org (full text, mbox):

From: 45mg <45mg.writes <at> gmail.com>
To: 75975 <at> debbugs.gnu.org
Cc: 45mg <45mg.writes <at> gmail.com>
Subject: [PATCH (WIP) 1/4] Add 'guix fork create'.
Date: Sat,  1 Feb 2025 00:02:48 +0530
* guix/scripts/fork.scm, guix/scripts/fork/create.scm: New files.
* Makefile.am (MODULES): Add the new files.
* guix/build/utils.scm (invoke/stdout): New procedure.
* guix/utils.scm (chain-cut): New procedure.
* guix/scripts/git/authenticate.scm
(commit-short-id): Remove procedure, and use its existing duplicate in
guix/channels.scm.
(openpgp-fingerprint*, current-branch, show-stats): Move procedures to
the files below.
* guix/channels.scm (openpgp-fingerprint*): Moved here.
* guix/git.scm (repository-current-branch): Moved here and renamed from
'current-branch'.
* guix/git-authenticate.scm (show-authentication-stats): Moved here and
renamed from 'show-stats'.

Change-Id: I45ba37f434e136f6d496c741d9a933280f9ccf88
---
 Makefile.am                       |   2 +
 guix/build/utils.scm              |  20 +++
 guix/channels.scm                 |  13 ++
 guix/git-authenticate.scm         |  17 ++
 guix/git.scm                      |  10 ++
 guix/scripts/fork.scm             |  67 ++++++++
 guix/scripts/fork/create.scm      | 257 ++++++++++++++++++++++++++++++
 guix/scripts/git/authenticate.scm |  45 +-----
 guix/utils.scm                    |  33 ++++
 9 files changed, 423 insertions(+), 41 deletions(-)
 create mode 100644 guix/scripts/fork.scm
 create mode 100644 guix/scripts/fork/create.scm

diff --git a/Makefile.am b/Makefile.am
index f759803b8b..c628450a5a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -377,6 +377,8 @@ MODULES =					\
   guix/scripts/size.scm				\
   guix/scripts/git.scm				\
   guix/scripts/git/authenticate.scm		\
+  guix/scripts/fork.scm			\
+  guix/scripts/fork/create.scm			\
   guix/scripts/graph.scm			\
   guix/scripts/weather.scm			\
   guix/scripts/container.scm			\
diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index 94714bf397..e8bd39f5de 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -10,6 +10,8 @@
 ;;; Copyright © 2021, 2022 Maxime Devos <maximedevos <at> telenet.be>
 ;;; Copyright © 2021 Brendan Tildesley <mail <at> brendan.scot>
 ;;; Copyright © 2023 Carlo Zancanaro <carlo <at> zancanaro.id.au>
+;;; Copyright © 2025 Tomas Volf <~@wolfsden.cz>
+;;; Copyright © 2025 45mg <45mg.writes <at> gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -39,6 +41,7 @@ (define-module (guix build utils)
   #:use-module (ice-9 rdelim)
   #:use-module (ice-9 format)
   #:use-module (ice-9 threads)
+  #:use-module (ice-9 popen)
   #:use-module (rnrs bytevectors)
   #:use-module (rnrs io ports)
   #:re-export (alist-cons
@@ -128,6 +131,7 @@ (define-module (guix build utils)
             report-invoke-error
 
             invoke/quiet
+            invoke/stdout
 
             make-desktop-entry-file
 
@@ -889,6 +893,22 @@ (define (invoke/quiet program . args)
         (line
          (loop (cons line lines)))))))
 
+(define (invoke/stdout program . args)
+  "Invoke PROGRAM with ARGS and capture PROGRAM's standard output.  If PROGRAM
+succeeds, return its standard output as a string.  Otherwise, raise an
+'&invoke-error' condition."
+  (let* ((port (apply open-pipe* OPEN_READ program args))
+         (data (get-string-all port))
+         (code (close-pipe port)))
+    (unless (zero? code)
+      (raise (condition (&invoke-error
+                         (program program)
+                         (arguments args)
+                         (exit-status (status:exit-val code))
+                         (term-signal (status:term-sig code))
+                         (stop-signal (status:stop-sig code))))))
+    data))
+
 
 ;;;
 ;;; Text substitution (aka. sed).
diff --git a/guix/channels.scm b/guix/channels.scm
index 4700f7a45d..6ca8e64881 100644
--- a/guix/channels.scm
+++ b/guix/channels.scm
@@ -47,6 +47,7 @@ (define-module (guix channels)
   #:use-module (guix packages)
   #:use-module (guix progress)
   #:use-module (guix derivations)
+  #:autoload   (rnrs bytevectors) (bytevector-length)
   #:use-module (guix diagnostics)
   #:use-module (guix sets)
   #:use-module (guix store)
@@ -81,6 +82,7 @@ (define-module (guix channels)
 
             openpgp-fingerprint->bytevector
             openpgp-fingerprint
+            openpgp-fingerprint*
 
             %default-guix-channel
             %default-channels
@@ -171,6 +173,17 @@ (define-syntax openpgp-fingerprint
       ((_ str)
        #'(openpgp-fingerprint->bytevector str)))))
 
+(define (openpgp-fingerprint* str)
+  "Like openpgp-fingerprint, but with error handling from (guix diagnostics)."
+    (unless (string-every (char-set-union char-set:hex-digit
+                                          char-set:whitespace)
+                          str)
+      (leave (G_ "~a: invalid OpenPGP fingerprint~%") str))
+    (let ((fingerprint (openpgp-fingerprint str)))
+      (unless (= 20 (bytevector-length fingerprint))
+        (leave (G_ "~a: wrong length for OpenPGP fingerprint~%") str))
+      fingerprint))
+
 (define %guix-channel-introduction
   ;; Introduction of the official 'guix channel.  The chosen commit is the
   ;; first one that introduces '.guix-authorizations' on the 'staging'
diff --git a/guix/git-authenticate.scm b/guix/git-authenticate.scm
index 37c69d0880..8bc7fb6fb3 100644
--- a/guix/git-authenticate.scm
+++ b/guix/git-authenticate.scm
@@ -40,6 +40,7 @@ (define-module (guix git-authenticate)
   #:use-module (rnrs bytevectors)
   #:use-module (rnrs io ports)
   #:use-module (ice-9 match)
+  #:use-module (ice-9 format)
   #:autoload   (ice-9 pretty-print) (pretty-print)
   #:export (read-authorizations
             commit-signing-key
@@ -52,6 +53,7 @@ (define-module (guix git-authenticate)
 
             repository-cache-key
             authenticate-repository
+            show-authentication-stats
 
             git-authentication-error?
             git-authentication-error-commit
@@ -449,3 +451,18 @@ (define* (authenticate-repository repository start signer
                                       (oid->string (commit-id end-commit)))
 
           stats))))
+
+(define (show-authentication-stats stats)
+  "Display STATS, an alist containing commit signing stats as returned by
+'authenticate-repository'."
+  (format #t (G_ "Signing statistics:~%"))
+  (for-each (match-lambda
+              ((signer . count)
+               (format #t "  ~a ~10d~%"
+                       (openpgp-format-fingerprint
+                        (openpgp-public-key-fingerprint signer))
+                       count)))
+            (sort stats
+                  (match-lambda*
+                    (((_ . count1) (_ . count2))
+                     (> count1 count2))))))
diff --git a/guix/git.scm b/guix/git.scm
index 6ac6e4e3a2..afeacb53aa 100644
--- a/guix/git.scm
+++ b/guix/git.scm
@@ -59,6 +59,7 @@ (define-module (guix git)
             with-git-error-handling
             false-if-git-not-found
             repository-info
+            repository-current-branch
             update-cached-checkout
             url+commit->name
             latest-repository-commit
@@ -401,6 +402,15 @@ (define (repository-info directory)
     (lambda _
       (values #f #f #f))))
 
+(define (repository-current-branch repository)
+  "Return the name of the checked out branch of REPOSITORY or #f if it could
+not be determined."
+  (and (not (repository-head-detached? repository))
+       (let* ((head (repository-head repository))
+              (name (reference-name head)))
+         (and (string-prefix? "refs/heads/" name)
+              (string-drop name (string-length "refs/heads/"))))))
+
 (define* (update-submodules repository
                             #:key (log-port (current-error-port))
                             (fetch-options #f))
diff --git a/guix/scripts/fork.scm b/guix/scripts/fork.scm
new file mode 100644
index 0000000000..2d97bcb93f
--- /dev/null
+++ b/guix/scripts/fork.scm
@@ -0,0 +1,67 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2025 45mg <45mg.writes <at> gmail.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix scripts fork)
+  #:use-module (ice-9 match)
+  #:use-module (guix ui)
+  #:use-module (guix scripts)
+  #:export (guix-fork))
+
+(define (show-help)
+  (display (G_ "Usage: guix fork ACTION ARGS...
+Create and manage authenticated forks of Guix.\n"))
+  (newline)
+  (display (G_ "The valid values for ACTION are:\n"))
+  (newline)
+  (display (G_ "\
+   create    set up a fork of Guix\n"))
+  (newline)
+  (display (G_ "
+  -h, --help             display this help and exit"))
+  (display (G_ "
+  -V, --version          display version information and exit"))
+  (newline)
+  (show-bug-report-information))
+
+(define %sub-commands '("create"))
+
+(define (resolve-sub-command name)
+  (let ((module (resolve-interface
+                 `(guix scripts fork ,(string->symbol name))))
+        (proc (string->symbol (string-append "guix-fork-" name))))
+    (module-ref module proc)))
+
+(define-command (guix-fork . args)
+  (category plumbing)
+  (synopsis "operate on Guix forks")
+
+  (with-error-handling
+    (match args
+      (()
+       (format (current-error-port)
+               (G_ "guix fork: missing sub-command~%")))
+      ((or ("-h") ("--help"))
+       (leave-on-EPIPE (show-help))
+       (exit 0))
+      ((or ("-V") ("--version"))
+       (show-version-and-exit "guix fork"))
+      ((sub-command args ...)
+       (if (member sub-command %sub-commands)
+           (apply (resolve-sub-command sub-command) args)
+           (format (current-error-port)
+                   (G_ "guix fork: invalid sub-command~%")))))))
diff --git a/guix/scripts/fork/create.scm b/guix/scripts/fork/create.scm
new file mode 100644
index 0000000000..8b5555947b
--- /dev/null
+++ b/guix/scripts/fork/create.scm
@@ -0,0 +1,257 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2025 Tomas Volf <~@wolfsden.cz>
+;;; Copyright © 2025 45mg <45mg.writes <at> gmail.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix scripts fork create)
+  #:use-module (guix ui)
+  #:use-module (guix scripts)
+  #:use-module ((guix utils) #:select (chain-cut))
+  #:use-module (guix build utils)
+  #:use-module (guix channels)
+  #:use-module (ice-9 exceptions)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 popen)
+  #:use-module (ice-9 pretty-print)
+  #:use-module (ice-9 string-fun)
+  #:use-module (ice-9 textual-ports)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-13)
+  #:use-module (srfi srfi-26)
+  #:use-module (srfi srfi-37)
+  #:use-module (srfi srfi-71)
+  #:export (guix-fork-create))
+
+;;; Commentary:
+;;;
+;;; Create a fork of Guix, by running a series of git commands.
+;;;
+;;; Code:
+
+(define %options
+  ;; Specifications of the command-line options.
+  (list (option '(#\h "help") #f #f
+                (lambda args
+                  (show-help)
+                  (exit 0)))
+        (option '(#\V "version") #f #f
+                (lambda args
+                  (show-version-and-exit "guix fork create")))
+        (option '("upstream") #t #f
+                (lambda (opt name arg result)
+                  (alist-cons 'upstream arg result)))
+        (option '("channel-url") #t #f
+                (lambda (opt name arg result)
+                  (alist-cons 'channel-url arg result)))
+        (option '("use-existing") #f #f
+                (lambda (opt name arg result)
+                  (alist-cons 'use-existing? #t result)))
+        (option '("git-parameter") #t #f
+                (lambda (opt name arg result)
+                  (let ((git-parameters (assoc-ref result 'git-parameters)))
+                    (if git-parameters
+                        (alist-cons 'git-parameters (cons arg git-parameters) result)
+                        (alist-cons 'git-parameters (list arg) result)))))))
+
+(define %default-options
+  `((upstream . ,(channel-url %default-guix-channel))))
+
+(define %usage
+  (format #f (G_ "Usage: guix fork create SIGNING_KEY [DIRECTORY OPTIONS...]
+Create a fork of Guix in DIRECTORY, using SIGNING_KEY to sign the introductory
+commit.
+DIRECTORY defaults to ./guix.
+
+      --upstream=URI     the repository to clone from
+                         (defaults to ~a)
+      --channel-url=URI  optional URI, used to replace the channel URL
+                         and the existing 'origin' remote (which is
+                         renamed to 'upstream')
+      --use-existing     Use existing clone of Guix in DIRECTORY
+      --git-parameter PARAMETER
+                         Specify configuration PARAMETER for git, via
+                         '-c' option (can pass multiple times)
+
+  -h, --help             display this help and exit
+  -V, --version          display version information and exit
+")
+      (channel-url %default-guix-channel)))
+
+(define (show-help)
+  (display %usage)
+  (newline)
+  (show-bug-report-information))
+
+(define (missing-arguments)
+    (leave (G_ "wrong number of arguments; \
+required SIGNING_KEY~%")))
+
+
+;;;
+;;; Helper prodecures.
+;;;
+
+(define (fingerprint->key-file-name fingerprint)
+  (let* ((listing (invoke/stdout "gpg" "--list-key" "--with-colons" fingerprint))
+         (uid (chain-cut listing
+                           (string-split <> #\newline)
+                           (filter (cut string-prefix? "uid:" <>) <>)
+                           first
+                           (string-split <> #\:)
+                           tenth))
+         (email-name (string-delete
+                      (cut eq? <> #\.)
+                      (substring uid
+                                 (1+ (or (string-index-right uid #\<)
+                                         -1))  ;no name in uid
+                                 (string-index uid #\@))))
+         (key-id (chain-cut listing
+                      (string-split <> #\newline)
+                      (filter (cut string-prefix? "pub:" <>) <>)
+                      car
+                      (string-split <> #\:)
+                      fifth
+                      (string-take-right <> 8))))
+    (string-append email-name "-" key-id ".key")))
+
+(define (update-channel-url file channel-url)
+  "Modify .guix_channel FILE.
+Change the channel url to CHANNEL-URL."
+  (let ((channel-data (call-with-input-file file read)))
+    (assq-set! (cdr channel-data) 'url (list channel-url))
+    (call-with-output-file file
+      (lambda (file)
+        (display ";; This is a Guix channel.\n\n" file)
+        (pretty-print channel-data file)))))
+
+(define (rewrite-authorizations file name fingerprint)
+  "Rewrite .guix-authorizations FILE to contain a single authorization
+consisting of NAME and FINGERPRINT."
+  (let ((auth-data (call-with-input-file file read)))
+    (list-set! auth-data (1- (length auth-data))
+               `((,fingerprint (name ,name))))
+    (call-with-output-file file
+      (lambda (file)
+        (display ";; This file, which is best viewed as -*- Scheme -*-, lists the OpenPGP keys
+;; currently authorized to sign commits in this fork branch.
+
+" file)
+        (pretty-print auth-data file)))))
+
+
+;;;
+;;; Entry point.
+;;;
+
+(define (guix-fork-create . args)
+  (define options
+    (parse-command-line args %options (list %default-options)
+                        #:build-options? #f))
+
+  (define (command-line-arguments lst)
+    (reverse (filter-map (match-lambda
+                           (('argument . arg) arg)
+                           (_ #f))
+                         lst)))
+
+  (with-error-handling
+    (let* ((signing-key directory (match (command-line-arguments options)
+                                    ((signing-key directory)
+                                     (values signing-key directory))
+                                    ((signing-key)
+                                     (values signing-key "guix"))
+                                    (_ (missing-arguments))))
+           (upstream (assoc-ref options 'upstream))
+           (channel-url (assoc-ref options 'channel-url))
+           (use-existing? (assoc-ref options 'use-existing?))
+           (git-parameters (assoc-ref options 'git-parameters))
+           (git-c-options  ;'("-c" "param1" "-c" "param2" ...)
+            (let loop ((opts '()) (params git-parameters))
+              (if (or (not params) (null-list? params))
+                  opts
+                  (loop (append
+                         opts (list "-c" (first params)))
+                        (drop params 1)))))
+
+           (key-file-name (fingerprint->key-file-name signing-key))
+           (introduction-name (car (string-split key-file-name #\-)))
+
+           (upstream-branch-name "master"))
+
+      (define (invoke-git . args)
+        (apply invoke `("git" ,@git-c-options "-C" ,directory ,@args)))
+
+      (unless use-existing?
+        (info (G_ "Cloning from upstream ~a...~%") upstream)
+        (invoke "git" "clone" upstream directory))
+
+      (info (G_ "Authenticating upstream commits...~%"))
+
+      (when channel-url
+        (info (G_ "Renaming existing 'origin' remote to 'upstream'...~%"))
+        (invoke-git "remote" "rename" "origin" "upstream")
+        (info (G_ "Using provided channel URL for new 'origin' remote...~%"))
+        (invoke-git "remote" "add" "origin" channel-url))
+
+      (set! upstream-branch-name
+            (chain-cut
+             (invoke/stdout "git"
+                            "-C" directory
+                            "symbolic-ref"
+                            (string-append "refs/remotes/"
+                                           (if channel-url "upstream" "origin")
+                                           "/HEAD"))
+             string-trim-right
+             (string-split <> #\/)
+             last))
+
+      (info (G_ "Adding key to keyring branch...~%"))
+      (invoke-git "switch" "keyring")
+      (invoke "gpg"
+              "--armor" "--export"
+              "-o" (string-append directory "/" key-file-name)
+              signing-key)
+      (invoke-git "add" "--" key-file-name)
+      (invoke-git "commit" "-m" "Add key for fork introduction.")
+
+      (info (G_ "Setting up fork branch...~%"))
+      (invoke-git "switch" "--create" "fork" "master")
+      (when channel-url
+        (update-channel-url (string-append directory "/.guix-channel")
+                            channel-url))
+      (rewrite-authorizations (string-append directory "/.guix-authorizations")
+                              introduction-name signing-key)
+      (invoke-git "add" "--"
+                  (string-append directory "/.guix-authorizations")
+                  (string-append directory "/.guix-channel"))
+      (invoke-git "commit"
+                  (string-append "--gpg-sign=" signing-key)
+                  "-m"
+                  (string-append
+                   "Initial fork commit.\n\n"
+                   ".guix-authorizations: Allow only " introduction-name "'s key."
+                   (if channel-url
+                       "\n.guix-channels: Update channel URL."
+                       "")))
+
+      (info (G_ "Successfully created Guix fork in ~a.
+You should run the following command next:
+guix fork authenticate ~a ~a ~a~%")
+            directory
+            upstream-branch-name
+            (string-trim-right (invoke/stdout "git" "-C" directory "rev-parse" "HEAD"))
+            signing-key))))
diff --git a/guix/scripts/git/authenticate.scm b/guix/scripts/git/authenticate.scm
index e3ecb67c89..154aae9b14 100644
--- a/guix/scripts/git/authenticate.scm
+++ b/guix/scripts/git/authenticate.scm
@@ -23,8 +23,8 @@ (define-module (guix scripts git authenticate)
   #:use-module (guix git-authenticate)
   #:autoload   (guix openpgp) (openpgp-format-fingerprint
                                openpgp-public-key-fingerprint)
-  #:use-module ((guix channels) #:select (openpgp-fingerprint))
-  #:use-module ((guix git) #:select (with-git-error-handling))
+  #:use-module ((guix channels) #:select (openpgp-fingerprint*))
+  #:use-module ((guix git) #:select (with-git-error-handling commit-short-id repository-current-branch))
   #:use-module (guix progress)
   #:use-module (guix base64)
   #:autoload   (rnrs bytevectors) (bytevector-length)
@@ -76,15 +76,6 @@ (define %options
 (define %default-options
   '())
 
-(define (current-branch repository)
-  "Return the name of the checked out branch of REPOSITORY or #f if it could
-not be determined."
-  (and (not (repository-head-detached? repository))
-       (let* ((head (repository-head repository))
-              (name (reference-name head)))
-         (and (string-prefix? "refs/heads/" name)
-              (string-drop name (string-length "refs/heads/"))))))
-
 (define (config-value repository key)
   "Return the config value associated with KEY in the 'guix.authentication' or
 'guix.authentication-BRANCH' name space in REPOSITORY, or #f if no such config
@@ -94,7 +85,7 @@ (define (config-value repository key)
                   ((_ exp)
                    (catch 'git-error (lambda () exp) (const #f))))))
     (let* ((config (repository-config repository))
-           (branch (current-branch repository)))
+           (branch (repository-current-branch repository)))
       ;; First try the BRANCH-specific value, then the generic one.`
       (or (and branch
                (false-if-git-error
@@ -194,21 +185,6 @@ (define (install-hooks repository)
       (warning (G_ "cannot determine where to install hooks\
  (Guile-Git too old?)~%"))))
 
-(define (show-stats stats)
-  "Display STATS, an alist containing commit signing stats as returned by
-'authenticate-repository'."
-  (format #t (G_ "Signing statistics:~%"))
-  (for-each (match-lambda
-              ((signer . count)
-               (format #t "  ~a ~10d~%"
-                       (openpgp-format-fingerprint
-                        (openpgp-public-key-fingerprint signer))
-                       count)))
-            (sort stats
-                  (match-lambda*
-                    (((_ . count1) (_ . count2))
-                     (> count1 count2))))))
-
 (define (show-help)
   (display (G_ "Usage: guix git authenticate COMMIT SIGNER [OPTIONS...]
 Authenticate the given Git checkout using COMMIT/SIGNER as its introduction.\n"))
@@ -251,19 +227,6 @@ (define (guix-git-authenticate . args)
                            (_ #f))
                          lst)))
 
-  (define commit-short-id
-    (compose (cut string-take <> 7) oid->string commit-id))
-
-  (define (openpgp-fingerprint* str)
-    (unless (string-every (char-set-union char-set:hex-digit
-                                          char-set:whitespace)
-                          str)
-      (leave (G_ "~a: invalid OpenPGP fingerprint~%") str))
-    (let ((fingerprint (openpgp-fingerprint str)))
-      (unless (= 20 (bytevector-length fingerprint))
-        (leave (G_ "~a: wrong length for OpenPGP fingerprint~%") str))
-      fingerprint))
-
   (define (make-reporter start-commit end-commit commits)
     (format (current-error-port)
             (G_ "Authenticating commits ~a to ~a (~h new \
@@ -321,7 +284,7 @@ (define (guix-git-authenticate . args)
          (install-hooks repository))
 
        (when (and show-stats? (not (null? stats)))
-         (show-stats stats))
+         (show-authentication-stats stats))
 
        (info (G_ "successfully authenticated commit ~a~%")
              (oid->string end))))))
diff --git a/guix/utils.scm b/guix/utils.scm
index b6cf5aea4f..e07e89c321 100644
--- a/guix/utils.scm
+++ b/guix/utils.scm
@@ -21,6 +21,8 @@
 ;;; Copyright © 2023 Zheng Junjie <873216071 <at> qq.com>
 ;;; Copyright © 2023 Foundation Devices, Inc. <hello <at> foundationdevices.com>
 ;;; Copyright © 2024 Herman Rimm <herman <at> rimm.ee>
+;;; Copyright © 2025 Tomas Volf <~@wolfsden.cz>
+;;; Copyright © 2025 45mg <45mg.writes <at> gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -163,6 +165,8 @@ (define-module (guix utils)
             call-with-compressed-output-port
             canonical-newline-port
 
+            chain-cut
+
             string-distance
             string-closest
 
@@ -1193,6 +1197,35 @@ (define-syntax current-source-directory
           ;; raising an error would upset Geiser users
           #f))))))
 
+
+;;;
+;;; Higher-order functions.
+;;;
+
+(define-syntax chain-cut
+  (lambda (x)
+    "Apply each successive form to the result of evaluating the previous one.
+Before applying, expand each form (op ...) to (cut op ...).
+
+Examples:
+
+    (chain-cut '(1 2 3) cdr car)
+ => (car (cdr '(1 2 3)))
+
+    (chain-cut 2 (- 3 <>) 1+)
+ => (1+ ((cut - 3 <>) 2))
+ => (1+ (- 3 2))
+"
+    (syntax-case x ()
+      ((chain-cut init op) (identifier? #'op)
+       #'(op init))
+      ((chain-cut init (op ...))
+       #'((cut op ...) init))
+      ((chain-cut init op op* ...) (identifier? #'op)
+       #'(chain-cut (op init) op* ...))
+      ((chain-cut init (op ...) op* ...)
+       #'(chain-cut ((cut op ...) init) op* ...)))))
+
 
 ;;;
 ;;; String comparison.

base-commit: b85d20e853192a92093cd8d6a5756ec80e94c658
prerequisite-patch-id: 2d660c1f16c3ac553886bc5a0bbdc6b66fcdfe4f
-- 
2.47.1





Information forwarded to guix <at> cbaines.net, dev <at> jpoiret.xyz, ludo <at> gnu.org, othacehe <at> gnu.org, zimon.toutoune <at> gmail.com, me <at> tobias.gr, guix-patches <at> gnu.org:
bug#75975; Package guix-patches. (Fri, 31 Jan 2025 18:35:02 GMT) Full text and rfc822 format available.

Message #11 received at 75975 <at> debbugs.gnu.org (full text, mbox):

From: 45mg <45mg.writes <at> gmail.com>
To: 75975 <at> debbugs.gnu.org
Cc: 45mg <45mg.writes <at> gmail.com>
Subject: [PATCH (WIP) 2/4] Add 'guix fork authenticate'.
Date: Sat,  1 Feb 2025 00:02:49 +0530
* guix/scripts/fork/authenticate.scm: New file.
* Makefile.am (MODULES): Add the new file.
* guix/scripts/fork.scm
(show-help): Mention new command.
(%sub-commands): Add new command.

Change-Id: Ic34a1b3d1642cedce8d1ff5bae825df30e47755c
---
 Makefile.am                        |   1 +
 guix/scripts/fork.scm              |   6 +-
 guix/scripts/fork/authenticate.scm | 331 +++++++++++++++++++++++++++++
 3 files changed, 336 insertions(+), 2 deletions(-)
 create mode 100644 guix/scripts/fork/authenticate.scm

diff --git a/Makefile.am b/Makefile.am
index c628450a5a..1c1f5d84fd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -379,6 +379,7 @@ MODULES =					\
   guix/scripts/git/authenticate.scm		\
   guix/scripts/fork.scm			\
   guix/scripts/fork/create.scm			\
+  guix/scripts/fork/authenticate.scm			\
   guix/scripts/graph.scm			\
   guix/scripts/weather.scm			\
   guix/scripts/container.scm			\
diff --git a/guix/scripts/fork.scm b/guix/scripts/fork.scm
index 2d97bcb93f..c5c7a59ba7 100644
--- a/guix/scripts/fork.scm
+++ b/guix/scripts/fork.scm
@@ -29,7 +29,9 @@ (define (show-help)
   (display (G_ "The valid values for ACTION are:\n"))
   (newline)
   (display (G_ "\
-   create    set up a fork of Guix\n"))
+   create          set up a fork of Guix\n"))
+  (display (G_ "\
+   authenticate    authenticate a fork of Guix\n"))
   (newline)
   (display (G_ "
   -h, --help             display this help and exit"))
@@ -38,7 +40,7 @@ (define (show-help)
   (newline)
   (show-bug-report-information))
 
-(define %sub-commands '("create"))
+(define %sub-commands '("create" "authenticate"))
 
 (define (resolve-sub-command name)
   (let ((module (resolve-interface
diff --git a/guix/scripts/fork/authenticate.scm b/guix/scripts/fork/authenticate.scm
new file mode 100644
index 0000000000..83d9d87d44
--- /dev/null
+++ b/guix/scripts/fork/authenticate.scm
@@ -0,0 +1,331 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2025 45mg <45mg.writes <at> gmail.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix scripts fork authenticate)
+  #:use-module (git)
+  #:use-module (guix git)
+  #:use-module (guix git-authenticate)
+  #:use-module (guix base16)
+  #:use-module (guix ui)
+  #:use-module (guix progress)
+  #:use-module (guix scripts)
+  #:use-module (guix build utils)
+  #:use-module (guix channels)
+  #:use-module (ice-9 exceptions)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 receive)
+  #:use-module (ice-9 popen)
+  #:use-module (ice-9 format)
+  #:use-module (ice-9 pretty-print)
+  #:use-module (ice-9 string-fun)
+  #:use-module (ice-9 textual-ports)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-13)
+  #:use-module (srfi srfi-26)
+  #:use-module (srfi srfi-37)
+  #:use-module (srfi srfi-71)
+  #:export (guix-fork-authenticate
+
+            fork-config-value
+            fork-configured?
+            fork-configured-keyring-reference
+            fork-configured-introduction))
+
+;;; Commentary:
+;;;
+;;; Authenticate a fork of Guix, in the same manner as `guix git
+;;; authenticate`.
+;;;
+;;; Code:
+
+(define %options
+  ;; Specifications of the command-line options.
+  (list (option '(#\h "help") #f #f
+                (lambda args
+                  (show-help)
+                  (exit 0)))
+        (option '(#\V "version") #f #f
+                (lambda args
+                  (show-version-and-exit "guix fork authenticate")))
+
+        (option '(#\r "repository") #t #f
+                (lambda (opt name arg result)
+                  (alist-cons 'directory arg result)))
+        (option '("upstream-commit") #f #f
+                (lambda (opt name arg result)
+                  (alist-cons 'upstream-commit (string->oid arg) result)))
+        (option '("upstream-signer") #f #f
+                (lambda (opt name arg result)
+                  (alist-cons 'upstream-signer (openpgp-fingerprint* arg) result)))
+
+        (option '(#\e "end") #t #f
+                (lambda (opt name arg result)
+                  (alist-cons 'end-commit (string->oid arg) result)))
+        (option '("upstream-end") #t #f
+                (lambda (opt name arg result)
+                  (alist-cons 'upstream-end-commit (string->oid arg) result)))
+        (option '(#\k "keyring") #t #f
+                (lambda (opt name arg result)
+                  (alist-cons 'keyring-reference arg result)))
+        (option '("upstream-keyring") #t #f
+                (lambda (opt name arg result)
+                  (alist-cons 'upstream-keyring arg result)))
+        (option '("cache-key") #t #f
+                (lambda (opt name arg result)
+                  (alist-cons 'cache-key arg result)))
+        (option '("historical-authorizations") #t #f
+                (lambda (opt name arg result)
+                  (alist-cons 'historical-authorizations arg
+                              result)))
+        (option '("stats") #f #f
+                (lambda (opt name arg result)
+                  (alist-cons 'show-stats? #t result)))))
+
+(define %default-options
+  (let ((introduction (channel-introduction %default-guix-channel)))
+    `((upstream-commit
+       . ,(string->oid (channel-introduction-first-signed-commit introduction)))
+      (upstream-signer
+       . ,(openpgp-fingerprint
+           (string-upcase
+            (bytevector->base16-string
+             (channel-introduction-first-commit-signer introduction)))))
+      (upstream-keyring
+       . "keyring"))))
+
+(define %usage
+  (format #f (G_ "Usage: guix fork authenticate UPSTREAM COMMIT SIGNER [OPTIONS...]
+Authenticate a fork of Guix, using COMMIT/SIGNER as the fork introduction.
+
+First, authenticate new commits from UPSTREAM, using Guix's default
+introduction. Then authenticate the remaining commits using the fork
+introduction.
+
+  -r, --repository=DIRECTORY
+                         Authenticate the Git repository in DIRECTORY
+
+      --upstream-commit=COMMIT
+      --upstream-signer=SIGNER
+                         Use COMMIT/SIGNER as the introduction for upstream
+                         Guix, overriding the default values
+                         ~a
+                        /~a
+                         (Guix's default introduction).
+
+  -k, --keyring=REFERENCE
+                         load keyring for fork commits from REFERENCE, a Git
+                         branch (default \"keyring\")
+      --upstream-keyring=REFERENCE
+                         load keyring for upstream commits from REFERENCE, a
+                         Git branch (default \"keyring\")
+      --end=COMMIT       authenticate fork commits up to COMMIT
+      --cache-key=KEY    cache authenticated commits under KEY
+      --historical-authorizations=FILE
+                         read historical authorizations from FILE
+      --stats            Display commit signing statistics upon completion
+
+  -h, --help             display this help and exit
+  -V, --version          display version information and exit
+")
+          (assoc-ref %default-options 'upstream-commit)
+          (assoc-ref %default-options 'upstream-signer)))
+
+(define (show-help)
+  (display %usage)
+  (newline)
+  (show-bug-report-information))
+
+(define (missing-arguments)
+  (leave (G_ "wrong number of arguments; \
+required UPSTREAM, COMMIT and SIGNER~%")))
+
+
+;;;
+;;; Helper prodecures.
+;;;
+
+(define (fork-config-value repository key)
+  "Return the config value associated with KEY in the
+'guix.fork-authentication' namespace in REPOSITORY, or #f if no such config
+was found."
+  (let* ((config (repository-config repository))
+         (branch (repository-current-branch repository)))
+    (catch 'git-error
+      (lambda ()
+        (config-entry-value
+         (config-get-entry config
+                           (string-append "guix.fork-authentication."
+                                          key))))
+      (const #f))))
+
+(define (fork-configured-introduction repository)
+  "Return three values: the upstream branch name, introductory commit, and
+signer fingerprint (strings) for this fork, as configured in REPOSITORY.
+Error out if any were missing."
+  (let* ((upstream-branch (fork-config-value repository "upstream-branch"))
+         (commit (fork-config-value repository "introduction-commit"))
+         (signer (fork-config-value repository "introduction-signer")))
+    (unless (and upstream-branch commit signer)
+      (leave (G_ "fork information in .git/config is incomplete;
+missing at least one of
+introduction-commit, introduction-signer, upstream-branch
+under [guix \"fork-authentication\"]")))
+    (values upstream-branch commit signer)))
+
+(define (fork-configured-keyring-reference repository)
+  "Return the keyring reference configured in REPOSITORY or #f if missing."
+  (fork-config-value repository "keyring"))
+
+(define (fork-configured? repository)
+  "Return true if REPOSITORY already contains fork introduction info in its
+'config' file."
+  (and (fork-config-value repository "upstream-branch")
+       (fork-config-value repository "introduction-commit")
+       (fork-config-value repository "introduction-signer")))
+
+(define* (record-fork-configuration
+          repository
+          #:key commit signer upstream-branch keyring-reference)
+  "Record COMMIT, SIGNER, UPSTREAM-BRANCH and KEYRING-REFERENCE in the
+'config' file of REPOSITORY."
+  (define config
+    (repository-config repository))
+
+  ;; Guile-Git < 0.7.0 lacks 'set-config-string'.
+  (if (module-defined? (resolve-interface '(git)) 'set-config-string)
+      (begin
+        (set-config-string config "guix.fork-authentication.introduction-commit"
+                           commit)
+        (set-config-string config "guix.fork-authentication.introduction-signer"
+                           signer)
+        (set-config-string config "guix.fork-authentication.upstream-branch"
+                           upstream-branch)
+        (set-config-string config "guix.fork-authentication.keyring"
+                           keyring-reference)
+        (info (G_ "introduction, upstream branch and keyring recorded \
+in repository configuration file~%")))
+      (warning (G_ "could not record introduction and keyring configuration\
+ (Guile-Git too old?)~%"))))
+
+
+(define (guix-fork-authenticate . args)
+  (define options
+    (parse-command-line args %options (list %default-options)
+                        #:build-options? #f))
+
+  (define (command-line-arguments lst)
+    (reverse (filter-map (match-lambda
+                           (('argument . arg) arg)
+                           (_ #f))
+                         lst)))
+
+  (define (make-reporter start-commit end-commit commits)
+    (format (current-error-port)
+            (G_ "Authenticating commits ~a to ~a (~h new \
+commits)...~%")
+            (commit-short-id start-commit)
+            (commit-short-id end-commit)
+            (length commits))
+    (if (isatty? (current-error-port))
+        (progress-reporter/bar (length commits))
+        progress-reporter/silent))
+
+  (with-error-handling
+    (with-git-error-handling
+     ;; TODO: BUG: it doesn't recognize '~' in paths
+     ;; How to do 'realpath' in Guile?
+     (let* ((repository (repository-open (or (assoc-ref options 'directory)
+                                             (repository-discover "."))))
+            (upstream commit signer (match (command-line-arguments options)
+                                      ((upstream commit signer)
+                                       (values
+                                        (branch-lookup repository upstream)
+                                        (string->oid commit)
+                                        (openpgp-fingerprint* signer)))
+                                      (()
+                                       (receive (upstream commit signer)
+                                           (fork-configured-introduction repository)
+                                         (values
+                                          (branch-lookup repository upstream)
+                                          (string->oid commit)
+                                          (openpgp-fingerprint* signer))))
+                                      (_
+                                       (missing-arguments))))
+            (upstream-commit (assoc-ref options 'upstream-commit))
+            (upstream-signer (assoc-ref options 'upstream-signer))
+            (history (match (assoc-ref options 'historical-authorizations)
+                       (#f '())
+                       (file (call-with-input-file file
+                               read-authorizations))))
+            (keyring (or (assoc-ref options 'keyring-reference)
+                         (fork-configured-keyring-reference repository)
+                         "keyring"))
+            (upstream-keyring (assoc-ref options 'upstream-keyring))
+            (end (match (assoc-ref options 'end-commit)
+                   (#f  (reference-target
+                         (repository-head repository)))
+                   (oid oid)))
+            (upstream-end (match (assoc-ref options 'upstream-end-commit)
+                            (#f
+                             (reference-target upstream))
+                            (oid oid)))
+            (cache-key (or (assoc-ref options 'cache-key)
+                           (repository-cache-key repository)))
+            (show-stats? (assoc-ref options 'show-stats?)))
+
+       (define upstream-authentication-args
+         (filter identity
+                 (list
+                  (oid->string upstream-commit)
+                  (bytevector->base16-string upstream-signer)
+                  (string-append "--repository="
+                                 (repository-directory repository))
+                  (string-append "--end="
+                                 (oid->string upstream-end))
+                  (and upstream-keyring
+                       (string-append "--keyring="
+                                      upstream-keyring))
+                  (and show-stats? "--stats"))))
+
+       (info (G_ "calling `guix git authenticate` for branch ~a...~%")
+             (branch-name upstream))
+
+       (apply run-guix-command 'git "authenticate"
+              upstream-authentication-args)
+
+       (define fork-stats
+         (authenticate-repository
+          repository commit signer
+          #:end end
+          #:keyring-reference keyring
+          #:historical-authorizations history
+          #:cache-key cache-key
+          #:make-reporter make-reporter))
+
+       (unless (fork-configured? repository)
+         (record-fork-configuration repository
+                               #:commit (oid->string commit)
+                               #:signer (bytevector->base16-string signer)
+                               #:upstream-branch (branch-name upstream)
+                               #:keyring-reference keyring))
+
+       (when (and show-stats? (not (null? fork-stats)))
+         (show-authentication-stats fork-stats))
+
+       (info (G_ "successfully authenticated commit ~a~%")
+             (oid->string end))))))
-- 
2.47.1





Information forwarded to guix <at> cbaines.net, dev <at> jpoiret.xyz, ludo <at> gnu.org, othacehe <at> gnu.org, zimon.toutoune <at> gmail.com, me <at> tobias.gr, guix-patches <at> gnu.org:
bug#75975; Package guix-patches. (Fri, 31 Jan 2025 18:36:01 GMT) Full text and rfc822 format available.

Message #14 received at 75975 <at> debbugs.gnu.org (full text, mbox):

From: 45mg <45mg.writes <at> gmail.com>
To: 75975 <at> debbugs.gnu.org
Cc: 45mg <45mg.writes <at> gmail.com>
Subject: [PATCH (WIP) 3/4] Add 'guix fork update'.
Date: Sat,  1 Feb 2025 00:02:50 +0530
* guix/scripts/fork/update.scm: New file.
* Makefile.am (MODULES): Add the new file.
* guix/scripts/fork.scm
(show-help): Mention new command.
(%sub-commands): Add new command.

Change-Id: I2017eb9a9286c02ca8bdf962bcbfe89d7607c413
---
 Makefile.am                  |   1 +
 guix/scripts/fork.scm        |   4 +-
 guix/scripts/fork/update.scm | 181 +++++++++++++++++++++++++++++++++++
 3 files changed, 185 insertions(+), 1 deletion(-)
 create mode 100644 guix/scripts/fork/update.scm

diff --git a/Makefile.am b/Makefile.am
index 1c1f5d84fd..8edd371ccd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -380,6 +380,7 @@ MODULES =					\
   guix/scripts/fork.scm			\
   guix/scripts/fork/create.scm			\
   guix/scripts/fork/authenticate.scm			\
+  guix/scripts/fork/update.scm			\
   guix/scripts/graph.scm			\
   guix/scripts/weather.scm			\
   guix/scripts/container.scm			\
diff --git a/guix/scripts/fork.scm b/guix/scripts/fork.scm
index c5c7a59ba7..bf9c86e0aa 100644
--- a/guix/scripts/fork.scm
+++ b/guix/scripts/fork.scm
@@ -32,6 +32,8 @@ (define (show-help)
    create          set up a fork of Guix\n"))
   (display (G_ "\
    authenticate    authenticate a fork of Guix\n"))
+  (display (G_ "\
+   update          update a fork of Guix\n"))
   (newline)
   (display (G_ "
   -h, --help             display this help and exit"))
@@ -40,7 +42,7 @@ (define (show-help)
   (newline)
   (show-bug-report-information))
 
-(define %sub-commands '("create" "authenticate"))
+(define %sub-commands '("create" "authenticate" "update"))
 
 (define (resolve-sub-command name)
   (let ((module (resolve-interface
diff --git a/guix/scripts/fork/update.scm b/guix/scripts/fork/update.scm
new file mode 100644
index 0000000000..5aed337b85
--- /dev/null
+++ b/guix/scripts/fork/update.scm
@@ -0,0 +1,181 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2025 Tomas Volf <~@wolfsden.cz>
+;;; Copyright © 2025 45mg <45mg.writes <at> gmail.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (guix scripts fork update)
+  #:use-module (guix scripts fork authenticate)
+  #:use-module (git repository)
+  #:use-module (git structs)
+  #:use-module (git config)
+  #:use-module (guix ui)
+  #:use-module (guix scripts)
+  #:use-module (guix build utils)
+  #:use-module (guix channels)
+  #:use-module (ice-9 exceptions)
+  #:use-module (ice-9 match)
+  #:use-module (ice-9 popen)
+  #:use-module (ice-9 pretty-print)
+  #:use-module (ice-9 string-fun)
+  #:use-module (ice-9 textual-ports)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-13)
+  #:use-module (srfi srfi-26)
+  #:use-module (srfi srfi-37)
+  #:use-module (srfi srfi-71)
+  #:export (guix-fork-update))
+
+;;; Commentary:
+;;;
+;;; Update a fork of Guix created via `guix fork create` and authenticated via
+;;; `guix fork authenticate`, by applying new commits from the upstream branch
+;;; onto it.
+;;;
+;;; Code:
+
+(define %options
+  ;; Specifications of the command-line options.
+  (list (option '(#\h "help") #f #f
+                (lambda args
+                  (show-help)
+                  (exit 0)))
+        (option '(#\V "version") #f #f
+                (lambda args
+                  (show-version-and-exit "guix fork create")))
+
+        (option '( "fork-branch") #t #f
+                (lambda (opt name arg result)
+                  (alist-cons 'fork-branch-name arg result)))
+        (option '(#\r "repository") #t #f
+                (lambda (opt name arg result)
+                  (alist-cons 'directory arg result)))))
+
+(define %default-options
+  '())
+
+(define %usage
+  (G_ "Usage: guix fork update [OPTIONS...]
+Pull into this Guix fork's configured upstream branch, then apply new commits
+onto the current branch.
+
+  -r, --repository=DIRECTORY
+                         Act in the Git repository in DIRECTORY
+      --fork-branch=BRANCH
+                         Apply new commits onto BRANCH instead of the current
+                         branch
+
+  -h, --help             display this help and exit
+  -V, --version          display version information and exit
+"))
+
+(define (show-help)
+  (display %usage)
+  (newline)
+  (show-bug-report-information))
+
+(define (missing-arguments)
+    (leave (G_ "wrong number of arguments; \
+required ~%")))
+
+
+;;;
+;;; Entry point.
+;;;
+
+(define (guix-fork-update . args)
+
+  (define options
+    (parse-command-line args %options (list %default-options)
+                        #:build-options? #f))
+
+  (define (command-line-arguments lst)
+    (reverse (filter-map (match-lambda
+                           (('argument . arg) arg)
+                           (_ #f))
+                         lst)))
+
+  (define-syntax invoke-git
+    (lambda (x)
+      (syntax-case x ()
+        ((_ args ...)
+         #`(invoke "git" "-C" #,(datum->syntax x 'directory) args ...)))))
+
+  (define-syntax invoke-git/stdout
+    (lambda (x)
+      (syntax-case x ()
+        ((_ args ...)
+         #`(string-trim-right
+            (invoke/stdout "git" "-C" #,(datum->syntax x 'directory) args ...))))))
+
+  (with-error-handling
+    (let* ((directory (or (assoc-ref options 'directory) "."))
+           (current-branch-name (invoke-git/stdout
+                                 "branch"
+                                 "--show-current"))
+           (current-head-location (invoke-git/stdout
+                                   "rev-parse"
+                                   "HEAD"))
+           (fork-branch-name (or (assoc-ref options 'fork-branch-name)
+                                 (if (string= current-branch-name "")
+                                     (leave (G_ "no current branch and --fork-branch not given"))
+                                     current-branch-name)))
+
+           (repository (repository-open directory))
+           (upstream-branch-name introduction-commit introduction-signer
+                                 (if (fork-configured? repository)
+                                     (fork-configured-introduction
+                                      (repository-open directory))
+                                     (leave (G_ "fork not fully configured.
+(Did you remember to run `guix fork authenticate` first?)%~"))))
+           (upstream-branch-commit
+            (invoke-git/stdout "rev-parse" upstream-branch-name))
+           (new-upstream-branch-commit "")
+           (config (repository-config repository))
+           (signing-key
+            (or
+             (catch 'git-error
+               (lambda ()
+                 (config-entry-value
+                  (config-get-entry config "user.signingkey")))
+               (const #f))
+             (begin
+               (info (G_ "user.signingkey not set for this repository.~%"))
+               (info (G_ "Will attempt to sign commits with fork introduction key.~%"))
+               introduction-signer))))
+
+      (info (G_ "Pulling into '~a'...~%") upstream-branch-name)
+      (invoke-git "switch" upstream-branch-name)
+      (invoke-git "pull")
+      (set! new-upstream-branch-commit
+            (invoke-git/stdout "rev-parse" upstream-branch-name))
+
+      (info (G_ "Rebasing commits from '~a' to '~a' onto fork branch '~a'...~%")
+            upstream-branch-commit
+            new-upstream-branch-commit
+            fork-branch-name)
+      (invoke-git "rebase" "--rebase-merges"
+                  (string-append "--gpg-sign=" signing-key)
+                  fork-branch-name new-upstream-branch-commit)
+
+      (info (G_ "Resetting fork branch '~a' to latest rebased commit...~%")
+            fork-branch-name)
+      (invoke-git "branch" "--force" fork-branch-name "HEAD")
+
+      (invoke-git "checkout" (or current-branch-name current-head-location))
+
+      (info (G_ "Successfully updated Guix fork in ~a~%")
+            directory))))
-- 
2.47.1





Information forwarded to ludo <at> gnu.org, maxim.cournoyer <at> gmail.com, guix-patches <at> gnu.org:
bug#75975; Package guix-patches. (Fri, 31 Jan 2025 18:36:02 GMT) Full text and rfc822 format available.

Message #17 received at 75975 <at> debbugs.gnu.org (full text, mbox):

From: 45mg <45mg.writes <at> gmail.com>
To: 75975 <at> debbugs.gnu.org
Cc: 45mg <45mg.writes <at> gmail.com>
Subject: [PATCH (WIP) 4/4] Document 'guix fork'.
Date: Sat,  1 Feb 2025 00:02:51 +0530
* doc/guix.texi (Invoking guix fork): New node.
* doc/contributing.texi (Using Your Own Patches): New node.

Change-Id: I06240f0fe8d1fe39f27130a72f5d0d92949c99da
---
 doc/contributing.texi |  50 ++++++++++++++
 doc/guix.texi         | 150 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 200 insertions(+)

diff --git a/doc/contributing.texi b/doc/contributing.texi
index c94ae940fa..bd4fd6c2ac 100644
--- a/doc/contributing.texi
+++ b/doc/contributing.texi
@@ -35,6 +35,7 @@ Contributing
 * Making Decisions::            Collectively choosing the way forward.
 * Commit Access::               Pushing to the official repository.
 * Reviewing the Work of Others::  Some guidelines for sharing reviews.
+* Using Your Own Patches::      Using your own work before it's accepted.
 * Updating the Guix Package::   Updating the Guix package definition.
 * Deprecation Policy::          Commitments and tools for deprecation.
 * Writing Documentation::       Improving documentation in GNU Guix.
@@ -3095,6 +3096,55 @@ Reviewing the Work of Others
 have reviewed more easily by adding a @code{reviewed-looks-good} usertag
 for the @code{guix} user (@pxref{Debbugs Usertags}).
 
+@node Using Your Own Patches
+@section Using Your Own Patches
+
+If you've taken the time to contribute code to Guix, chances are that
+you want the changes you've made to be reflected in your own Guix
+installation as soon as possible. Maybe you've added a package you want,
+and you want to start using it @emph{right now}. Or you've fixed a bug
+that affects you, and you want it to @emph{go away}.
+
+As described in the preceding sections, all contributions to Guix first
+go through a review process to ensure code quality. Sometimes, this can
+take longer than one would like. Ideally, the pace of the review process
+should not prevent you from benefiting from your own work.
+
+One way to work around this issue is to create an additional channel of
+your own (@pxref{Creating a Channel}), and add your code to it. For
+certain kinds of contributions, such as adding a new package, this is
+fairly straightforward - simply copy your new package definition(s) into
+a new file in the channel, and remove them when your contribution is
+accepted.
+
+However, there may be cases where this is not convenient. Certain kinds
+of changes, such as those that need to modify existing Guix internals,
+may be more challenging to incorporate into a channel. Moreoever, the
+more substantial your contribution is, the more work it will be to do
+so.
+
+@cindex fork, of Guix
+For such cases, there is another option. Recall that the patch series
+that you sent (@pxref{Sending a Patch Series}) was created from a one or
+more commits on a checkout of the Guix repository (@pxref{Building from
+Git}). You could simply specify this repository (referred to as your
+`Guix fork', or simply `fork', from here onwards), and its relevant
+branch, as your `@code{guix}' channel (@pxref{Using a Custom Guix
+Channel}). Now `@code{guix pull}' will fetch your new commits, and
+you'll see the changes you made reflected in your Guix installation!
+
+However, there's a potential complication to this approach - the issue
+of authentication (@pxref{Channel Authentication}). If your fork only
+exists on your local filesystem (a `local fork'), then you probably
+don't need to worry about this, and can pull without authentication
+(@pxref{Invoking guix pull}). But other situations, such as a remotely
+hosted fork, may make it important for your fork to be authenticated, in
+the same way that all channels are expected to be.
+
+Guix provides a @command{guix fork} command in order to simplify and
+automate many details of creating and managing and authenticated
+fork. For more information, @pxref{Invoking guix fork}.
+
 @node Updating the Guix Package
 @section Updating the Guix Package
 
diff --git a/doc/guix.texi b/doc/guix.texi
index b1b6d98e74..bbb5666d0a 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -311,6 +311,7 @@ Top
 * Invoking guix pack::          Creating software bundles.
 * The GCC toolchain::           Working with languages supported by GCC.
 * Invoking guix git authenticate::  Authenticating Git repositories.
+* Invoking guix fork::          Creating and managing authenticated forks of Guix.
 
 Programming Interface
 
@@ -5930,6 +5931,7 @@ Development
 * Invoking guix pack::          Creating software bundles.
 * The GCC toolchain::           Working with languages supported by GCC.
 * Invoking guix git authenticate::  Authenticating Git repositories.
+* Invoking guix fork::          Creating and managing authenticated forks of Guix.
 @end menu
 
 @node Invoking guix shell
@@ -7534,6 +7536,154 @@ Invoking guix git authenticate
 @end table
 
 
+@node Invoking guix fork
+@section Invoking @command{guix fork}
+
+@cindex @command{guix fork}
+
+The @command{guix fork} command provides the means to quickly set up,
+authenticate, and keep up-to-date an authenticated fork of Guix. For
+more information on authentication of a Guix checkout, @pxref{Invoking
+guix git authenticate}.
+
+Its syntax is:
+
+guix fork ACTION ARGS...
+
+ACTION specifies the fork-related action to perform. Currently, the
+following values are supported:
+
+@table @code
+@item create SIGNING_KEY [DIRECTORY OPTIONS...]
+Create a fork of Guix in DIRECTORY, using SIGNING_KEY to sign the introductory
+commit.
+DIRECTORY defaults to ./guix.
+
+First, clone Guix into DIRECTORY, unless @code{--use-existing} is
+given. Then, add SIGNING_KEY to the `@code{keyring}' branch of the
+repository. Finally, create a new `@code{fork}' branch based starting
+from the default branch, whose initial commit authorizes SIGNING_KEY
+alone (by adding it to @file{.guix-authorizations}) and is signed by it.
+
+The new `@code{fork}' branch is intended to mirror upstream
+Guix. Updating the fork amounts to applying all new commits to it (see
+the `@code{update}' command below for further explanation). You can work
+on patches in branches based off of this one, in much the same way as
+you would base them on Guix's default branch - every commit from the
+latter will be present in the former.
+
+To @command{guix pull} your changes, you could create a `build' branch
+starting from the initial fork commit, onto which you can cherry-pick or
+rebase commits from patch branches. This branch can then be specified
+for the `@code{guix}' channel (@pxref{Using a Custom Guix Channel}).
+Updating this channel can be done by merging the `@code{fork}' branch
+into it.
+
+OPTIONS can be one or more of the following:
+
+@table @code
+@item --use-existing
+Use existing clone of Guix in DIRECTORY. This is useful if you've
+already created commits for a patch series (@pxref{Using Your Own
+Patches}). However, all commits to the default branch, as well as any
+branches that may be merged into it in the future, must have been signed
+with an authorized key; otherwise, authentication will fail later.
+@item --upstream=URI
+The repository to clone from. This defaults to the default URL for the
+Guix repository.
+@item --channel-url=URI
+Optional URI, which if given, will be used to replace the channel URL.
+Furthermore, the existing `origin' remote (which tracks
+`@code{upstream}') is renamed to `upstream', and a new `origin' remote
+is created to track URI.
+@item --git-parameter PARAMETER
+Specify configuration PARAMETER for git, via `-c' option. You can pass
+this option multiple times.
+@end table
+
+@cindex authentication, of Guix forks
+@item authenticate UPSTREAM COMMIT SIGNER [OPTIONS...]
+Authenticate a Guix fork, using COMMIT and SIGNER as the fork
+introduction.
+
+First, authenticate new commits from UPSTREAM, using Guix's default
+introduction. Then authenticate the remaining commits using the fork
+introduction.
+
+As with @code{guix git authenticate}, all three of UPSTREAM, COMMIT and
+SIGNER will be cached in .git/config, so that you don't need to specify
+them after the first time.
+
+OPTIONS can be one or more of the following:
+
+@table @code
+@item --repository=DIRECTORY
+@itemx -r DIRECTORY
+Authenticate the git repository in DIRECTORY, instead of the current
+directory.
+@item --upstream-commit=COMMIT
+@itemx --upstream-signer=SIGNER
+Use COMMIT/SIGNER as the introduction for upstream
+Guix, instead of Guix's default channel introduction.
+@item --keyring=REFERENCE
+@itemx -k REFERENCE
+Load keyring for fork commits from REFERENCE, a Git branch (default
+`@code{keyring}').
+@item --upstream-keyring=REFERENCE
+Load keyring for upstream commits from REFERENCE, a Git branch (default
+`@code{keyring}').
+@item --end=COMMIT
+Authenticate fork commits up to COMMIT.
+@item --upstream-end=COMMIT
+Authenticate upstream commits up to COMMIT.
+
+@item --cache-key=KEY
+@itemx --historical-authorizations=FILE
+@itemx --stats
+Identical to the correponding options in @command{guix git authenticate}
+(@pxref{Invoking guix git authenticate}).
+@end table
+
+@item update [OPTIONS...]
+Pull into this Guix fork's configured upstream branch (from running
+@command{guix fork authenticate}), then apply new commits onto the
+current branch.
+
+This approach may seem less convenient than simply merging the upstream
+branch into the fork branch. Indeed, it duplicates every upstream commit
+under a different commit hash, and applying a large number of commits
+can be slow. However, this is currently the only feasible approach due
+to the nature of Guix's authentication mechanism. Namely, merge commits
+can only be authenticated if both their parents are signed by an
+authorized key, meaning that you can only use the merge workflow if
+you're authorized to commit to upstream Guix.
+
+For mapping commits on the fork branch to their equivalents on the
+upstream branch, you can use @command{guix fork identify} (see below).
+
+OPTIONS can be one or more of the following:
+
+@table @code
+@item --repository=DIRECTORY
+@itemx -r DIRECTORY
+Act in the Git repository in DIRECTORY.
+@item --fork-branch=BRANCH
+Apply new commits onto BRANCH instead of the current branch.
+@end table
+
+@item identify
+Coming soon!
+
+Given a commit hash from upstream Guix, print its equivalent on the fork
+branch, or vice versa.
+This uses the 'Change-Id:' line added to commit messages by Guix's
+'commit-msg' hook.
+The first invocation of this command will be slow, as the entire set of
+corresponding commits is built up as a hash table, and then
+cached. Subsequent invocations should be nearly instant.
+
+@end table
+
 @c *********************************************************************
 @node Programming Interface
 @chapter Programming Interface
-- 
2.47.1





Information forwarded to guix-patches <at> gnu.org:
bug#75975; Package guix-patches. (Fri, 31 Jan 2025 20:11:02 GMT) Full text and rfc822 format available.

Message #20 received at 75975 <at> debbugs.gnu.org (full text, mbox):

From: vicvbcun <guix <at> ikherbers.com>
To: 45mg <45mg.writes <at> gmail.com>
Cc: Nicolas Graves <ngraves <at> ngraves.fr>,
 Maxim Cournoyer <maxim.cournoyer <at> gmail.com>, Tomas Volf <~@wolfsden.cz>,
 Liliana Marie Prikler <liliana.prikler <at> gmail.com>,
 Ricardo Wurmus <rekado <at> elephly.net>, Attila Lendvai <attila <at> lendvai.name>,
 Ludovic Courtès <ludo <at> gnu.org>, 75975 <at> debbugs.gnu.org
Subject: Re: [bug#75975] [PATCH (WIP) 0/4] Add 'guix fork'.
Date: Fri, 31 Jan 2025 21:10:07 +0100
Hello,

On 2025-01-31T23:58:44+0530, 45mg wrote:
>[...]
>P.S For some reason, if I `guix pull` from a local clone with these patches
>applied, Guix tries to build stuff from (gnu packages commencement) from
>source, even though I applied them to a commit for which CI has already built
>substitutes [7]. It's been stuck on that for hours, so I don't even know the
>extent of the rebuild it's trying to do. I am unable to figure out why this is
>happening. Any ideas are welcome, since I'd like to start daily-driving this
>patch series as soon as possible.

I think this is because you modified the (guix build utils) module which 
just about any package will depend on.  In other words, every derivation 
changes and you will need to build every package yourself.  I'd 
recommend putting `invoke/stdout' somewhere else — at least as long as 
this is not in upstream Guix.

vicvbcun




Information forwarded to guix-patches <at> gnu.org:
bug#75975; Package guix-patches. (Fri, 31 Jan 2025 20:52:02 GMT) Full text and rfc822 format available.

Message #23 received at 75975 <at> debbugs.gnu.org (full text, mbox):

From: Tomas Volf <~@wolfsden.cz>
To: 45mg <45mg.writes <at> gmail.com>
Cc: Ricardo Wurmus <rekado <at> elephly.net>, Attila Lendvai <attila <at> lendvai.name>,
 Nicolas Graves <ngraves <at> ngraves.fr>,
 Liliana Marie Prikler <liliana.prikler <at> gmail.com>, 75975 <at> debbugs.gnu.org
Subject: Re: [PATCH (WIP) 0/4] Add 'guix fork'.
Date: Fri, 31 Jan 2025 21:51:29 +0100
[Message part 1 (text/plain, inline)]
45mg <45mg.writes <at> gmail.com> writes:

> The code here adapts certain procedures from Tomas Volf's original 'fork-guix'
> script [6]; namely: '-->', 'invoke/c', 'create-keyring-branch', 'git-C', and
> 'git-C/c'. That script is licensed under AGPL, so my understanding is that it,
> or the procedures I used from it, would need to be relicensed under GPLv3 to
> be included into Guix. Tomas - could you confirm here that you're willing to
> do so, as we discussed earlier? (Note that I didn't ask you about the last two
> of the five procedures above, since I hadn't used them yet at the
> time.)

I hereby declare the above mentioned procedures to be dual licensed
under AGPL-3.0-only and GPL-3.0-or-later.

That should remove any possible licensing issues for merging this
patch. ^_^

Tomas

-- 
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.
[signature.asc (application/pgp-signature, inline)]

Information forwarded to guix-patches <at> gnu.org:
bug#75975; Package guix-patches. (Fri, 31 Jan 2025 21:29:01 GMT) Full text and rfc822 format available.

Message #26 received at 75975 <at> debbugs.gnu.org (full text, mbox):

From: 45mg <45mg.writes <at> gmail.com>
To: Tomas Volf <~@wolfsden.cz>, 45mg <45mg.writes <at> gmail.com>,
 75975-done <at> debbugs.gnu.org, 75975 <at> debbugs.gnu.org 
Subject: Re: [PATCH (WIP) 0/4] Add 'guix fork'.
Date: Fri, 31 Jan 2025 21:28:13 +0000
Tomas Volf <~@wolfsden.cz> writes:

> I hereby declare the above mentioned procedures to be dual licensed
> under AGPL-3.0-only and GPL-3.0-or-later.
>
> That should remove any possible licensing issues for merging this
> patch. ^_^

Thank you, Tomas. I forwarded your message to #75981. Closing this one,
since I messed up sending the patches, based on how it looks on the
bug-guix archives.

Closing this.




Reply sent to 45mg <45mg.writes <at> gmail.com>:
You have taken responsibility. (Fri, 31 Jan 2025 21:29:02 GMT) Full text and rfc822 format available.

Notification sent to 45mg <45mg.writes <at> gmail.com>:
bug acknowledged by developer. (Fri, 31 Jan 2025 21:29:02 GMT) Full text and rfc822 format available.

Information forwarded to guix-patches <at> gnu.org:
bug#75975; Package guix-patches. (Fri, 31 Jan 2025 21:36:01 GMT) Full text and rfc822 format available.

Message #34 received at 75975 <at> debbugs.gnu.org (full text, mbox):

From: 45mg <45mg.writes <at> gmail.com>
To: vicvbcun <guix <at> ikherbers.com>, 45mg <45mg.writes <at> gmail.com>
Cc: 75975 <at> debbugs.gnu.org
Subject: Re: [bug#75975] [PATCH (WIP) 0/4] Add 'guix fork'.
Date: Fri, 31 Jan 2025 21:35:46 +0000
vicvbcun <guix <at> ikherbers.com> writes:

> I think this is because you modified the (guix build utils) module which 
> just about any package will depend on.  In other words, every derivation 
> changes and you will need to build every package yourself.  I'd 
> recommend putting `invoke/stdout' somewhere else — at least as long as 
> this is not in upstream Guix.

That seems likely. Thanks a ton for pointing it out; I was spinning my
wheels for hours trying to figure out what was causing it. I resubmitted
this series to bug #75981; I may send a v1.5 addressing this there.




This bug report was last modified 1 day ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.