{"thread":{"id":"30238","subject":"Merging changes from branches where file paths have changed","startedAt":"2012-04-14T13:15:38Z","lastAt":"2012-04-14T19:49:46Z","messageCount":4,"participants":["Thomas Adam","Johannes Sixt"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"189260","messageId":"CA+39Oz7m1hGrTEdpSAjBP3EDFSVyKdc6T9CORcwQkjuEbvD4Ug@mail.gmail.com","threadId":"30238","inReplyTo":null,"subject":"Merging changes from branches where file paths have changed","fromName":"Thomas Adam","fromEmail":"thomas.adam22@gmail.com","sentAt":"2012-04-14T13:15:38Z","receivedAt":"2012-04-14T13:15:38Z","isPatch":false,"sender":{"key":"thomas.adam22@gmail.com","avatar":"https://gravatar.com/avatar/137f9858bc6bfd5b2f743aefd988c81ce0cbd306248889df80e269519cfc8741?d=mp&s=160"},"body":"Hi all,\n\nI've got two git repositories -- for the purposes of illustration,\nI'll call them RepoA, and RepoB.  RepoA is a large repository\noriginally from a CVS conversion.  Repo B is a repository which has\nbeen formed from git-filter-branch (should it matter) from RepoA.\n\nIn doing the conversion -- RepoB contains the same history as in\nRepoA, except that RepoB is now a limited subset in terms of its files\nthat RepoA has (repoB contains commits out of repoA for a specific\nsubdirectory).   However, the problem I'm wanting to solve now, which\nis causing me to scratch my head and go \"hmm\", is how I go about\nmerging commits from RepoA and have them in RepoB -- where the commits\nfrom repoA are in the same *directory* as the one which formed RepoB.\n\nIn RepoA, for the directory (and all its sub-directories) which is\ncontained in RepoB, I've got a list of commits -- roughly like the\nfollowing:\n\n% cd ./distrib/build/sources/coretree/tree\n% git log --oneline master..my/topic/branch -- .\n\nNow in RepoB, I've got all of the directories and files from\n./distrib/build/sources/coretree/tree/ in the root, having obtained\nthis from git-filter-branch from RepoA.  Despite the change of file\nlocations, the history of the files between the two repositories are\nthe same.\n\nThe commits though coming from \"git log\" in RepoA touch files in\ndistrib/build/sources/coretree/tree, yet the files to which I want the\nchanges for in RepoB are not in \"distrib/build/sources/coretree/tree\"\n-- there all in \"./\" at the top-level directory for RepoB.  The files\nin both once shared the same history -- it's just that now the\nlocations of those files in RepoB which have changed.\n\nI want to cherry-pick the commits I obtained from the \"git log\"\ncommand in RepoA, and have them contained in RepoB.  So I thought\nsomething like this would work:\n\n[ In RepoB.... ]:\n% git remote add repoA file:///path/to/repoA/\n% git fetch repoA\n% git checkout specific/branch\n% git cherry-pick $SOME_COMMIT_FROM_REPOA\n\nHowever, this won't work, and doesn't.  Not only do the two\nrepositories not have any common ancestry, but even if they did, the\nfile paths from RepoA and RepoB do not match for the commit(s) I would\nwant to cherry-pick.  As far as I can tell, were I able to convince\nGit the file paths did work, then I could cherry-pick them.\n\nCan anyone suggest a good way round this?  I hope I've managed to\nexplain this adequately; just ask if not.\n\nThanks in Advance.\n\n-- Thomas Adam\n"},{"id":"189277","messageId":"4F89CE36.4000607@kdbg.org","threadId":"30238","inReplyTo":"CA+39Oz7m1hGrTEdpSAjBP3EDFSVyKdc6T9CORcwQkjuEbvD4Ug@mail.gmail.com","subject":"Re: Merging changes from branches where file paths have changed","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2012-04-14T19:21:26Z","receivedAt":"2012-04-14T19:21:26Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 14.04.2012 15:15, schrieb Thomas Adam:\n> The commits though coming from \"git log\" in RepoA touch files in\n> distrib/build/sources/coretree/tree, yet the files to which I want the\n> changes for in RepoB are not in \"distrib/build/sources/coretree/tree\"\n> -- there all in \"./\" at the top-level directory for RepoB.  The files\n> in both once shared the same history -- it's just that now the\n> locations of those files in RepoB which have changed.\n> \n> I want to cherry-pick the commits I obtained from the \"git log\"\n> command in RepoA, and have them contained in RepoB.  So I thought\n> something like this would work:\n> \n> [ In RepoB.... ]:\n> % git remote add repoA file:///path/to/repoA/\n> % git fetch repoA\n> % git checkout specific/branch\n> % git cherry-pick $SOME_COMMIT_FROM_REPOA\n\nYou have these histories\n\n\n  A--o--B--C--o--o--D--o--E   <- RepoA\n\n  A'----B'-C'                 <- RepoB\n\nand you want to cherry-pick D and E to RepoB. Right?\n\nI suggest that you install a graft in RepoB, then cherry-pick D and E:\n\n  echo $(git rev-parse C' C) >> .git/info/grafts\n  git cherry-pick D\n  git cherry-pick E\n\nThen it will look as if everything outside the directory was removed,\nand everything else was moved from the directory to the root with 100%\nsimilarity, which makes the merge process easy. (This works only if\nthere are no files with the same names in C's and C''s root; a Makefile\nin each would pose a problem.)\n\n(Remove the graft when you're done.)\n\n-- Hannes\n"},{"id":"189279","messageId":"CA+39Oz5Jc8Tj6WX+836h_fA6qHDYp6guaoniF6LX027MFHhP0A@mail.gmail.com","threadId":"30238","inReplyTo":"4F89CE36.4000607@kdbg.org","subject":"Re: Merging changes from branches where file paths have changed","fromName":"Thomas Adam","fromEmail":"thomas.adam22@gmail.com","sentAt":"2012-04-14T19:36:13Z","receivedAt":"2012-04-14T19:36:13Z","isPatch":false,"sender":{"key":"thomas.adam22@gmail.com","avatar":"https://gravatar.com/avatar/137f9858bc6bfd5b2f743aefd988c81ce0cbd306248889df80e269519cfc8741?d=mp&s=160"},"body":"Hello,\n\nOn 14 April 2012 20:21, Johannes Sixt <j6t@kdbg.org> wrote:\n> You have these histories\n>\n>\n>  A--o--B--C--o--o--D--o--E   <- RepoA\n>\n>  A'----B'-C'                 <- RepoB\n>\n> and you want to cherry-pick D and E to RepoB. Right?\n\nYes, that's about right.\n\n> I suggest that you install a graft in RepoB, then cherry-pick D and E:\n>\n>  echo $(git rev-parse C' C) >> .git/info/grafts\n\nCan you elaborate on this a little more please?  Or point me towards\nsome documentation.  Note that due to the way git-filter-branch works,\nalthough the history between RepoA and RepoB are common, the commit\nIDs between the two are completely different; presumably\ngit-filter-branch uses patch-id at some level to reform commits.\nNevertheless, if I'm understanding superficially what this graft is\nsupposed to do, I do not see how getting a list of commits from C' to\nC is going to help in repoB when neither RepoA or RepoB have any\nancestry in common?\n\nKindly,\n\n-- Thomas Adam\n"},{"id":"189282","messageId":"4F89D4DA.8010407@kdbg.org","threadId":"30238","inReplyTo":"CA+39Oz5Jc8Tj6WX+836h_fA6qHDYp6guaoniF6LX027MFHhP0A@mail.gmail.com","subject":"Re: Merging changes from branches where file paths have changed","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2012-04-14T19:49:46Z","receivedAt":"2012-04-14T19:49:46Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 14.04.2012 21:36, schrieb Thomas Adam:\n> Hello,\n> \n> On 14 April 2012 20:21, Johannes Sixt <j6t@kdbg.org> wrote:\n>> You have these histories\n>>\n>>\n>>  A--o--B--C--o--o--D--o--E   <- RepoA\n>>\n>>  A'----B'-C'                 <- RepoB\n>>\n>> and you want to cherry-pick D and E to RepoB. Right?\n> \n> Yes, that's about right.\n> \n>> I suggest that you install a graft in RepoB, then cherry-pick D and E:\n>>\n>>  echo $(git rev-parse C' C) >> .git/info/grafts\n> \n> Can you elaborate on this a little more please?  Or point me towards\n> some documentation.  Note that due to the way git-filter-branch works,\n> although the history between RepoA and RepoB are common, the commit\n> IDs between the two are completely different; presumably\n> git-filter-branch uses patch-id at some level to reform commits.\n> Nevertheless, if I'm understanding superficially what this graft is\n> supposed to do, I do not see how getting a list of commits from C' to\n> C is going to help in repoB when neither RepoA or RepoB have any\n> ancestry in common?\n\nThere is no \"list of commits from C' to C\". Look carefully: it's\nrev-parse, not rev-list. The command above only states that the (only)\nparent of C' is C, i.e., it fakes this history:\n\n  A--o--B--C--o--o--D--o--E   <- RepoA\n            \\\n             C'               <- RepoB\n\nand then the two repositories have history in common.\n\nAnd BTW:\n\n1. C' must be the top-most commit that was derived from RepoA.\n\n2. If D or E add new paths, they will not be moved to the root by the\ncherry-pick. Be sure to check the result.\n\n3. If you have additional commits in RepoB that were not derived from\nRepoA, it may not work out as smoothly, if the changes are so large that\nrename detection does not kick in anymore.\n\n-- Hannes\n"}]}