Merge changes from one repo to another with different tree structures

自古美人都是妖i 提交于 2019-12-03 11:22:48

You can split the changes out to the subtree level, and then merge with your other branch:

# from your foo project
git subtree split --prefix=dirA/dirB/ --branch=temp-branch [--onto=<onto-sub-note1>] [<commit-sub-note2>]

onto sub-note 1: It seems like since bar project exists at all, you must have copied it at some point in time, and started this as the new library, in which case, if you want all changes made after that, you'd specify this bar commit id when the changes were brought in.

commit sub-note 2: You'd then want to specify the commit id that was used when you copied the sub-project in the first place, so that you only get the changes since then to merge into the copy of bar you already have (this will maintain the history of what you missed). Use syntax like this to include the commit id itself up to the latest: 0abc210^..

You can also use --rejoin to make a commit back into your foo project, which will make it easier to push changes later if you would like to continue development on bar from withing your foo project. The commit back into foo is kind of pointless other than to help the subtree command base it's split changes more easily in the future.

After running the split command, you'll be in a branch of foo, which only has those files. From there you can do a normal merge with your bar project or start a new project and merge bar into that (since it probably doesn't have a proper history). You may want to rebase to the diverge point or something before trying to do that merge though.

Edit: Also here's the reference for git subtree commands

So, you are saying the files are essentially the same in both in foo & bar, just that the ones in foo are newer than those in bar:

If yes, then you can just take a diff:

diff -b /path_to/foo/dirA/dirB/ /path_to/bar/ > diff.patch

and then apply the patch onto bar:

cd bar

patch -p1 < diff.patch

Update: As per OPs updated, he's looking to maintain commit history, above won't work in that case.

Check out the git book and git magic. Depending on the exact changes, perhaps a round of history rewriting (git filter-branch and friends; or brute-force application of git rebase --interactive, straightening out each commit) can restore sanity to the mangled clone, and then allow a clean merge.

Other alternative is to export each commit as a patch (essentially run git format-patch), recover the commit data from there and reverse engineer the patches to apply. You could even use the oportunity to rewrite a cleaner/simpler history when doing this.

Clearly the viability depends on the extent of the divergence, and how many "wrongly applied" commits are at stake.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!