threads / discuss / 4182

[RFD] Git glossary: 'branch' and 'head' description

Subject: [RFD] Git glossary: 'branch' and 'head' description

## tl;dr

13 messages between May 17, 2006 and May 21, 2006.

replies: 12people: 6as markdown or json

Jakub Narebski· May 17, 2006, 11:37 UTC · lore

In #git channel somebody asked about 'branches' and 'heads' and was referred to the glossary. I had taken then a look at appropriate glossary entries.

In 'Documentation/glossary.txt' we have:
----  
branch::
        A non-cyclical graph of revisions, i.e. the complete history of
        a particular revision, which is called the branch head. The
        branch heads are stored in `$GIT_DIR/refs/heads/`.
head::
        The top of a branch. It contains a ref to the corresponding
        commit object.
head ref::
        A ref pointing to a head. Often, this is abbreviated to "head".
        Head refs are stored in `$GIT_DIR/refs/heads/`.
revision::
        A particular state of files and directories which was stored in
        the object database. It is referenced by a commit object.
---- 

It is just me or the glossary entry for `branch` is unnecessary complicated?

Let's take a look at other definitions:
  In software engineering, 'branch' is a separate line of development, which 
  among others allows development on a project to diverge in two directions, 
  such as a stable and a development version. (WikiPedia:Branch)
  In the CVS team development environment, a separate line of development 
  where changes can be isolated. When a programmer changes files on 
  a branch, those changes do not appear on the main trunk 
  or other branches. (cvs.info)

So from the user's point of view, 'branch' is simply _named line of development_. Refer to topic and tracking branches.

>From the point of view of commit, current branch (or rather branch

head/branch tip) is the place where we attach current development line (current commit has current head as parent, and head is advanced to the current commit), something akin to 'top' pointer for stack implemented as linked list.

ONLY from the point of view of HISTORY, branch define "non-cyclical graph of revisions, i.e. the complete history of a particular revision, which is called the branch head." Merges somewhat obscure the branches (as history), unless for example we assume that first parent is on the same branch, or use note header to mark appropriate parent/commit. Also git does not record where branch started... New branch commit logging proposal, and per-branch configuration should help with these issues.

No concrete proposal for git glossary update...
-- 
Jakub Narebski
Warsaw, Poland
Junio C Hamano· May 17, 2006, 18:28 UTC · re: Jakub Narebski · lore

Re: [RFD] Git glossary: 'branch' and 'head' description

Jakub Narebski <jnareb@gmail.com> writes:
Show 25 quoted lines
> In #git channel somebody asked about 'branches' and 'heads' and was referred
> to the glossary. I had taken then a look at appropriate glossary entries.
>
> In 'Documentation/glossary.txt' we have:
> ----  
> branch::
>         A non-cyclical graph of revisions, i.e. the complete history of
>         a particular revision, which is called the branch head. The
>         branch heads are stored in `$GIT_DIR/refs/heads/`.
>
> head::
>         The top of a branch. It contains a ref to the corresponding
>         commit object.
>
> head ref::
>         A ref pointing to a head. Often, this is abbreviated to "head".
>         Head refs are stored in `$GIT_DIR/refs/heads/`.
>
> revision::
>         A particular state of files and directories which was stored in
>         the object database. It is referenced by a commit object.
> ---- 
>
> It is just me or the glossary entry for `branch` is unnecessary 
> complicated? 

While technically it might be correct, the above description for "branch" completely misses the point in the context of other entries. I do not recall when this entry was first written, but I suspect it probably predates other entries that talk about the same thing.

As you point out it talks primarily about the mesh of all possible histories (i.e commit DAG), without talking much about what "branch" means and what role "branch" plays.

