Re: What actually is a branch?

2 messages, 2 authors, 2021-07-08 · open the first message on its own page

Re: What actually is a branch?

From: Sergey Organov <hidden>
Date: 2021-07-08 11:16:56

Felipe Contreras [off-list ref] writes:
Sergey Organov wrote:
quoted
Felipe Contreras [off-list ref] writes:
quoted
Since this is not strictly related to the topic of `git switch` I
renamed the thread.

Sergey Organov wrote:
quoted
Felipe Contreras [off-list ref] writes:
quoted
Sergey Organov wrote:
[...]
quoted
quoted
quoted
As for branch tail, I do have convention of marking start of a
long-standing branch with corresponding tag, where branch "foo" has
corresponding "foo-bp" tag marking its "branch point". Recently I
started to mark start of feature branch with yet another branch "foo-bp"
rather than tag, "foo" being set to track "foo-bp", that allows to
automate rebasing of "foo" against correct base.
So foo-bp is the upstream of foo, and you do basically:

  git rebase foo@{upstream}
Yep, but essential feature to me is that I in fact use tools that simply
run bare

   git rebase

and that "just works" (tm).
I typed the revision explicitly, but `git rebase` would work just
fine.
Sorry, I don't follow. Did you change semantic of `git rebase`? With
current mainstream Git, as far as I can tell,

  git rebase

essentially is:

  git rebase --fork-point @{upstream}

How introduction of @{tail} changes this, exactly?
quoted
quoted
This is works if your base (or tail, or whatever) is static, but many
branches jump around, and that's where @{tail} comes in handy.
Yeah, I see. When I need to make a branch jump around, I do need to
manually move my references, but that's fortunately very rare use-case
for me. Having direct support for that is still a win.
quoted
You can do this:

  git rebase --onto foo@{upstream} foo@{tail}

This will always rebase the right commits (no need to look into the
reflog). So you can say that the branch is foo@{tail}..foo.
I see where and when it's useful, but for a feature branch 99% of times
I don't want to rebase it onto some true upstream. I rather want to just
fiddle with the branch in place, and I prefer to setup things the way
that ensures that bare "git rebase" does "the right thing".
But that's precisely the point: when you do `git rebase` you don't have
to type the base or --onto anymore. It's done automatically.

Not just for your long-standing branches, but for *any* branch.
quoted
Probably that could be solved by a branch-local configuration that makes
"git rebase" become "git rebase @{tail}" for the branch instead of "git
rebase @{upstream}"
No. @{upstream} is where you want to rebase *to*, @{tail} is where you
want to rebase *from*.
My point is that for feature branch I rather want to rebase from @{tail}
to @{tail} 99% of times.
When you do:

  git rebase foo@{upstream}

This is basically the same as:

  git checkout foo@{upstream}^0
  git cherry-pick --right-only foo@{upstream}...foo
Yes, but you probably meant foo@{upstream}..foo (2 dots, not 3) here.
git is smart enough to figure out what commits are already part of
foo@{upstream}, and those are skipped, but at no point was any "base"
calculated (at least not from `git rebase`).

Most of the time `git rebase` works fine, because there aren't too many
commits to figure out where they should go, but it's definitely not
efficient, and there's many corner-cases (see a Linux kernel maintaner
baffled by what the hell `git rebase` is doing [1]).
Once again, how exactly the foo@{tail} fits in this picture?
quoted
quoted
Another advantage of having this notion is that `git rebase`
automatically updates the tail (in this case to foo@{upstream}).
Yep, looks useful. Is it all local to given repo, or else?
I implented it as 'refs/tails' (as opposed to 'refs/heads'), so it's
local to a given repo, but could easily be exported.
Do I get it right that now `git switch br1; git rebase --onto br2` will
likely have different outcome in the repository where "br1" has been
created compared to any other repository, as "br1@{tail}" will only
exist in that exact repo?

Thanks,
-- 
Sergey Organov

Re: What actually is a branch?

From: Felipe Contreras <hidden>
Date: 2021-07-08 18:05:25

Sergey Organov wrote:
Felipe Contreras [off-list ref] writes:
quoted
Sergey Organov wrote:
quoted
Felipe Contreras [off-list ref] writes:
quoted
Since this is not strictly related to the topic of `git switch` I
renamed the thread.

