Subject: [PATCH (WIP) v1 4/4] Document 'guix fork'.

From: 45mg <[email-masked]>
Date: Sat, 1 Feb 2025 02:48:47 +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.48.1