{"thread":{"id":"21209","subject":"Re: Questions about the new","startedAt":"2009-10-12T10:23:40Z","lastAt":"2009-10-13T21:33:49Z","messageCount":9,"participants":["David Kågedal","Johannes Sixt","Sergio Callegari","Dmitry Potapov","Junio C Hamano","Christian Couder","Jakub Narebski","Sergio"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"293730","messageId":"loom.20091012T115746-719@post.gmane.org","threadId":"21209","inReplyTo":null,"subject":"Questions about the new","fromName":"Sergio","fromEmail":"sergio.callegari@gmail.com","sentAt":"2009-10-12T10:23:40Z","receivedAt":"2009-10-12T10:23:40Z","isPatch":false,"sender":{"key":"sergio.callegari@gmail.com","avatar":"https://gravatar.com/avatar/c98f41317e0422c1e630385de0e3970227b8e5ad15f35ba8586066467cc833bc?d=mp&s=160"},"body":"\n\n\nHi,\n\nI read from the release notes of git 1.6.5 about the new \"replace\" mechanism.\nIt is presented as \"a replacement of the \"grafts\" mechanism, with the added\nadvantage that it can be transferred across repositories.\"\n\nSince there is still little information about it, I would like to ask the\nfollowing:\n\n1) Grafts and replace entries seem to operate on different aspects of the\nhistory graph. Grafts operate on arcs and replace on nodes. \nAs such, replace entries seem less general to me. \nApparently, to simulate a graft with replace entries, you need to introduce\nextra commit objects. For instance, if object B has no parents, to pretend that\nit derives from some A, one needs to create an object B' equivalent to B but\nfor the parents and then replace B by B', is this right? Conversely, I guess\nyou can always simulate a replace entry with the graft mechanism, without the\nneed to add any extra commit object. Am I overlooking something? \n\n2) Is it currently possible to use a replace entry to replace a commit object\nwith nothing? Namely if B has A as its sole parent, is it possible to have a\nreplace entry such as A-sha1 becomes null, to pretend that B is a hierarchy\nroot?  \n\n3) If I remember correctly, there was a reason why grafts were not considered\nsuitable for transferring across repos. Can someone remind me about it? How\ndoes the replace mechanism address this issue?\n\nThanks,\n\nSergio\n"},{"id":"124686","messageId":"871vl8ubw8.fsf@lysator.liu.se","threadId":"21209","inReplyTo":"loom.20091012T115746-719@post.gmane.org","subject":"Re: Questions about the new","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2009-10-12T10:47:35Z","receivedAt":"2009-10-12T10:47:35Z","isPatch":false,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"Sergio <sergio.callegari@gmail.com> writes:\n\n> Hi,\n>\n> I read from the release notes of git 1.6.5 about the new \"replace\" mechanism.\n> It is presented as \"a replacement of the \"grafts\" mechanism, with the added\n> advantage that it can be transferred across repositories.\"\n\nGrafts allow you to change a little part of commit objects (the parent\nrelationship). Replacements allow (and require) you to change the whole\ncommit object. So obviously, anything you can do with grafts can be done\nwith replacements.\n\nIf you have your A-B-x-x-x history and want to remove A from the\nhistory, you replace B with a commit object that is identical, except\nfor the missing parent link to A.\n\nReplacements allow you do to other kinds of changes as well (comments,\nauthorshiips) and changes to other object(?), so it is a much more\ngeneral mechanism.\n\nBut I missed the discussion about it, so I'm not sure why it was felt it\nwas needed, or why the grafts mechanism wasn't enough.\n\n-- \nDavid Kågedal\n"},{"id":"124688","messageId":"4AD31EBF.6090307@viscovery.net","threadId":"21209","inReplyTo":"loom.20091012T115746-719@post.gmane.org","subject":"Re: Questions about the new","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2009-10-12T12:19:11Z","receivedAt":"2009-10-12T12:19:11Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Sergio schrieb:\n> 1) Grafts and replace entries seem to operate on different aspects of the\n> history graph. Grafts operate on arcs and replace on nodes. \n\nCorrect, but see below about tree and blob objects.\n\n> As such, replace entries seem less general to me. \n\nWith grafts you can only change parenthood; with replace entries you can\nchange parenthood *and* all other aspects of a commit (message, author,\ncommitter, dates).\n\nHence, replace entries are more general than grafts.\n\n> Apparently, to simulate a graft with replace entries, you need to introduce\n> extra commit objects. For instance, if object B has no parents, to pretend that\n> it derives from some A, one needs to create an object B' equivalent to B but\n> for the parents and then replace B by B', is this right?\n\nYes. Use git-cat-file + edit + git-hash-object as explained in this\nmessage just the other day:\nhttp://thread.gmane.org/gmane.comp.version-control.git/129727/focus=129907\n\n> Conversely, I guess\n> you can always simulate a replace entry with the graft mechanism, without the\n> need to add any extra commit object. Am I overlooking something? \n\nYou cannot; see above. You can even replace tree objects and blob objects\nusing replace entries, IIUC, but you cannot do that with grafts.\n\n> 2) Is it currently possible to use a replace entry to replace a commit object\n> with nothing? Namely if B has A as its sole parent, is it possible to have a\n> replace entry such as A-sha1 becomes null, to pretend that B is a hierarchy\n> root?  \n\nSure. Just make a commit object that does not have parents.\n\n> 3) If I remember correctly, there was a reason why grafts were not considered\n> suitable for transferring across repos. Can someone remind me about it? How\n> does the replace mechanism address this issue?\n\nThe problem with grafts was that, for example, git-pack-objects obeyed the\ngraft, and could create a broken repository by removing grafted-away\nobjects. And since git-fsck also obeyed the graft, it did not notice the\nbreakage.\n\nOTOH, history walkers (upload-pack, send-pack, pack-objects) and fsck\nnever obey replace entries in the history. But they do keep track of them\n(and the history that they reference) because they are referenced from the\nrefs/replace namespace.\n\n-- Hannes\n"},{"id":"124718","messageId":"4AD3619C.6010808@gmail.com","threadId":"21209","inReplyTo":"4AD31EBF.6090307@viscovery.net","subject":"Re: Questions about the new","fromName":"Sergio Callegari","fromEmail":"sergio.callegari@gmail.com","sentAt":"2009-10-12T17:04:28Z","receivedAt":"2009-10-12T17:04:28Z","isPatch":false,"sender":{"key":"sergio.callegari@gmail.com","avatar":"https://gravatar.com/avatar/c98f41317e0422c1e630385de0e3970227b8e5ad15f35ba8586066467cc833bc?d=mp&s=160"},"body":"Thanks Johannes for all the detailed explanations\n\nJohannes Sixt <j.sixt <at> viscovery.net> writes:\n\n >\n > Sergio schrieb:\n > > 1) Grafts and replace entries seem to operate on different aspects \nof the\n > > history graph. Grafts operate on arcs and replace on nodes.\n >\n > Correct, but see below about tree and blob objects.\n\nOK, the replace mechanism also can replace a blob object or a tree.\nMy focus was on commit objects only.\n\n >\n > > As such, replace entries seem less general to me.\n >\n > With grafts you can only change parenthood; with replace entries you can\n > change parenthood *and* all other aspects of a commit (message, author,\n > committer, dates).\n >\n > Hence, replace entries are more general than grafts.\n\nLimiting the discussion to commit objects, I think there are two \npossible scenarios.\n\n1) You create new commits objects as needed\n2) You do not.\n\nIf you follow 1), I believe grafts and replace entries have exactly the same\nflexibility.\n\nIf I happen not to like commit B in A---B---C and I want A---B'---C \nwhere B' has\ncompletely different aspects from B I can either replace B by B' or \ngraft away\nB, pretending that the parent of A is B\n\nBut there are many things that can be done with grafts merely adding a graft\n(e.g. cutting away a part of history, joining history),  that cannot be done\nwith replace entries without creating new commits objects.\n\nI was asking because I was wandering whether replace entries were first \nor later\nmeant to make grafts deprecated. I hope not, because for a few things \nworking on\narcs seems still nice.\n\n > > Apparently, to simulate a graft with replace entries, you need to \nintroduce\n > > extra commit objects. For instance, if object B has no parents, to \npretend >\n > Yes. Use git-cat-file + edit + git-hash-object as explained in this\n > message just the other day:\n > \nhttp://thread.gmane.org/gmane.comp.version-control.git/129727/focus=129907\n\nThanks, good pointer. I missed this!\n\n > > Conversely, I guess\n > > you can always simulate a replace entry with the graft mechanism, \nwithout the\n > > need to add any extra commit object. Am I overlooking something?\n >\n > You cannot; see above.\n\nWell, I meant for what regards commit objects only.\n\nIf I want to replace some commit X by some commit X' I merely need to \nmodify the\nparent information of all the commits that are child of X so that they \npretend\nto be child of X', or am I missing something?\n\n > You can even replace tree objects and blob objects\n > using replace entries, IIUC, but you cannot do that with grafts.\n\nDefinitely right!\n \n > > 2) Is it currently possible to use a replace entry to replace a \ncommit object\n > > with nothing? Namely if B has A as its sole parent, is it possible \nto have a\n > > replace entry such as A-sha1 becomes null, to pretend that B is a \nhierarchy\n > > root? \n >\n > Sure. Just make a commit object that does not have parents.\n\nOK, you need to create a new commit object. At the beginning for some \nreason I\nthought that you could replace an object\nwith \"nothing\" or 00000000000000000000000000000000000000000000\n\n > > 3) If I remember correctly, there was a reason why grafts were not \nconsidered\n > > suitable for transferring across repos. Can someone remind me about \nit? How\n > > does the replace mechanism address this issue?\n >\n > The problem with grafts was that, for example, git-pack-objects \nobeyed the\n > graft, and could create a broken repository by removing grafted-away\n > objects. And since git-fsck also obeyed the graft, it did not notice the\n > breakage.\n >\n > OTOH, history walkers (upload-pack, send-pack, pack-objects) and fsck\n > never obey replace entries in the history. But they do keep track of them\n > (and the history that they reference) because they are referenced \nfrom the\n > refs/replace namespace.\n >\n\nThanks for the explanation. Can this be made possible for grafts too? \nWouldn't\nit be a matter of having history walkers never obey grafts but keep track of\nthem (i.e. of the history of the parenthood they reference)?\n\nLike we have \"annotated\" or heavyweight tags living as objects in the \ndatabase,\nwould it be possible or make sense to have annotated grafts or replace \nentries,\nso that one can express why, by whom and when history was changed?\n"},{"id":"124735","messageId":"20091012190347.GA26977@dpotapov.dyndns.org","threadId":"21209","inReplyTo":"4AD31EBF.6090307@viscovery.net","subject":"Re: Questions about the new","fromName":"Dmitry Potapov","fromEmail":"dpotapov@gmail.com","sentAt":"2009-10-12T19:03:47Z","receivedAt":"2009-10-12T19:03:47Z","isPatch":false,"sender":{"key":"dpotapov@gmail.com","avatar":"https://avatars.githubusercontent.com/u/6568595?v=4"},"body":"On Mon, Oct 12, 2009 at 02:19:11PM +0200, Johannes Sixt wrote:\n> \n> With grafts you can only change parenthood; with replace entries you can\n> change parenthood *and* all other aspects of a commit (message, author,\n> committer, dates).\n\nActually, you can. I have written a script that did exactly this. It\nrequired to modify parents to point to the new commit. The tricky part\nwas that modification could be on top of other modifications, but I was\nable to handle this case too. Yet, my script was so hackish that I have\nnever dared to share it with someone (and I used it only couple times\nduring CVS to Git conversion).\n\n> \n> Hence, replace entries are more general than grafts.\n\nI think both mechanism are theoretically equivalent, but with grafts,\nit was rather difficult to replace objects (but not impossible!).\n\n> The problem with grafts was that, for example, git-pack-objects obeyed the\n> graft, and could create a broken repository by removing grafted-away\n> objects. And since git-fsck also obeyed the graft, it did not notice the\n> breakage.\n\nMoreover, grafted-away objects could be removed by the garbage collector...\n\n\nDmitry\n"},{"id":"124752","messageId":"7v8wfge2zu.fsf@alter.siamese.dyndns.org","threadId":"21209","inReplyTo":"4AD3619C.6010808@gmail.com","subject":"Re: Questions about the new","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-12T21:06:29Z","receivedAt":"2009-10-12T21:06:29Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sergio Callegari <sergio.callegari@gmail.com> writes:\n\n> If I want to replace some commit X by some commit X' I merely need to\n> modify the\n> parent information of all the commits that are child of X so that they\n> pretend\n> to be child of X', or am I missing something?\n\nYou need to find all the commits that are child of X in the first place.\nWhat should happen if your colleague has such a commit in his repository\n(which you haven't fetched from yet), you enumerated all children of X\nknown to you in your graft file and then you fetch from him?  You need to\nenumerate all children of X again to keep the graft file up to date.\n\n> Thanks for the explanation. Can this be made possible for grafts too?\n> Wouldn't it be a matter of having history walkers never obey grafts but\n> keep track of them (i.e. of the history of the parenthood they\n> reference)?\n\nIn the past we discussed the possibility of that for quite a while but\nnever saw a successful implementation.  The replace mechanism seemed a\ncleaner way to do this, and it turned out to be the case.\n\nYou are welcome to try doing that for the grafts, of course.\n"},{"id":"124767","messageId":"200910122354.18318.chriscool@tuxfamily.org","threadId":"21209","inReplyTo":"4AD3619C.6010808@gmail.com","subject":"Re: Questions about the new","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2009-10-12T21:54:18Z","receivedAt":"2009-10-12T21:54:18Z","isPatch":false,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Monday 12 October 2009, Sergio Callegari wrote:\n> Thanks Johannes for all the detailed explanations\n>\n> Johannes Sixt <j.sixt <at> viscovery.net> writes:\n\n[...]\n\n>  > With grafts you can only change parenthood; with replace entries you\n>  > can change parenthood *and* all other aspects of a commit (message,\n>  > author, committer, dates).\n>  >\n>  > Hence, replace entries are more general than grafts.\n>\n> Limiting the discussion to commit objects, I think there are two\n> possible scenarios.\n>\n> 1) You create new commits objects as needed\n> 2) You do not.\n>\n> If you follow 1), I believe grafts and replace entries have exactly the\n> same flexibility.\n>\n> If I happen not to like commit B in A---B---C and I want A---B'---C\n> where B' has\n> completely different aspects from B I can either replace B by B' or\n> graft away\n> B, pretending that the parent of A is B\n\nYou mean \"pretending that the parent of C is A\", right?\n\n> But there are many things that can be done with grafts merely adding a\n> graft (e.g. cutting away a part of history, joining history),  that\n> cannot be done with replace entries without creating new commits objects.\n\nYes, but when you create a graft, you add a new line in the graft file. You \ndon't get the grafts for free.\n\n> I was asking because I was wandering whether replace entries were first\n> or later\n> meant to make grafts deprecated. I hope not, because for a few things\n> working on\n> arcs seems still nice.\n\nI don't think they will be deprecated soon. And anyway there will probably \nbe a warning when a graft is used if it is deprecated.\n\n[...]\n\n>  > > Conversely, I guess\n>  > > you can always simulate a replace entry with the graft mechanism,\n>\n> without the\n>\n>  > > need to add any extra commit object. Am I overlooking something?\n>  >\n>  > You cannot; see above.\n>\n> Well, I meant for what regards commit objects only.\n>\n> If I want to replace some commit X by some commit X' I merely need to\n> modify the\n> parent information of all the commits that are child of X so that they\n> pretend\n> to be child of X', or am I missing something?\n\nIf you use git replace you just need to create commit X' and then use \"git \nreplace X X'\". If you use grafts, yes, you have to modify the parent \ninformation of all the commits that are child of X.\n\n>  > You can even replace tree objects and blob objects\n>  > using replace entries, IIUC, but you cannot do that with grafts.\n>\n> Definitely right!\n>\n>  > > 2) Is it currently possible to use a replace entry to replace a\n>\n> commit object\n>\n>  > > with nothing? Namely if B has A as its sole parent, is it possible\n>\n> to have a\n>\n>  > > replace entry such as A-sha1 becomes null, to pretend that B is a\n>\n> hierarchy\n>\n>  > > root?\n>  >\n>  > Sure. Just make a commit object that does not have parents.\n>\n> OK, you need to create a new commit object. At the beginning for some\n> reason I\n> thought that you could replace an object\n> with \"nothing\" or 00000000000000000000000000000000000000000000\n>\n>  > > 3) If I remember correctly, there was a reason why grafts were not\n>\n> considered\n>\n>  > > suitable for transferring across repos. Can someone remind me about\n>\n> it? How\n>\n>  > > does the replace mechanism address this issue?\n>  >\n>  > The problem with grafts was that, for example, git-pack-objects\n>\n> obeyed the\n>\n>  > graft, and could create a broken repository by removing grafted-away\n>  > objects. And since git-fsck also obeyed the graft, it did not notice\n>  > the breakage.\n>  >\n>  > OTOH, history walkers (upload-pack, send-pack, pack-objects) and fsck\n>  > never obey replace entries in the history. But they do keep track of\n>  > them (and the history that they reference) because they are referenced\n>\n> from the\n>\n>  > refs/replace namespace.\n>\n> Thanks for the explanation. Can this be made possible for grafts too?\n> Wouldn't\n> it be a matter of having history walkers never obey grafts but keep track\n> of them (i.e. of the history of the parenthood they reference)?\n\nThe problem is that grafts are special, so all the history walking commands \nshould be changed to deal with them specially. With the replace mechanism, \ncommits and refs are used, and all the commands already know how to deal \nwith them.\n\n> Like we have \"annotated\" or heavyweight tags living as objects in the\n> database,\n> would it be possible or make sense to have annotated grafts or replace\n> entries,\n> so that one can express why, by whom and when history was changed?\n\nThere is a patch series about \"notes\" floating around that deals with \nannotating any commit. So it could be used for that.\n\nAnd anyway when you create the replacement commit, you can state in the \ncommit message that it is a replacement commit, who created it, etc.\n\nRegards,\nChristian.\n"},{"id":"124827","messageId":"4AD43123.3060401@gmail.com","threadId":"21209","inReplyTo":"7v8wfge2zu.fsf@alter.siamese.dyndns.org","subject":"Re: Questions about the new","fromName":"Sergio Callegari","fromEmail":"sergio.callegari@gmail.com","sentAt":"2009-10-13T07:49:55Z","receivedAt":"2009-10-13T07:49:55Z","isPatch":false,"sender":{"key":"sergio.callegari@gmail.com","avatar":"https://gravatar.com/avatar/c98f41317e0422c1e630385de0e3970227b8e5ad15f35ba8586066467cc833bc?d=mp&s=160"},"body":"Junio C Hamano wrote:\n> Sergio Callegari <sergio.callegari@gmail.com> writes:\n>\n>   \n>> If I want to replace some commit X by some commit X' I merely need to\n>> modify the\n>> parent information of all the commits that are child of X so that they\n>> pretend\n>> to be child of X', or am I missing something?\n>>     \n>\n> You need to find all the commits that are child of X in the first place.\n> What should happen if your colleague has such a commit in his repository\n> (which you haven't fetched from yet), you enumerated all children of X\n> known to you in your graft file and then you fetch from him?  You need to\n> enumerate all children of X again to keep the graft file up to date.\n>   \nOk, that is enlightening. When trying to sort out the differences, \nadvantages and disadvantages of\noperating on arcs (grafts like) or on nodes (replacements like) I was \nthinking local, rather than\ndistributed. Now the advantage of working on nodes is much clearer to me.\n\nThanks as usual for the very clear explanation.\n\nSergio\n"},{"id":"124900","messageId":"m3skdnf08l.fsf_-_@localhost.localdomain","threadId":"21209","inReplyTo":"4AD31EBF.6090307@viscovery.net","subject":"Re: Questions about the new refs/replace mechanism","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-10-13T21:33:49Z","receivedAt":"2009-10-13T21:33:49Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Johannes Sixt <j.sixt@viscovery.net> writes:\n\n> Sergio schrieb:\n\n> > 3) If I remember correctly, there was a reason why grafts were not\n> > considered suitable for transferring across repos. Can someone\n> > remind me about it? How does the replace mechanism address this\n> > issue?\n> \n> The problem with grafts was that, for example, git-pack-objects obeyed the\n> graft, and could create a broken repository by removing grafted-away\n> objects. And since git-fsck also obeyed the graft, it did not notice the\n> breakage.\n\nTo be more detailed, the problem is that if git-pack-objects, git-fsck\nand git-gc obeys grafts, it can create broken repository by removing\ngrafted away objects.  If git-pack-objects, git-fsck and git-gc\ndoesn't obey grafts, it can created broken repository (well, broken if\nwe include grafts) by removing grafted in objects.\n\n> \n> OTOH, history walkers (upload-pack, send-pack, pack-objects) and fsck\n> never obey replace entries in the history. But they do keep track of them\n> (and the history that they reference) because they are referenced from the\n> refs/replace namespace.\n\nIn the case of refs/replace git-pack-objects, git-fcsk and git-gc\ndoesn't \"obey\" refs/replace... but replaced objects are protected by\npruning by being referenced from refs/replace ref.\n\nOne of problems with grafts file was to come up with rule what do do\nif both repository you fetch from and the repository you fetch into\nhave both grafts; in the case of refs/replace the usual rules about\n(conflicting) refs apply.\n\nIt is also easy to select whether to follow refs/replace or not: you\nfetch them into your refs/replace or not; you would have to add extra\noption to git-fetch to select whether to fetch and follow grafts in\nremote you fetch from.\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"}]}