[bug#75981,(WIP),v1.5,4/4] Document 'guix fork'.

Message ID 49cb491b107b5f0899209905d7679ba389bc65e6.1738408683.git.45mg.writes@gmail.com
State New
Headers
Series Add 'guix fork'. |

Commit Message

45mg Feb. 1, 2025, 11:43 a.m. UTC
  * 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(+)
  

Comments

Maxim Cournoyer Feb. 3, 2025, 1:14 a.m. UTC | #1
Hello!

45mg <45mg.writes@gmail.com> writes:

> * 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}.

Eh :-).  Please use double space between the sentences in doc and
comments (including doc strings); that is a GNU convention we follow,
and it makes sentence separation unambiguous, allowing editors such as
Emacs to navigate between sentences.

> +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

Use triple hyphen for a em dash (longer variant), as described in info
'(texinfo) Conventions':

     Use three hyphens in a row, ‘---’, to produce a long dash--like
     this (called an “em dash”), used for punctuation in sentences.  Use
     two hyphens, ‘--’, to produce a medium dash (called an “en dash”),
     used primarily for numeric ranges, as in "June 25-26".  Use a
     single hyphen, ‘-’, to produce a standard hyphen used in compound
     words.

> +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

s/Moveoever/Moreover/

> +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

s/a one/one/

> +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

It'd be more correct to use @samp{guix pull}, as that is not code (it's
also not a @command per Texinfo, as these should only be used with the
name of the command, without arguments).

> +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

The chosen convention is 'file system' in Guix, as two words.

> +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

s/and/an/

> +fork. For more information, @pxref{Invoking guix fork}.

This should be @ref, since not used inside parentheses, and used at the
end of a sentence (info '(texinfo) Cross Reference Commands').

>  @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

keep up to date, without hyphens (not a compound adjective here; c.f.:
https://idioms.thefreedictionary.com/keep+up+to+date).

> +more information on authentication of a Guix checkout, @pxref{Invoking
> +guix git authenticate}.

s/@pxref/@ref/

> +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.

is given, in which case an existing Git checkout is expected to already
exist in DIRECTORY.

>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

s/starting from/based on/

> +alone (by adding it to @file{.guix-authorizations}) and is signed by it.

to the @file{.guix-authorizations} file

> +
> +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

/further explanation/more details/

> +on patches in branches based off of this one, in much the same way as

I'd use 's/based off of/based on/'

> +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

s/@command/@samp/ and s/`build'/``build''/

Double quoting is to be used sparringly, using `` '' in Texinfo.

> +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}).

Remove the ` ' quotes.

> +Updating this channel can be done by merging the `@code{fork}' branch
> +into it.

Ditto.

> +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

s/`origin'/@code{remote}/

> +`@code{upstream}') is renamed to `upstream', and a new `origin' remote

Use @code instead of ` '.  Do not use both together.

> +is created to track URI.
> +@item --git-parameter PARAMETER
> +Specify configuration PARAMETER for git, via `-c' option. You can pass

s/`-c'/@samp{-c}/

> +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.

Instead of 'cached', I'd use 'persisted' or 'written', which sounds more
accurate to me.

> +
> +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}').

Remove quotes.

> +@item --upstream-keyring=REFERENCE
> +Load keyring for upstream commits from REFERENCE, a Git branch (default
> +`@code{keyring}').

Ditto.  Perhaps this could be renamed '--keyring-branch', which is more descriptive?

> +@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.

Idea for a refinement: detect if the users's key is authorized by
upstream Guix, and use a merge in this situation?  Perhaps offer a
switch to force one flow or another, but error out when the user uses
--merge-strategy=merge and their key is not authorized in upstream Guix
(merge-strategy would default to rebase).

> +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

@samp{Change-Id} git trailer (see 'man git-interpret-trailers').

> +'commit-msg' hook.

I'd use @samp{commit-msg} or @code.

> +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.

Apart from my above comment and the double period thing, this LGTM.
It's obvious you've taken a lot of care/effort into producing this.

I'm warming up to the idea.

Thanks for the contribution.
  

Patch

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