I cannot easily do a glossary entry to describe that specific term, but maybe somebody else can split the following up and paraphrase.

        A project history is born by recording a particular
        state ("revision") as a root commit, and built up by
        recording subsequent states ("revisions") on top of the
        previous commits.  Thus, a group of commits connected by
        their parent fields form a directed acyclic graph
        ("DAG").  Often this linkage between commits by their
        parent fields is called "ancestry chain", and a commit
        that has another commit in its "parent" field is called
        a "child commit" of the latter.
        There can be multiple root commits in the history of a
        project.  In other words, projects born independently
        can later be glued together to become a single project.
        The history is grown by building on top of previous
        commits, and by the nature of distributed development,
        many lineages of histories are grown simultaneously.
        Each lineage is called a "branch".
        A commit that can be reached by following the ancestry
        chain from a commit that is "on the branch" is also "on
        the branch", and a commit that cannot be reached by
        following the ancestry chain from any commit that is "on
        the branch" is not "on the branch".  The commit that
        bootstraps this recursive definition of "on the branch"
        is called its "branch head", the "tip of the branch", or
        the "top commit".  In other words, it is topologically
        the latest commit on the branch.
	The above does not mean the top commit of a branch does
	not have any child commit in the global project
	histories.  It just means that these children are not on
	the branch; they may be on some other branches, forked
	from it.  To create a branch whose "on the branch"
	commits are strict superset of "on the branch" commits
	of another branch is called "forking" the branch.
Jakub Narebski· May 17, 2006, 19:13 UTC · re: Junio C Hamano · lore

Re: [RFD] Git glossary: 'branch' and 'head' description

Junio C Hamano wrote:
> Jakub Narebski <jnareb@gmail.com> writes:
Show 13 quoted lines
>> In 'Documentation/glossary.txt' we have:
>> ----  
>> branch::
>>         A non-cyclical graph of revisions, i.e. the complete history of
>>         a particular revision, which is called the branch head. The
>>         branch heads are stored in `$GIT_DIR/refs/heads/`.
>> ---- 
> 
> While technically it might be correct, the above description for
> "branch" completely misses the point in the context of other
> entries.  I do not recall when this entry was first written, but
> I suspect it probably predates other entries that talk about the
> same thing.
[cut long description]

The description you gave is nice, but it belongs in Tutorial rather than in Glossary. Additionally it mainly deals with branches fron the 'revision history' point of view, although the 'commit' point of view can also be seen.

Glossary entry should be short, up to the point, and encompass al three points of view:

 a.) conceptual point of view, i.e. "branch is separate line of
development" (be it stable or development direction, introducing new
feature aka. 'topic', or following aka. 'tracking' changes in other
repository),
 b) revision history point of view, i.e. "on branch means, roughly,
reachable from branch head aka. tip", or "branch is lineage of history of
project" (somewhat mudded by merges[*1*], fork points[*2*] and multiple
roots). This is what current glossary entry tries to present,
 c) commit point of view, i.e. "branch tip is where we do commit
changes" (branch tip is [one of] parent(s) of current commit, and branch
tip is advanced to new commit).
[*1*] Problem with merges:
   
   ---.---.---A-\--.---.---.---B-- branch1
                 \
   ---.---.---C---*D---.---.---E-- branch2   
   
Does A belong to branch2? It is one of parents of commit D. We can assume
that only first parent in merges continues branch. But what if we have the
following history:
   ---.---.---A-\  <---- there was branch1 here
                 \
   ---.---.---C---*D---.---.---E-- branch2 
To which branch belongs A then?
[*2*] Problem with fork point
           /--1---2---3-- maintenance/stable/fixes branch  
          /
  ---A---B----C---D---E-- master/development branch

Following the ancestry chain we get that commit A is on branch 'maint' (it is also on branch 'master'); git does not record fork points. Perhaps the branch logging and/or per branch configuration could be used to resolve this issue.

-- 
Jakub Narebski
Warsaw, Poland
Junio C Hamano· May 17, 2006, 19:57 UTC · re: Jakub Narebski · lore

Re: [RFD] Git glossary: 'branch' and 'head' description

