@node Gnulib Git Bundle
@section Gnulib Git Bundle

@set LATEST_GNULIB_BUNDLE 20260109

To provide a serialized archival copy of the Gnulib Git repository we
publish Git Bundles (@url{https://git-scm.com/docs/git-bundle}) of
Gnulib at @url{https://ftp.gnu.org/gnu/gnulib/}.  These may be useful
if Savannah happens to be offline or if you want to have a GnuPG
signed confirmation of the Gnulib content.

The files are named like @code{gnulib-YYYYMMDD.bundle}, for example
@code{gnulib-@value{LATEST_GNULIB_BUNDLE}.bundle}, where @code{YYYYMMDD} corresponds to
the Git commit date (in UTC0) of the last commit on the @code{master}
branch in the bundle.

After downloading the Git bundle you may use it to create a local
gnulib clone using normal Git commands:

@example
wget -nv https://ftp.gnu.org/gnu/gnulib/gnulib-@value{LATEST_GNULIB_BUNDLE}.bundle
git clone gnulib-@value{LATEST_GNULIB_BUNDLE}.bundle gnulib
cd gnulib
@end example

Below are SHA-256 and SHA3-256 checksums of known releases:

@example
9dae009ef9dd7cff17b74c0cda5d7a423e2ed98b4f5b7aa29a970565b0591c06  gnulib-20250303.bundle
f01e423a7ef6b48e947fabd24bb11744204f4549342416e15dc64f427caa32e2  gnulib-20250729.bundle
ae7f76abdf11d70f87170363b8f5807ec377a3ebf231499ab8278270c7a19f1a  gnulib-20260109.bundle

XMv72pyPrDiGrukOrQ9UwgLh+bbekQhQWuyaEmEf3Co=  gnulib-20250303.bundle
c3X/89WHMIRVqGpOHHQPZfw2bcxnZEIkgOam7WwRUyw=  gnulib-20250729.bundle
6kYv60oHv7kXpkJM2vUlADWNmh62nus1xA80bJJiJEs=  gnulib-20260109.bundle
@end example

Verify the SHA256 checksum
with either @code{sha256sum}, @code{sha256}, or @code{shasum -a 256}.

Verify the base64 SHA3-256 checksum
with @code{cksum -a sha3 -l 256 --base64} from coreutils 9.8 or newer,
or with @code{cksum -a sha3 --check} from coreutils 9.9 or newer.

Next to the Git Bundle is a GnuPG signature on the file, named
@code{gnulib-YYYYMMDD.bundle.sig}, which can be verified using GnuPG
as usual:

@example
gpg --verify gnulib-@value{LATEST_GNULIB_BUNDLE}.bundle.sig
@end example

Or using the simpler @code{gpgv} tool like this:

@example
gpgv gnulib-@value{LATEST_GNULIB_BUNDLE}.bundle.sig gnulib-@value{LATEST_GNULIB_BUNDLE}.bundle
@end example

The following GnuPG keys have signed releases:

@example
sec>  ed25519 2019-03-20 [SC] https://josefsson.org/key-20190320.txt
      B1D2BD1375BECB784CF4F8C4D73CF638C53C06BE
uid           [ultimate] Simon Josefsson <simon@@josefsson.org>
@end example

We desire that the Gnulib Git bundles will be forever bit-by-bit
reproducible for others from the official git repository.  Currently
gnulib maintainers invoke the following commands to prepare and upload
the latest Gnulib git bundle.  We appreciate ideas on how to improve
these set of commands (or the upstream Git tool) to make further
supply-chain security related improvements.

@example
cd $(mktemp -d)
REV=2961ed7a687c11aebdf5951d5267dec85d9e59cb   # master branch commit to package
S1REV=e93789db7e86c51d6cb9683ea508e676a55cdefa # stable-202601 branch commit
S2REV=b6d56475ad6d8bc59e85cdf7fa8dd60fbddc6ffc # stable-202507 branch commit
git clone https://git.savannah.gnu.org/git/gnulib.git
cd gnulib
git fsck # attempt to validate input
# Manually inspect that the new tree matches a trusted previous copy
git checkout -B master $REV # put $REV at master
# Add all stable-* branches locally:
for b in $(git branch -r | grep origin/stable- | sort --version-sort); do git checkout $@{b#origin/@}; done
git checkout -B stable-202501 $S1REV
git checkout -B stable-202507 $S2REV
git remote remove origin # drop some unrelated branches
git gc --prune=now # drop any unrelated commits, not clear this helps
git -c pack.threads=1 repack -adF
git -c 'pack.threads=1' bundle create gnulib.bundle --all
V=$(env TZ=UTC0 git show -s --date=format:%Y%m%d --pretty=%cd master)
mv gnulib.bundle gnulib-$V.bundle
build-aux/gnupload --to ftp.gnu.org:gnulib gnulib-$V.bundle
@end example
