I have a bunch of git repositories, each containing one file. I'd like to merge them all together, preferably in one step. What I'm aiming for is this graph:
*----¬ mergedrepo/master | \ \ \ | | | * repoA/master | | * repoB/master | | | | | * repoB/... | * repoC/master * repoD/master | * repoD/...
I tried a git merge
, but it appears the octopus strategy doesn't work for disjoint trees
$ git merge a/master b/master c/master d/master Unable to find common commit with a/master Automatic merge failed; fix conflicts and then commit the result.
I was also told that git merge --squash
would help, but that gave the same error.
This generates the right graph, but loses all the files:
$ git merge -s ours a/master b/master c/master d/master
How do I go about doing this?
So merging one branch into another has a secondary effect: it moves the merge base of those two branches. In particular, the new merge base of the two branches is now the second parent of the merge commit.
Octopus Merge: Octopus Merge strategy resolves cases with more than two heads but refuses to do a complex merge that needs manual resolution. It is primarily meant to be used for bundling topic branch heads together. This is the default merge strategy when pulling or merging more than one branch.
Go to either the git log or the GitHub UI and grab the unique commit hashes for each of the commits that you want. "Cherry pick" the commits you want into this branch. Run this command: git cherry-pick super-long-hash-here . That will pull just this commit into your current branch.
I've managed to resolve the problem with octopus merge of unrelated branches. Unfortunately the following applies only to rather simple cases where no real merge conflicts exist.
Do a merge as described in the OP.
git merge --allow-unrelated-histories a/master b/master c/master d/master
It will "fail" claiming about conflicts. But the merge has been performed and that fact recorded although there are no changes in the index.
Add contents of branches to the index with the read-tree
command:
git read-tree a/master b/master c/master d/master
This will not affect working tree, only the index will be updated. (It is possible that you want to add your current branch to the end. You need to add all of them in one command.)
If branches are not totally independent then adjust their order keeping in mind that the latter will overwrite contents of former branches.
git commit -m "octopus-merged remote 'a', 'b', 'c', 'd'"
)git reset --hard
) to get a consistent working tree.I suppose one can later edit and amend this commit but I personally haven't tried this.
Create an empty commit
git commit -m "Common commit" --allow-empty
look at its hash with log -1
and add it to the grafts file without any parents
echo HASH_OF_COMMON_COMMIT >> .git/info/grafts
then find all other roots with log --max-parents=0
and for each add their hash to the graft file with the above hash as parent
each HASH_OF_ROOT HASH_OF_COMMON_COMMIT >> .git/info/grafts
and now, merge!
The grafts file is a way to change the parents of a commit and once all your repos have a common commit your repo should accept the merge.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With