Jakub Narebski <jnareb@gmail.com> writes:
> [cut long description]
>
> The description you gave is nice, but it belongs in Tutorial rather than in
> Glossary.
I suspect I was not clear enough for you when I said:
        I cannot easily do a glossary entry to describe that specific
        term, but maybe somebody else can split the following up and
        paraphrase.
Jakub Narebski· May 17, 2006, 20:06 UTC · re: Junio C Hamano · lore

Re: [RFD] Git glossary: 'branch' and 'head' description

Junio C Hamano wrote:
Show 12 quoted lines
> Jakub Narebski <jnareb@gmail.com> writes:
> 
>> [cut long description]
>>
>> The description you gave is nice, but it belongs in Tutorial rather than 
>> in the Glossary.
> 
> I suspect I was not clear enough for you when I said:
> 
>         I cannot easily do a glossary entry to describe that specific
>         term, but maybe somebody else can split the following up and
>         paraphrase.

Maybe I should say that the description you gave is a nice source for eventual glossary entry, but I feel that as the whole is worth preserving in some tutorial text.

-- 
Jakub Narebski
Warsaw, Poland
David Kågedal· May 19, 2006, 06:53 UTC · re: Jakub Narebski · lore

Re: [RFD] Git glossary: 'branch' and 'head' description

Jakub Narebski <jnareb@gmail.com> writes:
Show 9 quoted lines
> In #git channel somebody asked about 'branches' and 'heads' and was referred
> to the glossary. I had taken then a look at appropriate glossary entries.
>
> In 'Documentation/glossary.txt' we have:
> ----  
> branch::
>         A non-cyclical graph of revisions, i.e. the complete history of
>         a particular revision, which is called the branch head. The
>         branch heads are stored in `$GIT_DIR/refs/heads/`.
[...]
Show 16 quoted lines
> It is just me or the glossary entry for `branch` is unnecessary 
> complicated? 
>
> Let's take a look at other definitions:
>
>   In software engineering, 'branch' is a separate line of development, which 
>   among others allows development on a project to diverge in two directions, 
>   such as a stable and a development version. (WikiPedia:Branch)
>
>   In the CVS team development environment, a separate line of development 
>   where changes can be isolated. When a programmer changes files on 
>   a branch, those changes do not appear on the main trunk 
>   or other branches. (cvs.info)
>
> So from the user's point of view, 'branch' is simply _named line of
> development_. Refer to topic and tracking branches.

But the definition of 'branch' in git is quite different from the definition in CVS or many other systems. It CVS, each revision (commit) belongs to a branch, and the branch is a linear sequence of revisions, not a full DAG. In git, a commit doesn't really "belong" in any specific branch.

So, while it makes sense to describe branches as "lines of development" in general terms, it is also important to note the specific meaning of 'branch' in the context of git; i.e. as the history of a single head commit.

I noticed that some of this seems to be changing slightly with the introduction of branch logs, but I don't know how those are supposed to be used yet.

-- 
David Kågedal
Shawn Pearce· May 19, 2006, 09:21 UTC · re: David Kågedal · lore

Re: [RFD] Git glossary: 'branch' and 'head' description

David K?gedal <davidk@lysator.liu.se> wrote:
> I noticed that some of this seems to be changing slightly with the
> introduction of branch logs, but I don't know how those are supposed
> to be used yet.
	$ git commit -a
	$ git pull . some/other-tag
	# go to lunch
	$ git pull . some/bad-stuff
	$ git commit -a
	# go home
	$ test...
	# realize this is all bad
	$ git reset --hard "master@{yesterday}"
:-)

Its really only useful for recording the history of your ref's state, so you can 'undo' a bad merge that you might have done a few days ago but not realized was bad until now.

-- 
Shawn.
Daniel Barkalow· May 20, 2006, 00:28 UTC · re: Shawn Pearce · lore

Re: [RFD] Git glossary: 'branch' and 'head' description

