Re: git-switch(1) then git-pull(1)

From: Xin Li <>
Date: Sun, 04 Dec 2022 01:50:00 UTC
On 2022-12-03 10:15 AM, Nuno Teixeira wrote:
> Really nice.
> I'm thinking on 3 trees for ports:
> - main (push)
> - 2022Qn (cherry-pick, push)
> - test (push to main when testing done)
> $ git clone 
> <> ports/main
> $ cd ports/main
> $ git worktree add ../2022Q4 -b 2022Q4 origin/2022Q4
> $ git worktree add ../test -b main origin/main

The third step would fail, because you have checked out main on 
ports/main.  You would want to do this instead:

$ git worktree add ../test -b test origin/main

> My question is how do I push a commit from 'test' to 'main'?

You can do:

$ git push origin test:main -n

(which will tell the SHA1s and you can inspect with git log; remove -n 
once satisfactory, or git pull --rebase as needed)

> This sugestion is because I can have several ports in testing fase on 
> 'test' branch and choose a specific commit to push to 'main' (local 
> branch) and then do a final push.

In this case I'd create multiple branches (to the extent that changes 
can be isolated in a self-containing manner), and have one branch for 

So the setup would roughly be: you have B1, B2, B3 working on 3 
different stuff which almost don't touch each other.  Conceptually, you 
can consider origin/main as a working branch used by someone else, too.

Now you want to test the stuff, e.g. with poudriere, or some integrated 
test of src/, you would create a new branch T for that, like:

(first time)
$ git worktree add ../testspace -b test origin/main
$ cd ../testspace
(blow away everything and reset to a known vanilla state)
$ cd ../testspace
$ git reset --hard origin/main      # Reset branch to origin/main


$ git merge B1
$ git merge B2
$ git merge B3

Now you have all your work merged into the test space, do whatever tests 
you want.  When the result is satisfactory, perform a 'git rebase 
origin/main' and squash commits if needed.

Assuming you saw some changes would be needed for B2, you would make the 
changes in B2's worktree, and redo the merge in 'testspace' with:

$ git merge B2

Or let's say origin/main moved, you can do:

$ git fetch origin
$ git merge origin/main

and continue to work.

If for whatever reason you feel B2 is not yet ready for prime time, do a 
reset and merge just B1 and B3:

$ cd ../testspace
$ git reset --hard origin/main      # Reset branch to origin/main
$ git merge B1
$ git merge B3


$ git rebase origin/main

then T would be what you would be pushing.

The benefit of this approach is that you don't really need to rebase 
often on your work branch (they will make the history harder to 
understand) and you got to choose when to do that, or just omit one 
branch at push time, etc., so it's very flexible when working on 
something really big.  The downside is slightly more 'git merge' work: 
usually they can be done automatically by git, however.

> Does this makes sense?
> Warner Losh < <>> escreveu no dia 
> sábado, 3/12/2022 à(s) 16:16:
>     On Sat, Dec 3, 2022 at 8:59 AM Nuno Teixeira <
>     <>> wrote:
>         Hello,
>             $ git clone
>             <> ports/main
>             $ cd ports/main
>             $ git worktree add ../2022Q4 -b 2022Q4 origin/2022Q4
>         So we will have ports/{main,2022Q4} and cd to main or 2022Q4
>         according if commit is to main or quarterly?
>         I will try this soon because swithing from branches is not the
>         best way (but I used it for about 1 year without problems).
>     I do this for my src commits. I have 3 trees: 'head', 'stable-13'
>     and 'stable-12'. I have a lot of branches off of head
>     for work in progress that I switch between all the time to refine,
>     finish  and land them. For especially large projects
>     I'll have a separate work tree, but usually the changes are small
>     enough that this works fine. I have a script that
>     rebases everything once and a while to keep my branches in sync. For
>     stable-12 I have a stable/12 branch locally
>     that mirrors upstream. I also have a stable/mfc12 branche that I
>     'insta-MFC' changes that I commit to head that need
>     time to cook before being pushed. I do this so I don't lose things.
>     I then rebase the stable/mfc12 onto stable/12 and push
>     when the time comes (doing the rebase dance as needed).
>     Warner
> -- 
> Nuno Teixeira
> FreeBSD Committer (ports)