{"thread":{"id":"15628","subject":"rebasing merges","startedAt":"2008-09-22T20:57:49Z","lastAt":"2008-09-23T18:29:16Z","messageCount":14,"participants":["Stephen Haberman","Johannes Sixt","Samuel Tardieu","Andreas Ericsson","SZEDER Gábor"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"91343","messageId":"20080922155749.c8070681.stephen@exigencecorp.com","threadId":"15628","inReplyTo":null,"subject":"rebasing merges","fromName":"Stephen Haberman","fromEmail":"stephen@exigencecorp.com","sentAt":"2008-09-22T20:57:49Z","receivedAt":"2008-09-22T20:57:49Z","isPatch":false,"sender":{"key":"stephen@exigencecorp.com","avatar":"https://gravatar.com/avatar/23b93ad70a06ce53505f17ddba65176edbcfb6588e7a4c1a2dca04aaf0a6aff1?d=mp&s=160"},"body":"Hello,\n\nI was wondering if there are any plans to enhance the rebase\nfunctionality to match something like [1], specifically to handle\nrebasing merge commits.\n\nMy understanding of the current rebase implementation is that it dumps\nall the changes as a patch, moves HEAD, and applies the patch.\n\nThis works great for regular commits, but if one of the new commits was\na merge, rebase seems to \"flatten\" the merge. Because the patch dump\ndoesn't include any information about the merged commit's existing\nhashes/parents, when the patch is applied, each merged commit gets\nreapplied as a new commit, with a new hash, and no DAG link back to\nwhere the original pre-rebase merge came from.\n\nWe've had this happen on topic branches when devs merged in a new\nstable release that contains ~100 commits, but had their branch's\nremote head move on them, so they pull --rebase as usual, but end up\nwith all ~100 commits from the release essentially cherry-picked into\ntheir topic branch. So now we have the disclaimer of \"usually pull\n--rebase...unless you've done a merge, then do a pull --merge\".\n\n[1] seems to solve this with some fairly complex cherry-picking and\nancestry manipulation that, admittedly, I don't quite understand, but\nit seems like it might be able to bring along a merge's multiple\nparents information throughout the rebase and maintain the merge as a\nsingle, non-flattened merge commit.\n\nThanks,\nStephen\n\n1: http://www.selenic.com/mercurial/wiki/index.cgi/RebasePlan\n"},{"id":"91351","messageId":"20080922231927.ef18f420.stephen@exigencecorp.com","threadId":"15628","inReplyTo":"20080922155749.c8070681.stephen@exigencecorp.com","subject":"Re: rebasing merges","fromName":"Stephen Haberman","fromEmail":"stephen@exigencecorp.com","sentAt":"2008-09-23T04:19:27Z","receivedAt":"2008-09-23T04:19:27Z","isPatch":false,"sender":{"key":"stephen@exigencecorp.com","avatar":"https://gravatar.com/avatar/23b93ad70a06ce53505f17ddba65176edbcfb6588e7a4c1a2dca04aaf0a6aff1?d=mp&s=160"},"body":"\n> [1] seems to solve this with some fairly complex cherry-picking and\n> ancestry manipulation that, admittedly, I don't quite understand, but\n> it seems like it might be able to bring along a merge's multiple\n> parents information throughout the rebase and maintain the merge as a\n> single, non-flattened merge commit.\n\nHm. Sorry for the noise about that Mercurial link--mostly talking to\nmyself now, but I've discovered `git rebase -i -p` does exactly what I\nwant (I think).\n\nIs there a reason the \"preserve merge\" option in the\ngit-rebase--interactive isn't also in the non-interactive git-rebase\nthat is invoked by a git pull --rebase?\n\nI noticed the t3400.sh test explicitly tests for the flattening\nbehavior, but I can't tell if that is because it's testing for\nexplicitly desired behavior or if the \"linear-izing\" is something\nthat is up for debate (or a command line/config option).\n\nWould it be foolish for me to work on something like this? I can\nprobably hold my own at copy/pasting around in the shell scripts.\n\nThanks,\nStephen\n"},{"id":"91354","messageId":"48D88813.9060400@viscovery.net","threadId":"15628","inReplyTo":"20080922231927.ef18f420.stephen@exigencecorp.com","subject":"Re: rebasing merges","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-09-23T06:09:23Z","receivedAt":"2008-09-23T06:09:23Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Stephen Haberman schrieb:\n> I noticed the t3400.sh test explicitly tests for the flattening\n> behavior, but I can't tell if that is because it's testing for\n> explicitly desired behavior or if the \"linear-izing\" is something\n> that is up for debate (or a command line/config option).\n\nThis is the expected behavior and not up for debate.\n\nConsider this use-case, for example: You keep a private patch or two on\ntop of upstream, and you also regularly pull from upstream. You get this\nhistory:\n\n  ---o--o--o--o--o--o    <-- origin\n      \\     \\        \\\n       A--B--M--------N  <-- master\n\nA and B are the private patches. From time to time you want to update them\nif they get out of date, which is indicated by merge conflicts in the\nmerges M and N. Then you want this result:\n\n  ---o--o--o--o--o--o         <-- origin\n                     \\\n                      A'--B'  <-- master\n\ni.e. linearized history without merges.\n\n-- Hannes\n"},{"id":"91360","messageId":"2008-09-23-09-30-47+trackit+sam@rfc1149.net","threadId":"15628","inReplyTo":"48D88813.9060400@viscovery.net","subject":"Re: rebasing merges","fromName":"Samuel Tardieu","fromEmail":"sam@rfc1149.net","sentAt":"2008-09-23T07:30:47Z","receivedAt":"2008-09-23T07:30:47Z","isPatch":false,"sender":{"key":"sam@rfc1149.net","avatar":"https://avatars.githubusercontent.com/u/44656?v=4"},"body":">>>>> \"Johannes\" == Johannes Sixt <j.sixt@viscovery.net> writes:\n\nJohannes> i.e. linearized history without merges.\n\nA few days ago, I had a question in my team quite similar to Stephen\nconcern. A developer had performed a merge of a complex feature and\nwas ready to commit it\n\n  --o--o--o--o--X        <-- origin\n     \\           \\\n      A--B--C--D--E      <-- master\n\nwhen he realized that someone just pushed another change on origin\nwhile he was doing the complicating merge (with lots of conflicts to\nresolve). The configuration was then:\n\n  --o--o--o--o--X--Y     <-- origin\n     \\           \\\n      A--B--C--D--E      <-- master\n\nHe would have wanted to have the merge rebased on E and Y instead of E\nand X before pushing, without going through all the conflicts\nresolution again (he didn't have \"rerere\" enabled).\n\nIs that possible with \"git rebase\"?\n\nBtw, would it be a good idea to unconditionally enable \"rerere\"\nconflict resolution *recording*, and add an option to \"rebase\" and\n\"merge\" to use \"rerere\" even when it is not enabled in the\nconfiguration file? I can't think of any drawback.\n\n  Sam\n-- \nSamuel Tardieu -- sam@rfc1149.net -- http://www.rfc1149.net/\n"},{"id":"91361","messageId":"20080923024653.a3bb8666.stephen@exigencecorp.com","threadId":"15628","inReplyTo":"48D88813.9060400@viscovery.net","subject":"Re: rebasing merges","fromName":"Stephen Haberman","fromEmail":"stephen@exigencecorp.com","sentAt":"2008-09-23T07:46:53Z","receivedAt":"2008-09-23T07:46:53Z","isPatch":false,"sender":{"key":"stephen@exigencecorp.com","avatar":"https://gravatar.com/avatar/23b93ad70a06ce53505f17ddba65176edbcfb6588e7a4c1a2dca04aaf0a6aff1?d=mp&s=160"},"body":"\n> This is the expected behavior and not up for debate.\n\nCool, thanks for the reply. However, I debate... :-)\n\n>   ---o--o--o--o--o--o         <-- origin\n>                      \\\n>                       A'--B'  <-- master\n\nNice. That makes sense in your scenario.\n\nHere is mine:\n\n ---A--B--C--D           <-- origin/stable\n     \\       |\n      E--F   |           <-- origin/topica\n          \\  |\n             g--h        <-- topica\n\nAll the upper case commits have been published to origin. Other\ndevs, etc., know about them, their hashes are in the bug tracking\nsystem.\n\nI'm bringing topica up to date, but with a merge because I have\npublished history already on topica, so I merge stable and get a\nnew merge commit: g. And maybe make another change: h.\n\nEverything's cool...now, with surprising frequency, someone beats\nme to moving origin/topica:\n\n ---A--B--C--D           <-- origin/stable\n     \\       |\n      E--F---|--I        <-- origin/topica\n          \\  |\n             g--h        <-- topica\n\nPushing h gets rejected as a rewind. Good. I want to pull, which\nwe had previously always used \"--rebase\" for, and the desired output\nof a pull --rebase, to me, would be:\n\n ---A--B--C--D           <-- origin/stable\n     \\        \\\n      E--F--I |          <-- origin/topica\n             \\|\n              g'--h'     <-- topica\n\nInstead, I get:\n\n ---A--B--C--D           <-- origin/stable\n     \\\n      E--F--I            <-- origin/topica\n             \\\n              B'-C'-D'-h'<-- topica\n\nSo, yes, linearized history with no merges. However, this leads\nto quizzical looks when B'/C'/D' hit the email list, bug tracker, etc.\nas new commits.\n\nCurrently I just try to pull/merge/push in quick succession, but\nit's a manual collaboration hack (\"okay, I'm merging now, no\ncommitting...\") that would be nice to not have to worry about.\n\nI need to investigate the interactive rebase more, but my hesitant\nassertion is that it's parent rewriting seems smart enough to handle\nthis. Perhaps not, and I admit our desired DAG output may not be\nattainable without manual intervention.\n\nI apologize--I should have included the example DAGs in my first\npost, but since I didn't I felt the need to clarify. So, humoring\nme, is the B'/C'/D' from this example really the expected behavior?\n\nI can work on a new test in t3400/etc. if that is of interest.\n\nThanks for your time,\nStephen\n"},{"id":"91363","messageId":"48D8A052.6000101@viscovery.net","threadId":"15628","inReplyTo":"2008-09-23-09-30-47+trackit+sam@rfc1149.net","subject":"Re: rebasing merges","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-09-23T07:52:50Z","receivedAt":"2008-09-23T07:52:50Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Samuel Tardieu schrieb:\n>>>>>> \"Johannes\" == Johannes Sixt <j.sixt@viscovery.net> writes:\n> \n> Johannes> i.e. linearized history without merges.\n> \n> A few days ago, I had a question in my team quite similar to Stephen\n> concern. A developer had performed a merge of a complex feature and\n> was ready to commit it\n> \n>   --o--o--o--o--X        <-- origin\n>      \\           \\\n>       A--B--C--D--E      <-- master\n> \n> when he realized that someone just pushed another change on origin\n> while he was doing the complicating merge (with lots of conflicts to\n> resolve). The configuration was then:\n> \n>   --o--o--o--o--X--Y     <-- origin\n>      \\           \\\n>       A--B--C--D--E      <-- master\n> \n> He would have wanted to have the merge rebased on E and Y instead of E\n> and X before pushing, without going through all the conflicts\n> resolution again (he didn't have \"rerere\" enabled).\n\nIf you mean \"merge\", and you are willing to keep E, then you do another\nmerge to get this history:\n\n  --o--o--o--o--X--Y     <-- origin\n     \\           \\  \\\n      A--B--C--D--E--F   <-- master\n\nand the previous conflicts will not show up again. But if you do not want\nE to show up in the history, like this:\n\n  --o--o--o--o--X--Y     <-- origin\n     \\              \\\n      A--B--C--D-----F   <-- master\n\nthen you will have to resolve all conflicts again. Of course, you can keep\n E in a temporary branch, and you can selectively check out files from\nthat tree to safe some work, but whether this is possible depends on the\nchanges that Y introduces.\n\nIf you mean \"rebase\", then you get this after the first rebase:\n\n  --o--o--o--o--X--Y               <-- origin\n                 \\\n                  A'--B'--C'--D'   <-- master\n\nThen you can rebase again to get this:\n\n  --o--o--o--o--X--Y                  <-- origin\n                    \\\n                     A\"--B\"--C\"--D'   <-- master\n\nat which time you don't see the old conflicts again.\n\n-- Hannes\n"},{"id":"91365","messageId":"48D8A209.6090708@viscovery.net","threadId":"15628","inReplyTo":"20080923024653.a3bb8666.stephen@exigencecorp.com","subject":"Re: rebasing merges","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2008-09-23T08:00:09Z","receivedAt":"2008-09-23T08:00:09Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Stephen Haberman schrieb:\n>> This is the expected behavior and not up for debate.\n> \n> Cool, thanks for the reply. However, I debate... :-)\n> \n>>   ---o--o--o--o--o--o         <-- origin\n>>                      \\\n>>                       A'--B'  <-- master\n> \n> Nice. That makes sense in your scenario.\n> \n> Here is mine:\n\nI understand your problem very well. pull --rebase does not help your case\nbecause it was not designed for your workflow (it was designed to help the\none that I sketched).\n\nYou are probably better served using fetch + rebase -i -p.\n\n-- Hannes\n"},{"id":"91366","messageId":"48D8A371.4030909@op5.se","threadId":"15628","inReplyTo":"2008-09-23-09-30-47+trackit+sam@rfc1149.net","subject":"Re: rebasing merges","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2008-09-23T08:06:09Z","receivedAt":"2008-09-23T08:06:09Z","isPatch":false,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Samuel Tardieu wrote:\n> \n> Btw, would it be a good idea to unconditionally enable \"rerere\"\n> conflict resolution *recording*, and add an option to \"rebase\" and\n> \"merge\" to use \"rerere\" even when it is not enabled in the\n> configuration file? I can't think of any drawback.\n> \n\nI'm all for that. I actually thought (4 months ago) that that was\nhow it worked.\n\nIt would be a backwards incompatible change though, as we currently\nfall back to \"does rr-cache exist?\" to determine if rerere is enabled\nin case it isn't explicitly so in the configuration. Perhaps print\na warning if !rerere.enabled but $GIT_DIR/rr-cache exists. OTOH,\nthat will create a lot of warnings since we'd have to create that\nrr-cache directory to record the resolutions.\n\nTo maintain backwards compatibility, we could ofcourse do like this;\n* move rr-cache to rere (\"recorded resolutions\"; bikeshed color goes here)\n* if rr-cache exists, implicitly enable rerere\n* if rr-cache holds resolutions when setting up rerere, move them\n  to rere\nOR\n* look for resolutions in both rr-cache and rere indefinitely.\n\nIt's not exactly performance critical, so swapping the pattern from\nO(n) (or whatever it is now) to O(2n) for replaying resolutions\nprobably won't make that much of a difference.\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"91367","messageId":"48D8A6EA.4020805@op5.se","threadId":"15628","inReplyTo":"20080923024653.a3bb8666.stephen@exigencecorp.com","subject":"Re: rebasing merges","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2008-09-23T08:20:58Z","receivedAt":"2008-09-23T08:20:58Z","isPatch":false,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Stephen Haberman wrote:\n>> This is the expected behavior and not up for debate.\n> \n> Cool, thanks for the reply. However, I debate... :-)\n> \n>>   ---o--o--o--o--o--o         <-- origin\n>>                      \\\n>>                       A'--B'  <-- master\n> \n> Nice. That makes sense in your scenario.\n> \n> Here is mine:\n> \n>  ---A--B--C--D           <-- origin/stable\n>      \\       |\n>       E--F   |           <-- origin/topica\n>           \\  |\n>              g--h        <-- topica\n> \n> All the upper case commits have been published to origin. Other\n> devs, etc., know about them, their hashes are in the bug tracking\n> system.\n> \n> I'm bringing topica up to date, but with a merge because I have\n> published history already on topica, so I merge stable and get a\n> new merge commit: g. And maybe make another change: h.\n> \n\nWhy do you merge stable at this point?\n\nIf you want the latest and greatest for testing/conflict resolution\npurposes, you can simply throw away the merge later and just know\nthat it works.\nIf you need some bugfix on stable but not everything else, cherrypick\nonly that change. Otherwise you're applying a huge patch to fix a\nsmall problem.\n\n> Everything's cool...now, with surprising frequency, someone beats\n> me to moving origin/topica:\n> \n>  ---A--B--C--D           <-- origin/stable\n>      \\       |\n>       E--F---|--I        <-- origin/topica\n>           \\  |\n>              g--h        <-- topica\n> \n> Pushing h gets rejected as a rewind. Good. I want to pull, which\n> we had previously always used \"--rebase\" for, and the desired output\n> of a pull --rebase, to me, would be:\n> \n>  ---A--B--C--D           <-- origin/stable\n>      \\        \\\n>       E--F--I |          <-- origin/topica\n>              \\|\n>               g'--h'     <-- topica\n> \n> Instead, I get:\n> \n>  ---A--B--C--D           <-- origin/stable\n>      \\\n>       E--F--I            <-- origin/topica\n>              \\\n>               B'-C'-D'-h'<-- topica\n> \n> So, yes, linearized history with no merges. However, this leads\n> to quizzical looks when B'/C'/D' hit the email list, bug tracker, etc.\n> as new commits.\n> \n> Currently I just try to pull/merge/push in quick succession, but\n> it's a manual collaboration hack (\"okay, I'm merging now, no\n> committing...\") that would be nice to not have to worry about.\n> \n\nI think you just need to ask yourself *why* you're doing that\nfirst merge of \"stable\" into your topic. If they aren't really\nseparate, using a topic-branch doesn't make so much sense. If\nthey *are* separate, doing the merge doesn't make much sense,\nunless you're integration testing a snapshot build, but in that\ncase you'd want to throw away the merge once it's done and\ntested.\n\n> I need to investigate the interactive rebase more, but my hesitant\n> assertion is that it's parent rewriting seems smart enough to handle\n> this. Perhaps not, and I admit our desired DAG output may not be\n> attainable without manual intervention.\n> \n> I apologize--I should have included the example DAGs in my first\n> post, but since I didn't I felt the need to clarify. So, humoring\n> me, is the B'/C'/D' from this example really the expected behavior?\n> \n\nAssuming the person who did \"h\" doesn't have the merge commit, then\nyes.\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"91370","messageId":"20080923040302.c4d0d33b.stephen@exigencecorp.com","threadId":"15628","inReplyTo":"48D8A6EA.4020805@op5.se","subject":"Re: rebasing merges","fromName":"Stephen Haberman","fromEmail":"stephen@exigencecorp.com","sentAt":"2008-09-23T09:03:02Z","receivedAt":"2008-09-23T09:03:02Z","isPatch":false,"sender":{"key":"stephen@exigencecorp.com","avatar":"https://gravatar.com/avatar/23b93ad70a06ce53505f17ddba65176edbcfb6588e7a4c1a2dca04aaf0a6aff1?d=mp&s=160"},"body":"\n> >  ---A--B--C--D           <-- origin/stable\n> >      \\       |\n> >       E--F   |           <-- origin/topica\n> >           \\  |\n> >              g--h        <-- topica\n> > \n> > All the upper case commits have been published to origin. Other\n> > devs, etc., know about them, their hashes are in the bug tracking\n> > system.\n> > \n> > I'm bringing topica up to date, but with a merge because I have\n> > published history already on topica, so I merge stable and get a\n> > new merge commit: g. And maybe make another change: h.\n> > \n> \n> Why do you merge stable at this point?\n\nGood question--I appreciate the sanity check.\n\nI merged stable because we had a new release of the software. E.g.\nA=1.0, B=1.1, C=1.2, and finally D=1.3.\n\nSo, topica is a new feature, \"Add widgets/whatever\", but it's not ready\nfor stable (production) yet, so, yes, I think it is a topic branch.\n\nHowever, D=1.4 is now out the door, I've had two commits E and F on\ntopica that I had already committed and pushed out for code review, our\nemail list, and our bug tracker, and now, post-1.4, qa wants to see\ntopica up and running to see if it's good enough to go into the next\nrelease.\n\nIf our deployment guy pushes out F, qa is going to (and did) complain\nthat they're not seeing the latest features from 1.4 in topica.\n\nAs you said, integration testing.\n\nOkay, so I merge g, however, I really want to push it back out so that\nthe deployment guy can push it to qa (he would rather not resolve my\nconflicts by making his own local g). And even if I did the deployment\nmyself, locally against g, I would prefer to share g in case another\ndev working on the same topic gets feedback about funkiness from qa and\nwould like to see the code as it is in qa. E.g.: g.\n\nI can appreciate that if I was doing integration testing all by myself,\nwith only automated tests, I could throw g away. However, even then, I\nwould prefer to push g out and let our integration server run the tests\nfor me.\n\nDoes this sound reasonable?\n\nThanks,\nStephen\n"},{"id":"91371","messageId":"48D8B2C1.5070800@op5.se","threadId":"15628","inReplyTo":"20080923040302.c4d0d33b.stephen@exigencecorp.com","subject":"Re: rebasing merges","fromName":"Andreas Ericsson","fromEmail":"ae@op5.se","sentAt":"2008-09-23T09:11:29Z","receivedAt":"2008-09-23T09:11:29Z","isPatch":false,"sender":{"key":"ae@op5.se","avatar":"https://gravatar.com/avatar/426e89595c75a8f5252dd0c989e5fabe5bcac616e68557427ad9aef6b0ca342a?d=mp&s=160"},"body":"Stephen Haberman wrote:\n>>>  ---A--B--C--D           <-- origin/stable\n>>>      \\       |\n>>>       E--F   |           <-- origin/topica\n>>>           \\  |\n>>>              g--h        <-- topica\n>>>\n>>> All the upper case commits have been published to origin. Other\n>>> devs, etc., know about them, their hashes are in the bug tracking\n>>> system.\n>>>\n>>> I'm bringing topica up to date, but with a merge because I have\n>>> published history already on topica, so I merge stable and get a\n>>> new merge commit: g. And maybe make another change: h.\n>>>\n>> Why do you merge stable at this point?\n> \n> Good question--I appreciate the sanity check.\n> \n> I merged stable because we had a new release of the software. E.g.\n> A=1.0, B=1.1, C=1.2, and finally D=1.3.\n> \n> So, topica is a new feature, \"Add widgets/whatever\", but it's not ready\n> for stable (production) yet, so, yes, I think it is a topic branch.\n> \n> However, D=1.4 is now out the door, I've had two commits E and F on\n> topica that I had already committed and pushed out for code review, our\n> email list, and our bug tracker, and now, post-1.4, qa wants to see\n> topica up and running to see if it's good enough to go into the next\n> release.\n> \n> If our deployment guy pushes out F, qa is going to (and did) complain\n> that they're not seeing the latest features from 1.4 in topica.\n> \n> As you said, integration testing.\n> \n> Okay, so I merge g, however, I really want to push it back out so that\n> the deployment guy can push it to qa (he would rather not resolve my\n> conflicts by making his own local g). And even if I did the deployment\n> myself, locally against g, I would prefer to share g in case another\n> dev working on the same topic gets feedback about funkiness from qa and\n> would like to see the code as it is in qa. E.g.: g.\n> \n> I can appreciate that if I was doing integration testing all by myself,\n> with only automated tests, I could throw g away. However, even then, I\n> would prefer to push g out and let our integration server run the tests\n> for me.\n> \n> Does this sound reasonable?\n> \n\nIt sounds very reasonable indeed, but then I don't understand why you\nheld off pushing the merge.\n\nThat's beside the point though, as I firmly believe git should be more\nhelpful in this situation. If \"git rebase -i -p\" doesn't help you fix\nthe problems, I'll see what I can do to help.\n\n-- \nAndreas Ericsson                   andreas.ericsson@op5.se\nOP5 AB                             www.op5.se\nTel: +46 8-230225                  Fax: +46 8-230231\n"},{"id":"91372","messageId":"20080923043039.bf380694.stephen@exigencecorp.com","threadId":"15628","inReplyTo":"48D8B2C1.5070800@op5.se","subject":"Re: rebasing merges","fromName":"Stephen Haberman","fromEmail":"stephen@exigencecorp.com","sentAt":"2008-09-23T09:30:39Z","receivedAt":"2008-09-23T09:30:39Z","isPatch":false,"sender":{"key":"stephen@exigencecorp.com","avatar":"https://gravatar.com/avatar/23b93ad70a06ce53505f17ddba65176edbcfb6588e7a4c1a2dca04aaf0a6aff1?d=mp&s=160"},"body":"\n> > Does this sound reasonable?\n> \n> It sounds very reasonable indeed\n\nAh, cool, thanks for validating our approach. We have so far been\nslowly figuring it out and it has been nice.\n\n> but then I don't understand why you held off pushing the merge.\n\nAh, yes, that is the trick, to get it out quickly. Usually it is not a\nproblem, but in ~2-3 months of using git, it's happened on high-churn\nbranches about 4-5 times (usually it is the next release candidate\nbranch where people are actively making small bug fixes and one guy\ngets caught with a non-trivial merge in from stable).\n\nNot all that bad, really, other than it caused a few \"wtf git\"\ncomments. Which is unfortunate as, while I enjoy git, the team as a\nwhole is still learning. Seeing the DAGs, and understanding the\npatch/apply approach of the non-interactive rebase, it makes sense to\nme what git is doing. And so while I know to watch for it, I'm trying to\nfind a more bullet proof approach.\n\n> That's beside the point though, as I firmly believe git should be more\n> helpful in this situation. If \"git rebase -i -p\" doesn't help you fix\n> the problems, I'll see what I can do to help.\n\nThat's very cool, thanks. I'll start writing a test now.\n\n- Stephen\n"},{"id":"91378","messageId":"20080923111624.GA20259@neumann","threadId":"15628","inReplyTo":"48D8B2C1.5070800@op5.se","subject":"Re: rebasing merges","fromName":"SZEDER Gábor","fromEmail":"szeder@ira.uka.de","sentAt":"2008-09-23T11:16:24Z","receivedAt":"2008-09-23T11:16:24Z","isPatch":false,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"Hi,\n\nOn Tue, Sep 23, 2008 at 11:11:29AM +0200, Andreas Ericsson wrote:\n> That's beside the point though, as I firmly believe git should be more\n> helpful in this situation. If \"git rebase -i -p\" doesn't help you fix\n> the problems, I'll see what I can do to help.\nI will just throw in an other workflow, where keeping merges during\n(non-interactive) rebase would be really helpful for me.\n\nThe DAG looks like this:\n\n  -A--------------H    master\n    \\\n     B--C------F--G    topic\n         \\    /\n          D--E         subtopic\n\nI develop a new feature in my private repository on branch 'topic'.\nEvery now and then there are two or more commits that somehow belong\ntogether (e.g. a refactoring consisting of multiple commits).  I\nprefer having this \"belong together\" information explicitly in the\nrepository, therefore for these commits (D and E) I create the new\nbranch 'subtopic' that will be merged back into 'topic' (with\n--no-ff).  This way I can see in the logs or in gitk explicitly that\nthose commits belong together.  While working on a bigger feature\nthere might be multiple 'subtopic' branches that get merged back into\n'topic'.\n\nBut now I can't rebase 'topic' on top of master, because rebase would\nlinearize the history, losing the subtopic merges.\n\n\nBest,\nGábor\n"},{"id":"91412","messageId":"20080923132916.b9603658.stephen@exigencecorp.com","threadId":"15628","inReplyTo":"20080923043039.bf380694.stephen@exigencecorp.com","subject":"Re: rebasing merges","fromName":"Stephen Haberman","fromEmail":"stephen@exigencecorp.com","sentAt":"2008-09-23T18:29:16Z","receivedAt":"2008-09-23T18:29:16Z","isPatch":false,"sender":{"key":"stephen@exigencecorp.com","avatar":"https://gravatar.com/avatar/23b93ad70a06ce53505f17ddba65176edbcfb6588e7a4c1a2dca04aaf0a6aff1?d=mp&s=160"},"body":"\n> > That's beside the point though, as I firmly believe git should be more\n> > helpful in this situation. If \"git rebase -i -p\" doesn't help you fix\n> > the problems, I'll see what I can do to help.\n> \n> That's very cool, thanks. I'll start writing a test now.\n\nI've attached a test. You were both correct, `git rebase -i -p` keeps\nthe merge intact and doesn't duplicate the commits. This is awesome.\n\nSo, I'm wondering what the best way to integrate this into our workflow\nis. Ideally, I think it would be great to just do:\n\n    git pull --rebase --preserve-merges\n\nOr even better just `git pull` with branch.x.rebase=true and\nbranch.x.preserve-merges=true property (throw in a\nbranch.autosetuppreservemerges and I'll be set, haha).\n\nWhile `git fetch + git rebase -i -p` will work every time, it won't be\nfun to have the editor pop open, just exit it because we're not really\ndoing an interactive rebase, we're just borrowing its more powerful\nrebase implementation, and repeat this each time a dev wants to do a\npull. Or, tell them to do a \"git pull --rebase\" most of the time, until\nit screws up, then back up and do the other. Both doable, but not ideal.\n\nI understand Johannes's scenario of rebasing the entire branch, and it\nlooks like rebase--interactive already supports this as well--e.g. if\nyou pass `-p`, you get our desired behavior, and if you don't pass `-p`,\nyou get Johannes's desired behavior of merge squashing.\n\nGiven rebase--interactive seems to be a superset of the current rebase\nimplementation, could the current rebase implementation just go away and\ninstead become a non-interactive caller (e.g. just avoid popping up the\neditor with the pick list) of rebase--interactive's more powerful\nrebase logic?\n\n(Disclaimer: I'm throwing the term \"more powerful\" around without really\nknowing whether that is true or not--for our scenario, it seems that\nway, but there could be other cases I don't know about where the current\nrebase implementation is superior to rebase--interactive's.)\n\nThanks,\nStephen\n\n\n\n#!/bin/sh\n#\n# Copyright (c) 2005 Amos Waterland\n#\n\ntest_description='git rebase should not destroy author information\n\nThis test runs git rebase and checks that the author information is not lost.\n'\n. ./test-lib.sh\n\nGIT_AUTHOR_EMAIL=bogus_email_address\nexport GIT_AUTHOR_EMAIL\n\necho 'Setting up:\n\nA1--A2  <-- origin/master\n \\   \\\n  B1--M  <-- topic\n   \\\n    B2  <-- origin/topic\n\n'\n\ntest_expect_success 'prepare repository with topic branches' \\\n    'echo First > A &&\n     git add A &&\n     git-commit -m \"Add A1\" &&\n     git checkout -b topic &&\n     echo Second > B &&\n     git add B &&\n     git-commit -m \"Add B1\" &&\n     git checkout -f master &&\n     echo Third >> A &&\n     git-commit -a -m \"Modify A2\" &&\n\n     git clone ./. clone1 &&\n     cd clone1 &&\n     git checkout -b topic origin/topic &&\n     git merge origin/master &&\n     cd ..\n\n     git clone ./. clone2\n     cd clone2 &&\n     git checkout -b topic origin/topic &&\n     git merge origin/master &&\n     cd .. &&\n\n     git checkout topic &&\n     echo Fourth >> B &&\n     git commit -a -m \"Modify B2\"\n'\n\n# Blatant copy/paste from t3404-rebase-interactive.sh--needs cleaned up\necho \"#!$SHELL_PATH\" >fake-editor.sh\ncat >> fake-editor.sh <<\\EOF\ncase \"$1\" in\n*/COMMIT_EDITMSG)\n\ttest -z \"$FAKE_COMMIT_MESSAGE\" || echo \"$FAKE_COMMIT_MESSAGE\" > \"$1\"\n\ttest -z \"$FAKE_COMMIT_AMEND\" || echo \"$FAKE_COMMIT_AMEND\" >> \"$1\"\n\texit\n\t;;\nesac\ntest -z \"$EXPECT_COUNT\" ||\n\ttest \"$EXPECT_COUNT\" = $(sed -e '/^#/d' -e '/^$/d' < \"$1\" | wc -l) ||\n\texit\ntest -z \"$FAKE_LINES\" && exit\ngrep -v '^#' < \"$1\" > \"$1\".tmp\nrm -f \"$1\"\ncat \"$1\".tmp\naction=pick\nfor line in $FAKE_LINES; do\n\tcase $line in\n\tsquash|edit)\n\t\taction=\"$line\";;\n\t*)\n\t\techo sed -n \"${line}s/^pick/$action/p\"\n\t\tsed -n \"${line}p\" < \"$1\".tmp\n\t\tsed -n \"${line}s/^pick/$action/p\" < \"$1\".tmp >> \"$1\"\n\t\taction=pick;;\n\tesac\ndone\nEOF\n\ntest_set_editor \"$(pwd)/fake-editor.sh\"\nchmod a+x fake-editor.sh\n\ntest_expect_failure 'rebase merge on moved topic' '\n     cd clone1 &&\n     git pull --rebase &&\n     test $(git rev-list --all --pretty=oneline | grep \"Modify A\" | wc -l) = 1\n'\n\ntest_expect_success 'rebase -i -p merge on moved topic' '\n     cd ../clone2 &&\n     git fetch &&\n     FAKE_LINES=\"1 2\" git rebase -i -p origin/topic &&\n     test 1 = $(git rev-list --all --pretty=oneline | grep \"Modify A\" | wc -l) &&\n     test 1 = $(git rev-list --all --pretty=oneline | grep \"Merge commit\" | wc -l)\n'\n\ntest_done\n\n"}]}