Sergey Organov wrote:
quoted
Felipe Contreras [off-list ref] writes:
quoted
Sergey Organov wrote:
[...]
quoted
quoted
quoted
quoted
As for branch tail, I do have convention of marking start of a
long-standing branch with corresponding tag, where branch "foo" has
corresponding "foo-bp" tag marking its "branch point". Recently I
started to mark start of feature branch with yet another branch "foo-bp"
rather than tag, "foo" being set to track "foo-bp", that allows to
automate rebasing of "foo" against correct base.
So foo-bp is the upstream of foo, and you do basically:

  git rebase foo@{upstream}
Yep, but essential feature to me is that I in fact use tools that simply
run bare

   git rebase

and that "just works" (tm).
I typed the revision explicitly, but `git rebase` would work just
fine.
Sorry, I don't follow. Did you change semantic of `git rebase`? With
current mainstream Git, as far as I can tell,

  git rebase

essentially is:

  git rebase --fork-point @{upstream}
More explicitly, it's

  git rebase --onto @{upstream} --fork-point @{upstream}
How introduction of @{tail} changes this, exactly?
Now --fork-point is not necessary:

  git rebase --onto @{upstream} @{tail}
quoted
quoted
quoted
This is works if your base (or tail, or whatever) is static, but many
branches jump around, and that's where @{tail} comes in handy.
Yeah, I see. When I need to make a branch jump around, I do need to
manually move my references, but that's fortunately very rare use-case
for me. Having direct support for that is still a win.
quoted
You can do this:

  git rebase --onto foo@{upstream} foo@{tail}

This will always rebase the right commits (no need to look into the
reflog). So you can say that the branch is foo@{tail}..foo.
I see where and when it's useful, but for a feature branch 99% of times
I don't want to rebase it onto some true upstream. I rather want to just
fiddle with the branch in place, and I prefer to setup things the way
that ensures that bare "git rebase" does "the right thing".
But that's precisely the point: when you do `git rebase` you don't have
to type the base or --onto anymore. It's done automatically.

Not just for your long-standing branches, but for *any* branch.
quoted
Probably that could be solved by a branch-local configuration that makes
"git rebase" become "git rebase @{tail}" for the branch instead of "git
rebase @{upstream}"
No. @{upstream} is where you want to rebase *to*, @{tail} is where you
want to rebase *from*.
My point is that for feature branch I rather want to rebase from @{tail}
to @{tail} 99% of times.
Just make @{upstream} = @{tail}, then you get your desired result.
quoted
When you do:

  git rebase foo@{upstream}

This is basically the same as:

  git checkout foo@{upstream}^0
  git cherry-pick --right-only foo@{upstream}...foo
Yes, but you probably meant foo@{upstream}..foo (2 dots, not 3) here.
I think if you do foo@{upstream}..foo then that --right-only doesn't do
the same thing.

`--right-only foo@{upstream}...foo` will drop commits that already part of
upstream. Another way you can find commits already part of upstream is
with `git cherry foo@{upstream}`.
quoted
git is smart enough to figure out what commits are already part of
foo@{upstream}, and those are skipped, but at no point was any "base"
calculated (at least not from `git rebase`).

Most of the time `git rebase` works fine, because there aren't too many
commits to figure out where they should go, but it's definitely not
efficient, and there's many corner-cases (see a Linux kernel maintaner
baffled by what the hell `git rebase` is doing [1]).
Once again, how exactly the foo@{tail} fits in this picture?
It sets <upstream> so no --fork-point is necessary.
quoted
quoted
quoted
Another advantage of having this notion is that `git rebase`
automatically updates the tail (in this case to foo@{upstream}).
Yep, looks useful. Is it all local to given repo, or else?
I implented it as 'refs/tails' (as opposed to 'refs/heads'), so it's
local to a given repo, but could easily be exported.
Do I get it right that now `git switch br1; git rebase --onto br2` will
likely have different outcome in the repository where "br1" has been
created compared to any other repository, as "br1@{tail}" will only
exist in that exact repo?
It very well could, if `--fork-point @{upstream}` finds a different base
than `@{tail}`.

Cheers.

-- 
Felipe Contreras
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help