unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
From: Brennan Vincent <brennan@umanwizard.com>
To: 64426@debbugs.gnu.org
Subject: [bug#64426] [PATCH] * gnu: rust: Introduce rust-next package and various intermediates.
Date: Sun, 2 Jul 2023 15:13:47 -0400	[thread overview]
Message-ID: <f072ae9d-7488-d65f-88ad-07ec328f778d@umanwizard.com> (raw)

This change introduces intermediate bootstrapping packages rust-1.69 and
rust-1.70. It also refactors the code that raises the intermediate
bootstrapping rust-1.67 package into the public "rust" package into a reusable
function so that we can make more such packages. It then uses that function to
create three more packages: rust-next-1.68, rust-next-1.69, and
rust-next (which is version 1.70).

The only one of these that this change exposes publicly is rust-next (i.e.,
rust 1.70). This will allow developers who require recent Rust versions to use
Guix to manage their development environment.
---
  gnu/packages/rust.scm | 450 ++++++++++++++++++++++++++----------------
  1 file changed, 281 insertions(+), 169 deletions(-)

diff --git a/gnu/packages/rust.scm b/gnu/packages/rust.scm
index 8e106a9927..9145d4bc10 100644
--- a/gnu/packages/rust.scm
+++ b/gnu/packages/rust.scm
@@ -702,183 +702,295 @@ (define rust-1.67
                               (replace "llvm" llvm-15))))))
   (define rust-1.68
-  (rust-bootstrapped-package
-   rust-1.67 "1.68.2" "15ifyd5jj8rd979dkakp887hgmhndr68pqaqvd2hqkfdywirqcwk"))
+  (let ((base-rust (rust-bootstrapped-package
+                    rust-1.67 "1.68.2" "15ifyd5jj8rd979dkakp887hgmhndr68pqaqvd2hqkfdywirqcwk")))
+    (package
+      (inherit base-rust)
+      (arguments
+       (substitute-keyword-arguments (package-arguments base-rust)
+         ((#:validate-runpath? _) #f))))))
  -;;; Note: Only the latest versions of Rust are supported and tested.  The
-;;; intermediate rusts are built for bootstrapping purposes and should not
-;;; be relied upon.  This is to ease maintenance and reduce the time
-;;; required to build the full Rust bootstrap chain.
-;;;
-;;; Here we take the latest included Rust, make it public, and re-enable tests
-;;; and extra components such as rustfmt.
-(define-public rust
-  (let ((base-rust rust-1.67))
+(define rust-1.69
+  (let ((base-rust (rust-bootstrapped-package
+                    rust-1.68 "1.69.0" "03zn7kx5bi5mdfsqfccj4h8gd6abm7spj0kjsfxwlv5dcwc9f1gv")))
+    (package
+      (inherit base-rust)
+      (source
+       (origin
+         (inherit (package-source base-rust))
+         (snippet
+          '(begin
+             (for-each delete-file-recursively
+                       '("src/llvm-project"
+                         "vendor/tikv-jemalloc-sys/jemalloc"))
+             ;; find . -not -type d -executable -exec file {} \+ | grep ELF
+             ;; returns nothing.
+
+             ;; Also remove the bundled (mostly Windows) libraries.
+             (for-each delete-file
+                       (find-files "vendor" ".*\\.(a|dll|exe|lib)$")))))))))
+
+(define rust-1.70
+  (let ((base-rust (rust-bootstrapped-package
+                    rust-1.69 "1.70.0" "0z6j7d0ni0rmfznv0w3mrf882m11kyh51g2bxkj40l3s1c0axgxj")))
      (package
        (inherit base-rust)
-      (outputs (cons "rustfmt" (package-outputs base-rust)))
        (arguments
         (substitute-keyword-arguments (package-arguments base-rust)
-         ((#:tests? _ #f)
-          (not (%current-target-system)))
           ((#:phases phases)
            `(modify-phases ,phases
-             (add-after 'unpack 'relax-gdb-auto-load-safe-path
-               ;; Allow GDB to load binaries from any location, otherwise the
-               ;; gdbinfo tests fail.  This is only useful when testing with a
-               ;; GDB version newer than 8.2.
-               (lambda _
-                 (setenv "HOME" (getcwd))
-                 (with-output-to-file (string-append (getenv "HOME") "/.gdbinit")
-                   (lambda _
-                     (format #t "set auto-load safe-path /~%")))
-                 ;; Do not launch gdb with '-nx' which causes it to not execute
-                 ;; any init file.
-                 (substitute* "src/tools/compiletest/src/runtest.rs"
-                   (("\"-nx\".as_ref\\(\\), ")
-                    ""))))
-             (add-after 'unpack 'patch-cargo-env-shebang
-               (lambda _
-                 (substitute* '("src/tools/cargo/tests/testsuite/build.rs"
-                                "src/tools/cargo/tests/testsuite/fix.rs")
-                   ;; The cargo *_wrapper tests set RUSTC.*WRAPPER environment
-                   ;; variable which points to /usr/bin/env.  Since it's not a
-                   ;; shebang, it needs to be manually patched.
-                   (("/usr/bin/env")
-                    (which "env")))))
-             (add-after 'unpack 'disable-tests-requiring-git
-               (lambda _
-                 (substitute* "src/tools/cargo/tests/testsuite/new.rs"
-                   (("fn author_prefers_cargo")
-                    "#[ignore]\nfn author_prefers_cargo")
-                   (("fn finds_author_git")
-                    "#[ignore]\nfn finds_author_git")
-                   (("fn finds_local_author_git")
-                    "#[ignore]\nfn finds_local_author_git"))))
-             (add-after 'unpack 'disable-tests-requiring-mercurial
+             ;; Rustix ships with some bundled assembly-language
+             ;; libraries. We strip the pre-assembled versions from
+             ;; the sources, so regenerate them here.
+             (add-after 'configure 'assemble-rustix-outline-asm
                 (lambda _
-                 (substitute*
-                   "src/tools/cargo/tests/testsuite/init/simple_hg_ignore_exists/mod.rs"
-                   (("fn simple_hg_ignore_exists")
-                    "#[ignore]\nfn simple_hg_ignore_exists"))
-                 (substitute*
-                   "src/tools/cargo/tests/testsuite/init/mercurial_autodetect/mod.rs"
-                   (("fn mercurial_autodetect")
-                    "#[ignore]\nfn mercurial_autodetect"))))
-             (add-after 'unpack 'disable-tests-broken-on-aarch64
-               (lambda _
-                 (with-directory-excursion "src/tools/cargo/tests/testsuite/"
-                   (substitute* "build_script_extra_link_arg.rs"
-                     (("^fn build_script_extra_link_arg_bin_single" m)
-                      (string-append "#[ignore]\n" m)))
-                   (substitute* "build_script.rs"
-                     (("^fn env_test" m)
-                      (string-append "#[ignore]\n" m)))
-                   (substitute* "collisions.rs"
-                     (("^fn collision_doc_profile_split" m)
-                      (string-append "#[ignore]\n" m)))
-                   (substitute* "concurrent.rs"
-                     (("^fn no_deadlock_with_git_dependencies" m)
-                      (string-append "#[ignore]\n" m)))
-                   (substitute* "features2.rs"
-                     (("^fn dep_with_optional_host_deps_activated" m)
-                      (string-append "#[ignore]\n" m))))))
-             (add-after 'unpack 'patch-command-exec-tests
-               ;; This test suite includes some tests that the stdlib's
-               ;; `Command` execution properly handles in situations where
-               ;; the environment or PATH variable are empty, but this fails
-               ;; since we don't have `echo` available at its usual FHS
-               ;; location.
-               (lambda _
-                 (substitute* (match (find-files "." "^command-exec.rs$")
-                                ((file) file))
-                   (("Command::new\\(\"echo\"\\)")
-                    (format #f "Command::new(~s)" (which "echo"))))))
-             (add-after 'unpack 'patch-command-uid-gid-test
-               (lambda _
-                 (substitute* (match (find-files "." "^command-uid-gid.rs$")
-                                ((file) file))
-                   (("/bin/sh")
-                    (which "sh")))))
-             (add-after 'unpack 'skip-shebang-tests
-               ;; This test make sure that the parser behaves properly when a
-               ;; source file starts with a shebang. Unfortunately, the
-               ;; patch-shebangs phase changes the meaning of these edge-cases.
-               ;; We skip the test since it's drastically unlikely Guix's
-               ;; packaging will introduce a bug here.
-               (lambda _
-                 (delete-file "src/test/ui/parser/shebang/sneaky-attrib.rs")))
-             (add-after 'unpack 'patch-process-tests
-               (lambda* (#:key inputs #:allow-other-keys)
-                 (let ((bash (assoc-ref inputs "bash")))
-                   (substitute* "library/std/src/process/tests.rs"
-                     (("\"/bin/sh\"")
-                      (string-append "\"" bash "/bin/sh\"")))
-                   ;; The three tests which are known to fail upstream on QEMU
-                   ;; emulation on aarch64 and riscv64 also fail on x86_64 in Guix's
-                   ;; build system. Skip them on all builds.
-                   (substitute* "library/std/src/sys/unix/process/process_common/tests.rs"
-                     (("target_arch = \"arm\",") "target_os = \"linux\",")))))
-             (add-after 'unpack 'disable-interrupt-tests
-               (lambda _
-                 ;; This test hangs in the build container; disable it.
-                 (substitute* (match (find-files "." "^freshness.rs$")
-                                ((file) file))
-                   (("fn linking_interrupted")
-                    "#[ignore]\nfn linking_interrupted"))
-                 ;; Likewise for the ctrl_c_kills_everyone test.
-                 (substitute* (match (find-files "." "^death.rs$")
-                                ((file) file))
-                   (("fn ctrl_c_kills_everyone")
-                    "#[ignore]\nfn ctrl_c_kills_everyone"))))
-             (add-after 'configure 'add-gdb-to-config
-               (lambda* (#:key inputs #:allow-other-keys)
-                 (let ((gdb (assoc-ref inputs "gdb")))
-                   (substitute* "config.toml"
-                     (("^python =.*" all)
-                      (string-append all
-                                     "gdb = \"" gdb "/bin/gdb\"\n"))))))
-             (replace 'build
-               ;; Phase overridden to also build rustfmt.
-               (lambda* (#:key parallel-build? #:allow-other-keys)
-                 (let ((job-spec (string-append
-                                  "-j" (if parallel-build?
-                                           (number->string (parallel-job-count))
-                                           "1"))))
-                   (invoke "./x.py" job-spec "build"
-                           "library/std" ;rustc
-                           "src/tools/cargo"
-                           "src/tools/rustfmt"))))
-             (replace 'check
-               ;; Phase overridden to also test rustfmt.
-               (lambda* (#:key tests? parallel-build? #:allow-other-keys)
-                 (when tests?
-                   (let ((job-spec (string-append
-                                    "-j" (if parallel-build?
-                                             (number->string (parallel-job-count))
-                                             "1"))))
-                     (invoke "./x.py" job-spec "test" "-vv"
-                             "library/std"
-                             "src/tools/cargo"
-                             "src/tools/rustfmt")))))
-             (replace 'install
-               ;; Phase overridden to also install rustfmt.
-               (lambda* (#:key outputs #:allow-other-keys)
-                 (invoke "./x.py" "install")
-                 (substitute* "config.toml"
-                   ;; Adjust the prefix to the 'cargo' output.
-                   (("prefix = \"[^\"]*\"")
-                    (format #f "prefix = ~s" (assoc-ref outputs "cargo"))))
-                 (invoke "./x.py" "install" "cargo")
-                 (substitute* "config.toml"
-                   ;; Adjust the prefix to the 'rustfmt' output.
-                   (("prefix = \"[^\"]*\"")
-                    (format #f "prefix = ~s" (assoc-ref outputs "rustfmt"))))
-                 (invoke "./x.py" "install" "rustfmt")))))))
-      ;; Add test inputs.
-      (native-inputs (cons* `("gdb" ,gdb/pinned)
-                            `("procps" ,procps)
-                            (package-native-inputs base-rust))))))
+                 (let* ((system (or ,(%current-target-system)
+                                    ,(%current-system)))
+                        (arch
+                         (match system
+                           ("x86_64-linux"   "x86_64")
+                           ("i686-linux"     "x86")
+                           ("armhf-linux"    "arm")
+                           ("aarch64-linux"  "aarch64")
+                           ("mips64el-linux" "mips64")
+                           ("riscv64-linux"  "riscv64")
+                           (_                (let ((dash (string-index system #\-)))
+                                               (substring system 0 dash))))))
+                   (for-each
+                    (lambda (dir)
+                      (with-directory-excursion dir
+                        (invoke "gcc" "-c" (format #f "~a.s" arch))
+                        (invoke "ar" "r"
+                                (format #f "debug/librustix_outline_~a.a" arch)
+                                (format #f "~a.o" arch))
+                        (invoke "ar" "r"
+                                (format #f "release/librustix_outline_~a.a" arch)
+                                (format #f "~a.o" arch))))
+                    '("vendor/rustix-0.36.5/src/backend/linux_raw/arch/outline/"
+                      "vendor/rustix/src/backend/linux_raw/arch/outline/"))))))))))))
+
+(define public-rust-1.67-phase-mods
+  '((add-after 'unpack 'relax-gdb-auto-load-safe-path
+      ;; Allow GDB to load binaries from any location, otherwise the
+      ;; gdbinfo tests fail.  This is only useful when testing with a
+      ;; GDB version newer than 8.2.
+      (lambda _
+        (setenv "HOME" (getcwd))
+        (with-output-to-file (string-append (getenv "HOME") "/.gdbinit")
+          (lambda _
+            (format #t "set auto-load safe-path /~%")))
+        ;; Do not launch gdb with '-nx' which causes it to not execute
+        ;; any init file.
+        (substitute* "src/tools/compiletest/src/runtest.rs"
+          (("\"-nx\".as_ref\\(\\), ")
+           ""))))
+    (add-after 'unpack 'patch-cargo-env-shebang
+      (lambda _
+        (substitute* '("src/tools/cargo/tests/testsuite/build.rs"
+                       "src/tools/cargo/tests/testsuite/fix.rs")
+          ;; The cargo *_wrapper tests set RUSTC.*WRAPPER environment
+          ;; variable which points to /usr/bin/env.  Since it's not a
+          ;; shebang, it needs to be manually patched.
+          (("/usr/bin/env")
+           (which "env")))))
+    (add-after 'unpack 'disable-tests-requiring-git
+      (lambda _
+        (substitute* "src/tools/cargo/tests/testsuite/new.rs"
+          (("fn author_prefers_cargo")
+           "#[ignore]\nfn author_prefers_cargo")
+          (("fn finds_author_git")
+           "#[ignore]\nfn finds_author_git")
+          (("fn finds_local_author_git")
+           "#[ignore]\nfn finds_local_author_git"))))
+    (add-after 'unpack 'disable-tests-requiring-mercurial
+      (lambda _
+        (substitute*
+            "src/tools/cargo/tests/testsuite/init/simple_hg_ignore_exists/mod.rs"
+          (("fn simple_hg_ignore_exists")
+           "#[ignore]\nfn simple_hg_ignore_exists"))
+        (substitute*
+            "src/tools/cargo/tests/testsuite/init/mercurial_autodetect/mod.rs"
+          (("fn mercurial_autodetect")
+           "#[ignore]\nfn mercurial_autodetect"))))
+    (add-after 'unpack 'disable-tests-broken-on-aarch64
+      (lambda _
+        (with-directory-excursion "src/tools/cargo/tests/testsuite/"
+          (substitute* "build_script_extra_link_arg.rs"
+            (("^fn build_script_extra_link_arg_bin_single" m)
+             (string-append "#[ignore]\n" m)))
+          (substitute* "build_script.rs"
+            (("^fn env_test" m)
+             (string-append "#[ignore]\n" m)))
+          (substitute* "collisions.rs"
+            (("^fn collision_doc_profile_split" m)
+             (string-append "#[ignore]\n" m)))
+          (substitute* "concurrent.rs"
+            (("^fn no_deadlock_with_git_dependencies" m)
+             (string-append "#[ignore]\n" m)))
+          (substitute* "features2.rs"
+            (("^fn dep_with_optional_host_deps_activated" m)
+             (string-append "#[ignore]\n" m))))))
+    (add-after 'unpack 'patch-command-exec-tests
+      ;; This test suite includes some tests that the stdlib's
+      ;; `Command` execution properly handles in situations where
+      ;; the environment or PATH variable are empty, but this fails
+      ;; since we don't have `echo` available at its usual FHS
+      ;; location.
+      (lambda _
+        (substitute* (match (find-files "." "^command-exec.rs$")
+                       ((file) file))
+          (("Command::new\\(\"echo\"\\)")
+           (format #f "Command::new(~s)" (which "echo"))))))
+    (add-after 'unpack 'patch-command-uid-gid-test
+      (lambda _
+        (substitute* (match (find-files "." "^command-uid-gid.rs$")
+                       ((file) file))
+          (("/bin/sh")
+           (which "sh")))))
+    (add-after 'unpack 'skip-shebang-tests
+      ;; This test make sure that the parser behaves properly when a
+      ;; source file starts with a shebang. Unfortunately, the
+      ;; patch-shebangs phase changes the meaning of these edge-cases.
+      ;; We skip the test since it's drastically unlikely Guix's
+      ;; packaging will introduce a bug here.
+      (lambda _
+        (delete-file "src/test/ui/parser/shebang/sneaky-attrib.rs")))
+    (add-after 'unpack 'patch-process-tests
+      (lambda* (#:key inputs #:allow-other-keys)
+        (let ((bash (assoc-ref inputs "bash")))
+          (substitute* "library/std/src/process/tests.rs"
+            (("\"/bin/sh\"")
+             (string-append "\"" bash "/bin/sh\"")))
+          ;; The three tests which are known to fail upstream on QEMU
+          ;; emulation on aarch64 and riscv64 also fail on x86_64 in Guix's
+          ;; build system. Skip them on all builds.
+          (substitute* "library/std/src/sys/unix/process/process_common/tests.rs"
+            (("target_arch = \"arm\",") "target_os = \"linux\",")))))
+    (add-after 'unpack 'disable-interrupt-tests
+      (lambda _
+        ;; This test hangs in the build container; disable it.
+        (substitute* (match (find-files "." "^freshness.rs$")
+                       ((file) file))
+          (("fn linking_interrupted")
+           "#[ignore]\nfn linking_interrupted"))
+        ;; Likewise for the ctrl_c_kills_everyone test.
+        (substitute* (match (find-files "." "^death.rs$")
+                       ((file) file))
+          (("fn ctrl_c_kills_everyone")
+           "#[ignore]\nfn ctrl_c_kills_everyone"))))
+    (add-after 'configure 'add-gdb-to-config
+      (lambda* (#:key inputs #:allow-other-keys)
+        (let ((gdb (assoc-ref inputs "gdb")))
+          (substitute* "config.toml"
+            (("^python =.*" all)
+             (string-append all
+                            "gdb = \"" gdb "/bin/gdb\"\n"))))))
+    (replace 'build
+      ;; Phase overridden to also build rustfmt.
+      (lambda* (#:key parallel-build? #:allow-other-keys)
+        (let ((job-spec (string-append
+                         "-j" (if parallel-build?
+                                  (number->string (parallel-job-count))
+                                  "1"))))
+          (invoke "./x.py" job-spec "build"
+                  "library/std" ;rustc
+                  "src/tools/cargo"
+                  "src/tools/rustfmt"))))
+    (replace 'check
+      ;; Phase overridden to also test rustfmt.
+      (lambda* (#:key tests? parallel-build? #:allow-other-keys)
+        (when tests?
+          (let ((job-spec (string-append
+                           "-j" (if parallel-build?
+                                    (number->string (parallel-job-count))
+                                    "1"))))
+            (invoke "./x.py" job-spec "test" "-vv"
+                    "library/std"
+                    "src/tools/cargo"
+                    "src/tools/rustfmt")))))
+    (replace 'install
+      ;; Phase overridden to also install rustfmt.
+      (lambda* (#:key outputs #:allow-other-keys)
+        (invoke "./x.py" "install")
+        (substitute* "config.toml"
+          ;; Adjust the prefix to the 'cargo' output.
+          (("prefix = \"[^\"]*\"")
+           (format #f "prefix = ~s" (assoc-ref outputs "cargo"))))
+        (invoke "./x.py" "install" "cargo")
+        (substitute* "config.toml"
+          ;; Adjust the prefix to the 'rustfmt' output.
+          (("prefix = \"[^\"]*\"")
+           (format #f "prefix = ~s" (assoc-ref outputs "rustfmt"))))
+        (invoke "./x.py" "install" "rustfmt")))))
+
+;;; Here we take a given version of Rust and re-enable tests
+;;; and extra components such as rustfmt.
+;;;
+;;; This function was designed for Rust 1.67. Future versions of Rust may require
+;;; further overriding and customization.
+(define* (mk-public-rust
+          base-rust
+          #:optional (phase-mods public-rust-1.67-phase-mods))
+  (package
+    (inherit base-rust)
+    (outputs (cons "rustfmt" (package-outputs base-rust)))
+    (arguments
+     (substitute-keyword-arguments (package-arguments base-rust)
+       ((#:tests? _ #f)
+        (not (%current-target-system)))
+       ((#:phases phases)
+        `(modify-phases ,phases
+           ,@phase-mods))))
+    ;; Add test inputs.
+    (native-inputs (cons* `("gdb" ,gdb/pinned)
+                          `("procps" ,procps)
+                          (package-native-inputs base-rust)))))
+
+;;; Note: Only the version 1.67 of Rust is supported and tested.  The
+;;; intermediate rusts are built for bootstrapping purposes and should not
+;;; be relied upon.  This is to ease maintenance and reduce the time
+;;; required to build the full Rust bootstrap chain.
+(define-public rust
+  (mk-public-rust rust-1.67))
+
+(define public-rust-1.68-phase-mods
+  (append public-rust-1.67-phase-mods
+          '((replace 'skip-shebang-tests
+              (lambda _
+                (delete-file "tests/ui/parser/shebang/sneaky-attrib.rs"))))))
+
+(define rust-next-1.68
+  (mk-public-rust rust-1.68 public-rust-1.68-phase-mods))
+
+(define public-rust-1.69-phase-mods
+  (append public-rust-1.68-phase-mods
+          '((replace 'disable-tests-requiring-mercurial
+              (lambda _
+                (substitute*
+                    "src/tools/cargo/tests/testsuite/init/simple_hg_ignore_exists/mod.rs"
+                  (("fn case")
+                   "#[ignore]\nfn case"))
+                (substitute*
+                    "src/tools/cargo/tests/testsuite/init/mercurial_autodetect/mod.rs"
+                  (("fn case")
+                   "#[ignore]\nfn case")))))))
+
+(define rust-next-1.69
+  (mk-public-rust rust-1.69 public-rust-1.69-phase-mods))
+
+(define public-rust-1.70-phase-mods
+  (append public-rust-1.69-phase-mods
+          '((add-after 'disable-tests-requiring-git 'disable-more-tests-requiring-git
+               (lambda _                 +                 (substitute* "src/tools/cargo/tests/testsuite/git.rs"
+                   (("fn fetch_downloads_with_git2_first_then_with_gitoxide_and_vice_versa")
+                    "#[ignore]\nfn fetch_downloads_with_git2_first_then_with_gitoxide_and_vice_versa")))))))
+
+(define-public rust-next
+  (let ((base-rust (mk-public-rust rust-1.70 public-rust-1.70-phase-mods)))
+    (package
+      (inherit base-rust)
+      (name "rust-next"))))
   (define-public rust-src
    (hidden-package

base-commit: b24a05830d11e3011eee4bc5f60a41e26188cde1
-- 
2.40.1






             reply	other threads:[~2023-07-02 20:14 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-02 19:13 Brennan Vincent [this message]
2023-07-02 19:52 ` [bug#64426] [PATCH] * gnu: rust: Introduce rust-next package and various intermediates Brennan Vincent
2024-12-19 17:24   ` bug#64426: " Efraim Flashner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f072ae9d-7488-d65f-88ad-07ec328f778d@umanwizard.com \
    --to=brennan@umanwizard.com \
    --cc=64426@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).