{"thread":{"id":"22265","subject":"idea: git \"came from\" tags","startedAt":"2010-01-18T04:22:02Z","lastAt":"2010-01-19T05:02:11Z","messageCount":3,"participants":["D Herring","Michael J Gruber"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"132014","messageId":"hj0nl9$uds$2@ger.gmane.org","threadId":"22265","inReplyTo":null,"subject":"idea: git \"came from\" tags","fromName":"D Herring","fromEmail":"dherring@tentpost.com","sentAt":"2010-01-18T04:22:02Z","receivedAt":"2010-01-18T04:22:02Z","isPatch":false,"sender":{"key":"dherring@tentpost.com","avatar":null},"body":"Actors:\n- public \"upstream\" repository\n- public \"local\" repository\n- end users tracking both\n\nSituation:\n- local starts by tracking upstream\n- local makes changes, commits, and sends upstream\n- users now tracking local ahead of upstream\n- upstream makes modified commits\n- local satisfied, wants to reset master to upstream/master\n\nProblem:\n- A merge will perpetually leave two parallel branches.  Even though\nthere are no longer any diffs, local/master cannot use the same\nobjects as upstream/master.\n- A hard reset lets local/master return to sharing objects with\nupstream/master; but this may break pulls or cause other problems for\nusers.\n\nProposed solution:\n- Local adds a \"came from\" tag to upstream/master, leaves a tag on the\nhead of local/master, and does a hard reset from local/master to\nupstream/master.  When a user tracking local/master does a pull, their\nclient detects a non-fast-forward, finds the came-from tag, and treats\nit as a fast-forward.\n\nBasically, this is a protocol to glue a \"strategy ours\" merge onto an\nexisting tree.  This way local can cleanly track upstream, with no\nadded complexity in the nominal (no local changes) case.\n\n\nExample:\nWithout this addition, local/master looks something like\nu1 - u2 - u3 - u4 - u5 - u6 ...\n   \\- l1 - l2\\+ m1 -   \\+ m2\\+ m3 ...\n\nWith this addition, local/master looks like\nu1 - u2 - u3(tcf) - u4 - u5 - u6 ...\n   \\- l1 - l2 - t0\nwhere\n* u# = upstream changes\n* l# = local changes\n* m# = local merges (m1=u3, m2=u5, m3=u6, ...)\n* the tcf tag points to t0, and t0 tags the end of the local mods\n\n\nPseudo-shell-code addition to git-pull:\nfetch local/master\nfast_forward=usual test whether local/master contains user/master\nif test $fast_forward = no\nthen\n   for tag in $fetched_tags # something like this or git-describe\n   do\n     if is_came_from($tag) && (came_from($tag) contains user/master)\n     then\n       fast_forward=yes\n       break\n     fi\n   done\nfi\n\nComments?  I think this is completely implementable (though I'm not\nwell-versed in git internals).  Since it only triggers during\nnon-fast-forward operations, it should have negligible performance impact.\n\nOf course, it would be even better if somebody shows me how to do this\nwith the current tools.  Maybe I'm just doing it all wrong.\n\nThanks,\nDaniel\n"},{"id":"132024","messageId":"4B542EB2.5030407@drmicha.warpmail.net","threadId":"22265","inReplyTo":"hj0nl9$uds$2@ger.gmane.org","subject":"Re: idea: git \"came from\" tags","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2010-01-18T09:49:38Z","receivedAt":"2010-01-18T09:49:38Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"D Herring venit, vidit, dixit 18.01.2010 05:22:\n> Actors:\n> - public \"upstream\" repository\n> - public \"local\" repository\n> - end users tracking both\n> \n> Situation:\n> - local starts by tracking upstream\n> - local makes changes, commits, and sends upstream\n> - users now tracking local ahead of upstream\n\nHere I have to ask why. If users choose to track a volatile branch then\nthey have to live with rebasing or hard resets. If they want something\nstable then they should track upstream.\n\n> - upstream makes modified commits\n> - local satisfied, wants to reset master to upstream/master\n> \n> Problem:\n> - A merge will perpetually leave two parallel branches.  Even though\n> there are no longer any diffs, local/master cannot use the same\n> objects as upstream/master.\n\nIf there are no diffs then, in fact, it can share most objects since\nmost trees will be the same, only a few commit objects will differ.\n\n> - A hard reset lets local/master return to sharing objects with\n> upstream/master; but this may break pulls or cause other problems for\n> users.\n> \n> Proposed solution:\n> - Local adds a \"came from\" tag to upstream/master, leaves a tag on the\n> head of local/master, and does a hard reset from local/master to\n> upstream/master.  When a user tracking local/master does a pull, their\n> client detects a non-fast-forward, finds the came-from tag, and treats\n> it as a fast-forward.\n> \n> Basically, this is a protocol to glue a \"strategy ours\" merge onto an\n> existing tree.  This way local can cleanly track upstream, with no\n> added complexity in the nominal (no local changes) case.\n\nBut doesn't that mean that users completely trust you about what they\nshould consider a fast forward, i.e. when they should do a hard reset?\nSo, this is completely equivalent to following one of your branches with\n+f, i.e. having a public a branch which they pull from no matter what,\nand having a private branch which pushes to the public one in case of\nfast-forwards as well as in the case when you would use your special tag.\n\nMichael\n"},{"id":"132070","messageId":"hj3ecj$836$1@ger.gmane.org","threadId":"22265","inReplyTo":"4B542EB2.5030407@drmicha.warpmail.net","subject":"Re: idea: git \"came from\" tags","fromName":"D Herring","fromEmail":"dherring@tentpost.com","sentAt":"2010-01-19T05:02:11Z","receivedAt":"2010-01-19T05:02:11Z","isPatch":false,"sender":{"key":"dherring@tentpost.com","avatar":null},"body":"Michael J Gruber wrote:\n> D Herring venit, vidit, dixit 18.01.2010 05:22:\n>> Actors:\n>> - public \"upstream\" repository\n>> - public \"local\" repository\n>> - end users tracking both\n>>\n>> Situation:\n>> - local starts by tracking upstream\n>> - local makes changes, commits, and sends upstream\n>> - users now tracking local ahead of upstream\n> \n> Here I have to ask why. If users choose to track a volatile branch then\n> they have to live with rebasing or hard resets. If they want something\n> stable then they should track upstream.\n\nI'm maintaining the \"local\" repository in a distribution of upstream \nlibraries.  I'm trying to avoid both volatile branches and unnecessary \nclutter.  Here, both upstream and local are stable; they are just \nmaintained by different teams.  Upstream often accepts patches; but \nthey may tweak things, use a different version control system, etc. \nand so the commit objects differ.\n\n\n>> - upstream makes modified commits\n>> - local satisfied, wants to reset master to upstream/master\n>>\n>> Problem:\n>> - A merge will perpetually leave two parallel branches.  Even though\n>> there are no longer any diffs, local/master cannot use the same\n>> objects as upstream/master.\n> \n> If there are no diffs then, in fact, it can share most objects since\n> most trees will be the same, only a few commit objects will differ.\n\nBut once I have a local diff, the local tree must always use different \ngit objects, even though the file contents are the same...\n\n\n>> - A hard reset lets local/master return to sharing objects with\n>> upstream/master; but this may break pulls or cause other problems for\n>> users.\n>>\n>> Proposed solution:\n>> - Local adds a \"came from\" tag to upstream/master, leaves a tag on the\n>> head of local/master, and does a hard reset from local/master to\n>> upstream/master.  When a user tracking local/master does a pull, their\n>> client detects a non-fast-forward, finds the came-from tag, and treats\n>> it as a fast-forward.\n>>\n>> Basically, this is a protocol to glue a \"strategy ours\" merge onto an\n>> existing tree.  This way local can cleanly track upstream, with no\n>> added complexity in the nominal (no local changes) case.\n> \n> But doesn't that mean that users completely trust you about what they\n> should consider a fast forward, i.e. when they should do a hard reset?\n> So, this is completely equivalent to following one of your branches with\n> +f, i.e. having a public a branch which they pull from no matter what,\n> and having a private branch which pushes to the public one in case of\n> fast-forwards as well as in the case when you would use your special tag.\n\nThis almost works, but it destroys some history preserved by a proper \nmerge or this proposed extension.  For example, suppose there are \nthree commits between the user's last fetch and this merge/forced \nupdate; a proper merge will download them, but a forced update will \nnot.  This becomes important when a release tarball is based on one of \nthese missing commits.\n\nIf local uses merge objects to track this properly, it creates a \nparallel branch that is simply nuisance clutter.  Normally, the \nnuisance is limited to a visual distraction in gitk; but it can be \nsignificant if a user is trying to track both local and upstream. \nWhen there are and have been no local changes, local is following \nupstream; so the user can freely follow either until a local change is \nmade.  When there are no but have been local changes that were merged, \nthe user must pick a branch even thought the contents are the same.\n\nI could be obsessing over a minor detail; but the proposed change \ndoesn't seem drastic.\n\n\nTo reiterate,\nGiven\nA - C - E - ... - Z\n  \\   \\\n   - B + D\nwhere A-Z are commit objects and the contents of merge D are identical \nto C, it would be nice to have a protocol that tags D for posterity \nand allows D->E to be a fast forward, without requiring cooperation \nfrom the source of E to Z.\n\nLater,\nDaniel\n"}]}