{"thread":{"id":"14177","subject":"Re: is rebase the same as merging every commit?","startedAt":"2008-06-27T06:30:56Z","lastAt":"2016-08-14T00:43:20Z","messageCount":5,"participants":["Matthieu Moy","David Jeske","Petr Baudis"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"81361","messageId":"vpqfxqz5qzj.fsf@bauges.imag.fr","threadId":"14177","inReplyTo":"willow-jeske-01l78ZaEFEDjCZEG","subject":"Re: is rebase the same as merging every commit?","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2008-06-27T06:30:56Z","receivedAt":"2008-06-27T06:30:56Z","isPatch":false,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"\"David Jeske\" <jeske@willowmail.com> writes:\n\n> Rebasing is described in the docs I've read as turning this: (sorry for the\n> dots)\n>\n> ..........A---B---C topic\n> ........./\n> ....D---E---F---G master\n>\n> Into this:\n>\n> ...................A'--B'--C' topic\n> ................../\n> .....D---E---F---G master\n>\n> If I understand it right (and that's a BIG if), it's the same as doing a merge\n> of C into G where every individual commit in the C-line is individually\n> committed into the new C' line.\n>\n> ...........-------------A---B---C\n> ........../            /   /   /\n> ........./        /---A'--B'--C'  topic\n> ......../        /\n> ....D---E---F---G - master\n\nI'd draw that the other way:\n\n  ...........---------A---B---C\n  ........../          \\   \\   \\\n  ........./        /---A'--B'--C'  topic\n  ......../        /\n  ....D---E---F---G - master\n\n> (1) Is the above model a valid explanation?\n\nSounds correct to me.\n\n> (2) From the documentation diagrams, it looks like the rebased A' has only (G)\n> as a parent, not (A,G). If this is the case, why?\n\nWell, one could imagine a \"rebase keeping ancestry\" command, which\nwould keep A and G (indeed, you can do that by hand with multiple\ncalls to \"merge\"). The advantage being that further merges involving\nboth A and A' have better chance to succeed.\n\nBut philosophy of \"rebase\" is different: the idea is that you usually\nrebase your private branches before submission, and the guys you\nsubmit to are interested in your changes (i.e. the patch serie\ndiff(G,A'), diff(A',B'), ...), not the way you got this patch serie.\n\nSo, discarding this ancestry information is a bit like discarding your\n*~ files (or whatever backup files your editor might create) after\nsome time: it has been valuable information, but at some point, it\nbecomes noise you don't want to hear.\n\n> (i.e. not connecting those nodes throws away useful information)\n\nFor the use-cases where this information is useful, \"rebase\" is not\nfor you. Indeed, in these cases, a plain \"merge\" is usually what you\nwant.\n\n> (3) If it only has (G) as a parent, does the rebase explicitly remove the\n> source A,B,C nodes from the repository?\n\nMost commands, and this includes rebase, are \"add-only\". The objects\nwill remain unreferenced and will be pruned by the next git gc\n--prune. Unreferenced objects do not harm, they just eat your disk\nspace.\n\nWell, that was a first approximation. Indeed, the reflog still\nreferences C, see \"git reflog\". For example, after the rebase, if you\nrealize that you actually didn't want this rebase, you can still\n\"git reset --hard HEAD@{1}\" or something like that.\n\n-- \nMatthieu\n"},{"id":"81363","messageId":"2864.14964725754$1214549743@news.gmane.org","threadId":"14177","inReplyTo":"vpqfxqz5qzj.fsf@bauges.imag.fr","subject":"Re: is rebase the same as merging every commit?","fromName":"David Jeske","fromEmail":"jeske@willowmail.com","sentAt":null,"receivedAt":"2008-06-27T06:50:06Z","isPatch":false,"sender":{"key":"jeske@willowmail.com","avatar":null},"body":"-- Matthieu Moy wrote:\n\n> > (3) If it only has (G) as a parent, does the rebase explicitly remove the\n> > source A,B,C nodes from the repository?\n>\n> Most commands, and this includes rebase, are\n> \"add-only\". The objects will remain unreferenced and\n> will be pruned by the next git gc --prune. Unreferenced\n> objects do not harm, they just eat your disk space.\n\nI see. So it would be reasonable for the documentation to be altered slightly\nto show that the original nodes are still there, and that the primary\ndifference between merging those changes one-by-one and rebasing is that rebase\ndoes not connect the new to the old. If you want to keep the old, you can toss\na branch name on it, and if not, it still lives until the gc timeout.\n\nThe current docs showing those nodes missing tells me that they disappear,\nwhich is both scarry, and apparently inaccurate.\n"},{"id":"81371","messageId":"20080627083419.GD12567@machine.or.cz","threadId":"14177","inReplyTo":"vpqfxqz5qzj.fsf@bauges.imag.fr","subject":"Re: is rebase the same as merging every commit?","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2008-06-27T08:34:19Z","receivedAt":"2008-06-27T08:34:19Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Fri, Jun 27, 2008 at 08:30:56AM +0200, Matthieu Moy wrote:\n> \"David Jeske\" <jeske@willowmail.com> writes:\n> \n> > Rebasing is described in the docs I've read as turning this: (sorry for the\n> > dots)\n> >\n> > ..........A---B---C topic\n> > ........./\n> > ....D---E---F---G master\n> >\n> > Into this:\n> >\n> > ...................A'--B'--C' topic\n> > ................../\n> > .....D---E---F---G master\n> >\n> > If I understand it right (and that's a BIG if), it's the same as doing a merge\n> > of C into G where every individual commit in the C-line is individually\n> > committed into the new C' line.\n> >\n> > ...........-------------A---B---C\n> > ........../            /   /   /\n> > ........./        /---A'--B'--C'  topic\n> > ......../        /\n> > ....D---E---F---G - master\n> \n> I'd draw that the other way:\n> \n>   ...........---------A---B---C\n>   ........../          \\   \\   \\\n>   ........./        /---A'--B'--C'  topic\n>   ......../        /\n>   ....D---E---F---G - master\n> \n> > (1) Is the above model a valid explanation?\n> \n> Sounds correct to me.\n\nI don't think you can call it correct since it assumes !(2) while (2)\nholds. Drawing the diagram this way is misleading; merging commits\none-by-one implies preserving the merge information in the history\ngraph; nothing like that is done by rebase.\n\nRebase is more like _cherry-picking_ all the patches on your branch on\ntop of the upstream branch. You just essentially take each patch (commit\nmessage + diff to parent) growing on top of upstream's E and recommit it\non top of G.\n\n> > (2) From the documentation diagrams, it looks like the rebased A' has only (G)\n> > as a parent, not (A,G). If this is the case, why?\n..snip..\n> > (i.e. not connecting those nodes throws away useful information)\n> \n> For the use-cases where this information is useful, \"rebase\" is not\n> for you. Indeed, in these cases, a plain \"merge\" is usually what you\n> want.\n\nIndeed, noone forces you into the rebase workflow for your own projects.\nI personally never ever rebase (I do use StGIT though, but it records\nper-patch history and makes sure I'm always in some consistent state).\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nThe last good thing written in C++ was the Pachelbel Canon. -- J. Olson\n"},{"id":"299238","messageId":"willow-jeske-01l78ZaEFEDjCZEG","threadId":"14177","inReplyTo":null,"subject":"is rebase the same as merging every commit?","fromName":"David Jeske","fromEmail":"jeske@willowmail.com","sentAt":null,"receivedAt":"2016-08-14T00:43:18Z","isPatch":false,"sender":{"key":"jeske@willowmail.com","avatar":null},"body":"Rebasing is described in the docs I've read as turning this: (sorry for the\ndots)\n\n..........A---B---C topic\n........./\n....D---E---F---G master\n\nInto this:\n\n...................A'--B'--C' topic\n................../\n.....D---E---F---G master\n\nIf I understand it right (and that's a BIG if), it's the same as doing a merge\nof C into G where every individual commit in the C-line is individually\ncommitted into the new C' line.\n\n...........-------------A---B---C\n........../            /   /   /\n........./        /---A'--B'--C'  topic\n......../        /\n....D---E---F---G - master\n\n\n(1) Is the above model a valid explanation?\n\n(2) From the documentation diagrams, it looks like the rebased A' has only (G)\nas a parent, not (A,G). If this is the case, why?  (i.e. not connecting those\nnodes throws away useful information)\n\n(3) If it only has (G) as a parent, does the rebase explicitly remove the\nsource A,B,C nodes from the repository? (the diagrams make it look like it\ndoes) ..or do they just get cleaned up during GC?\n"},{"id":"299240","messageId":"willow-jeske-01l7GnVAFEDjCe9c","threadId":"14177","inReplyTo":"vpqfxqz5qzj.fsf@bauges.imag.fr","subject":"Re: is rebase the same as merging every commit?","fromName":"David Jeske","fromEmail":"jeske@willowmail.com","sentAt":null,"receivedAt":"2016-08-14T00:43:20Z","isPatch":false,"sender":{"key":"jeske@willowmail.com","avatar":null},"body":"-- Matthieu Moy wrote:\n\n> > (3) If it only has (G) as a parent, does the rebase explicitly remove the\n> > source A,B,C nodes from the repository?\n>\n> Most commands, and this includes rebase, are\n> \"add-only\". The objects will remain unreferenced and\n> will be pruned by the next git gc --prune. Unreferenced\n> objects do not harm, they just eat your disk space.\n\nI see. So it would be reasonable for the documentation to be altered slightly\nto show that the original nodes are still there, and that the primary\ndifference between merging those changes one-by-one and rebasing is that rebase\ndoes not connect the new to the old. If you want to keep the old, you can toss\na branch name on it, and if not, it still lives until the gc timeout.\n\nThe current docs showing those nodes missing tells me that they disappear,\nwhich is both scarry, and apparently inaccurate.\n"}]}