Reputation: 1008
I have two repositories that I would like to merge. Lets call them old-style and new-style. My team stopped using old-style December 31, 2016 and began using new-style January 1, 2017. The directory/project style was copied over from old-style and moved to new-style except the history. I would like to merge these two history's together so I can see what has changed in the project.
How would I do this? A lot of blogs suggest taking old-style and making it a child directory of new-style and then merging their unrelated histories. But I believe my histories are related. Doing this would make it appear that the code bases were not similar.
old-style: c1--c2--c3--c4--c5 <- master
January 1 2017
new-style: c1--c2--c3--c4--c5--c6-- <- master
If I make old-style a child directory of new-style I would have to have a commit indicating that a merge happened at some point.
old-style: c1--c2--c3--c4--c5 <- master
January 1 2017 \
new-style: c1'--c2'--c3'--c4'--c5'--c6'--c7 <- master
message at c7 indicating that old-style was added to new-style
What the ideal output would be
c1--c2--c3--c4--c5--c1'--c2'--c3'--c4'--c5'--c6'--c7-- <- master
Upvotes: 3
Views: 121
Reputation: 1008
I found a solution that worked for me. This all needs to be done in GitBash and not in Powershell.
You will need to know the first commit hash of your new style repository and your last commit hash of your old style repository.
In your new-style clone run
git rev-list --max-parents=0 HEAD
Output
2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
In your old-style clone run
git rev-parse HEAD
Output
de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3
Clone the new-style repository
git clone https://GitWebsite.repos/new-style.git
cd new-style
Add the old-style repository as a remote
git remote add history https://GitWebsite.repos/old-style.git
git fetch history
Now to convert the branch I am going to use git-filter-branch. I understand this to work in a way similar to how TFVC works. You're taking a snapshot of the commit and moving forward and not working with the diffs between commits. Git will not try to do any resolution between the two commits. It reminds me of the Wallace and Gromit movie "The Wrong Trousers" during the train chase scene Grommit is placing trackdown in front of the train as it is moving forward.
git filter-branch --parent-filter 'test $GIT_COMMIT = 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12 && echo "-p de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3" || cat' HEAD
Now many hours later that is done. You can force push this repository up to your git host.
git push -f
You should see the code in a single linear history now.
A lot of thanks to this answer https://stackoverflow.com/a/44078243/2375884
Upvotes: 1
Reputation: 77034
Your ideal situation graph describes a rebase, which you can do. If you have these two repositories as branches, you can run git rebase --root --onto old-style new-style
, which will produce a linear history.
You may also want to use --rebase-merges
if new-style
is a main development branch that uses a typical merging workflow to preserve the merge commits instead of omitting them. This requires a reasonably recent Git version.
If you really want to use a merge, you'll need to merge with --allow-unrelated-histories
, since the branches, while sharing code, don't share an actual common commit.
Upvotes: 1