On Fri, 19 May 2006, Shawn Pearce wrote:
Show 20 quoted lines
> David K?gedal <davidk@lysator.liu.se> wrote:
> > I noticed that some of this seems to be changing slightly with the
> > introduction of branch logs, but I don't know how those are supposed
> > to be used yet.
> 
> 	$ git commit -a
> 	$ git pull . some/other-tag
> 	# go to lunch
> 	$ git pull . some/bad-stuff
> 	$ git commit -a
> 	# go home
> 	$ test...
> 	# realize this is all bad
> 	$ git reset --hard "master@{yesterday}"
> 
> :-)
> 
> Its really only useful for recording the history of your ref's state,
> so you can 'undo' a bad merge that you might have done a few days
> ago but not realized was bad until now.

I still think it's useful for presenting a local view of how things have changed. I.e.:

$ git pull . stuff # Notice that the diffstat is exciting # What did I just get? $ git log master@{5 minutes ago}..master

This is about the only easy way to find out that the fast-forward you just did included merging a line which contains a commit from several weeks ago. (Because the "before" state isn't easily accessible for a fast-forward, and the date of the old commit puts it way back in a date-ordered log.)

I still think that a local changelog, which groups the additions due to each logged value, would be a useful way of viewing the history in a way that's meaningful to the particular user, and I think it would fit user expectations of gitweb (i.e., when looking at Linus's tree's summary, things would be ordered by when they hit Linus's tree, not when they were originally committed, so between the listing of the merge at 23:48:54 today and the one 7 minutes before would be those things which weren't in Linus's tree during those 7 minutes).

	-Daniel
*This .sig left intentionally blank*
Junio C Hamano· May 20, 2006, 00:35 UTC · re: Daniel Barkalow · lore

Re: [RFD] Git glossary: 'branch' and 'head' description

Daniel Barkalow <barkalow@iabervon.org> writes:
Show 10 quoted lines
> $ git pull . stuff
> # Notice that the diffstat is exciting
> # What did I just get?
> $ git log master@{5 minutes ago}..master
>
> This is about the only easy way to find out that the fast-forward you just 
> did included merging a line which contains a commit from several weeks 
> ago. (Because the "before" state isn't easily accessible for a 
> fast-forward, and the date of the old commit puts it way back in a 
> date-ordered log.)
Did you forget about "git log ORIG_HEAD.."?
Daniel Barkalow· May 20, 2006, 01:36 UTC · re: Junio C Hamano · lore

Re: [RFD] Git glossary: 'branch' and 'head' description

On Fri, 19 May 2006, Junio C Hamano wrote:
Show 14 quoted lines
> Daniel Barkalow <barkalow@iabervon.org> writes:
> 
> > $ git pull . stuff
> > # Notice that the diffstat is exciting
> > # What did I just get?
> > $ git log master@{5 minutes ago}..master
> >
> > This is about the only easy way to find out that the fast-forward you just 
> > did included merging a line which contains a commit from several weeks 
> > ago. (Because the "before" state isn't easily accessible for a 
> > fast-forward, and the date of the old commit puts it way back in a 
> > date-ordered log.)
> 
> Did you forget about "git log ORIG_HEAD.."?

I guess I did forget that it sticks around. So you have to be doing something somewhat more complicated, like fetching the latest versions of multiple topic branches.

	-Daniel
*This .sig left intentionally blank*
Linus Torvalds· May 20, 2006, 02:06 UTC · re: Daniel Barkalow · lore

Re: [RFD] Git glossary: 'branch' and 'head' description

On Fri, 19 May 2006, Daniel Barkalow wrote:
> 
> I guess I did forget that it sticks around. So you have to be doing 
> something somewhat more complicated, like fetching the latest versions of 
> multiple topic branches.
I actually don't think it's at all unlikely that I'd start using this.

I tend to work in "spurts", where I do one thing for a while, and then merge several pull requests in fairly short order. So while I use ORIG_HEAD a lot, I can certainly imagine myself using the "since 2 hours ago" format too.

