Subject: [bug#43442] Subversion keyword substitution

From: Timothy Sample <[email-masked]>
Date: Fri, 24 Mar 2023 17:31:51 -0600

Hey,

Ludovic Courtès <[email-masked]> writes:

> Hi Timothy,
>
> Timothy Sample <[email-masked]> skribis:
>
>> I was starting with doing a simple check for the “easy” Subversion
>> repositories.  That is, no externals (‘recursive?’) and no
>> ‘svn-multi-fetch’ [1].  I immediately hit a problem.  Guix hashes the
>> export of the repository with the keywords processed, while SWH hashes
>> it with unprocessed keywords.
>
> Ouch.  I had forgotten keywords were also a thing in Subversion.  :-/
>
> Can we tell Subversion to not expand them?  That could be the way
> forward in Guix, though it won’t help for past revisions.

Thinking entirely abstractly, the keywords should be expanded.  I’m not
really long enough in the tooth (old enough) to know how people use
keywords, but one might be tempted to do something like:

    printf ("This is foo version %s\n", "$Revision$");

If that ever happens, processing the keywords would be very important.

Thinking practically, we’ve never encountered anything like that (see
below), and compatibility with SWH is nice.

It’s not clear to me why SWH passes ‘--ignore-keywords’ to Subversion in
the first place.  I guess it saves storage, because having identical
files allows deduplication.

> How frequent is the use of keywords though?

Well, you found 11 in the current Guix, and I see 30 when I process
everything I have (from version 1.0 to a few weeks ago).  Furthermore,
the only usage pattern I see is “$Id” in a comment.

> So, how about applying the ‘--ignore-keywords’ change and updating
> hashes accordingly?

It’s probably the right default given the circumstances.

It seems like there’s a direct conflict between ease of packaging and
ease of time travel.  In the hypothetical case that a keyword mattered,
it would be a nasty surprise to the package author.  They would have to
(a) discover the problem and (b) manually do the keyword substitution in
Scheme (or work around it).

Similarly, for recursive checkouts (including Git), it would be easier
to do time travel if we explicitly listed each source and how to compose
them.  However, that’s a pain for package authors and maintainers.

Add to those two examples all the discussions about multihashing or
keeping track of the SWHID and something of a theme emerges....

Having said that, it’s nice that the work we are doing is letting us
think very clearly about this trade-off.

>> [1] More precisely, I was going to process recursive ‘svn-fetch’
>> origins because a lot of them are needlessly marked as recursive.  In
>> some (many?) cases, the repositories don’t actually have external
>> references, so the flag does nothing.  I was only going to skip the
>> ones where it makes a difference.
>
> We should remove that recursive flag when it has no effect.  Perhaps we
> could proceed similarly?

Huh.  My scripts tell me that we haven’t needed it at all in the last
three years.  That’s a suspicious enough result that I wonder if there’s
a bug in my scripts.  The results are looking good so far, but there are
a few things I still need to look over.

I ran your same experiment, passing all the packages through:

    (define (make-svn-package-non-recursive pkg)
      (package
       (inherit pkg)
       (source
        (origin
         (inherit (package-source pkg))
         (uri (match (origin-uri (package-source pkg))
                ((? svn-reference? ref)
                 (svn-reference
                  (inherit ref)
                  (recursive? #f)))
                ((? svn-multi-reference? ref)
                 (svn-multi-reference
                  (inherit ref)
                  (recursive? #f)))))))))

All of them were fine.  Maybe we just haven’t had a truly recursive
Subversion source in recent memory.

-- Tim