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

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: got: gotadmin init and got import -b coherence
To:
Mark Jamsek <mark@jamsek.com>
Cc:
Game of Trees <gameoftrees@openbsd.org>
Date:
Sat, 20 Aug 2022 22:14:17 +0200

Download raw body.

Thread
On Sun, Aug 21, 2022 at 12:01:33AM +1000, Mark Jamsek wrote:
> I introduced some Fossilers to Got today and came across this issue.
> 
> In Fossil, the default branch is "trunk", so for familiarity I thought
> I'd use the -b option to `got import` to make the initial commit on
> "trunk" and thus expected HEAD to reference "trunk":
> 
>   $ gotadmin init new.git
>   $ got import -r new.git -b trunk -m "initial commit" ~/src/tmp
>   A  /home/mark/src/tmp/runnit.c
>   Created branch refs/heads/trunk with commit 85e40007698d1e988e97d8c8f94171f77b2a8579
>   $ got co new.git
>   got: reference refs/heads/main not found
>   $ got co -b trunk new.git
>   A  /home/mark/src/new/runnit.c
>   Checked out refs/heads/trunk: 85e40007698d1e988e97d8c8f94171f77b2a8579
>   Now shut up and hack
>   $ cd new && tog
>   tog: reference refs/heads/main not found
>   $ got log
>   got: reference refs/heads/main not found
>   $ got log -c trunk
>   got: reference refs/heads/main not found
> 
> As a new repository, I incorrectly assumed that `got import -b trunk`
> would make HEAD point to "trunk". However, HEAD is still "main", which
> doesn't exist.
> 
> I just had a quick look and made this patch to check if we create new
> repositories with a "trunk" HEAD if anything noticeable breaks.
> 
>   $ gotadmin init -b trunk new.git
>   $ got import -r new.git -b trunk -m "initial commit" ~/src/tmp
>   A  /home/mark/src/tmp/runnit.c
>   Created branch refs/heads/trunk with commit bafecf8a578c2a1d80dcfdc81084840453d30007
>   $ got co new.git
>   A  /home/mark/src/new/runnit.c
>   Checked out refs/heads/trunk: bafecf8a578c2a1d80dcfdc81084840453d30007
>   Now shut up and hack
>   $ cd new && got log
>   -----------------------------------------------
>   commit bafecf8a578c2a1d80dcfdc81084840453d30007 (trunk)
>   from: Mark Jamsek <mark@jamsek.dev>
>   date: Sat Aug 20 13:47:28 2022 UTC
> 
>    initial commit
> 
> So far so good, but I have a few questions:
> 
>   - have I missed something and there's already a way to do this?
>   - assuming I haven't, do we just want users to manually edit
>     repo.git/HEAD if they want a new repo with something other than
>     "main"?
>   - if not, are we open to something like this (or something else
>     entirely) so users can make HEAD reference <branch-other-than-main>
>     when creating new repositories?
>   - if yes, I'm not sure I like making the user have to use -b with
>     `gotadmin init` and then again with `got import`; would it be better
>     to either read or write HEAD during import so the user only needs to
>     use -b once (either with `gotadmin init -b` or `got import -b`) to
>     have HEAD point to something other than "main"? OTOH, it's at least
>     consistent and easy to remember using -b for both init and import,
>     and the change is minimal

The way we should go about this is a bit unclear to me.

The basic problem is that, given a non-bare Git repository, the HEAD
ref is special for Git's work tree. And we do not want to interfere
with Git's work tree, which could be for instance in the middle of a
rebase operation, relying on HEAD to point to a specific branch or object.

This is why I would be cautious about modifying HEAD. So far we only read
this file, for instance to find out which branch to clone/fetch/checkout
by default if the user does not specify a branch. This is not fool-proof
because Git's HEAD might not even point to a reference name, it could point
to some arbitrary commt object (which Git calls "detached HEAD state").

There is an item in Got's TOOD file related to this problem, though not it
is not exactly the same case as yours. I have quoted it below.
I was thinking if HEAD is obviously bogus we should feel free to modify it.
But if HEAD points to an existing branch or something that isn't even a
branch name, then we could break the correspdoning Git work tree if we
change HEAD.

Overall, it would be good to determine a set of rules under which it is safe
for us to change HEAD. ANd perhaps such rules should make a distinction between
bare and non-bare Git repositories. In your example, the repository will be
bare because Git is not even being used. But we cannot assume this to be the
case in general, otherwise we risk breaking inter-op with Git.

TODO:
- When a clone fails the HEAD symref will always point to "refs/heads/main"
  (ie. the internal default HEAD symref of Got). Resuming a failed clone with
  'got fetch' is supposed to work. To make this easier, if the HEAD symref
  points to a non-existent reference it should be updated by 'got fetch'
  to match the HEAD symref sent by the server.