{"thread":{"id":"18087","subject":"How can I merge some files rather than all files modified on one branch to my branch?","startedAt":"2009-03-02T09:19:05Z","lastAt":"2009-03-04T00:10:40Z","messageCount":5,"participants":["Emily Ren","Junio C Hamano","Boyd Stephen Smith Jr.","Nicolas Sebrecht"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"106684","messageId":"856bfe0e0903020119y68188a39m90c683949220b2f@mail.gmail.com","threadId":"18087","inReplyTo":null,"subject":"How can I merge some files rather than all files modified on one branch to my branch?","fromName":"Emily Ren","fromEmail":"lingyan.ren@gmail.com","sentAt":"2009-03-02T09:19:05Z","receivedAt":"2009-03-02T09:19:05Z","isPatch":false,"sender":{"key":"lingyan.ren@gmail.com","avatar":null},"body":"Hi,\n\nI want to merge some files rather than all files modified on one\nbranch to my branch, how can I do?\n\nThanks,\nEmily\n"},{"id":"106688","messageId":"7v1vtgnsuk.fsf@gitster.siamese.dyndns.org","threadId":"18087","inReplyTo":"856bfe0e0903020119y68188a39m90c683949220b2f@mail.gmail.com","subject":"Re: How can I merge some files rather than all files modified on one branch to my branch?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-02T10:04:35Z","receivedAt":"2009-03-02T10:04:35Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Ren <lingyan.ren@gmail.com> writes:\n\n> I want to merge some files rather than all files modified on one\n> branch to my branch, how can I do?\n\nIn general, you do not want to, simply because the result is not really a\nmerge.\n\nYou are rejecting one of the two primary advantages git brings over other\ntraditional systems: merge tracking [*1*]..\n\nBut if you really wanted to, here is how.\n\nSuppose you are on branch A, and if you merged branch B in a natural way\nit would bring in changes to file1 and file2.  But you do not want any\nchange to file2.  You can do this:\n\n (1) Start from a clean state.  No uncommitted changes (if you have some,\n     stash them away first).  Merge the branch the usual way:\n\n     $ git merge B\n\n (2) (1) may get conflicts in file1 and/or file2.  Resolve the conflicts\n     only in the file(s) you are interested in (in this example file1).\n     Ignore conflicts in files you do not want to get changed in this\n     merge.  And then conclude the merge with:\n\n     $  git commit -a\n\n     This step is necessary only if (1) does not cleanly merge; otherwise\n     it would have created a merge commit already.\n\n (3) You did not want changes to certain paths (in this example, file2) in\n     the \"merge\", but we recorded such change in the previous step, so you\n     amend it.  At this point HEAD is the merge you created, and HEAD^ is\n     before you started the merge.  You want the contents of file2 before\n     the merge happened, i.e. from HEAD^:\n\n     $ git checkout HEAD^ file2\n     $ git commit --amend\n\nThe result would record a \"merge\" that ignores what B did to file2.\n\nThe reason you do not want to do this is because git tracks merges.\n\nSuppose you have this topology:\n\n             A---M\n            /   /\n    ---o---C---B\n\nA is where you were before this \"merge\", B is the other branch, and M is\nthe result of the \"merge\".\n\nNow, suppose branch B later improves on what it has done, and now what the\nbranch has is satisfactory for your needs.  There is no reason you would\nnot want to have any of its improvements.  You try to merge again.\n\n             A---M-----------?\n            /   /           /\n    ---o---C---B---D---E---F\n\nBecause you declared (when you made the \"merge\" at M) that anything B did\nto file2 was unwanted to your branch, git remembers that declaration.  The\ninformation is used when computing the merge between M and F.  That is\nwhat merge tracking is.\n\nPerhaps changes to file2 when you inspected B were not good enough, but\nwith improvements made in D, E and/or F it may now be perfect.  But you\nare denying to take this whole sequence of changes, and the merge you\nwould create between M and F will have only what D/E/F did to file2;\nit won't contain what B did.  That makes the sequence of changes B-D-E-F\ndid to file2 incomplete and inconsistent.\n\nIf you are lucky, it will result in huge conflicts and you will notice the\nsituation.  But if you are not lucky, it may merge cleanly, but because\nD/E/F builds on top of what B did, which possibly was half-baked back\nthen, for the merge result to work as well as F does, you need to have\nwhat B did.  But you won't have it, because you already rejected it at M.\n\nTwo advises are:\n\n (1) To avoid problems in future merges, do not record the result as a\n     \"merge\". You want to cherry-pick partially; in other words, you would\n     want to record this topology when you create this \"merge\" (which is\n     not a merge):\n\n             A---M\n            /\n    ---o---C---B\n\n    with the same tree as you would have recorded in the first picture.\n    For that, I think you could run \"git merge --squash B\" in step (1) in\n    the main part of this message.\n\n (2) More importantly, your wish to take only one but not the other part\n     of B is a strong indication that the branch B is doing too many\n     things, either in a single commit or either on a single branch or\n     both. Separate these distinct bits into different topic branches so\n     that each individual bits can be independently merged to other\n     branches.\n\n[Footnote]\n\n*1* The other advantage is distributedness, which is \"separation between\nthe act of committing and the act of publishing\".\n"},{"id":"106752","messageId":"200903022110.23207.bss@iguanasuicide.net","threadId":"18087","inReplyTo":"856bfe0e0903020119y68188a39m90c683949220b2f@mail.gmail.com","subject":"Re: How can I merge some files rather than all files modified on one branch to my branch?","fromName":"Boyd Stephen Smith Jr.","fromEmail":"bss@iguanasuicide.net","sentAt":"2009-03-03T03:10:17Z","receivedAt":"2009-03-03T03:10:17Z","isPatch":false,"sender":{"key":"bss@iguanasuicide.net","avatar":"https://gravatar.com/avatar/84b95eeff194b816c1568b1339e63e4b229825298664a9037b9f1ec713ead1e3?d=mp&s=160"},"body":"On Monday 02 March 2009 03:19:05 Emily Ren wrote:\n> I want to merge some files rather than all files modified on one\n> branch to my branch, how can I do?\n\nIn addition to what Junio suggested, I'll offer another method, assuming the \nbranch you are merging from is not yet published:\n(1) Rewrite the history of the to-be-merged branch so that all the changes to \nthe files you want occur \"before\" and in separate commits from the file you \nwant to ignore.  So the current tree:\n\nA-->B-->C (yours)\n \\\n  ->D-->E (theirs)\n\nbecomes:\n\nA-->B-->C (yours)\n \\\n  ->D1-->E1-->D2-->E2 (theirs)\n\nwith D1 and D2 being the separate parts of commit D and similarly for E1 and \nE2.\n\n(2) Merge in the rewritten history, but only the part that you want, giving:\n\nA-->B-->C--->F (yours)\n \\         /\n  ->D1-->E1-->D2-->E2 (theirs)\n\nThis preserves the full intent of what you are trying to do, a partial merge.  \nIf you merge \"theirs\" in fully at some point in the future, you shouldn't see \nany conflicts arising from not recording the merge or missing changes arising \nfrom recording a full merge that did not happen.\n-- \nBoyd Stephen Smith Jr.                   ,= ,-_-. =.\nbss@iguanasuicide.net                   ((_/)o o(\\_))\nICQ: 514984 YM/AIM: DaTwinkDaddy         `-'(. .)`-'\nhttp://iguanasuicide.net/                    \\_/\n\n"},{"id":"106753","messageId":"856bfe0e0903021956l549e41d2l97d7e0997067c133@mail.gmail.com","threadId":"18087","inReplyTo":"200903022110.23207.bss@iguanasuicide.net","subject":"Re: How can I merge some files rather than all files modified on one branch to my branch?","fromName":"Emily Ren","fromEmail":"lingyan.ren@gmail.com","sentAt":"2009-03-03T03:56:03Z","receivedAt":"2009-03-03T03:56:03Z","isPatch":false,"sender":{"key":"lingyan.ren@gmail.com","avatar":null},"body":"Junio and Boyd,\n\nThank you very much for your kindly guide ! I'll try these method.\n\nBoyd,\nHow to rewrite the history of the branch ?\n\nThanks,\nEmily\n\nOn Tue, Mar 3, 2009 at 11:10 AM, Boyd Stephen Smith Jr.\n<bss@iguanasuicide.net> wrote:\n> On Monday 02 March 2009 03:19:05 Emily Ren wrote:\n>> I want to merge some files rather than all files modified on one\n>> branch to my branch, how can I do?\n>\n> In addition to what Junio suggested, I'll offer another method, assuming the\n> branch you are merging from is not yet published:\n> (1) Rewrite the history of the to-be-merged branch so that all the changes to\n> the files you want occur \"before\" and in separate commits from the file you\n> want to ignore.  So the current tree:\n>\n> A-->B-->C (yours)\n>  \\\n>  ->D-->E (theirs)\n>\n> becomes:\n>\n> A-->B-->C (yours)\n>  \\\n>  ->D1-->E1-->D2-->E2 (theirs)\n>\n> with D1 and D2 being the separate parts of commit D and similarly for E1 and\n> E2.\n>\n> (2) Merge in the rewritten history, but only the part that you want, giving:\n>\n> A-->B-->C--->F (yours)\n>  \\         /\n>  ->D1-->E1-->D2-->E2 (theirs)\n>\n> This preserves the full intent of what you are trying to do, a partial merge.\n> If you merge \"theirs\" in fully at some point in the future, you shouldn't see\n> any conflicts arising from not recording the merge or missing changes arising\n> from recording a full merge that did not happen.\n> --\n> Boyd Stephen Smith Jr.                   ,= ,-_-. =.\n> bss@iguanasuicide.net                   ((_/)o o(\\_))\n> ICQ: 514984 YM/AIM: DaTwinkDaddy         `-'(. .)`-'\n> http://iguanasuicide.net/                    \\_/\n>\n>\n"},{"id":"106937","messageId":"20090304001040.GA13040@vidovic","threadId":"18087","inReplyTo":"856bfe0e0903021956l549e41d2l97d7e0997067c133@mail.gmail.com","subject":"Re: How can I merge some files rather than all files modified on one branch to my branch?","fromName":"Nicolas Sebrecht","fromEmail":"nicolas.s-dev@laposte.net","sentAt":"2009-03-04T00:10:40Z","receivedAt":"2009-03-04T00:10:40Z","isPatch":false,"sender":{"key":"nicolas.s-dev@laposte.net","avatar":null},"body":"\nOn Tue, Mar 03, 2009 at 11:56:03AM +0800, Emily Ren wrote:\n\n> Boyd,\n> How to rewrite the history of the branch ?\n\nhttp://www.kernel.org/pub/software/scm/git/docs/user-manual.html#cleaning-up-history\n\n-- \nNicolas Sebrecht\n"}]}