{"thread":{"id":"20347","subject":"Subtree merging of sub-directories between repositories?","startedAt":"2009-08-02T06:37:01Z","lastAt":"2009-08-02T18:53:31Z","messageCount":4,"participants":["skillzero@gmail.com","Avery Pennarun"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"119376","messageId":"2729632a0908012337l6d84ba76o81239d324ba11cf2@mail.gmail.com","threadId":"20347","inReplyTo":null,"subject":"Subtree merging of sub-directories between repositories?","fromName":"","fromEmail":"skillzero@gmail.com","sentAt":"2009-08-02T06:37:01Z","receivedAt":"2009-08-02T06:37:01Z","isPatch":false,"sender":{"key":"skillzero@gmail.com","avatar":null},"body":"Is it possible to use the subtree merge strategy to import just one\ndirectory from a repository into a directory of a different\nrepository? The subtree merge example describes bringing in an entire\nrepository as a directory, but I'm not sure how to adapt that to just\nimport part of the source repository. The repositories are completely\ndifferent, but repository A has a couple directories I want to import\ninto repository B (along with the history that affected those\ndirectories). I may also make changes on either side and it would be\nnice to be able to re-merge in either direction.\n\nI was thinking I might need something like the git-subtree script, but\nmaybe this can be done with standard git commands?\n"},{"id":"119380","messageId":"32541b130908020130q11f1fa03yca276ab86c2ea4d5@mail.gmail.com","threadId":"20347","inReplyTo":"2729632a0908012337l6d84ba76o81239d324ba11cf2@mail.gmail.com","subject":"Re: Subtree merging of sub-directories between repositories?","fromName":"Avery Pennarun","fromEmail":"apenwarr@gmail.com","sentAt":"2009-08-02T08:30:58Z","receivedAt":"2009-08-02T08:30:58Z","isPatch":false,"sender":{"key":"apenwarr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/20592?v=4"},"body":"On Sun, Aug 2, 2009 at 2:37 AM, <skillzero@gmail.com> wrote:\n> Is it possible to use the subtree merge strategy to import just one\n> directory from a repository into a directory of a different\n> repository? The subtree merge example describes bringing in an entire\n> repository as a directory, but I'm not sure how to adapt that to just\n> import part of the source repository. The repositories are completely\n> different, but repository A has a couple directories I want to import\n> into repository B (along with the history that affected those\n> directories). I may also make changes on either side and it would be\n> nice to be able to re-merge in either direction.\n>\n> I was thinking I might need something like the git-subtree script, but\n> maybe this can be done with standard git commands?\n\ngit tracks the history of the entire tree, not each subtree.  So if\nyou use the existing set of commit objects in A, then you'll pull in\n*all* the files of A.\n\nYou have basically two choices here:\n\n1) Merge the *entire* history of project A into project B, and during\nthe merge, delete the files you don't want.  (This will result in a\nrepo that's about the size of A+B, even if you only keep 1% of the\nfiles, and every change to every file in A will now show up in B's\nhistory.)  Merging future changes from A to B will be relatively easy\n(although you'll get conflicts on those files you deleted), but\nmerging from B back to A will probably make a mess.\n\n2) Use \"git subtree split\" to take the subdir of A and give it a\nhistory of its own, then merge that history into a subdir of B (using\n\"git subtree add\" or any other subtree merge method you want to use).\nYou can then git subtree split/merge back and forth between A and B in\nthe future to copy future changes from one to the other.\n\nThe disadvantage of #2 is that git subtree ends up creating new \"fake\"\ncommit objects for your new shared subproject.  If you merge the new\nsubproject back into A, you'll end up with some duplicate commit\nmessages (unless you use --squash).\n\nHope this helps.\n\nHave fun,\n\nAvery\n"},{"id":"119383","messageId":"2729632a0908021105m10bfb8ddx700464d06fd38023@mail.gmail.com","threadId":"20347","inReplyTo":"32541b130908020130q11f1fa03yca276ab86c2ea4d5@mail.gmail.com","subject":"Re: Subtree merging of sub-directories between repositories?","fromName":"","fromEmail":"skillzero@gmail.com","sentAt":"2009-08-02T18:05:43Z","receivedAt":"2009-08-02T18:05:43Z","isPatch":false,"sender":{"key":"skillzero@gmail.com","avatar":null},"body":"On Sun, Aug 2, 2009 at 1:30 AM, Avery Pennarun<apenwarr@gmail.com> wrote:\n> On Sun, Aug 2, 2009 at 2:37 AM, <skillzero@gmail.com> wrote:\n>> Is it possible to use the subtree merge strategy to import just one\n>> directory from a repository into a directory of a different\n>> repository? The subtree merge example describes bringing in an entire\n>> repository as a directory, but I'm not sure how to adapt that to just\n>> import part of the source repository. The repositories are completely\n>> different, but repository A has a couple directories I want to import\n>> into repository B (along with the history that affected those\n>> directories). I may also make changes on either side and it would be\n>> nice to be able to re-merge in either direction.\n>>\n>> I was thinking I might need something like the git-subtree script, but\n>> maybe this can be done with standard git commands?\n>\n> git tracks the history of the entire tree, not each subtree.  So if\n> you use the existing set of commit objects in A, then you'll pull in\n> *all* the files of A.\n>\n> You have basically two choices here:\n>\n> 1) Merge the *entire* history of project A into project B, and during\n> the merge, delete the files you don't want.  (This will result in a\n> repo that's about the size of A+B, even if you only keep 1% of the\n> files, and every change to every file in A will now show up in B's\n> history.)  Merging future changes from A to B will be relatively easy\n> (although you'll get conflicts on those files you deleted), but\n> merging from B back to A will probably make a mess.\n>\n> 2) Use \"git subtree split\" to take the subdir of A and give it a\n> history of its own, then merge that history into a subdir of B (using\n> \"git subtree add\" or any other subtree merge method you want to use).\n> You can then git subtree split/merge back and forth between A and B in\n> the future to copy future changes from one to the other.\n>\n> The disadvantage of #2 is that git subtree ends up creating new \"fake\"\n> commit objects for your new shared subproject.  If you merge the new\n> subproject back into A, you'll end up with some duplicate commit\n> messages (unless you use --squash).\n\nThanks for the help. I tried #2 and it sort of worked. The history was\nimported, but the resulting paths were flattened. Here's what I did:\n\nFrom repository 1:\ngit subtree split --prefix=A/B/C --rejoin\n... printed commit ID 11f1ef890c49634e822a40a818a6ac88bfc50f07\n\nFrom repository 2:\ngit remote add -f Repo1 /path/to/repo/1\ngit subtree add --prefix=X/Y/C 11f1ef890c49634e822a40a818a6ac88bfc50f07\n\nIf I do 'git log X/Y/C', I only see a single commit:\n\n    Add 'X/Y/C/' from commit '11f1ef890c49634e822a40a818a6ac88bfc50f07'\n\n    git-subtree-dir: X/Y/C\n    git-subtree-mainline: 8b07aa647895aa8a7597dc545821bfd195ecaf7f\n    git-subtree-split: 11f1ef890c49634e822a40a818a6ac88bfc50f07\n\nThe full history doesn't seem to be associated with that directory. If\nI do 'git log --name-only --topo-order', I see the full history, but\nthe files are listed as:\n\nfile.c\n\nand I was expecting to see:\n\nX/Y/C/file.c\n\nBecause I'd want to be able to do 'git log X/Y/C' and see all the\ncommits that affect that directory.\n\nIs there a way to import such that the relative paths are retained? So\nfor the above example, since file.c came from A/B/C/file.c in the\noriginal repository, I'd want it to show up in the log for\nX/Y/C/file.c.\n"},{"id":"119384","messageId":"32541b130908021153j28872a34v84dccfdfbc99b607@mail.gmail.com","threadId":"20347","inReplyTo":"2729632a0908021105m10bfb8ddx700464d06fd38023@mail.gmail.com","subject":"Re: Subtree merging of sub-directories between repositories?","fromName":"Avery Pennarun","fromEmail":"apenwarr@gmail.com","sentAt":"2009-08-02T18:53:31Z","receivedAt":"2009-08-02T18:53:31Z","isPatch":false,"sender":{"key":"apenwarr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/20592?v=4"},"body":"On Sun, Aug 2, 2009 at 2:05 PM, <skillzero@gmail.com> wrote:\n> On Sun, Aug 2, 2009 at 1:30 AM, Avery Pennarun<apenwarr@gmail.com> wrote:\n>> 2) Use \"git subtree split\" to take the subdir of A and give it a\n>> history of its own, then merge that history into a subdir of B (using\n>> \"git subtree add\" or any other subtree merge method you want to use).\n>> You can then git subtree split/merge back and forth between A and B in\n>> the future to copy future changes from one to the other.\n>\n> Thanks for the help. I tried #2 and it sort of worked. The history was\n> imported, but the resulting paths were flattened. Here's what I did:\n[...]\n> The full history doesn't seem to be associated with that directory. If\n> I do 'git log --name-only --topo-order', I see the full history, but\n> the files are listed as:\n>\n> file.c\n>\n> and I was expecting to see:\n>\n> X/Y/C/file.c\n>\n> Because I'd want to be able to do 'git log X/Y/C' and see all the\n> commits that affect that directory.\n\nYeah, this is a tricky one.  Git has all the necessary information to\n\"know\" that the files were \"moved\" from file.c (in the subtree project\nhistory) to X/Y/C.file.c (in your superproject).  But \"git log\"\ndoesn't use this information for anything at the moment, and\n\"--follow\" doesn't seem to make it work.\n\nSince I don't have the required skills or knowledge to fix git's\nhistory following, my hope is that this will magically start working\nin a future version of git because someone like you gets annoyed with\nit :)\n\nHave fun,\n\nAvery\n"}]}