I'm not entirely sure about the syntax, though. It ends up being pretty command-line-unfriendly. The "gitk ORIG_HEAD.." thing is fairly easy to type, but typing

	gitk 'master@{2 hours ago}'..

on a Finnish keyboard (yeah, that's what I still use) is "interesting", since all of '@', '{' and '}' are complex characters (AltGr + '2', AltGr + '7' and AltGr + '0' respectively), and you have to remember the quoting.

Not that I see any obvious better syntax. Although allowing a shorthand like "@2.hours.ago" for "current branch, at given date" might help a bit, at least that wouldn't need quoting:

	gitk @2.hours.ago..
			Linus
Shawn Pearce· May 21, 2006, 01:01 UTC · re: Linus Torvalds · lore

Re: [RFD] Git glossary: 'branch' and 'head' description

Linus Torvalds <torvalds@osdl.org> wrote:
Show 8 quoted lines
> 
> On Fri, 19 May 2006, Daniel Barkalow wrote:
> > 
> > I guess I did forget that it sticks around. So you have to be doing 
> > something somewhat more complicated, like fetching the latest versions of 
> > multiple topic branches.
> 
> I actually don't think it's at all unlikely that I'd start using this.
Hey, if its useful.  :-) If its not then I'm doing something
wrong here...
 
[snip]
Show 9 quoted lines
> I'm not entirely sure about the syntax, though. It ends up being pretty 
> command-line-unfriendly. The "gitk ORIG_HEAD.." thing is fairly easy to 
> type, but typing
> 
> 	gitk 'master@{2 hours ago}'..
> 
> on a Finnish keyboard (yeah, that's what I still use) is "interesting", 
> since all of '@', '{' and '}' are complex characters (AltGr + '2', AltGr + 
> '7' and AltGr + '0' respectively), and you have to remember the quoting.

Wow. So what you are saying is writing any sort of C code must be rather painful. :-)

I received a suggestion of using ' (single quote) rather than { as the quoting character. I didn't make the quoting character optional as I realized users were likely to forget they needed it on date specs which contain ':', so I just made them required to keep things consistent at all times. Further {} won out over '' as {} is also used with the ^ operator (e.g. v1.3.3^{tree}).

Show 5 quoted lines
> Not that I see any obvious better syntax. Although allowing a shorthand 
> like "@2.hours.ago" for "current branch, at given date" might help a 
> bit, at least that wouldn't need quoting:
> 
> 	gitk @2.hours.ago..

The empty prefix for `HEAD` is simple. The '.' part would need to be fixed in approxidate() (and thus --since would also benefit). Omitting the {} might be OK but see above...

-- 
Shawn.
Jakub Narebski· May 21, 2006, 08:30 UTC · re: David Kågedal · lore

Re: [RFD] Git glossary: 'branch' and 'head' description

David Kågedal wrote:
> Jakub Narebski <jnareb@gmail.com> writes:
[...]
Show 13 quoted lines
>> So from the user's point of view, 'branch' is simply _named line of
>> development_. Refer to topic and tracking branches.
> 
> But the definition of 'branch' in git is quite different from the
> definition in CVS or many other systems.  It CVS, each revision
> (commit) belongs to a branch, and the branch is a linear sequence of
> revisions, not a full DAG.  In git, a commit doesn't really "belong"
> in any specific branch.
> 
> So, while it makes sense to describe branches as "lines of
> development" in general terms, it is also important to note the
> specific meaning of 'branch' in the context of git; i.e. as the
> history of a single head commit.

We can always say that branch is 1-st parent linear history of head branch, up to unmarked but computable branching/fork/creation point, i.e.

  {i = 0..N: branch-head~i}
where N is the length of the branch.
BTW. HEAD~0 == HEAD, isn't it?
-- 
Jakub Narebski
Warsaw, Poland

← back to recent threads