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

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: Following src with got (sic!)
To:
Sebastien Marie <semarie@online.fr>
Cc:
Christian Weisgerber <naddy@mips.inka.de>, gameoftrees@openbsd.org
Date:
Fri, 25 Dec 2020 14:19:34 +0100

Download raw body.

Thread
On Fri, Dec 25, 2020 at 12:25:31PM +0100, Sebastien Marie wrote:
> On Fri, Dec 25, 2020 at 12:13:51AM +0100, Christian Weisgerber wrote:
> > Over on freebsd-git@freebsd.org I wrote:
> > 
> > > Update your source:
> > > $ cd /usr/src
> >   $ got fetch -a
> > > $ got update -b origin/stable/12
> > > $ got rebase stable/12
> > > 
> > > This is the standard configuration which allows you to have changes
> > > on a local branch distinct from the upstream origin/* one.
> > 
> > Something I'm still not clear on: Where do I keep local changes?
> > 
> > origin/foo and foo are effectively different branches, so I guess
> > I can just commit my local changes to foo.
> > 
> > Alternatively, I can create a local branch mystuff off foo, but then
> > updating looks like
> >   ...
> >   update -b origin/foo
> >   rebase foo
> >   rebase mystuff
> > 
> > which seems redundant.
> > 
> > I can understand keeping foo and mystuff separate if I want to push
> > changes on foo, but in a setup where you never push anything?
> 
> I tried two differents workflows with pros and cons on them. Both are
> using mirror mode (what I am usually using).

Thanks for writing this up. It is very interesting to see how you are
using this tool.

> 1. mirror mode and do not commit anything
> 
> $ got br
> master
> $ got fetch
> $ got update
> 
> it is simple, and work relatively well. the main drawback I saw when
> uncommited stuff starts to be mixed purpose (wip bugs fixes + wip test
> + local commits + ...) as it is complex to separate the differents
> works.
> 
> Ideally it should be one checkout per tasks, but for bigs checkouts
> (as src/) it isn't necessary desirable.

Fully agreed. And mixing up changes is the only possibility in this case.
This is just like having a read-only CVS tree in /usr/src and being stuck
with cvs diff and patch(1).

> For commiting something, it is creating a separated branch, stage
> wanted changes and commit.
> 
> $ got br bugfix
> $ got stage file1    # with -p if file1 contains bugfix + others things
> $ got commit
> 
> 
> 2. local branch + rebase
> 
> it is what I am currently using.
> 
> $ got br
> local
> $ got fetch
> $ got update -b master
> $ got rebase local
> 
> Drawbacks:
> 
> - all files in local commits are modified (some 'make' will happily
>   rerun all compilation - I am workaround that with ccache)

This has been brought up before. In theory we could avoid changing the
timestamp of files that have not been modified during rebase. In general,
not updating timestamps on files can cause other problems such as mixing
objects files compiled with different build configurations. So the next
problem becomes keeping track of situations when you must run 'make clean'.

But if the current behaviour is too annoying we can try to change it.
Are you often waiting for amdgpu or clang to compile because of this?

> - rebasing mean losing some commits attributes which could be
>   interesting (like the original date of the commit)

It was done this way on purpose. Is keeping information about when
a change was first committed to a local repo really interesting?

Note that each commit contains two timestamps, for the author and committer.
We could keep the author timestamp intact during rebase. But at present the
only got command which displays this timestamp is 'got cat'.
'got log' will display both committer and author if name or email address
does not match, but it completely ignores the author date.

> - if there is uncommited changes, 'got update' will change the branch
>   (and possibly merge uncommited + master), but 'got rebase' will
>   fail. Going back to 'local' (with 'got update -b local') is annoying
>   (operation could be long as the worktree is big) and could possibly
>   garbage some of uncommited changes.

Would you prefer 'got update -b' to fail if local changes are present?
This could easily be done.

The current behaviour of 'update -n' was implemented before 'got branch'
performed an implicit update of the work tree. It was intended to support
this case:

$ cd /usr/src
hack hack hack
# hmmm... this change should be on a branch
$ got branch foo
$ got update -b foo
$ got commit

Nowadays we don't need a separate 'update -b' step anymore because
that step has now become an implicit part of 'got branch':

$ cd /usr/src
hack hack hack
# hmmm... this change should be on a branch
$ got branch foo
$ got commit

So I suppose we could now require a clean work tree for 'update -b'?
One disadvantage is that if you start editing files on the wrong branch
accidentally it becomes harder to commit local changes to the correct branch.

> - 'got histedit' is need to cleanup the local commits list:
>    $ got update -c basecommitid
>    $ got histedit
>    fold / delete / ...
> 
>    finding the basecommitid could be annoying (as I am using mirror
>    mode 'master' reference is changing on 'fetch'). usually I am using
>    histedit after rebasing (so I could use 'got up -c master' to just
>    to the common commit while keeping 'local' branch)

Hmmm. You could create 'backup' reference before fetching:

 $ got branch -nc master oldmaster 
 $ got fetch
 ...
 $ got update -c oldmaster
 $ got histedit

However, if this is only a problem in mirror mode, perhaps the answer
is not to use mirror mode? :)
Mirror mode is really intended for read-only mirrors.

> When I want to commit something, I am creating a separated branch, and
> I am using cherrypick + commit.
> 
> $ got br bugfix
> $ got cy commitid1
> $ got ci
> 
> 
> -- 
> Sebastien Marie
> 
>