Re: What actually is a branch?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Martin wrote:
> On 08/07/2021 19:33, Felipe Contreras wrote:
> > The only reason I mentioned @{tail} (or @{base}) is to have a better
> > mental model of what a branch is.
> > 
> >   1. A branch is whatever is inside `branch@{base}..branch`
> 
> For this part "branch" = some series of commits.
> 
> Then this is what I would say is a common misunderstanding.
> 
> Yet that may be the difference between what people want the branch to 
> be, and what it (afaik) technically is.

I'm not talking about what a branch technically is, I'm talking about
what it is semantically.

Technically a branch is a file with an object id in it. That doesn't
give the user any useful information.

What is important is the *meaning* of that file.

> People indeed tend to thing, I branched at X, so anything before is not 
> part of the branch.
> "--contains" says otherwise.

Yes, that is the status quo, but the fact that X is the case doesn't
mean it *should* be the case.

The ideal user interface doesn't need to be explained. The more you need
to explain a concept the less intuitive it is, and the more you should
look for another concept that is perhaps more intuitive.

A branch that you hold, or point to, is a concete concept easy to
underand. When I say: "me, my sister, and my father are one tiny branch
of the Contreras family", people understand what that means inuitively.

On the other hand saying "Felipe contains his great-great-grandfather"
would stop anyone on their tracks.

> Thinking of it.
> 
> If I look at a feature branch, then my feature starts where I created 
> the branch. I want my feature branch to represent this.
> 
> But if I look at my local master branch (or any tracking branch), I like 
> to believe that it contains the same as the remote branch.
> And well, if we just set the base for the local tracking branch to be 
> the same as the base for the remote branch that would be fine.
> But if (after diverging, due to changes pulled from remote) then, I run
>     git rebase @{base} @{remote}
> then rebase has to skip all the shared commits.
> 
> And since rebase also repoints the "base", my local branch then no 
> longer contains the same as the remote.

That is a *very* interesting case that exemplifies the lack of our
current semantic arsenal.

Every time you do a rebase you are in effect creating a new branch with
new commits, a new head, and a new base. The only thing that remains
the same is the name.

It is no longer the same as the remote branch, or an outgrowth; it's
a new branch.

If you send a pull request for your 'master' branch, which then gets
merged to 'origin/master', then you can do `git merge --ff-only` to
advance the head pointer of the 'master' branch to the remote branch so
both are in sync... Except the base won't be the same.

With the current semantics this recreated 'master' is now exactly the
same as the remote 'origin/master'. But not with the @{base} semantics;
since both branches have a different base, they are strictly speaking
different branchs.

But if you do `git reset --hard origin/master`, you are saying: drop
everything about this branch, and make it the same 'origin/master'.
*Now* we have a reason to distinguish `git merge --ff-only` from `git
reset --hard`.

> So limiting the branch to branch@{base}..branch only works for feature 
> branches.
> 
> 
> So yes, what is a branch? More exactly what does it contain.
> Two examples, that to me suggest two answers.

Not necessarily. See above.

> Also if branch@{base}..branch  then there is a problem.
> - branch@{base} is then correctly not part of the branch
> - So immediately after "git switch -c branch" the branch is empty => ok
> But if so, then what is the branch head at that time?
> The Pointer would point the @{base}, but @base is outside the branch. So 
> the pointer of the branch points outside the branch?

Yes, the base pointer doesn't include the branch. When you do
`branch@{base}..branch` that's the same as `^branch@{base} branch` so that
excludes all the commits rechable from branch@{base} *including* that
commit iself.

> >   2. `branch` is the branch head (`branch@{head}`), but it's not the
> >      branch itself
> Well technically "branch" is the "pointer" to the head.
> Assuming we want "head" to be a commit?

No, the branch head is a reference: 'refs/heads/master'. The reference
points to a commit, but it's not the commit itself.

So it's a pointer to a pointer.

> The only problem is:
> branch is too often used for "the commits contained in the branch". That 
> is way to common to even try to stop it.

We don't need to stop it, we can sidestep it.

Instead of talking about the branch, talk about the branch head:
"the brach head is moved to X".

Or if you want to use the branch, don't assume any specifics:
"the branch is recreated to be the same as X".

> > When you change the branch head you are effectively changing the branch.
> Well if branch is the pointer, then you change the branch, and head is 
> being changed.
> If branch is the content, then you change the head, and yes the content 
> changes.

Exactly, so regardless of which semantics you choose, everyone
understands that the branch is not the same anymore.

-- 
Felipe Contreras



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux