{"thread":{"id":"14172","subject":"is rebase the same as merging every commit?","startedAt":"2008-06-26T23:42:03Z","lastAt":"2016-08-14T00:43:21Z","messageCount":11,"participants":["David Jeske","Junio C Hamano","Matthieu Moy","Pascal Obry","しらいしななこ"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"81344","messageId":"1006.35704952783$1214525911@news.gmane.org","threadId":"14172","inReplyTo":null,"subject":"is rebase the same as merging every commit?","fromName":"David Jeske","fromEmail":"jeske@willowmail.com","sentAt":null,"receivedAt":"2008-06-26T23:42:03Z","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":"81348","messageId":"7vzlp7n1j4.fsf@gitster.siamese.dyndns.org","threadId":"14172","inReplyTo":"1006.35704952783$1214525911@news.gmane.org","subject":"Re: is rebase the same as merging every commit?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-06-27T00:51:11Z","receivedAt":"2008-06-27T00:51:11Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?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>\n>\n> (1) Is the above model a valid explanation?\n\nI would presume that the resulting trees A' in the second picture and in\nthe first picture would be the same, so are B' and C'.  But that is only\ntrue when commits between A and C do not have any duplicate with the\ndevelopment that happened between E and G.\n\nThinking about it like that is an interesting mental exercise, but it is\nnot very useful otherwise.\n\n> (2) From the documentation diagrams, it looks like the rebased A' has\n> only (G) as a parent, not (A,G). If this is the case, why?  (i.e. not\n> connecting those nodes throws away useful information)\n\nYou would rebase ONLY WHEN the project as the whole (either \"other people\nin the project\", or \"yourself down the road one year from now\") is\ninterested mostly in the progress of 'master' D-E-F-G, and nobody cares\nwhether you developed your A (or B or C) on top of E or G.  So the answer\nis definite \"no\" --- the line you drew between A and A' is a useless\ninformation.  Nobody cares you did it first on top of E but then you have\nredone the patches based on G (because things changed between E and G).\n\nIf there were no \"rebase\", your changes will be integrated into 'master'\nbranch like this:\n\n          A---B---C\n         /         \\\n    D---E---F---G---M\n\nRebasing is a way to _help you_ pretend that you did _not_ start working\non an ancient code base that was at E.  You redo your series on top of the\nlatest and greatest G, the commit that everybody else agrees is the\ncurrent state of affairs when he sees your changes for the first time, to\nproduce a history like this:\n\n\n    D---E---F---G---A'--B'--C'\n\nDoing so tends to make the history easier to understand, and more\nimportantly, it reduces mistakes during the integration _and_ distributes\nthe burden of integration from central point.\n\nIf E..G and A..C happen to have conflicting changes, rebasing puts the\nburden to rewrite the changes A..C into A'..C', based on the modified base\ncode G, on _you_ (the person who is rebasing).  Some people do not like\nthis, as they feel that is an added, unwanted burden.  On the other hand,\nif your upstream maintainer is integrating like the above picture to\ncreate a merge 'M', it is more likely that he would make mistakes during\nthe conflict resolution, than you make incorrect adjustment during your\nrebasing to recreate the series A'..C'.  You read what G gives you as the\nfoundation to build your changes on, determine what got changed since E,\non which you originally based your changes, and adjust your changes to\nbetter integrate on top of G.  After all, A..C is _your code_ and you\nunderstand what it assumes better than anybody else.\n\nIf the fact that parallel developments have happened is important, instead\nof the second picture like you drew, you will just do the real merge\nnaturally to create a merge \"M\" like the picture I drew above.\n\nYour \"A' is merge between E and A, B' is merge between A' and B\" is not\nsomething anybody is interested in if you are going to rebase.  It is not\ninteresting because it is not how things happened in the real life at all,\nand it is not interesting because it is not simplifying the history for\nlater analysis nor reducing mistakes during the conflict resolution.\n"},{"id":"81351","messageId":"7vvdzvn0ql.fsf@gitster.siamese.dyndns.org","threadId":"14172","inReplyTo":"7vzlp7n1j4.fsf@gitster.siamese.dyndns.org","subject":"Re: is rebase the same as merging every commit?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-06-27T01:08:18Z","receivedAt":"2008-06-27T01:08:18Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> \"David Jeske\" <jeske@willowmail.com> writes:\n> ...\n>> (2) From the documentation diagrams, it looks like the rebased A' has\n>> only (G) as a parent, not (A,G). If this is the case, why?  (i.e. not\n>> connecting those nodes throws away useful information)\n>\n> You would rebase ONLY WHEN the project as the whole (either \"other people\n> in the project\", or \"yourself down the road one year from now\") is\n> interested mostly in the progress of 'master' D-E-F-G, and nobody cares\n> whether you developed your A (or B or C) on top of E or G.  So the answer\n> is definite \"no\" --- the line you drew between A and A' is a useless\n> information.  Nobody cares you did it first on top of E but then you have\n> redone the patches based on G (because things changed between E and G).\n\nThe last sentence came out in somewhat inappropriate way.\n\n\tIn the situation \"rebase\" (which is a way to help you pretend you\n\tdid not start building on a stale codebase) is appropriate, nobody\n\twants to know you did it first on E\n\nis what I meant.  More importantly, _you_ do not want anybody to know.\nThat is the whole reason you would rebase.\n\nWith that clarification in mind, the explanation would flow more smoothly\nto this part...\n\n> If the fact that parallel developments have happened is important, instead\n> of the second picture like you drew, you will just do the real merge\n> naturally to create a merge \"M\" like the picture I drew above.\n\nSo you have a choice between merging and rebasing.  And your extra parents\ngoes against the reason you chose rebasing in the first place.  That is\nwhy we do not record the original parents anywhere.\n"},{"id":"81369","messageId":"4864892E.2060508@obry.net","threadId":"14172","inReplyTo":"7vzlp7n1j4.fsf@gitster.siamese.dyndns.org","subject":"Re: is rebase the same as merging every commit?","fromName":"Pascal Obry","fromEmail":"pascal@obry.net","sentAt":"2008-06-27T06:31:10Z","receivedAt":"2008-06-27T06:31:10Z","isPatch":false,"sender":{"key":"pascal@obry.net","avatar":"https://avatars.githubusercontent.com/u/467069?v=4"},"body":"Junio C Hamano a écrit :\n> You would rebase ONLY WHEN the project as the whole (either \"other people\n> in the project\", or \"yourself down the road one year from now\") is\n> interested mostly in the progress of 'master' D-E-F-G, and nobody cares\n> whether you developed your A (or B or C) on top of E or G.  So the answer\n\nOr if you are using git-svn as nobody will ever see your local branches. \nSo rebasing is just the right way to go when tracking a Subversion tree \nI would say.\n\nPascal.\n\n-- \n\n--|------------------------------------------------------\n--| Pascal Obry                           Team-Ada Member\n--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE\n--|------------------------------------------------------\n--|              http://www.obry.net\n--| \"The best way to travel is by means of imagination\"\n--|\n--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595\n"},{"id":"81364","messageId":"5594.86673814735$1214549880@news.gmane.org","threadId":"14172","inReplyTo":"7vvdzvn0ql.fsf@gitster.siamese.dyndns.org","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":"Thanks for the explanation.\n\nHowever, when considering an SCM perspective, I don't understand why I have to\nmake a tradeoff between personal reproducibility (which I get from the original\nchanges), and upstream readability (which the community gets from my rebase).\n\nI could get both of these if the rebase kept both the old and new.\n\nIs there some reason that losing personal reproducability, and personal/local\ntracking back to those changes of A-B-C is necessary as part of the process?\n\nFurther, the rebase machinery seems like it would be great for operations that\nare even more 'dangerous', where I would really really want the history of the\ntransitions in case I realized a problem later.\n\nConsider this set of commits on a personal branch\n\n0 - feature a\n1 - feature b\n2 - bugfix a\n3 - feature c / d\n4 - bugfix b\n5 - bugfix a2\n\n>From all I've read about rebase, bisect, and the big tree management, it seems\nlike the three steps are Reorder, combine, rebase.  (In a more complicated\nsituation, i'd want to split a commit into pieces)\n\n(1'')\n0' - feature A\n1' - bugfix a\n2' - bugfix a2\n(2'')\n3' - feature b\n4' - bugfix b\n(3'')\n5' - feature c (split)\n(4'')\n6' - feature d (split)\n\nFrankly, I'm super impressed, because I can imagine how I might do this in git.\nI'm guessing some of you are already doing this. But how do you do it? Can you\nrebase a patch back into it's own history? (such as bugfix a from 2, to 1')\n\nI want to mess around and try this stuff out, but I'm scared of doing bad\nthings to the tree and them being unrecoverable because rebase tosses the old\nstuff. I don't understand why I have to lose my original work and/or the\nconnection to my original work, in order to reorder/combine/split for public\nconsumption. What is the argument for that? (other than the fact that the\ncurrent dag link propagation model would force others to get these changes if\nthey remained connected together. Something easily remidied by out of band\nmetadata, or different link types)\n"},{"id":"81368","messageId":"vpqd4m349hk.fsf@bauges.imag.fr","threadId":"14172","inReplyTo":"willow-jeske-01l7GhRWFEDjChtB","subject":"Re: is rebase the same as merging every commit?","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2008-06-27T07:34:15Z","receivedAt":"2008-06-27T07:34:15Z","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> However, when considering an SCM perspective, I don't understand why I have to\n> make a tradeoff between personal reproducibility (which I get from the original\n> changes), and upstream readability (which the community gets from my rebase).\n\nWell, look at the [PATCH] messages on this list, and how they evolve.\nPatch series give a clean way to go from a point to another. That's\nwhat you want to see in upstream history.\n\nThen, patch series usually get reviewed, and the patches themselves\nare modified. There's a kind of meta-history: the changes you make to\nyour own changes.\n\nSuppose I send a patch containing\n\n+\tint * x = malloc(sizeof(char));\n\nand someone notices how wrong it is. I send another patch with\n\n+\tint * x = malloc(sizeof(int));\n\nThe first version was basicaly a mistake, and if it hasn't been\nreleased, no one want to bother with it longer that the time to resend\nthe patch. No one want to be hit by the bug while using bisect later\non the upstream repository. And no one wants to see both patches when\nreviewing or \"git blame\"-ing.\n\nThings you rebase in Git are just like things for which you don't make\nintermediate commits in SVN.\n\n>>From all I've read about rebase, bisect, and the big tree management, it seems\n> like the three steps are Reorder, combine, rebase.  (In a more complicated\n> situation, i'd want to split a commit into pieces)\n>\n> (1'')\n> 0' - feature A\n> 1' - bugfix a\n> 2' - bugfix a2\n> (2'')\n> 3' - feature b\n> 4' - bugfix b\n> (3'')\n> 5' - feature c (split)\n> (4'')\n> 6' - feature d (split)\n>\n> Frankly, I'm super impressed, because I can imagine how I might do\n> this in git.\n\ngit rebase -i will help you to do that painlessly.\n\n> I want to mess around and try this stuff out, but I'm scared of doing bad\n> things to the tree and them being unrecoverable\n\nThey won't. The reflog is still there. Try it, an cancel it if you\ndon't like.\n\nThe huge difference between the reflog and the history is that the\nreflog is local, it's your own mess, other people won't get disturbed\nby how messy it can be.\n\n> (other than the fact that the current dag\n> link propagation model would force others to get these changes if\n> they remained connected together. Something easily remidied by out\n> of band metadata, or different link types)\n\nNo. One fundamental principle of Git is that objects are immutable. If\nyour objects have a link, of whatever kind, then the same object moved\nin another repository have the same link.\n\nBut what's wrong with the reflog?\n\n-- \nMatthieu\n"},{"id":"81376","messageId":"20080627193328.6117@nanako3.lavabit.com","threadId":"14172","inReplyTo":"7vzlp7n1j4.fsf@gitster.siamese.dyndns.org","subject":"Re: is rebase the same as merging every commit?","fromName":"しらいしななこ","fromEmail":"nanako3@lavabit.com","sentAt":"2008-06-27T10:33:28Z","receivedAt":"2008-06-27T10:33:28Z","isPatch":false,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"Quoting Junio C Hamano <gitster@pobox.com>:\n\n> \"David Jeske\" <jeske@willowmail.com> writes:\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>>\n>> (1) Is the above model a valid explanation?\n>\n> I would presume that the resulting trees A' in the second picture and in\n> the first picture would be the same, so are B' and C'.  But that is only\n> true when commits between A and C do not have any duplicate with the\n> development that happened between E and G.\n\nSorry, but I think you are wrong, Junio.\n\nRebase can be used to backport changes, not just porting your changes forward, using --onto option:\n\n..........maint\n............1-------A'--B'--C'   \n.........../       .   .   . <-- ???\n........../.......A---B---C\n........./......./\n......../......./\n.......0--...--D---E---F---G - master\n\nHere, A, B, C that are based on D (that is way ahead of the top of the maintenance branch 1) is rebased to the maintenance branch.\n\nBut in this case, A' is *not* a merge between 1 and A.  For A' to be a merge between 1 and A, it *must* contain all the development that happened up to 1 and all the development that happened up to A since these two branches were forked (that is 0 in the above picture).\n\nInstead, the difference to go from 1 to A' is similar to the difference to go from D to A. It does not and must not include anything that happened between 0 and D.  That is not a merge.\n\nI agree that your explanation why A is not recorded as a parent of A' is right for the philosophical reason (the purpose of rebasing to create A' is so that you do not have to record them).  But from the point-of-view of correctness of commit history, I think A must not be recorded as a parent of A', either.\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n"},{"id":"81413","messageId":"42989.1632324599$1214581901@news.gmane.org","threadId":"14172","inReplyTo":"vpqd4m349hk.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-27T15:07:32Z","isPatch":false,"sender":{"key":"jeske@willowmail.com","avatar":null},"body":"This example you provided Matthieu is exactly my confusion with rebase..\n\nIf I want to bring a 'broken feature-a' branch into my topic branch to build on\nit, one commit of which is this:\n\n> +\tint * x = malloc(sizeof(char));\n\nif I merge, my tree looks like:\n\n:         /<--G<--H<--Qj jeske/topic1\n:        /           /\n:       /<--P<------Q    feature-a\n:      /\n: -----A<---B<---C master\n\nor if I rebase, it looks like:\n\n:                  /<--G'<--H' jeske/topic1\n:                 /\n:       /<--P<---Q    feature-a\n:      /\n: -----A<---B<---C master\n\n-----\n\n..and then through 'fixing' the patch, it ends up rebased and accepted onto the\nmainline origin/master, as a single patch, which (among other things) changed\nthis line to:\n\n> +\tint * x = malloc(sizeof(int));\n\n...if I merged above, it will look like,\n\n:         /<--G<--H<--Qj jeske/topic1\n:        /           /\n:       /<--P<------Q    feature-a\n:      /\n: -----A<---B<---C<---Q' master\n\n...if I rebased above, it will look like:\n\n:                  /<--G'<--H' jeske/topic1\n:                 /\n:       /<--P<---Q    feature-a\n:      /\n: -----A<---B<---C<---Q' master\n\n\nHowever, in both cases, because Q' is not connected to Q, I don't see how git\nwill do anything sane to help me accept Q' correctly.\n\nIf I rebased my merge-q-branch against the master, I would expect to get this\n(which will cause a conflict I have to resolve):\n\n:           /<--G<--H<--Qj jeske/topic1\n:          /\n: <--C<---Q' master\n\nIf I rebased my rebase-q-branch against master, I would expect to get this\n(which will cause a conflict I have to resolve):\n\n:                     /<--G'<--H' jeske/topic1\n:                    /\n:          /<--P<---Q    feature-a\n:         /\n: --C<---Q' master\n\nHowever, if that Q' rebase contained a link back to (P,Q), it would know that\nthe Q' rebase was replacing (P,Q), and would know to back them out of my tree\nwhen I rebased back onto the head, producing this in BOTH cases above (whether\nI rebased or merged from the feature-a branch):\n\n\n:          /<--G'<--H' jeske/topic1\n:         /\n: --C<---Q' master\n\nThis operation above of \"working will pulling uncompleted patches into my tree\"\nseems like a fairly common thing for developers. I've never provided any\npatches to linux-kernel, but when I did try hacking on it years ago, I was\ndoing exactly this. (pulling unaccepted patches into my kernel, then building\non those patches). When I read about the DAG and its universal naming, I always\nassumed that the above workflow was what it was DESIGNED to make automatic. I'm\nconfused, how does this work in git?\n\n\n\n-- Matthieu Moy wrote:\n> Well, look at the [PATCH] messages on this list, and how they evolve.\n> Patch series give a clean way to go from a point to another. That's\n> what you want to see in upstream history.\n>\n> Then, patch series usually get reviewed, and the patches themselves\n> are modified. There's a kind of meta-history: the changes you make to\n> your own changes.\n>\n> Suppose I send a patch containing\n>\n> +\tint * x = malloc(sizeof(char));\n>\n> and someone notices how wrong it is. I send another patch with\n>\n> +\tint * x = malloc(sizeof(int));\n>\n> The first version was basicaly a mistake, and if it hasn't been\n> released, no one want to bother with it longer that the time to resend\n> the patch. No one want to be hit by the bug while using bisect later\n> on the upstream repository. And no one wants to see both patches when\n> reviewing or \"git blame\"-ing.\n"},{"id":"81476","messageId":"7vskuypmve.fsf@gitster.siamese.dyndns.org","threadId":"14172","inReplyTo":"20080627193328.6117@nanako3.lavabit.com","subject":"Re: is rebase the same as merging every commit?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-06-27T21:51:49Z","receivedAt":"2008-06-27T21:51:49Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"しらいしななこ  <nanako3@lavabit.com> writes:\n\n> Quoting Junio C Hamano <gitster@pobox.com>:\n>\n>> \"David Jeske\" <jeske@willowmail.com> writes:\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>>>\n>>> (1) Is the above model a valid explanation?\n>>\n>> I would presume that the resulting trees A' in the second picture and in\n>> the first picture would be the same, so are B' and C'.  But that is only\n>> true when commits between A and C do not have any duplicate with the\n>> development that happened between E and G.\n>\n> Sorry, but I think you are wrong, Junio.\n> ...\n> I agree that your explanation why A is not recorded as a parent of A' is\n> right for the philosophical reason (the purpose of rebasing to create A'\n> is so that you do not have to record them).  But from the point-of-view\n> of correctness of commit history, I think A must not be recorded as a\n> parent of A', either.\n\nAll correct.  Sorry about the confusion.\n"},{"id":"299239","messageId":"willow-jeske-01l7GhRWFEDjChtB","threadId":"14172","inReplyTo":"7vvdzvn0ql.fsf@gitster.siamese.dyndns.org","subject":"Re: is rebase the same as merging every commit?","fromName":"David Jeske","fromEmail":"jeske@willowmail.com","sentAt":null,"receivedAt":"2016-08-14T00:43:19Z","isPatch":false,"sender":{"key":"jeske@willowmail.com","avatar":null},"body":"Thanks for the explanation.\n\nHowever, when considering an SCM perspective, I don't understand why I have to\nmake a tradeoff between personal reproducibility (which I get from the original\nchanges), and upstream readability (which the community gets from my rebase).\n\nI could get both of these if the rebase kept both the old and new.\n\nIs there some reason that losing personal reproducability, and personal/local\ntracking back to those changes of A-B-C is necessary as part of the process?\n\nFurther, the rebase machinery seems like it would be great for operations that\nare even more 'dangerous', where I would really really want the history of the\ntransitions in case I realized a problem later.\n\nConsider this set of commits on a personal branch\n\n0 - feature a\n1 - feature b\n2 - bugfix a\n3 - feature c / d\n4 - bugfix b\n5 - bugfix a2\n\n>From all I've read about rebase, bisect, and the big tree management, it seems\nlike the three steps are Reorder, combine, rebase.  (In a more complicated\nsituation, i'd want to split a commit into pieces)\n\n(1'')\n0' - feature A\n1' - bugfix a\n2' - bugfix a2\n(2'')\n3' - feature b\n4' - bugfix b\n(3'')\n5' - feature c (split)\n(4'')\n6' - feature d (split)\n\nFrankly, I'm super impressed, because I can imagine how I might do this in git.\nI'm guessing some of you are already doing this. But how do you do it? Can you\nrebase a patch back into it's own history? (such as bugfix a from 2, to 1')\n\nI want to mess around and try this stuff out, but I'm scared of doing bad\nthings to the tree and them being unrecoverable because rebase tosses the old\nstuff. I don't understand why I have to lose my original work and/or the\nconnection to my original work, in order to reorder/combine/split for public\nconsumption. What is the argument for that? (other than the fact that the\ncurrent dag link propagation model would force others to get these changes if\nthey remained connected together. Something easily remidied by out of band\nmetadata, or different link types)\n"},{"id":"299241","messageId":"willow-jeske-01l7T9zdFEDjCigG","threadId":"14172","inReplyTo":"vpqd4m349hk.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:21Z","isPatch":false,"sender":{"key":"jeske@willowmail.com","avatar":null},"body":"This example you provided Matthieu is exactly my confusion with rebase..\n\nIf I want to bring a 'broken feature-a' branch into my topic branch to build on\nit, one commit of which is this:\n\n> +\tint * x = malloc(sizeof(char));\n\nif I merge, my tree looks like:\n\n:         /<--G<--H<--Qj jeske/topic1\n:        /           /\n:       /<--P<------Q    feature-a\n:      /\n: -----A<---B<---C master\n\nor if I rebase, it looks like:\n\n:                  /<--G'<--H' jeske/topic1\n:                 /\n:       /<--P<---Q    feature-a\n:      /\n: -----A<---B<---C master\n\n-----\n\n..and then through 'fixing' the patch, it ends up rebased and accepted onto the\nmainline origin/master, as a single patch, which (among other things) changed\nthis line to:\n\n> +\tint * x = malloc(sizeof(int));\n\n...if I merged above, it will look like,\n\n:         /<--G<--H<--Qj jeske/topic1\n:        /           /\n:       /<--P<------Q    feature-a\n:      /\n: -----A<---B<---C<---Q' master\n\n...if I rebased above, it will look like:\n\n:                  /<--G'<--H' jeske/topic1\n:                 /\n:       /<--P<---Q    feature-a\n:      /\n: -----A<---B<---C<---Q' master\n\n\nHowever, in both cases, because Q' is not connected to Q, I don't see how git\nwill do anything sane to help me accept Q' correctly.\n\nIf I rebased my merge-q-branch against the master, I would expect to get this\n(which will cause a conflict I have to resolve):\n\n:           /<--G<--H<--Qj jeske/topic1\n:          /\n: <--C<---Q' master\n\nIf I rebased my rebase-q-branch against master, I would expect to get this\n(which will cause a conflict I have to resolve):\n\n:                     /<--G'<--H' jeske/topic1\n:                    /\n:          /<--P<---Q    feature-a\n:         /\n: --C<---Q' master\n\nHowever, if that Q' rebase contained a link back to (P,Q), it would know that\nthe Q' rebase was replacing (P,Q), and would know to back them out of my tree\nwhen I rebased back onto the head, producing this in BOTH cases above (whether\nI rebased or merged from the feature-a branch):\n\n\n:          /<--G'<--H' jeske/topic1\n:         /\n: --C<---Q' master\n\nThis operation above of \"working will pulling uncompleted patches into my tree\"\nseems like a fairly common thing for developers. I've never provided any\npatches to linux-kernel, but when I did try hacking on it years ago, I was\ndoing exactly this. (pulling unaccepted patches into my kernel, then building\non those patches). When I read about the DAG and its universal naming, I always\nassumed that the above workflow was what it was DESIGNED to make automatic. I'm\nconfused, how does this work in git?\n\n\n\n-- Matthieu Moy wrote:\n> Well, look at the [PATCH] messages on this list, and how they evolve.\n> Patch series give a clean way to go from a point to another. That's\n> what you want to see in upstream history.\n>\n> Then, patch series usually get reviewed, and the patches themselves\n> are modified. There's a kind of meta-history: the changes you make to\n> your own changes.\n>\n> Suppose I send a patch containing\n>\n> +\tint * x = malloc(sizeof(char));\n>\n> and someone notices how wrong it is. I send another patch with\n>\n> +\tint * x = malloc(sizeof(int));\n>\n> The first version was basicaly a mistake, and if it hasn't been\n> released, no one want to bother with it longer that the time to resend\n> the patch. No one want to be hit by the bug while using bisect later\n> on the upstream repository. And no one wants to see both patches when\n> reviewing or \"git blame\"-ing.\n"}]}