{"thread":{"id":"37302","subject":"\"Branch objects\" (was: Re: cherry picking and merge)","startedAt":"2014-08-06T18:31:18Z","lastAt":"2014-08-07T22:59:25Z","messageCount":9,"participants":["Jakub Narębski","Nico Williams","Tony Finch"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"247349","messageId":"CANQwDwcHSO+KwhZbo4BTcWnAWGWbJzNQ7CY2m3nq+p0t9uDeqg@mail.gmail.com","threadId":"37302","inReplyTo":null,"subject":"\"Branch objects\" (was: Re: cherry picking and merge)","fromName":"Jakub Narębski","fromEmail":"jnareb@gmail.com","sentAt":"2014-08-06T18:31:18Z","receivedAt":"2014-08-06T18:31:18Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Wed, Aug 6, 2014 at 6:26 PM, Nico Williams <nico@cryptonector.com> wrote:\n> On Wed, Aug 6, 2014 at 10:58 AM, Jakub Narębski <jnareb@gmail.com> wrote:\n>> W dniu 2014-08-01 22:55, Nico Williams pisze:\n>>>\n>>> It would help if cherry-pick history where recorded somewhere (beyond\n>>> the reflog)...\n>>>\n>>> Cherry-picks should record two parents, like merges.\n>>>\n>>> (Of course, it does no good to know about an unreachable parent, when\n>>> a commit with two parents is pushed to a repo that doesn't have one of\n>>> those parents, which can happen when topic branches aren't pushed\n>>> upstream.)\n>>\n>> There was (long time ago) a long thread about idea of adding some\n>> kind of 'weak' references (links), 'weakparent' that can be automatically\n>> used by Git but do not pollute the commit message,\n>> and do not affect reachability calculations.  Ultimately it went\n>> nowhere (as you can see) - there were many problems.\n>\n> My proposal was to put this sort of ancillary history info in a\n> \"branch object\" (and that branches should be objects).  This would\n> have a number of benefits, not the least of which is that at push time\n> you can drop such ancillary history without having to alter the\n> commits being pushed.\n\nIs it something like object-ified reflog, similar to how replacement\nobjects (git-replace) can be thought to be object-ified grafts (I know\nthey are more)? Do I understand it correctly?\n\nDid you plan to (ab)use known object types: tree and commit (a bit\nsimilar to git-replace and git-note object, though there is no need for\nfanout trees - the top level tree can reproduce refs hierarchy)? I see\nthat you planned to (ab)use existing transfer mechanism of refs and\nobjects...\n\n\nBTW. sometimes I do wonder if we are not making a mistake trying\nto shoehorn new features like stash, replacements and notes into\nDAG, objects (commit, tree, blob), refs and reflogs. I'd rather Git\ndid not make the same mistake (well, I think it was a mistake) that\nMercurial did with .hgtags file, (ab)using file transfer for tags, instead\nof adding separate transfer mechanism like Git has... which led to\ncontortions in interpreting / deling with said file (most recent version\nis used, not the one in checked out revision) and things like having\nto commit creating a tag for it to be transferrable.\n\n>> For example: how it would work for reverts and rebases?\n>\n> Reverts upstream?  The revert should record the commit hash of the\n> commit it reverts (but file-level reverts lose), so that this could be\n> noticed.\n\nIf it is object-ified reflog then reverts are not a problem...\n\n> Rebases upstream?  Well, that shouldn't happen, but if it does then\n> you must rebase --onto and any cherry-picks of upstream rebased\n> commits lose their ties to those (but this can be detected).\n\nWith rebases the problem is that it would be nice to have (at least\nfor a short time) the history of series of patches (the metahistory,\nor history of a branch), but usually one doesn't need old pre-rebase\nversion after cleaning up the history for publishing.\n\n> In general recording more metadata (assuming there's not privacy\n> issues to consider) can't hurt.  Using it might, but having the option\n> to can also help.\n\nTrue...\n\n-- \nJakub Narębski\n"},{"id":"247360","messageId":"20140806200726.GE23449@localhost","threadId":"37302","inReplyTo":"CANQwDwcHSO+KwhZbo4BTcWnAWGWbJzNQ7CY2m3nq+p0t9uDeqg@mail.gmail.com","subject":"Re: \"Branch objects\" (was: Re: cherry picking and merge)","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-06T20:07:27Z","receivedAt":"2014-08-06T20:07:27Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Wed, Aug 06, 2014 at 08:31:18PM +0200, Jakub Narębski wrote:\n> On Wed, Aug 6, 2014 at 6:26 PM, Nico Williams <nico@cryptonector.com> wrote:\n> > My proposal was to put this sort of ancillary history info in a\n> > \"branch object\" (and that branches should be objects).  This would\n> > have a number of benefits, not the least of which is that at push time\n> > you can drop such ancillary history without having to alter the\n> > commits being pushed.\n> \n> Is it something like object-ified reflog, similar to how replacement\n> objects (git-replace) can be thought to be object-ified grafts (I know\n> they are more)? Do I understand it correctly?\n\nYes, per-branch.  At push time a commit would be pushed to the upstream\nbranch listing the commits pushed now (and who by).  Locally every\nrebase/cherry-pick/merge/commit onto the branch would appear in the\nbranch object's history, kinda just like the reflog.  The main\ndifference is that the upstream branch's history could be viewed.\n\n> Did you plan to (ab)use known object types: tree and commit (a bit\n> similar to git-replace and git-note object, though there is no need for\n> fanout trees - the top level tree can reproduce refs hierarchy)? I see\n> that you planned to (ab)use existing transfer mechanism of refs and\n> objects...\n\nJust like signed tags, basically.\n\n> > Reverts upstream?  The revert should record the commit hash of the\n> > commit it reverts (but file-level reverts lose), so that this could be\n> > noticed.\n> \n> If it is object-ified reflog then reverts are not a problem...\n\nRight.\n\n> > Rebases upstream?  Well, that shouldn't happen, but if it does then\n> > you must rebase --onto and any cherry-picks of upstream rebased\n> > commits lose their ties to those (but this can be detected).\n> \n> With rebases the problem is that it would be nice to have (at least\n> for a short time) the history of series of patches (the metahistory,\n> or history of a branch), but usually one doesn't need old pre-rebase\n> version after cleaning up the history for publishing.\n\nRight.\n\n> > In general recording more metadata (assuming there's not privacy\n> > issues to consider) can't hurt.  Using it might, but having the option\n> > to can also help.\n> \n> True...\n\nThe principle should be to record as much metadata as possible, pruning\nancillary metadata (reflog-like metadata that isn't on the commits) only\nat push time.  \n\nNico\n-- \n"},{"id":"247411","messageId":"alpine.LSU.2.00.1408071222510.13901@hermes-1.csi.cam.ac.uk","threadId":"37302","inReplyTo":"20140806200726.GE23449@localhost","subject":"Re: \"Branch objects\" (was: Re: cherry picking and merge)","fromName":"Tony Finch","fromEmail":"dot@dotat.at","sentAt":"2014-08-07T11:38:48Z","receivedAt":"2014-08-07T11:38:48Z","isPatch":false,"sender":{"key":"dot@dotat.at","avatar":"https://avatars.githubusercontent.com/u/68429?v=4"},"body":"Nico Williams <nico@cryptonector.com> wrote:\n> On Wed, Aug 06, 2014 at 08:31:18PM +0200, Jakub Narębski wrote:\n> > On Wed, Aug 6, 2014 at 6:26 PM, Nico Williams <nico@cryptonector.com> wrote:\n> > >\n> > > My proposal was to put this sort of ancillary history info in a\n> > > \"branch object\" (and that branches should be objects).\n> >\n> > Is it something like object-ified reflog, similar to how replacement\n> > objects (git-replace) can be thought to be object-ified grafts (I know\n> > they are more)? Do I understand it correctly?\n>\n> Yes, per-branch.  At push time a commit would be pushed to the upstream\n> branch listing the commits pushed now (and who by).  Locally every\n> rebase/cherry-pick/merge/commit onto the branch would appear in the\n> branch object's history, kinda just like the reflog.  The main\n> difference is that the upstream branch's history could be viewed.\n>\n> > With rebases the problem is that it would be nice to have (at least\n> > for a short time) the history of series of patches (the metahistory,\n> > or history of a branch), but usually one doesn't need old pre-rebase\n> > version after cleaning up the history for publishing.\n>\n> Right.\n\nI have been fiddling around in this area.\n\nWhat I want to be able to do is develop fixes for open source code that I\nrun, and get those fixes upstream. This means I need a rebasing workflow,\nto keep the patches up-to-date and to deal with code review feedback.\n\nBut this is inconvenient for deploying the patched version to production\n(which is the point of developing the fixes) - I want a fast-forwarding\nbranch for that. And it would be nice to be able to share the history of\nthe patch series, so others can see what changed between revisions more\neasily.\n\nSo I have a small tool which maintains a publication branch which tracks\nthe head of a rebasing branch. It's reasonably satisfactory so far...\n\nhttps://git.csx.cam.ac.uk/x/ucs/git/git-repub.git\n\n... though the structure of the publication branch is weird and not very\neasy to navigate. You can see it in action in my git.git repo:\n\nhttps://git.csx.cam.ac.uk/x/ucs/git/git.git/shortlog/refs/heads/ucam/fanf2/patch\n\nTony.\n-- \nf.anthony.n.finch  <dot@dotat.at>  http://dotat.at/\nIrish Sea: Variable 4. Slight. Showers. Good."},{"id":"247424","messageId":"20140807155828.GM23449@localhost","threadId":"37302","inReplyTo":"alpine.LSU.2.00.1408071222510.13901@hermes-1.csi.cam.ac.uk","subject":"Re: \"Branch objects\" (was: Re: cherry picking and merge)","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-07T15:58:29Z","receivedAt":"2014-08-07T15:58:29Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Thu, Aug 07, 2014 at 12:38:48PM +0100, Tony Finch wrote:\n> I have been fiddling around in this area.\n> \n> What I want to be able to do is develop fixes for open source code\n> that I run, and get those fixes upstream. This means I need a rebasing\n> workflow, to keep the patches up-to-date and to deal with code review\n> feedback.\n\nRight.\n\n> But this is inconvenient for deploying the patched version to\n> production (which is the point of developing the fixes) - I want a\n\nI'm not sure I follow this.  You deploy what you build, and you build\nthe HEAD of the production branch, whatever that is.  If it gets\nrebased, so it it does.\n\n> fast-forwarding branch for that. And it would be nice to be able to\n> share the history of the patch series, so others can see what changed\n> between revisions more easily.\n\nBut yes, it's nice to have a history of all the rebases.  For example:\nso you can show the work you've done (rebasing to please an upstream is\nwork).\n\nThe reflog does this, of course, but you can't push it.  Of course, my\nconception of branch object wouldn't push rebase history to an upstream\nthat doesn't want it, but you could push it to repos that do.\n\n> So I have a small tool which maintains a publication branch which\n> tracks the head of a rebasing branch. It's reasonably satisfactory so\n> far...\n> \n> https://git.csx.cam.ac.uk/x/ucs/git/git-repub.git\n\nYeah, that's useful.\n\nNico\n-- \n"},{"id":"247440","messageId":"alpine.LSU.2.00.1408071735410.23775@hermes-1.csi.cam.ac.uk","threadId":"37302","inReplyTo":"20140807155828.GM23449@localhost","subject":"Re: \"Branch objects\" (was: Re: cherry picking and merge)","fromName":"Tony Finch","fromEmail":"dot@dotat.at","sentAt":"2014-08-07T16:42:34Z","receivedAt":"2014-08-07T16:42:34Z","isPatch":false,"sender":{"key":"dot@dotat.at","avatar":"https://avatars.githubusercontent.com/u/68429?v=4"},"body":"Nico Williams <nico@cryptonector.com> wrote:\n> On Thu, Aug 07, 2014 at 12:38:48PM +0100, Tony Finch wrote:\n>\n> > But [a rebasing workflow] is inconvenient for deploying the patched\n> > version to production (which is the point of developing the fixes) - I\n> > want a fast-forwarding branch for that.\n>\n> I'm not sure I follow this.  You deploy what you build, and you build\n> the HEAD of the production branch, whatever that is.  If it gets\n> rebased, so it it does.\n\nThe problem is that the production branch gets copied around: pushed to\nthe repo server, pulled by other team members, etc. Forced pushes\nare accident-prone, as is resetting a rebased branch after a pull.\n\n> > So I have a small tool which maintains a publication branch which\n> > tracks the head of a rebasing branch. It's reasonably satisfactory so\n> > far...\n> >\n> > https://git.csx.cam.ac.uk/x/ucs/git/git-repub.git\n>\n> Yeah, that's useful.\n\nGlad you think so :-)\n\nTony.\n-- \nf.anthony.n.finch  <dot@dotat.at>  http://dotat.at/\nThames: Northeast veering southeast 4 or 5, occasionally 6. Slight, becoming\nslight or moderate. Fair then rain or thundery showers. Good, becoming\nmoderate or poor for a time.\n"},{"id":"247444","messageId":"20140807172207.GP23449@localhost","threadId":"37302","inReplyTo":"alpine.LSU.2.00.1408071735410.23775@hermes-1.csi.cam.ac.uk","subject":"Re: \"Branch objects\" (was: Re: cherry picking and merge)","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-07T17:22:08Z","receivedAt":"2014-08-07T17:22:08Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Thu, Aug 07, 2014 at 05:42:34PM +0100, Tony Finch wrote:\n> Nico Williams <nico@cryptonector.com> wrote:\n> > On Thu, Aug 07, 2014 at 12:38:48PM +0100, Tony Finch wrote:\n> > > But [a rebasing workflow] is inconvenient for deploying the patched\n> > > version to production (which is the point of developing the fixes) - I\n> > > want a fast-forwarding branch for that.\n> >\n> > I'm not sure I follow this.  You deploy what you build, and you build\n> > the HEAD of the production branch, whatever that is.  If it gets\n> > rebased, so it it does.\n> \n> The problem is that the production branch gets copied around: pushed to\n> the repo server, pulled by other team members, etc. Forced pushes\n> are accident-prone, as is resetting a rebased branch after a pull.\n\nWhen I rebase and I need the old HEAD around I do something like this:\n\n$ git checkout $branch_to_rebase\n$ ver=${branch_to_rebase##*-}\n$ git checkout -b ${branch_to_rebase%-${ver}}-$((ver+1))\n$ git rebase ...\n\nor like this:\n\n$ git checkout $branch_to_rebase\n$ git branch ${branch_to_rebase}-$(date +%Y-%m-%d)\n$ git rebase ...\n\nEither way I retain the old HEAD with some name.  This requires\ndiscipline, so scripting it is useful.  But if you want discipline then\nyou want git to know that \"for this branch, don't prune/gc old HEADs\norphaned after rebases\" and \"push the rebase history for this branch\".\n\n> > > https://git.csx.cam.ac.uk/x/ucs/git/git-repub.git\n> >\n> > Yeah, that's useful.\n> \n> Glad you think so :-)\n\nThank you.\n\nNico\n-- \n"},{"id":"247445","messageId":"alpine.LSU.2.00.1408071829470.13901@hermes-1.csi.cam.ac.uk","threadId":"37302","inReplyTo":"20140807172207.GP23449@localhost","subject":"Re: \"Branch objects\" (was: Re: cherry picking and merge)","fromName":"Tony Finch","fromEmail":"dot@dotat.at","sentAt":"2014-08-07T17:47:04Z","receivedAt":"2014-08-07T17:47:04Z","isPatch":false,"sender":{"key":"dot@dotat.at","avatar":"https://avatars.githubusercontent.com/u/68429?v=4"},"body":"Nico Williams <nico@cryptonector.com> wrote:\n> On Thu, Aug 07, 2014 at 05:42:34PM +0100, Tony Finch wrote:\n> >\n> > The problem is that the production branch gets copied around: pushed to\n> > the repo server, pulled by other team members, etc. Forced pushes\n> > are accident-prone, as is resetting a rebased branch after a pull.\n>\n> When I rebase and I need the old HEAD around I do something like this:\n> [...]\n> Either way I retain the old HEAD with some name.\n\nHmm, yes, I can see that would work. However my previous workflow was\nrather branch-heavy and I found the accumulation of names annoying. I have\nnot yet had enough usage out of git-repub to see if it goes too far in the\ndirection of lack-of-names. A big omission is no opportunity to edit its\ncommit messages.\n\nTony.\n-- \nf.anthony.n.finch  <dot@dotat.at>  http://dotat.at/\nRockall: Southwesterly becoming cyclonic in north, 5 to 7. Moderate or rough.\nRain or showers. Moderate or good.\n"},{"id":"247462","messageId":"CAK3OfOiEMm3FiP_1Ho12pvccsyWvC13BRJH+FpMRTNObM3j0iw@mail.gmail.com","threadId":"37302","inReplyTo":"alpine.LSU.2.00.1408071829470.13901@hermes-1.csi.cam.ac.uk","subject":"Re: \"Branch objects\" (was: Re: cherry picking and merge)","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-07T22:54:28Z","receivedAt":"2014-08-07T22:54:28Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Thu, Aug 7, 2014 at 12:47 PM, Tony Finch <dot@dotat.at> wrote:\n> Nico Williams <nico@cryptonector.com> wrote:\n>> Either way I retain the old HEAD with some name.\n>\n> Hmm, yes, I can see that would work. However my previous workflow was\n> rather branch-heavy and I found the accumulation of names annoying. I have\n> not yet had enough usage out of git-repub to see if it goes too far in the\n> direction of lack-of-names. A big omission is no opportunity to edit its\n> commit messages.\n\nOh, I just read your script more carefully and looked at your example\nhistory again.  You're using parent metadata in the commits to keep\nthe history alive without the extra names, correct?  *That* is\n_clever_.  Hats off.  I may have to steal this script :)\n\nNico\n--\n"},{"id":"293727","messageId":"CAK3OfOgg3fwQ2KZyG-V6-gHaWknZN_Y9KxQWwRZGcUOo7yjg5w@mail.gmail.com","threadId":"37302","inReplyTo":"alpine.LSU.2.00.1408071222510.13901@hermes-1.csi.cam.ac.uk","subject":"Re: \"Branch objects\" (was: Re: cherry picking and merge)","fromName":"Nico Williams","fromEmail":"nico@cryptonector.com","sentAt":"2014-08-07T22:59:25Z","receivedAt":"2014-08-07T22:59:25Z","isPatch":false,"sender":{"key":"nico@cryptonector.com","avatar":null},"body":"On Thu, Aug 7, 2014 at 6:38 AM, Tony Finch <dot@dotat.at> wrote:\n> So I have a small tool which maintains a publication branch which tracks\n> the head of a rebasing branch. It's reasonably satisfactory so far...\n>\n> https://git.csx.cam.ac.uk/x/ucs/git/git-repub.git\n>\n> ... though the structure of the publication branch is weird and not very\n> easy to navigate. You can see it in action in my git.git repo:\n\nYou know, maybe you could even use this to automatically figure out\nthe merge base for downstreams that follow your rebased branch:\nauto-generate the git rebase --onto <head> <head as it was prior to\nall the upstream rebases>.\n\nThat would be awesome, particularly if integrated into git.  It would\nthen be fine to rebase published branches in most cases, for example.\n\nNico\n"}]}