"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Mark Jamsek <mark@jamsek.com>
Subject:
Re: got {diff,log,update} -c KEYWORD (cf. svn revision keywords)
To:
Stefan Sperling <stsp@stsp.name>
Cc:
gameoftrees@openbsd.org
Date:
Thu, 13 Jul 2023 21:23:12 +1000

Download raw body.

Thread
Stefan Sperling <stsp@stsp.name> wrote:
> On Thu, Jul 13, 2023 at 01:31:22PM +1000, Mark Jamsek wrote:
> > # "branch-ref-abc-1" resolves to branch: return branch id
> > got up -c branch-ref-abc-1
> > 
> > # "branch-ref-abc-1-2" does not resolve: parse -2 as the modifier
> > # "branch-ref-abc-1" resolves to branch: return 2nd gen ancestor's id
> > got up -c branch-ref-abc-1-2
> 
> The character - is particularly nasty because it often appears in
> branch names in form of a hyphen.
> 
> Assume these two references exist:
> 
>   branch-ref-abc-2
>   branch-ref-abc
> 
> And now someone decides to delete branch-ref-abc-2. The same command
> which previously yielded branch-ref-abc-2 before this deletion will
> now resolve to two commits prior to branch-ref-abc without any warning
> or error, yielding a different result. What if something like this happens
> in a script while nobody is watching?

Yes, it requires some awareness from the user, so although the example
doesn't exactly cause a problem, it is not ideal in that respect.
Without context, the user could be surprised when the second invocation
of the same command (e.g., got diff -cbranch-ref-abc-2) returns a diff!
Untill they drill-down further and see it's actually branch-ref-abc and
branch-ref-abc-2 actually has been deleted, they would be confused.

And given we can eliminate any ambiguity by prefixing the modifier with
a colon (or some other reserved symbol), I think it would be prudent to
do that.

> If we used any of the reserved symbols as a separator we would avoid
> this problem and Got would report that branch branch-ref-abc-2 does
> not exist. Because now we can scan forward for this separator and parse
> anything after it as a keyword, knowing the branch name with certainty.
> 
> The colon is one possible choice. Your proposed syntax would become:
> 
>   :{+,-}[N]
> 
> instead of the currently proposed:
> 
>   {+,-}[N]
> 
> With this, branch-ref-abc:-2 is no longer ambiguous.
> 
> Granted, users would now write -c BASE:-2 instead of the simpler -c BASE-2
> but in return we obtain consistent behaviour when branches are deleted.
> 
> Alternatively, we could use any of these:
> 
>   ~{+,-}[N]
>   ^{+,-}[N]
>   ?{+,-}[N]
>   *{+,-}[N]
>   \\{+,-}[N]
> 
> At first sight, I prefer the colon.

Me too! I'll make this change.

> > # "branch-ref-def+" does not resolve to branch: parse + as the modifier
> > # branch-ref-def does not resolve:
> > # return "reference branch-ref-def+ not found"
> > got up -c branch-ref-def+
> > 
> > That said, while I find +/- to be very intuitive, we can always use
> > something else; I was flirting with ":" and "^" at first, but I started
> > using mblaze recently and it uses +/- for its mmsg(7) syntax to refer to
> > the next and previous message of the current message, which is ".".
> > And I thought it made perfect sense!
> > 
> > The third stage is to add the TIME syntax for temporal resolution.
> 
> A reserved separator would help with time and date syntax as well.
> As an example, consider data specifications supported by cvs(1):
> 
> 			1 month ago
> 			2 hours ago
> 			400000 seconds ago
> 			last year
> 			last Monday
> 			yesterday
> 			a fortnight ago
> 			3/31/92 10:00:07 PST
> 			January 23, 1987 10:05pm
> 			22:00 GMT
> 
> We could have something like this:
> 
>   got up -c main:"a fortnight ago"
>   got up -c main:yesterday
> 
> I don't see a need for TIME or DATE keywords unless we end up in a
> situation where a valid keyword also appear in a time specification.
> Which is simple to avoid with a bit of planning ahead.

Yes, with such temporal specifications, no keywords would be needed.
And if we run with the colon delimiter, I think that would suffice
irrespective of which specs we use. It would still be a good idea to
decide on a set of time specs beforehand. tbh, I wasn't thinking of
offering so many and instead keeping it minimal, such as:

:+YYYYMMDD	->  after YYYYMMDD
:-YYYYMMDD	->  before YYYYMMDD
:YYYYMMDD	-> on YYYYMMDD
:+HHMMSS[Z]	-> after HHMMSS (local or [UTC]) today
:-HHMMSS[Z]	-> before HHMMSS
:HHMMSS[Z]	-> on or as close to HHMMSS

and, in the same vein, full timestamps (i.e., YYYYMMDDTHHMMSS[Z]).

Admittedly, beyond planning to add it, I have not given the details of
temporal resolution a lot of thought. After BASE and HEAD, I want to add
ref support first, and then think more about it.

Stefan Sperling <stsp@stsp.name> wrote:
> On Wed, Jul 12, 2023 at 07:50:29PM +0200, Christian Weisgerber wrote:
> > I guess "HEAD" is already special in git/got.  Would it make sense
> > to use a special symbol instead of "BASE", e.g. "."?
> 
> Following this line of questioning, how can we deal with the
> situation where a user creates branches such as HEAD or BASE?
> 
> Should we add a reserved symbol prefix which forces keyword evaluation
> instead of reference resolution?
> 
>   got update -c BASE	# use work tree base while branch BASE doesn't exist
>   got branch BASE	# create the branch
>   got update -c BASE		# now uses the BASE branch refs/heads/BASE
>   got update -c refs/heads/BASE	# same
>   got update -c :BASE		# force use of the BASE keyword
>   got update -c :BASE-2		# force use of keyword and resolve ancestors
> 
> Should we always require a prefix symbol to be specified for keywords?
> 
>   got update -c BASE		# errors if branch BASE does not exist
>   got update -c :BASE		# use work tree base
>   got update -c :BASE:-2	# same, and resolve ancestors
>   got update -c main:-2		# use with regular refs needs only one colon
> 
> I am leaning towards the latter since it does not carry any risk of
> changes in our run-time behaviour depending on branches being created
> and deleted again.

Yes, I like it [the latter]!

Come to think of it, this is what we did in fossil, too, to avoid
ambiguities, albeit with an extra keyword (e.g., tag:, root:, start:)
before the colon. But I think the prefixed colon will suffice!
Alternatively, in the first case:

got update -c BASE	# branch BASE if it exists, else worktree base
got update -c :BASE	# use work tree base
got update -c :BASE:-2	# same, and resolve ancestors
got update -c main:-2	# use with regular refs needs only one colon

But perhaps it will be better to make :KEYWORD explicit all the time.

In any case, I'll make some tweaks and see how it looks.


-- 
Mark Jamsek <https://bsdbox.org>
GPG: F2FF 13DE 6A06 C471 CA80  E6E2 2930 DC66 86EE CF68