{"thread":{"id":"53558","subject":"rationale behind git not tracking history of branches","startedAt":"2020-05-26T21:01:26Z","lastAt":"2020-05-27T19:31:53Z","messageCount":5,"participants":["Kevin Buchs","Jonathan Nieder","Randall S. Becker","Michal Suchánek"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"398602","messageId":"CAKTRx=09tjsH0j+Nf4_1uzn-GwasWFB_Q96KEO=qtr5nVBkAew@mail.gmail.com","threadId":"53558","inReplyTo":null,"subject":"rationale behind git not tracking history of branches","fromName":"Kevin Buchs","fromEmail":"kevin.buchs@newcontext.com","sentAt":"2020-05-26T21:01:11Z","receivedAt":"2020-05-26T21:01:26Z","isPatch":false,"sender":{"key":"kevin.buchs@newcontext.com","avatar":null},"body":"For many years of using Git, I always struggled to make sense of\ncommit history graphs (git log --graph; gitk). Just recently I\ndiscovered that git does not track the history of branches to which\ncommits belonged and the lightbulb turned on. This is proving to be\npainful in a project I inherited with permanent multiple branches.\nNow, I am a bit curious as to the rationale behind this intentional\ndecision not to track branch history. Is it entirely a matter of\nkeeping branches lightweight?\n\nI am assuming one can backfill for the missing capability by using a\ncommit hook to manually track when a branch head is changed. Perhaps\nby storing the branch in the commit notes.\n\nKevin Buchs, Senior Engineer, New Context Services\nkevin.buchs@newcontext.com  507-251-7463  St. Cloud, MN\n"},{"id":"398609","messageId":"20200527025048.GC172669@google.com","threadId":"53558","inReplyTo":"CAKTRx=09tjsH0j+Nf4_1uzn-GwasWFB_Q96KEO=qtr5nVBkAew@mail.gmail.com","subject":"Re: rationale behind git not tracking history of branches","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2020-05-27T02:50:48Z","receivedAt":"2020-05-27T02:50:54Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi,\n\nKevin Buchs wrote:\n\n> For many years of using Git, I always struggled to make sense of\n> commit history graphs (git log --graph; gitk). Just recently I\n> discovered that git does not track the history of branches to which\n> commits belonged and the lightbulb turned on. This is proving to be\n> painful in a project I inherited with permanent multiple branches.\n> Now, I am a bit curious as to the rationale behind this intentional\n> decision not to track branch history. Is it entirely a matter of\n> keeping branches lightweight?\n>\n> I am assuming one can backfill for the missing capability by using a\n> commit hook to manually track when a branch head is changed. Perhaps\n> by storing the branch in the commit notes.\n\nI think this comes down to a question of mental model: one thing I\nvalue when using Git is that each commit does *not* belong to a\nspecific branch --- branches describe the shape of history, and\ncommits are points in that history.\n\nThis becomes particularly relevant when working with multiple\ncolleagues, sharing history between different servers: I may have a\nbranch I call \"linus\" that points to the same history that a colleague\ncalled \"master\".\n\nThat said, I can understand how that may be difficult to get used to\ncoming from other version control systems (such as Subversion) in\nwhich a revision does belong to a branch.\n\nCan you say a little more about what aim you're trying to achieve when\nyou want to make this lookup?  For example:\n\n- are you looking to figure out what the commit author was working\n  on when they made the commit?  For that, the commit message is meant\n  to provide context, and a commit hook like you describe can be a\n  good way to enforce that (for example if you want every commit\n  message to contain a bug number for context).\n\n- are you looking to find out *when* a commit became part of a\n  particular published branch?  It's true that Git doesn't provide a\n  good way to do that today.  I have some hope that some best\n  practices like discussed in [1][2] will coalesce for attesting to\n  the history of a branch's state.\n\n  If you always perform merges with --no-ff, then you can find some\n  things out using the --first-parent history.  It is possible to\n  enforce such practices using hooks, but this may be a lot of fuss\n  for little gain, depending on the underlying need.\n\n  I find \"git log --ancestry-path\" to be very useful for finding out\n  *how* a commit became part of a particular published branch.\n\n- or are you looking for this information for some other purpose?\n\nReturning to your question: one reason that I find Git not recording\nthe current branch name to be liberating is that I am not great at\nnaming things.  I can use a placeholder name, knowing that I am its\nonly audience, without fear of embarrassment.\n\nThanks and hope that helps,\nJonathan\n\n[1] https://git.eclipse.org/r/c/51128, describing refs/meta/push-certs\n[2] https://lore.kernel.org/git/22945.15202.337224.529980@chiark.greenend.org.uk/\n"},{"id":"398641","messageId":"022f01d63441$58846ac0$098d4040$@nexbridge.com","threadId":"53558","inReplyTo":"CAKTRx=09tjsH0j+Nf4_1uzn-GwasWFB_Q96KEO=qtr5nVBkAew@mail.gmail.com","subject":"RE: rationale behind git not tracking history of branches","fromName":"Randall S. Becker","fromEmail":"rsbecker@nexbridge.com","sentAt":"2020-05-27T16:10:25Z","receivedAt":"2020-05-27T16:10:37Z","isPatch":false,"sender":{"key":"randall.becker@nexbridge.ca","avatar":"https://avatars.githubusercontent.com/u/28956764?v=4"},"body":"On May 26, 2020 5:01 PM, Kevin Buchs wrote:\n> For many years of using Git, I always struggled to make sense of commit\n> history graphs (git log --graph; gitk). Just recently I discovered that git does\n> not track the history of branches to which commits belonged and the\n> lightbulb turned on. This is proving to be painful in a project I inherited with\n> permanent multiple branches.\n> Now, I am a bit curious as to the rationale behind this intentional decision\n> not to track branch history. Is it entirely a matter of keeping branches\n> lightweight?\n> \n> I am assuming one can backfill for the missing capability by using a commit\n> hook to manually track when a branch head is changed. Perhaps by storing\n> the branch in the commit notes.\n\nBased on the distributed nature of git, the interpretation of the history of a branch can be different based on local clones. The history only comes together as commits are merged together on an upstream repository, so even in the upstream, the interpretation is potentially different from what the branch's interpretation is in someone's clone. The parent-child commit structure in the underlying Merkel tree is the only definitive interpretation and is a post-merge perspective independent of any interpretation of the branch itself.\n\nThe point-in-time interpretation of a branch is simply the HEAD where the branch pointer is located, but the point-in-time interpretation is ambiguous across multiple clones and even the upstream. In order to disambiguate the interpretation, the branch contents have to be moved to a common repository which only understands its branch HEAD post push, which may be disallowed without a merge depending on the current tree structure.\n\nTo track a branch's history across all domains, and make it meaningful, you could write a commit, push, etc. hook, that understands what the current state of the branch is and where, and interpret the history based on your own project needs. It would be something like a relation set something like the tuple: {some-unique-repo-clone-identifier; branch; commit; date-and-time}, as the branch state (HEAD) is time-varying and can repeat its presence on a commit multiple times (git branch -f branch-name commit-ish) . The \"some-unique-repo-clone-identifier\" is problematic, because there isn't one currently AFAIK.\n\nThat's my interpretation anyway based on how I see things in today's git world - I might very well be wrong.\n\nRegards,\nRandall\n\n-- Brief whoami:\n NonStop developer since approximately 211288444200000000\n UNIX developer since approximately 421664400\n-- In my real life, I talk too much.\n\n\n\n"},{"id":"398643","messageId":"CAKTRx=29XBtKgt0m1+aCex_YZeiDzk5oBBxuM45NvVHmuqUVNQ@mail.gmail.com","threadId":"53558","inReplyTo":"20200527025048.GC172669@google.com","subject":"Re: rationale behind git not tracking history of branches","fromName":"Kevin Buchs","fromEmail":"kevin.buchs@newcontext.com","sentAt":"2020-05-27T16:24:59Z","receivedAt":"2020-05-27T16:25:13Z","isPatch":false,"sender":{"key":"kevin.buchs@newcontext.com","avatar":null},"body":"Hi Jonathan,\n\nThanks for the reply. I will give you my current situation. I am just\ntaking over a project that many cooks were involved in previously. We\nhave three persistent branches: dev, staging and master which\ncorrespond directly to three CD environments: dev, staging and prod.\nThe nominal commit history ought to be that all changes happen in the\ndev branch, and that the latest dev is merged into staging and then to\nmaster at appropriate milestones of testing. However, the history of\ncommit chains clearly show that is not the case. Here is what gitk\nshows me: https://1drv.ms/u/s!AgKA2HL-SveIha4Y_5lihkQO7ulfKQ?e=oA9PEi\n.\nNow, you can see that the nominal practice was not followed. Sure,\nthere are many commit messages to indicate merges and I could assume\nthose are correct and possibly reconstruct which branch each commit\nmight have belonged to. However, you can see there were a series of\nchanges to multiple commit chains, when there should have just been a\nsingle chain - corresponding to the dev branch. How do I know there\nwere not changes that should be included in dev that were stranded?\nBased on the overall \"smell\" of this project, I really don't believe I\nshould trust those commit messages. So, what would make my task a\nwhole lot easier would be if there were a display of columns\ncorresponding to the branches and any commits that were in multiple\nbranches, due to merge fast forwarding, would explicitly show up in\nthe corresponding columns.\n\nGoing forward, I believe I can make my own work much clearer for\nothers who might pick it up by having some way to sort out branch\nhistory. I will probably use --no-ff to make history clearer. And\nmaybe notes to actually record to which branch a commit belongs.\n\nI had been studying this Q&A:\nhttps://stackoverflow.com/questions/2706797/finding-what-branch-a-git-commit-came-from\n. I have come to realize the only item that is really useful there is\nthe first comment on the question. It says that the lack of recording\nof branch history in git is \"by design\". I understand the point of\nmaking branches lightweight. though I don't know that recording a\nbranch would make them much heavier. I wondered if there was another\nmotivation in the design of git. Knowing that might help me to use the\ntool more effectively or adapt it to where I would like it to be.\n\nKevin Buchs, Senior Engineer, New Context Services\nkevin.buchs@newcontext.com  507-251-7463  St. Cloud, MN\n\nKevin Buchs, Senior Engineer, New Context Services\nkevin.buchs@newcontext.com  507-251-7463  St. Cloud, MN\n\n\nOn Tue, May 26, 2020 at 9:50 PM Jonathan Nieder <jrnieder@gmail.com> wrote:\n>\n> Hi,\n>\n> Kevin Buchs wrote:\n>\n> > For many years of using Git, I always struggled to make sense of\n> > commit history graphs (git log --graph; gitk). Just recently I\n> > discovered that git does not track the history of branches to which\n> > commits belonged and the lightbulb turned on. This is proving to be\n> > painful in a project I inherited with permanent multiple branches.\n> > Now, I am a bit curious as to the rationale behind this intentional\n> > decision not to track branch history. Is it entirely a matter of\n> > keeping branches lightweight?\n> >\n> > I am assuming one can backfill for the missing capability by using a\n> > commit hook to manually track when a branch head is changed. Perhaps\n> > by storing the branch in the commit notes.\n>\n> I think this comes down to a question of mental model: one thing I\n> value when using Git is that each commit does *not* belong to a\n> specific branch --- branches describe the shape of history, and\n> commits are points in that history.\n>\n> This becomes particularly relevant when working with multiple\n> colleagues, sharing history between different servers: I may have a\n> branch I call \"linus\" that points to the same history that a colleague\n> called \"master\".\n>\n> That said, I can understand how that may be difficult to get used to\n> coming from other version control systems (such as Subversion) in\n> which a revision does belong to a branch.\n>\n> Can you say a little more about what aim you're trying to achieve when\n> you want to make this lookup?  For example:\n>\n> - are you looking to figure out what the commit author was working\n>   on when they made the commit?  For that, the commit message is meant\n>   to provide context, and a commit hook like you describe can be a\n>   good way to enforce that (for example if you want every commit\n>   message to contain a bug number for context).\n>\n> - are you looking to find out *when* a commit became part of a\n>   particular published branch?  It's true that Git doesn't provide a\n>   good way to do that today.  I have some hope that some best\n>   practices like discussed in [1][2] will coalesce for attesting to\n>   the history of a branch's state.\n>\n>   If you always perform merges with --no-ff, then you can find some\n>   things out using the --first-parent history.  It is possible to\n>   enforce such practices using hooks, but this may be a lot of fuss\n>   for little gain, depending on the underlying need.\n>\n>   I find \"git log --ancestry-path\" to be very useful for finding out\n>   *how* a commit became part of a particular published branch.\n>\n> - or are you looking for this information for some other purpose?\n>\n> Returning to your question: one reason that I find Git not recording\n> the current branch name to be liberating is that I am not great at\n> naming things.  I can use a placeholder name, knowing that I am its\n> only audience, without fear of embarrassment.\n>\n> Thanks and hope that helps,\n> Jonathan\n>\n> [1] https://git.eclipse.org/r/c/51128, describing refs/meta/push-certs\n> [2] https://lore.kernel.org/git/22945.15202.337224.529980@chiark.greenend.org.uk/\n"},{"id":"398687","messageId":"20200527193149.GJ25173@kitsune.suse.cz","threadId":"53558","inReplyTo":"CAKTRx=29XBtKgt0m1+aCex_YZeiDzk5oBBxuM45NvVHmuqUVNQ@mail.gmail.com","subject":"Re: rationale behind git not tracking history of branches","fromName":"Michal Suchánek","fromEmail":"msuchanek@suse.de","sentAt":"2020-05-27T19:31:49Z","receivedAt":"2020-05-27T19:31:53Z","isPatch":false,"sender":{"key":"msuchanek@suse.de","avatar":"https://avatars.githubusercontent.com/u/787652?v=4"},"body":"On Wed, May 27, 2020 at 11:24:59AM -0500, Kevin Buchs wrote:\n> Hi Jonathan,\n> \n> Thanks for the reply. I will give you my current situation. I am just\n> taking over a project that many cooks were involved in previously. We\n> have three persistent branches: dev, staging and master which\n> correspond directly to three CD environments: dev, staging and prod.\n> The nominal commit history ought to be that all changes happen in the\n> dev branch, and that the latest dev is merged into staging and then to\n> master at appropriate milestones of testing. However, the history of\nIn this setup you should have merges on dev only. staging should be\nbehind dev and master behid staging but any merge between these branches\nshould be fast-forward. Creating the merge commits would only add noise.\n\n> commit chains clearly show that is not the case. Here is what gitk\n> shows me: https://1drv.ms/u/s!AgKA2HL-SveIha4Y_5lihkQO7ulfKQ?e=oA9PEi\n> .\n> Now, you can see that the nominal practice was not followed. Sure,\n> there are many commit messages to indicate merges and I could assume\n> those are correct and possibly reconstruct which branch each commit\n> might have belonged to. However, you can see there were a series of\n> changes to multiple commit chains, when there should have just been a\n> single chain - corresponding to the dev branch. How do I know there\n> were not changes that should be included in dev that were stranded?\nFind commits that are not ancestors of dev branch tip.\n\nBut if you are taking over the project maybe just auditing the actual\ndifference between the branches might be easier. Then you can use git\nblame to see how the pieces of code that differ entered the branch in\nquestion.\n\nGoing from the diverging history to one where the branches are as\ndescribed you can merge master to dev once to make all commits formally\nancestors of dev, preferably after examining and reconciling the\ndifferences.\n\nHTH\n\nMichal\n"}]}