{"thread":{"id":"18954","subject":"What are branches?","startedAt":"2009-04-19T15:17:52Z","lastAt":"2009-04-25T11:11:58Z","messageCount":28,"participants":["Johannes Schindelin","Michael Witten","Tuncer Ayaz","Dmitry Potapov","Michael J Gruber","Björn Steinbrink","Brian Gernhardt","Jakub Narebski","Michał Kiedrowicz","Junio C Hamano","Marius Vollmer","Felipe Contreras"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"111651","messageId":"alpine.DEB.1.00.0904191709220.10279@pacific.mpi-cbg.de","threadId":"18954","inReplyTo":null,"subject":"What are branches?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-04-19T15:17:52Z","receivedAt":"2009-04-19T15:17:52Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nif you're like me, you used Git for _way_ too long to really understand \nhow anybody can say that Git is hard to learn.  The concepts underlying \nGit have sunk so deep that I do not question them anymore.\n\nBut it is important to keep in mind that our concept of branches is not \nintuitive:\n\nhttp://longair.net/blog/2009/04/16/git-fetch-and-merge/\n\nIn particular, we have some pretty confusing nomenclature when it comes to \nbranches, and we might want to think how to improve the situation.\n\nFood for thought on a lazy Sunday afternoon.\n\nCiao,\nDscho\n"},{"id":"111652","messageId":"b4087cc50904190824k4b02a34uf901428e20cb8c7@mail.gmail.com","threadId":"18954","inReplyTo":"alpine.DEB.1.00.0904191709220.10279@pacific.mpi-cbg.de","subject":"Re: What are branches?","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2009-04-19T15:24:31Z","receivedAt":"2009-04-19T15:24:31Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"On Sun, Apr 19, 2009 at 10:17, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> if you're like me, you used Git for _way_ too long to really understand\n> how anybody can say that Git is hard to learn.\n\nI think that the human brain struggles with indirection. Consider that\nso many programmers have a hard time understanding pointers; no wonder\nso many people find git's underlying concepts boggling.\n\nMichael WItten\n"},{"id":"111662","messageId":"4ac8254d0904191510v72ab2f92t6839c8354d0c6fe4@mail.gmail.com","threadId":"18954","inReplyTo":"alpine.DEB.1.00.0904191709220.10279@pacific.mpi-cbg.de","subject":"Re: What are branches?","fromName":"Tuncer Ayaz","fromEmail":"tuncer.ayaz@gmail.com","sentAt":"2009-04-19T22:10:52Z","receivedAt":"2009-04-19T22:10:52Z","isPatch":false,"sender":{"key":"tuncer.ayaz@gmail.com","avatar":null},"body":"On Sun, Apr 19, 2009 at 5:17 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi,\n>\n> if you're like me, you used Git for _way_ too long to really understand\n> how anybody can say that Git is hard to learn.  The concepts underlying\n> Git have sunk so deep that I do not question them anymore.\n>\n> But it is important to keep in mind that our concept of branches is not\n> intuitive:\n>\n> http://longair.net/blog/2009/04/16/git-fetch-and-merge/\n>\n> In particular, we have some pretty confusing nomenclature when it comes to\n> branches, and we might want to think how to improve the situation.\n>\n> Food for thought on a lazy Sunday afternoon.\n\nProbably in the same confusion department:\nhttp://blog.teksol.info/2009/04/15/beware-of-gits-content-tracking.html\n\nIs he right and is this the defined correct behavior?\n"},{"id":"111663","messageId":"alpine.DEB.1.00.0904200028340.10279@pacific.mpi-cbg.de","threadId":"18954","inReplyTo":"4ac8254d0904191510v72ab2f92t6839c8354d0c6fe4@mail.gmail.com","subject":"Re: What are branches?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-04-19T22:29:25Z","receivedAt":"2009-04-19T22:29:25Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 20 Apr 2009, Tuncer Ayaz wrote:\n\n> On Sun, Apr 19, 2009 at 5:17 PM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n>\n> > if you're like me, you used Git for _way_ too long to really \n> > understand how anybody can say that Git is hard to learn.  The \n> > concepts underlying Git have sunk so deep that I do not question them \n> > anymore.\n> >\n> > But it is important to keep in mind that our concept of branches is \n> > not intuitive:\n> >\n> > http://longair.net/blog/2009/04/16/git-fetch-and-merge/\n> >\n> > In particular, we have some pretty confusing nomenclature when it \n> > comes to branches, and we might want to think how to improve the \n> > situation.\n> >\n> > Food for thought on a lazy Sunday afternoon.\n> \n> Probably in the same confusion department:\n> http://blog.teksol.info/2009/04/15/beware-of-gits-content-tracking.html\n> \n> Is he right and is this the defined correct behavior?\n\nCould you please at least change the subject to something like \"Something \nelse, was Re: ...\" when you abduct the thread?\n\nThanks,\nDscho\n"},{"id":"111664","messageId":"4ac8254d0904191534q3abc4bdq7aebb0559803739@mail.gmail.com","threadId":"18954","inReplyTo":"alpine.DEB.1.00.0904200028340.10279@pacific.mpi-cbg.de","subject":"Re: What are branches?","fromName":"Tuncer Ayaz","fromEmail":"tuncer.ayaz@gmail.com","sentAt":"2009-04-19T22:34:05Z","receivedAt":"2009-04-19T22:34:05Z","isPatch":false,"sender":{"key":"tuncer.ayaz@gmail.com","avatar":null},"body":"On Mon, Apr 20, 2009 at 12:29 AM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi,\n>\n> On Mon, 20 Apr 2009, Tuncer Ayaz wrote:\n>\n>> On Sun, Apr 19, 2009 at 5:17 PM, Johannes Schindelin\n>> <Johannes.Schindelin@gmx.de> wrote:\n>>\n>> > if you're like me, you used Git for _way_ too long to really\n>> > understand how anybody can say that Git is hard to learn.  The\n>> > concepts underlying Git have sunk so deep that I do not question them\n>> > anymore.\n>> >\n>> > But it is important to keep in mind that our concept of branches is\n>> > not intuitive:\n>> >\n>> > http://longair.net/blog/2009/04/16/git-fetch-and-merge/\n>> >\n>> > In particular, we have some pretty confusing nomenclature when it\n>> > comes to branches, and we might want to think how to improve the\n>> > situation.\n>> >\n>> > Food for thought on a lazy Sunday afternoon.\n>>\n>> Probably in the same confusion department:\n>> http://blog.teksol.info/2009/04/15/beware-of-gits-content-tracking.html\n>>\n>> Is he right and is this the defined correct behavior?\n>\n> Could you please at least change the subject to something like \"Something\n> else, was Re: ...\" when you abduct the thread?\n\nsorry, will repost. I have to admit that I was 25% unsure whether\nthis is related and the right/wrong context. oh and that number is\nexact :).\n"},{"id":"111722","messageId":"20090420113216.GC25059@dpotapov.dyndns.org","threadId":"18954","inReplyTo":"alpine.DEB.1.00.0904191709220.10279@pacific.mpi-cbg.de","subject":"Re: What are branches?","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2009-04-20T11:32:16Z","receivedAt":"2009-04-20T11:32:16Z","isPatch":false,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Sun, Apr 19, 2009 at 05:17:52PM +0200, Johannes Schindelin wrote:\n> \n> But it is important to keep in mind that our concept of branches is not \n> intuitive:\n> \n> http://longair.net/blog/2009/04/16/git-fetch-and-merge/\n\nI don't see how our concept of branches is any different from what other\nversion control systems have; but I see why it is so confusing for many\npeople. We define a branch as a line of development (I'm still think it\nis a pretty good and widely accepted definition of branch), yet when a\nnewcomer runs gitk, what he or she sees is not a line but a graph.\n\nThus anyone looking at a gitk image may ask you: \"Where is this line\nthat represents the master branch?\" Indeed, it is nearly impossible to\nsee it, but it does not mean this line does not exist. If you run:\ngitk --first-parent master\nyou can see it.\n\nUnfortunately, this line is far from being one straight line drawn in\na single color. Thus, not surprisingly that this line cannot be seen in\nthe graph, and here is where the mental image that a new user has about\nbranches (based on different books and diagrams) clashes with the image\npresented by gitk. No one will ever draw the mainline like this:\n\n-o--o--o         o--o--o\n        \\       /\n         o--o--o\n\nbut it is not uncommon for gitk to display it in this way, and when\nthis line is intervene with many other branches that forking from and\nmerging to this mainline, all what you can see a complex graph and\nnothing more.\n\nThere is one more thing. In Git, all branches are equal and that is a\nreally good feature from the implementation point of view as it makes\ndesign simpler and more powerful. But the user point of view, branches\nare never equal -- there is a _big_ difference between the master and\nany feature branch. All diagrams explaining branching and merging will\nshow the mainline as a thick straight line running through all history\n(like a tree trunk) while feature branches fork and merge back to it.\n\nThat is the mental image that a new user has, and that image clashes\nwith what he or she sees in gitk. BTW, when I started to use Git, I\nstrongly preferred qgit over gitk. Admittedly, gitk displays branches\nmuch better when you have a really bushy tree, but straight lines\ndisplayed by qgit were much easier to understand and to follow.\n\nSo, I don't think that we have any conceptual problem here. It may be\na visualization problem, but if you have a really complex tree, it may\nbe impossible to present it as nice and simple as artificial diagrams\nin textbooks.\n\n\nDmitry\n"},{"id":"111724","messageId":"49EC6596.8060208@drmicha.warpmail.net","threadId":"18954","inReplyTo":"20090420113216.GC25059@dpotapov.dyndns.org","subject":"Re: What are branches?","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2009-04-20T12:07:50Z","receivedAt":"2009-04-20T12:07:50Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Dmitry Potapov venit, vidit, dixit 20.04.2009 13:32:\n> On Sun, Apr 19, 2009 at 05:17:52PM +0200, Johannes Schindelin wrote:\n>>\n>> But it is important to keep in mind that our concept of branches is not \n>> intuitive:\n>>\n>> http://longair.net/blog/2009/04/16/git-fetch-and-merge/\n> \n> I don't see how our concept of branches is any different from what other\n> version control systems have; but I see why it is so confusing for many\n\nIt is very different, and for a good reason, indeed.\n\ngit's branches really are moving tags. As such, there is no single\nbranch that a commit would be tied to. A commit does not belong to a\nspecific branch; you commit on a branch (usually), and it may be\ncontained in 1 or more branches, of course. Which branch (name) may\nactually depend on the repository: branch names are not stored in\ncommits, only (backward) relations between commits.\n\nThis is fundamentally different from what is named \"branch\" in hg, e.g.\nThere, a commit stores the branch name, which is why you can't delete\nbranches easily. [For me, this is also why hg branches are useless, but\nI don't want to start flames here - for me they are useless, for others\nthey may still be perfect.]\n\nBranches in cvs etc. are much like the latter: You commit on a specific\nbranch, *and* you can't change that later. The branch name at time of\ncreating a commit is stored in the commit.\n\nHg is introducing \"bookmarks\" now, corresponding to git branches. I\nthink this name describes the nature of git branches very well.\n\n> people. We define a branch as a line of development (I'm still think it\n> is a pretty good and widely accepted definition of branch), yet when a\n> newcomer runs gitk, what he or she sees is not a line but a graph.\n> \n> Thus anyone looking at a gitk image may ask you: \"Where is this line\n> that represents the master branch?\" Indeed, it is nearly impossible to\n> see it, but it does not mean this line does not exist. If you run:\n> gitk --first-parent master\n> you can see it.\n> \n> Unfortunately, this line is far from being one straight line drawn in\n> a single color. Thus, not surprisingly that this line cannot be seen in\n> the graph, and here is where the mental image that a new user has about\n> branches (based on different books and diagrams) clashes with the image\n> presented by gitk. No one will ever draw the mainline like this:\n> \n> -o--o--o         o--o--o\n>         \\       /\n>          o--o--o\n> \n> but it is not uncommon for gitk to display it in this way, and when\n> this line is intervene with many other branches that forking from and\n> merging to this mainline, all what you can see a complex graph and\n> nothing more.\n> \n> There is one more thing. In Git, all branches are equal and that is a\n> really good feature from the implementation point of view as it makes\n> design simpler and more powerful. But the user point of view, branches\n> are never equal -- there is a _big_ difference between the master and\n> any feature branch. All diagrams explaining branching and merging will\n> show the mainline as a thick straight line running through all history\n> (like a tree trunk) while feature branches fork and merge back to it.\n> \n> That is the mental image that a new user has, and that image clashes\n> with what he or she sees in gitk. BTW, when I started to use Git, I\n> strongly preferred qgit over gitk. Admittedly, gitk displays branches\n> much better when you have a really bushy tree, but straight lines\n> displayed by qgit were much easier to understand and to follow.\n> \n> So, I don't think that we have any conceptual problem here. It may be\n> a visualization problem, but if you have a really complex tree, it may\n> be impossible to present it as nice and simple as artificial diagrams\n> in textbooks.\n> \n> \n> Dmitry\n"},{"id":"111729","messageId":"20090420132414.GD25059@dpotapov.dyndns.org","threadId":"18954","inReplyTo":"49EC6596.8060208@drmicha.warpmail.net","subject":"Re: What are branches?","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2009-04-20T13:24:14Z","receivedAt":"2009-04-20T13:24:14Z","isPatch":false,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Mon, Apr 20, 2009 at 02:07:50PM +0200, Michael J Gruber wrote:\n> Dmitry Potapov venit, vidit, dixit 20.04.2009 13:32:\n> > On Sun, Apr 19, 2009 at 05:17:52PM +0200, Johannes Schindelin wrote:\n> >>\n> >> But it is important to keep in mind that our concept of branches is not \n> >> intuitive:\n> >>\n> >> http://longair.net/blog/2009/04/16/git-fetch-and-merge/\n> > \n> > I don't see how our concept of branches is any different from what other\n> > version control systems have; but I see why it is so confusing for many\n> \n> It is very different, and for a good reason, indeed.\n> \n> git's branches really are moving tags. As such, there is no single\n> branch that a commit would be tied to. A commit does not belong to a\n> specific branch; you commit on a branch (usually), and it may be\n> contained in 1 or more branches, of course.\n\nWhen you create a new commit, it is always belong to _one_ branch and\nnever to two or more branches. After that you can create a child branch\nthat will also contain this commit, but it is so in any other VCS.\n\nPerhaps, the only difference with some other VCSes can be that some VCS\nremember name on what branch the commit was initially created, but you\ncan add that information to Git commit manually if you really want.\n\nBut even better approach is to write the branch name only once when\nit is merged to the upstream, and Git does that by default. Have you\nseen a lot of merge commits like this:\n\n   Merge branch 'bs/maint-1.6.0-tree-walk-prefix' into maint\n   ....\n\nthough the name of branch does not exist in the upstream repository,\nthere is no problem to find all commits created on that branch. In fact,\nif Git stored those names in the upstream then Git repository would\ncontain over 2,000 branches already and that number would be only grow.\n\n> \n> This is fundamentally different from what is named \"branch\" in hg, e.g.\n> There, a commit stores the branch name, which is why you can't delete\n> branches easily. [For me, this is also why hg branches are useless, but\n> I don't want to start flames here - for me they are useless, for others\n> they may still be perfect.]\n\nI don't see it as fundamentally different. Basically, Hg has some\nrestriction that does not let you to remove branches that outlived their\nusefulness (and thus polluting name space), but the underlying structure\nis the same...\n\n> \n> Branches in cvs etc. are much like the latter: You commit on a specific\n> branch, *and* you can't change that later. The branch name at time of\n> creating a commit is stored in the commit.\n\nIIRC, it is not. CVS uses numbers which identify each branch. The name\nof branch can be changed later, but you cannot change the underlying ID.\nYou can even remove the name, but branch will remain, and you can follow\nit if you know numbers. Incidentally, you can always follow Git branch\nin similar way by using --first-parent option...\n\n> \n> Hg is introducing \"bookmarks\" now, corresponding to git branches. I\n> think this name describes the nature of git branches very well.\n\nHonestly, the first thing that comes to my mind when I hear bookmarks\nin relation to VCS is unannotated tags... The idea of self advancing\nbookmarks is really weird...\n\n\nDmitry\n"},{"id":"111733","messageId":"49EC7E3B.9050909@drmicha.warpmail.net","threadId":"18954","inReplyTo":"20090420132414.GD25059@dpotapov.dyndns.org","subject":"Re: What are branches?","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2009-04-20T13:52:59Z","receivedAt":"2009-04-20T13:52:59Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Dmitry Potapov venit, vidit, dixit 20.04.2009 15:24:\n> On Mon, Apr 20, 2009 at 02:07:50PM +0200, Michael J Gruber wrote:\n>> Dmitry Potapov venit, vidit, dixit 20.04.2009 13:32:\n>>> On Sun, Apr 19, 2009 at 05:17:52PM +0200, Johannes Schindelin wrote:\n>>>>\n>>>> But it is important to keep in mind that our concept of branches is not \n>>>> intuitive:\n>>>>\n>>>> http://longair.net/blog/2009/04/16/git-fetch-and-merge/\n>>>\n>>> I don't see how our concept of branches is any different from what other\n>>> version control systems have; but I see why it is so confusing for many\n>>\n>> It is very different, and for a good reason, indeed.\n>>\n>> git's branches really are moving tags. As such, there is no single\n>> branch that a commit would be tied to. A commit does not belong to a\n>> specific branch; you commit on a branch (usually), and it may be\n>> contained in 1 or more branches, of course.\n> \n> When you create a new commit, it is always belong to _one_ branch and\n> never to two or more branches. After that you can create a child branch\n> that will also contain this commit, but it is so in any other VCS.\n\nThere is nothing in a git commit that ties it to a specific branch; in\nthat sense, it does not \"belong\" to any.\n\nA git branch is a pointer to a commit. That commit and its predecessors\nare contained in the branch. A commit may be contained in multiple\nbranches, on equal footing: there is no \"prime branch\".\n\n> \n> Perhaps, the only difference with some other VCSes can be that some VCS\n> remember name on what branch the commit was initially created, but you\n> can add that information to Git commit manually if you really want.\n\nI don't want it. I want things the git way ;)\n\nI just want to emphasize that the branch concept is really different.\nEmphasizing that helps people who switch from other VCS to git.\n\nIn other VCS, a commit always belongs to exactly one branch: the one you\ncommitted it to, which is stored in the commit. It may be contained in\nmultiple branches, but belongs to the one only.\n\n> \n> But even better approach is to write the branch name only once when\n> it is merged to the upstream, and Git does that by default. Have you\n> seen a lot of merge commits like this:\n> \n>    Merge branch 'bs/maint-1.6.0-tree-walk-prefix' into maint\n>    ....\n> \n> though the name of branch does not exist in the upstream repository,\n> there is no problem to find all commits created on that branch. In fact,\n> if Git stored those names in the upstream then Git repository would\n> contain over 2,000 branches already and that number would be only grow.\n> \n>>\n>> This is fundamentally different from what is named \"branch\" in hg, e.g.\n>> There, a commit stores the branch name, which is why you can't delete\n>> branches easily. [For me, this is also why hg branches are useless, but\n>> I don't want to start flames here - for me they are useless, for others\n>> they may still be perfect.]\n> \n> I don't see it as fundamentally different. Basically, Hg has some\n> restriction that does not let you to remove branches that outlived their\n> usefulness (and thus polluting name space), but the underlying structure\n> is the same...\n\nThe underlying structure is the directed graph, with predecessorship\nbeing the incidence relation. But what's being discussed here is the\nvarious VCS concepts going by the name \"branch\" (the concept overlaying\nthe graph structure), and those are inherently different. Not being able\nto delete a branch (without taking all its commits down) is one\nconsequence of a specific concept.\n\n> \n>>\n>> Branches in cvs etc. are much like the latter: You commit on a specific\n>> branch, *and* you can't change that later. The branch name at time of\n>> creating a commit is stored in the commit.\n> \n> IIRC, it is not. CVS uses numbers which identify each branch. The name\n> of branch can be changed later, but you cannot change the underlying ID.\n> You can even remove the name, but branch will remain, and you can follow\n> it if you know numbers. \n\nSo, that ID is exactly equivalent to hg's branch name: stored in the\ncommit; just like svn's branches/paths if you follow a standard layout.\n\n> Incidentally, you can always follow Git branch\n> in similar way by using --first-parent option...\n> \n>>\n>> Hg is introducing \"bookmarks\" now, corresponding to git branches. I\n>> think this name describes the nature of git branches very well.\n> \n> Honestly, the first thing that comes to my mind when I hear bookmarks\n> in relation to VCS is unannotated tags... The idea of self advancing\n> bookmarks is really weird...\n\n... but exactly what git's branches are, and what makes them so useful ;)\n\nMichael\n"},{"id":"111739","messageId":"alpine.DEB.1.00.0904201621290.6771@intel-tinevez-2-302","threadId":"18954","inReplyTo":"20090420132414.GD25059@dpotapov.dyndns.org","subject":"Re: What are branches?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-04-20T14:25:38Z","receivedAt":"2009-04-20T14:25:38Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 20 Apr 2009, Dmitry Potapov wrote:\n\n> When you create a new commit, it is always belong to _one_ branch and \n> never to two or more branches.\n\nCertainly you forgot about detached HEADs?  And about the ability to \ncreate new branches which point to the _exact_ same commit as other \nbranches?  And about the option to delete the original branch, not \nremoving the commit, or the other branches, at all?\n\nNo, this all shows: we _have_ a different branch model from most other \nVCSes, and we _obviously_ make that not clear enough.\n\nMeaning, we should point out that our branches are different, _and_ we \nshould describe the light-weighted nature of them better in our \ndocumentation (especially the tutorials).\n\nCiao,\nDscho\n"},{"id":"111741","messageId":"49EC8648.6000608@warpmail.net","threadId":"18954","inReplyTo":"200904201614.07735.fge@one2team.com","subject":"Re: What are branches?","fromName":"Michael J Gruber","fromEmail":"drmicha@warpmail.net","sentAt":"2009-04-20T14:27:20Z","receivedAt":"2009-04-20T14:27:20Z","isPatch":false,"sender":{"key":"drmicha@warpmail.net","avatar":null},"body":"Francis Galiegue venit, vidit, dixit 20.04.2009 16:14:\n> Le lundi 20 avril 2009, vous avez écrit :\n>> Dmitry Potapov venit, vidit, dixit 20.04.2009 15:24:\n>>\n>> There is nothing in a git commit that ties it to a specific branch; in\n>> that sense, it does not \"belong\" to any.\n>>\n> \n> Yes there is: the branch you are currently on (shown by, among others, \"git \n> branch\").\n\nNo, there is not.\n\nProof: Delete that branch and the commit will still be there. QED\n\n> \n>> A git branch is a pointer to a commit. That commit and its predecessors\n>> are contained in the branch. A commit may be contained in multiple\n>> branches, on equal footing: there is no \"prime branch\".\n>>\n> \n> No. A commit's SHA1 depends on all other commits.\n\n...on all predecessors' SHA1s, to be exact.\n\nNow, what does this have to do with the existence of a \"prime branch\",\nwhich you claim?\n\n> \n> Why do you think the rebase command exists at all?\n> \n\nIn order to change the DAG. It rewrites commits.\n\nOn the other hand: If I want to change what branch a commit \"is on\", I\nuse git branch -m to rename the branch or git reset etc. to change some\n*descendant* commits of the commit in question. All of this does not\nrewrite the commit in question, but changes the names resp. the number\nof branches the commit is on. Which exactly proves my point.\n\ngit branches are different. Luckily they are!\n\nMichael\n\nP.S.: Please don't cull cc:\nP.P.S.: I'll stop here with this thread. I assume you'll believe at\nleast Dscho if you don't believe me ;)\n"},{"id":"111752","messageId":"20090420160633.GA17241@atjola.homenet","threadId":"18954","inReplyTo":"alpine.DEB.1.00.0904201621290.6771@intel-tinevez-2-302","subject":"Re: What are branches?","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-04-20T16:06:33Z","receivedAt":"2009-04-20T16:06:33Z","isPatch":false,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.04.20 16:25:38 +0200, Johannes Schindelin wrote:\n> On Mon, 20 Apr 2009, Dmitry Potapov wrote:\n> \n> > When you create a new commit, it is always belong to _one_ branch\n> > and never to two or more branches.\n> \n> Certainly you forgot about detached HEADs? And about the ability to\n> create new branches which point to the _exact_ same commit as other\n> branches? And about the option to delete the original branch, not\n> removing the commit, or the other branches, at all?\n> \n> No, this all shows: we _have_ a different branch model from most other\n> VCSes, and we _obviously_ make that not clear enough.\n\nBasically, git has no actual entities that I'd call \"branches\", it just\nhas named branch heads. The branches themselves are implicit in the\ncommit DAG.\n\nIf you go out, and look at a tree lit-up by the evil daystar, branches\nstart at the trunk and end at their tip. The trunk isn't part of the\nbranch. And as e.g. a SVN user, you can use an analogy and say \"There's\nbranch XYZ and it has these three commits\", ignoring commits from the\ntrunk or other branches leading up to this one. And you can even ask SVN\nwhich commits make up that branch, by using a \"stop on copy\" feature\n(because that copy usually tells where the branching point is).\n\nLet's take this history:\n\nA---B---C---D (refs/heads/master)\n \\\n  E---F---G (refs/heads/foo)\n       \\\n        H---I---J (refs/heads/bar)\n\nThe branches might be thought of to contain these commits:\n\nmaster: A, B, C, D\nfoo: E, F, G\nbar: H, I, J\n\nBecause those commits are (from a task oriented view) what makes those\nbranches. If branch \"bar\" implements feature Y, then the commits A, E\nand F might not be interesting when talking about the branch in the\ncontext of the feature it implements.\n\nWith SVN you could do:\nsvn log --stop-on-copy .../bar\n\nWhich automatically ignores commits that are on other branches.\n\nWith git you need:\ngit log foo..bar\n\nWhich gives the same result, but you need to be more explicit about what\nyou want to ignore. Because git just sees branch heads, not branches.\nThe same \"you need to think a bit more/different\" applies to merging\nbranches. As svn has just glorified cherry-picking, you can ignore the\nwhole history leading up to a branch, and still think of just \"this\nbranch does this task\", and \"merge\" that branch. For git, that obviously\nwon't do, you need to see the branch as it's embedded into the history.\nI'm not saying this is bad, as it gives you a more useful history, and\nmore flexibility, but it is definitely different from at least one wide\nspread system.\n\nThe only thing I'm aware of where git really draws a line between\n\"branches\" and branch heads is git checkout. You can checkout a \"branch\"\nusing its name:\n\tgit checkout master\n\nBut using the name of the branch head, will detach HEAD:\n\tgit checkout refs/heads/master\n\n(The quotes are there because this \"branch\" doesn't match the definition\nof a branch as I used it earlier...)\n\n\nSo basically, we don't have explicit branches, just a mechanism to\ncontrol where the branches grow.\n\nBjörn\n"},{"id":"111753","messageId":"49C4B512-6BE0-48A6-A689-05528B9D3DDE@silverinsanity.com","threadId":"18954","inReplyTo":"20090420132414.GD25059@dpotapov.dyndns.org","subject":"Re: What are branches?","fromName":"Brian Gernhardt","fromEmail":"benji@silverinsanity.com","sentAt":"2009-04-20T16:13:13Z","receivedAt":"2009-04-20T16:13:13Z","isPatch":false,"sender":{"key":"benji@silverinsanity.com","avatar":"https://gravatar.com/avatar/e06c101dbc25c68114d859b4a9ec7cf8a2c52fd2b0270ef0eac0e2e63ff22311?d=mp&s=160"},"body":"\nOn Apr 20, 2009, at 9:24 AM, Dmitry Potapov wrote:\n\n> On Mon, Apr 20, 2009 at 02:07:50PM +0200, Michael J Gruber wrote:\n>> Hg is introducing \"bookmarks\" now, corresponding to git branches. I\n>> think this name describes the nature of git branches very well.\n>\n> Honestly, the first thing that comes to my mind when I hear bookmarks\n> in relation to VCS is unannotated tags... The idea of self advancing\n> bookmarks is really weird...\n\nThat's because you're thinking of browser bookmarks instead of a real  \nbookmark.  A bookmark in a book would be rather pointless if I  \ncouldn't advance it as I read pages.  :-D\n\n~~ Brian\n"},{"id":"111768","messageId":"20090420184048.GF25059@dpotapov.dyndns.org","threadId":"18954","inReplyTo":"49EC7E3B.9050909@drmicha.warpmail.net","subject":"Re: What are branches?","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2009-04-20T18:40:48Z","receivedAt":"2009-04-20T18:40:48Z","isPatch":false,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Mon, Apr 20, 2009 at 03:52:59PM +0200, Michael J Gruber wrote:\n> Dmitry Potapov venit, vidit, dixit 20.04.2009 15:24:\n> > On Mon, Apr 20, 2009 at 02:07:50PM +0200, Michael J Gruber wrote:\n> >> Dmitry Potapov venit, vidit, dixit 20.04.2009 13:32:\n> >>> On Sun, Apr 19, 2009 at 05:17:52PM +0200, Johannes Schindelin wrote:\n> >>>>\n> >>>> But it is important to keep in mind that our concept of branches is not \n> >>>> intuitive:\n> >>>>\n> >>>> http://longair.net/blog/2009/04/16/git-fetch-and-merge/\n> >>>\n> >>> I don't see how our concept of branches is any different from what other\n> >>> version control systems have; but I see why it is so confusing for many\n> >>\n> >> It is very different, and for a good reason, indeed.\n> >>\n> >> git's branches really are moving tags. As such, there is no single\n> >> branch that a commit would be tied to. A commit does not belong to a\n> >> specific branch; you commit on a branch (usually), and it may be\n> >> contained in 1 or more branches, of course.\n> > \n> > When you create a new commit, it is always belong to _one_ branch and\n> > never to two or more branches. After that you can create a child branch\n> > that will also contain this commit, but it is so in any other VCS.\n> \n> There is nothing in a git commit that ties it to a specific branch; in\n> that sense, it does not \"belong\" to any.\n\nLet's take a look at definition of \"branch\" in different sources:\n\n\"Branching, in revision control and software configuration management,\nis the duplication of an object under revision control (such as a source\ncode file, or a directory tree) so that modifications can happen in\nparallel along both branches.\"\nSource: http://en.wikipedia.org/wiki/Branching_(software)\n\n\"This is the basic concept of a branch—namely, a line of development\nthat exists independently of another line, yet still shares a common\nhistory if you look far enough back in time. A branch always begins life\nas a copy of something, and moves on from there, generating its own\nhistory.\"\nSource: http://svnbook.red-bean.com/en/1.1/ch04.html#svn-ch-4-sect-1\n\n\"When we need to be precise, we will use the word \"branch\" to mean a\nline of development, and \"branch head\" (or just \"head\") to mean a\nreference to the most recent commit on a branch.\"\nSource: http://www.kernel.org/pub/software/scm/git/docs/v1.6.2.3/user-manual.html#what-is-a-branch\n\nIt is not that Git commit is not belong to any, but it may appear as\nbeing to many branches in shared history. Yet, I don't see anything\nin definition of branch that would preclude this.\n\n> \n> A git branch is a pointer to a commit. That commit and its predecessors\n> are contained in the branch. A commit may be contained in multiple\n> branches, on equal footing: there is no \"prime branch\".\n\nThis is not accurate description. The aforementioned pointer is called\n\"branch head\". Branch (in strictly sense) is a line of development,\nwhich is defined by its head. A usual commit has one parent; a merge\ncommit can have more than one parent, the first parent defines the\nbranch line while other parents point to branches merged to it.\n\n> \n> In other VCS, a commit always belongs to exactly one branch: the one you\n> committed it to, which is stored in the commit. It may be contained in\n> multiple branches, but belongs to the one only.\n\nI am not sure that it is the case, but actually it depends how you\ndefine terms \"belong\", \"contained\", \"branch\", etc... Anyway, no commonly\nused definition of \"branch\" implies any idea of exclusiveness ownership\nof some commit.\n\n> >>\n> >> This is fundamentally different from what is named \"branch\" in hg, e.g.\n> >> There, a commit stores the branch name, which is why you can't delete\n> >> branches easily. [For me, this is also why hg branches are useless, but\n> >> I don't want to start flames here - for me they are useless, for others\n> >> they may still be perfect.]\n> > \n> > I don't see it as fundamentally different. Basically, Hg has some\n> > restriction that does not let you to remove branches that outlived their\n> > usefulness (and thus polluting name space), but the underlying structure\n> > is the same...\n> \n> The underlying structure is the directed graph, with predecessorship\n> being the incidence relation. But what's being discussed here is the\n> various VCS concepts going by the name \"branch\" (the concept overlaying\n> the graph structure), and those are inherently different. Not being able\n> to delete a branch (without taking all its commits down) is one\n> consequence of a specific concept.\n\nI think you confuse two different things branch and its name. It is not\nexactly same things in most VCSes, though you usually use branch name to\nrefer to any branch. In Git (as in CVS and SVN), you can delete branch\nname without deleting commits.\n\n> \n> So, that ID is exactly equivalent to hg's branch name: stored in the\n> commit; just like svn's branches/paths if you follow a standard layout.\n\nNo, ID is just ID. You have commit ID in Git too, and you cannot remove\nit without removing commits, and if you have commit ID of the branch\nhead, you can follow the whole branch line even if it does not have any\nname.\n\n> \n> > Incidentally, you can always follow Git branch\n> > in similar way by using --first-parent option...\n> > \n> >>\n> >> Hg is introducing \"bookmarks\" now, corresponding to git branches. I\n> >> think this name describes the nature of git branches very well.\n> > \n> > Honestly, the first thing that comes to my mind when I hear bookmarks\n> > in relation to VCS is unannotated tags... The idea of self advancing\n> > bookmarks is really weird...\n> \n> ... but exactly what git's branches are, and what makes them so useful ;)\n\nNo, Git branches are branches, anyway \"bookmarks\" is clearly a wrong\nterm. If you do not like \"branch\", there are many other terms that can\nbe used instead, for example: streams, codelines.\n\n> That's because you're thinking of browser bookmarks instead of a real\n> bookmark.  A bookmark in a book would be rather pointless if I couldn't\n> advance it as I read pages.  :-D\n\nYou can advance them or move backward, but bookmarks do not move on its\nown. They always point to the place where you put them. That's why this\nterm remembers me more unannotated tags.\n\n\nDmitry\n"},{"id":"111769","messageId":"20090420184746.GG25059@dpotapov.dyndns.org","threadId":"18954","inReplyTo":"alpine.DEB.1.00.0904201621290.6771@intel-tinevez-2-302","subject":"Re: What are branches?","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2009-04-20T18:47:46Z","receivedAt":"2009-04-20T18:47:46Z","isPatch":false,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Mon, Apr 20, 2009 at 04:25:38PM +0200, Johannes Schindelin wrote:\n> \n> On Mon, 20 Apr 2009, Dmitry Potapov wrote:\n> \n> > When you create a new commit, it is always belong to _one_ branch and \n> > never to two or more branches.\n> \n> Certainly you forgot about detached HEADs?\n\nI suppose it is a branch without any name given to it, but it is an\nadvanced feature. I don't think many beginners know about it, so it\nis something that can confuse beginners.\n\n> And about the ability to \n> create new branches which point to the _exact_ same commit as other \n> branches?\n\nIn essence, we mark the starting point of the branch. Obviously, it\npoints to a commit that is on other branch or branches. Not every\nVCS creates a commit when a new branch is created, though overhead\nof creating of a new branch in other VCSes is usually much larger.\n\n> And about the option to delete the original branch, not \n> removing the commit, or the other branches, at all?\n\nAgain, there is nothing unique about it. If I remember correctly, it is\nso in CVS too. You could remove branch name, but it was still available\nby ID.\n\n\nDmitry\n"},{"id":"111770","messageId":"m3ab6bp2we.fsf@localhost.localdomain","threadId":"18954","inReplyTo":"20090420160633.GA17241@atjola.homenet","subject":"Re: What are branches?","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-04-20T18:59:38Z","receivedAt":"2009-04-20T18:59:38Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Björn Steinbrink <B.Steinbrink@gmx.de> writes:\n\n> If you go out, and look at a tree lit-up by the evil daystar, branches\n> start at the trunk and end at their tip. The trunk isn't part of the\n> branch.  [...]\n\nWell, you have to remember that the 'branch' metaphor should not be\ntaken too literaly; take for example merges which do not have\nequivalent in a tree build.\n\nBut if we are talking about literal branches: take a closer loog at\nthe tip of tree (plant) branch.  You can find growong tip there\n(apical meristem) where new cells grow.  In Git you have 'branches'\n(branch heads) where you create new commits...\n\nBut I agree that there isn't for example true notion of 'trunk' in\ngit, and this is what allows Git to be truly distributed...\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"111772","messageId":"alpine.DEB.1.00.0904202117010.6771@intel-tinevez-2-302","threadId":"18954","inReplyTo":"20090420184746.GG25059@dpotapov.dyndns.org","subject":"Re: What are branches?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-04-20T19:19:10Z","receivedAt":"2009-04-20T19:19:10Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 20 Apr 2009, Dmitry Potapov wrote:\n\n> On Mon, Apr 20, 2009 at 04:25:38PM +0200, Johannes Schindelin wrote:\n> > \n> > On Mon, 20 Apr 2009, Dmitry Potapov wrote:\n> > \n> > > When you create a new commit, it is always belong to _one_ branch \n> > > and never to two or more branches.\n> > \n> > Certainly you forgot about detached HEADs?\n> \n> I suppose it is a branch without any name given to it, but it is an \n> advanced feature. I don't think many beginners know about it, so it is \n> something that can confuse beginners.\n\nI'm sorry, the direction of this discussion does not please me.\n\nThe purpose of my message was to make Git old-timers _aware_ of the \nproblems newbies have with our notion of branches.  And a wish to come up \nwith less confusing documentation.\n\nThe purpose was not to discuss at length what branches are in Git (and \nthe intended discussion was certainly not about CVS!).\n\nCiao,\nDscho\n"},{"id":"111773","messageId":"20090420212454.203b9b72@gmail.com","threadId":"18954","inReplyTo":"alpine.DEB.1.00.0904202117010.6771@intel-tinevez-2-302","subject":"Re: What are branches?","fromName":"Michał Kiedrowicz","fromEmail":"michal.kiedrowicz@gmail.com","sentAt":"2009-04-20T19:24:54Z","receivedAt":"2009-04-20T19:24:54Z","isPatch":false,"sender":{"key":"michal.kiedrowicz@gmail.com","avatar":"https://avatars.githubusercontent.com/u/14072847?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n\n> I'm sorry, the direction of this discussion does not please me.\n> \n> The purpose of my message was to make Git old-timers _aware_ of the \n> problems newbies have with our notion of branches.  And a wish to\n> come up with less confusing documentation.\n> \n> The purpose was not to discuss at length what branches are in Git\n> (and the intended discussion was certainly not about CVS!).\n> \n> Ciao,\n> Dscho\n\nI think you did something more. You made them aware that\nthey do not even agree what a branch in Git is.\n\nMichal Kiedrowicz\n"},{"id":"111776","messageId":"20090420201606.GH25059@dpotapov.dyndns.org","threadId":"18954","inReplyTo":"alpine.DEB.1.00.0904202117010.6771@intel-tinevez-2-302","subject":"Re: What are branches?","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2009-04-20T20:16:06Z","receivedAt":"2009-04-20T20:16:06Z","isPatch":false,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Mon, Apr 20, 2009 at 09:19:10PM +0200, Johannes Schindelin wrote:\n> \n> The purpose of my message was to make Git old-timers _aware_ of the \n> problems newbies have with our notion of branches.  And a wish to come up \n> with less confusing documentation.\n\nThank you for your attempt bringing attention to this problem, but I\nthink anyone who remember their first steps with Git or have observed\nother people starting to use Git recently have noticed that already.\n\nI will try quickly summarize my view of it:\n\n- branches in Git are not fundamentally different than in other VCSes,\n  and clearly correspond commonly used definition of this term.\n  Obviously, every VCS has some difference in the way how it manages\n  branches (which makes use of branches in some VCS much easier than in\n  others).\n\n- obviously, all newcomers have some ideas about branches based on their\n  previous experience (whether it was another VCS or some books), but\n  often they do not give much thought to branches before, because they\n  rarely used them except two or three branches (like maint and master),\n  and many have never merged branches.\n\n- the graph shown by gitk may be very confusing for beginners, because\n  they cannot see the branch line, in particular, of the master branch.\n\n- I don't find documentation to be confusing, but it doesn't mean that it\n  cannot be improved. Yet, based on my observation, most confusion are\n  among those users who has shown less propensity to read documentation.\n\n\nDmitry\n"},{"id":"111778","messageId":"20090420202329.GB17241@atjola.homenet","threadId":"18954","inReplyTo":"m3ab6bp2we.fsf@localhost.localdomain","subject":"Re: What are branches?","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-04-20T20:23:29Z","receivedAt":"2009-04-20T20:23:29Z","isPatch":false,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.04.20 11:59:38 -0700, Jakub Narebski wrote:\n> Björn Steinbrink <B.Steinbrink@gmx.de> writes:\n> \n> > If you go out, and look at a tree lit-up by the evil daystar, branches\n> > start at the trunk and end at their tip. The trunk isn't part of the\n> > branch.  [...]\n> \n> Well, you have to remember that the 'branch' metaphor should not be\n> taken too literaly; take for example merges which do not have\n> equivalent in a tree build.\n\nTrue, but that just happened to fit the task-oriented branch view so\nwell, and I wanted the reference to the evil daystar (obviously ;-)).\n\n> But if we are talking about literal branches: take a closer loog at\n> the tip of tree (plant) branch.  You can find growong tip there\n> (apical meristem) where new cells grow.  In Git you have 'branches'\n> (branch heads) where you create new commits...\n\nYeah, see the end of my mail, where I said that git has a mechanism to\ncontrol where branches grow. Seems to fit :-)\n\n> But I agree that there isn't for example true notion of 'trunk' in\n> git, and this is what allows Git to be truly distributed...\n\nHm, not just no trunk, but also no branches that have a starting point\nand an end point. In general, you can't say \"My branch starts _here_\"\nunless you use the root commit(s) as the starting point, or you apply\n\"extra\" knowledge (you know from which other branch this branch forked).\n\nBjörn\n"},{"id":"111781","messageId":"7viqkzdoua.fsf@gitster.siamese.dyndns.org","threadId":"18954","inReplyTo":"20090420184048.GF25059@dpotapov.dyndns.org","subject":"Re: What are branches?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-04-20T20:58:37Z","receivedAt":"2009-04-20T20:58:37Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dmitry Potapov <dpotapov@gmail.com> writes:\n\n> On Mon, Apr 20, 2009 at 03:52:59PM +0200, Michael J Gruber wrote:\n> ...\n>> A git branch is a pointer to a commit. That commit and its predecessors\n>> are contained in the branch. A commit may be contained in multiple\n>> branches, on equal footing: there is no \"prime branch\".\n>\n> This is not accurate description.\n\nOn the contrary, Michael's description is very accurate; its problem may\nbe that it is too accurate to be useful for people who do not use certain\nfeatures.\n\n> The aforementioned pointer is called\n> \"branch head\". Branch (in strictly sense) is a line of development,\n> which is defined by its head. A usual commit has one parent; a merge\n> commit can have more than one parent, the first parent defines the\n> branch line while other parents point to branches merged to it.\n\nNow, that again is technically accurate but is not very useful or even\nharmful if you read too much into --first-parent.\n\nDscho may have been working on this nifty feature while my tree added tons\nof changes that conflict with his work based on an older tree of mine.\nAnd then he says \"I have a clean history of this new feature; please pull\".\n\n\n         o---o---o---o---o Dscho's changes\n        /\n    ---o---D---D---D---o My tree\n       ^     \n       |       D = changes from Dmitry that conflicts with Dscho's branch\n    v1.6.2\n\nI may pull, and see a lot of conflicts; being unfamiliar with what he did,\nI may say \"I tried to pull, and I give up---there are too many conflicts\nwith what patches from Dmitry did recently since your tree forked, and I\ndo not know the area affected very well, so I feel uneasy doing the merge\nmyself.\"\n\n         o---o---o---o---o Dscho's changes\n        /                 .\n    ---o---D---D---D---o...X My tree, unable to resolve conflicts\n       ^     \n       |       D = changes from Dmitry that conflicts with Dscho's branch\n    v1.6.2\n\nDscho can do two things.  One is to rebase, but his code was in use\noutside of my tree for some time and doing so will screw up other people.\n\nBut he can merge my tree and resolve the conflicts, and then tell me to\npull again.\n\n\n           Dscho's changes\n         o---o---o---o---o---M\n        /                   /    \n    ---o---D---D---D---o---. My tree\n       ^     \n       |       D = changes from Dmitry that conflicts with Dscho's branch\n    v1.6.2     M = merge made by Dscho for me\n\nNow, if I did the merge, the first parent of X would have been the tip of\nmy tree that had patches from you, and it would have merged Dscho's\nchanges as a side branch.  But if Dscho did a merge _for me_, then his\nmerge M will have his history as the first parent, and your patches\n(together with possibly ones from other people) will be merged into the\nhistory as a side branch.\n\nHowever, especially after I fast-forward my branch tip to M and continue\nbuilding on it, it is more useful to treat Dscho's topic as the side\nbranch that was merged to my mainline that had your patches, for the\npurpose of most people.  Your \"first parent\" rule does not match that\nexpectation.\n\nIf we made it easy for Dscho to create the merge M to record my tree as\nthe first parent, you _could_ make the \"first parent\" rule to be more\nmeaningful than it currently is, but without it, it still is merely one of\nthe heuristics as people suggested in this discussion.\n"},{"id":"111782","messageId":"20090420210429.GC17241@atjola.homenet","threadId":"18954","inReplyTo":"20090420184746.GG25059@dpotapov.dyndns.org","subject":"Re: What are branches?","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-04-20T21:04:29Z","receivedAt":"2009-04-20T21:04:29Z","isPatch":false,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.04.20 22:47:46 +0400, Dmitry Potapov wrote:\n> On Mon, Apr 20, 2009 at 04:25:38PM +0200, Johannes Schindelin wrote:\n> > \n> > On Mon, 20 Apr 2009, Dmitry Potapov wrote:\n> > \n> > > When you create a new commit, it is always belong to _one_ branch and \n> > > never to two or more branches.\n> > \n> > Certainly you forgot about detached HEADs?\n> \n> I suppose it is a branch without any name given to it,\n\nStrictly, you don't give names to branches with git. But if you do, that\nhas some \"interesting\" consequences. Let's say you have \"master\" checked\nout and do:\n\ngit branch foo\ngit checkout -b bar\n\nYou now have a single line of development and three names that reference\nit. So your branch would have three names, right?\n\ngit commit --allow-empty -m 123\n\nNow, your previous branch only has two names left, and you have a new\nbranch with a single name.\n\ngit reset foo\n\nAnd now, you again have three names for the original branch and the new\nbranch is unnamed.\n\nSo when you go and say that branch heads provide names for branches, your\nactions become pretty weird. \"git branch <name>\" gives new names to\nexisting branches, and \"git commit\" is what actually creates the branch\n(this is always the case), plus it might remove a name from an existing\nbranch. \"git reset\" removes a name from one branch and gives it to\nanother branch. \"git rebase\" does the same, and it's in general not\nvalid to think of rebase as rewriting the branch's history. For example:\n\ngit checkout -b for-v2 for-v1\ngit rebase --onto v2 v1 for-v2\n\nThat would create a new branch, add for-v2 as a name for it and remove\nthe for-v2 name from the old branch (so the number of names for it is\nreduced by one, but it's still called for-v1)\n\n\nSo, IMHO, if you think the whole \"branches have names\" scheme through,\nusing the \"a branch is a line of development\" definition and keeping in\nmind how git actually works, using branch heads, things do get pretty\nconfusing.\n\n> but it is an advanced feature. I don't think many beginners know about\n> it, so it is something that can confuse beginners.\n\nBut it should not. In my experience, telling someone how HEAD works\noften leads to some kind of epiphany. And a detached HEAD is probably\neasier to grasp than the \"normal\" situation where HEAD is a symbolic\nreference to some branch head. Btw, writing those emails, I can now\nunderstand _why_ the explanation of HEAD and how it controls which\nreference gets updated upon e.g. \"git commit\" might be so helpful to\nsome users. It might just be the fact that they suddenly realize that\ngit does not have a true directly user-accesible notion of branches, but\njust branch heads. I can imagine how users that think in branches that\nhave a start and an end might get confused.\n\nBjörn\n"},{"id":"111793","messageId":"87r5znashf.fsf@gmail.com","threadId":"18954","inReplyTo":"7viqkzdoua.fsf@gitster.siamese.dyndns.org","subject":"Re: What are branches?","fromName":"Marius Vollmer","fromEmail":"marius.vollmer@gmail.com","sentAt":"2009-04-20T22:08:12Z","receivedAt":"2009-04-20T22:08:12Z","isPatch":false,"sender":{"key":"marius.vollmer@gmail.com","avatar":"https://gravatar.com/avatar/0259e7306d873f39e608c3b342fe2649a9399c672b69f0d5064efec0b3429f7a?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> If we made it easy for Dscho to create the merge M to record my tree as\n> the first parent, [...]\n\nBut it _is_ easy for Dscho to do that, isn't it?  He just needs to\nremember to do the merge the other way around, checking out your branch\nand merging his into it.\n\nThis doesn't change much, of course, since we still can't follow a\nbranch backwards in time reliably.  Would it make sense to record\nadditional information in a merge commit, such as the branch name for\neach parent?  Then tools could automatically draw the history of the\ncurrent branch as a straight line, say.\n"},{"id":"111806","messageId":"7vd4b6ddzn.fsf@gitster.siamese.dyndns.org","threadId":"18954","inReplyTo":"87r5znashf.fsf@gmail.com","subject":"Re: What are branches?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-04-21T00:53:00Z","receivedAt":"2009-04-21T00:53:00Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Marius Vollmer <marius.vollmer@gmail.com> writes:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> If we made it easy for Dscho to create the merge M to record my tree as\n>> the first parent, [...]\n>\n> But it _is_ easy for Dscho to do that, isn't it?  He just needs to\n> remember to do the merge the other way around, checking out your branch\n> and merging his into it.\n>\n> This doesn't change much, of course, since we still can't follow a\n> branch backwards in time reliably.  Would it make sense to record\n> additional information in a merge commit, such as the branch name for\n> each parent?  Then tools could automatically draw the history of the\n> current branch as a straight line, say.\n\nWe already have record of that, but I do not think using it is necessarily\nhealthy.\n\nThere are certainly cases where the relationship between the maintainer\nand a contributor makes one branch \"the primary\" in the sense that it is\nthe integration ground for everything under the sun, as opposed to the\nother one that is \"the side branch that was merged\" in the sense that it\nbrought in a more narrowly focused set of patches.  If you examine the\nmerge commit M Dscho makes in the example in my previous message, it shows\nthat one of the parents was committed by me and the other was committed by\nDscho.  By following my commits over Dscho's, you will identify which one\nof the parents of a merge is the mainline.  You would perhaps instead of\n\"git log --first-parent\" use \"git log --mainline=gitster\" or something\nlike that.\n\nThe point is that a convention to follow my commits over Dscho's commits\nis just as valid as a convention to follow the first parent.  It is purely\na social convention.\n\nA more problematic is that in a distributed environment, there doesn't\nnecessarily such a \"mainline vs side branch\" relationship exist, and it is\nnot healthy to try to introduce such a concept like \"mainline\" when there\nis no such thing.\n\nPerhaps Alice and Bob forked at the same point, agreeing between\nthemselves that Alice works on the code updates while Bob updates the\ndocumentation as a team of two to produce a new feature.  Before they\ncollectively conclude their work and send a pull request to the project\nmanagement, they will merge their branches to produce the end result that\nis pullable.  From the overall project's point of view, the merge to get\ntheir work into the mainline will be \"the mainline merges one side branch\nfor the feature\", but what about the merges between Alice and Bob while\nthey work together?  There is no \"this is the mainline and this is a side\nbranch\" relationship between what they do.\n"},{"id":"111870","messageId":"20090421114155.GK25059@dpotapov.dyndns.org","threadId":"18954","inReplyTo":"7viqkzdoua.fsf@gitster.siamese.dyndns.org","subject":"Re: What are branches?","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2009-04-21T11:41:55Z","receivedAt":"2009-04-21T11:41:55Z","isPatch":false,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Mon, Apr 20, 2009 at 01:58:37PM -0700, Junio C Hamano wrote:\n> \n> However, especially after I fast-forward my branch tip to M and continue\n> building on it, it is more useful to treat Dscho's topic as the side\n> branch that was merged to my mainline that had your patches, for the\n> purpose of most people.  Your \"first parent\" rule does not match that\n> expectation.\n\nYes, it does not work here. However, fast-forward merge is not a real\nmerge (though it is often very useful, because it avoids useless commits,\nyet, it is clearly Git specific thing). Still, what you describe is not\nvery like to happen in practice, because it usually takes some time for\nany branch to \"graduate\" to master, and in meanwhile some other branches\nget merged, so it is not very likely to be fast-forward (and some people\nalways prefer to merge anything to master with --no-ff).\n\n> \n> If we made it easy for Dscho to create the merge M to record my tree as\n> the first parent, you _could_ make the \"first parent\" rule to be more\n> meaningful than it currently is, but without it, it still is merely one of\n> the heuristics as people suggested in this discussion.\n\nAgreed. It is merely a heuristic unless it is not reinforced (like using\n--no-ff merges to master), but still it is a very good heuristic for most\npractical purposes, and it even can be improved based on merge messages.\n\n\nDmitry\n"},{"id":"112182","messageId":"200904241508.08569.jnareb@gmail.com","threadId":"18954","inReplyTo":"20090420202329.GB17241@atjola.homenet","subject":"Re: What are branches?","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-04-24T13:08:05Z","receivedAt":"2009-04-24T13:08:05Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Mon, 20 April 2009, Björn Steinbrink wrote:\n> On 2009.04.20 11:59:38 -0700, Jakub Narebski wrote:\n> > Björn Steinbrink <B.Steinbrink@gmx.de> writes:\n> > \n> > > If you go out, and look at a tree lit-up by the evil daystar, branches\n> > > start at the trunk and end at their tip. The trunk isn't part of the\n> > > branch.  [...]\n> > \n> > Well, you have to remember that the 'branch' metaphor should not be\n> > taken too literaly; take for example merges which do not have\n> > equivalent in a tree build.\n> \n> True, but that just happened to fit the task-oriented branch view so\n> well, and I wanted the reference to the evil daystar (obviously ;-)).\n\nAlso in (botanical) trees you can usually distinguish between trunk\nand side branches, and I think in most cases also which branch forked\nfrom which one.  Making one of branches (trunk) special might make\nsense for centralized version control systems like CVS (1.2 vs 1.2.2.4\nversion numbers) or Subversion (<project>/trunk for trunk (main branch)\nvs <project>/branches/<branchname>; although this is only convention\nand is not enforced by the tool), but in my opinion contradicts\ndistributed nature of distributed SCM such like Git (and Mercurial).\n\n> > But if we are talking about literal branches: take a closer loog at\n> > the tip of tree (plant) branch.  You can find growong tip there\n> > (apical meristem) where new cells grow.  In Git you have 'branches'\n> > (branch heads) where you create new commits...\n> \n> Yeah, see the end of my mail, where I said that git has a mechanism to\n> control where branches grow. Seems to fit :-)\n\nThe difference is that you can (usually) see which branch was first.\nIt is not the case for Git (and it wouldn't make sense, as for DSCM\nthere is no sense of 'first' wrt. time).\n\n> > But I agree that there isn't for example true notion of 'trunk' in\n> > git, and this is what allows Git to be truly distributed...\n> \n> Hm, not just no trunk, but also no branches that have a starting point\n> and an end point. In general, you can't say \"My branch starts _here_\"\n> unless you use the root commit(s) as the starting point, or you apply\n> \"extra\" knowledge (you know from which other branch this branch forked).\n\nWell, you can use reflog... if it is not expired.  Or the tracking info\nin a config.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"112212","messageId":"20090424162959.GA8397@atjola.homenet","threadId":"18954","inReplyTo":"200904241508.08569.jnareb@gmail.com","subject":"Re: What are branches?","fromName":"Björn Steinbrink","fromEmail":"b.steinbrink@gmx.de","sentAt":"2009-04-24T16:29:59Z","receivedAt":"2009-04-24T16:29:59Z","isPatch":false,"sender":{"key":"b.steinbrink@gmx.de","avatar":"https://avatars.githubusercontent.com/u/230962?v=4"},"body":"On 2009.04.24 15:08:05 +0200, Jakub Narebski wrote:\n> On Mon, 20 April 2009, Björn Steinbrink wrote:\n> > On 2009.04.20 11:59:38 -0700, Jakub Narebski wrote:\n> > > Björn Steinbrink <B.Steinbrink@gmx.de> writes:\n> > > \n> > > > If you go out, and look at a tree lit-up by the evil daystar, branches\n> > > > start at the trunk and end at their tip. The trunk isn't part of the\n> > > > branch.  [...]\n> > > \n> > > Well, you have to remember that the 'branch' metaphor should not be\n> > > taken too literaly; take for example merges which do not have\n> > > equivalent in a tree build.\n> > \n> > True, but that just happened to fit the task-oriented branch view so\n> > well, and I wanted the reference to the evil daystar (obviously ;-)).\n> \n> Also in (botanical) trees you can usually distinguish between trunk\n> and side branches, and I think in most cases also which branch forked\n> from which one.  Making one of branches (trunk) special might make\n> sense for centralized version control systems like CVS (1.2 vs 1.2.2.4\n> version numbers) or Subversion (<project>/trunk for trunk (main branch)\n> vs <project>/branches/<branchname>; although this is only convention\n> and is not enforced by the tool), but in my opinion contradicts\n> distributed nature of distributed SCM such like Git (and Mercurial).\n> \n> > > But if we are talking about literal branches: take a closer loog at\n> > > the tip of tree (plant) branch.  You can find growong tip there\n> > > (apical meristem) where new cells grow.  In Git you have 'branches'\n> > > (branch heads) where you create new commits...\n> > \n> > Yeah, see the end of my mail, where I said that git has a mechanism to\n> > control where branches grow. Seems to fit :-)\n> \n> The difference is that you can (usually) see which branch was first.\n> It is not the case for Git (and it wouldn't make sense, as for DSCM\n> there is no sense of 'first' wrt. time).\n\nHm, I'd say we're agreeing, right? What you said basically proves my\npoint. You don't have \"direct\" access to the \"branches\" (the already\ngrown parts, where you can tell where they start, end and originate\nfrom), but just to the branch heads/tip (where branches grow). I'm just\nsaying that we might have to accept that fact and make it clear in the\ndocumentation. Not that we should make git support \"branches\" as first\nclass entities. Even for \"simple\" things like repeated merges the\nanalogy to branches in plants make little sense (as you said).\n\n> > > But I agree that there isn't for example true notion of 'trunk' in\n> > > git, and this is what allows Git to be truly distributed...\n> > \n> > Hm, not just no trunk, but also no branches that have a starting point\n> > and an end point. In general, you can't say \"My branch starts _here_\"\n> > unless you use the root commit(s) as the starting point, or you apply\n> > \"extra\" knowledge (you know from which other branch this branch forked).\n> \n> Well, you can use reflog... if it is not expired.  Or the tracking info\n> in a config.\n\nNone of that is available in a cloned repo where you might want to look\nat the history some \"branches\", wondering which commits form them, in a\ntask oriented fashion.\n\nBjörn\n"},{"id":"112293","messageId":"94a0d4530904250411k7cb074baidcc5c7d9710115ec@mail.gmail.com","threadId":"18954","inReplyTo":"alpine.DEB.1.00.0904191709220.10279@pacific.mpi-cbg.de","subject":"Re: What are branches?","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2009-04-25T11:11:58Z","receivedAt":"2009-04-25T11:11:58Z","isPatch":false,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Sun, Apr 19, 2009 at 6:17 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi,\n>\n> if you're like me, you used Git for _way_ too long to really understand\n> how anybody can say that Git is hard to learn.  The concepts underlying\n> Git have sunk so deep that I do not question them anymore.\n>\n> But it is important to keep in mind that our concept of branches is not\n> intuitive:\n>\n> http://longair.net/blog/2009/04/16/git-fetch-and-merge/\n>\n> In particular, we have some pretty confusing nomenclature when it comes to\n> branches, and we might want to think how to improve the situation.\n>\n> Food for thought on a lazy Sunday afternoon.\n\nCompletely agree. The problem is that git doesn't really have branches.\n\nIn my mind a true branch has a divergence start-point from another\nbranch, so if you rebase a branch, it must be from the start-point.\n\nWhat git has been referring to \"branches\" are actually mere\nreferences. That's why 'git rebase' needs either a start-point\nspecified manually, or it will need to travel the acyclic graph\nfinding commits that are not already in the graph of the new\nstart-point.\n\nAFAIK TopGit makes true branches possible in git.\n\n-- \nFelipe Contreras\n"}]}