11

we're having 3 separate git repositories (each with some branches) which we'd like to combine into one keeping full history and the ability to access the branches, like so:

so this is what we have. 3 repos:

/A/.git
/B/.git
/C/.git

and we'd like to have one super-repo with 3 subdirectories:

super/.git
super/A
super/B
super/C

and say when switching to branch feature1 (which was originally in repo B, introduced at a time that repo C didn't exist yet) we'd expect the result to be:

super/.git
super/A
super/B

we've read Combining multiple git repositories but had troubles using git-stitch-repo which basically worked as advertised only that quite a large number of commits were missing in the super-repo (without any error messages that would point to a problem).

any idea what we could be doing wrong here?

EDIT we are aware of submodules and subtree-merging, but both are not an option. this is supposed to be a one time operation. we need the repos joined once and forever.

EDIT probably a simpler way to put basically the same question: say we have one repo with 3 totally unrelated branches. we can merge them without a conflict to one branch (since they share no files). now when looking at the history we see 3 unrelated branches of commits and the one point where they come together. but what we'd like to see is one branch made up of the interleaved (by date/time) commits of all 3 branches.

Community
  • 1
  • 1
joreg
  • 247
  • 1
  • 2
  • 13
  • Did you try any of the other methods suggested in that question (Combining multiple git repositories)? There are several options given there. – ebneter Sep 28 '11 at 02:02
  • yes we did. none of them seems to do what git-stitch-repo does, which really interleaves the commits in a timely order so that the resulting repo totally feels as if it included all parts from the beginning. only, as mentioned, git-stitch-repo randomly leaves files out.. – joreg Sep 28 '11 at 22:33
  • ok then, make a file from `git log --format=%d%H` from each branch. Pipe this through sort then to xargs and git cherry-pick on a new branch. You may want to flatten out the histories first with rebase. – Adam Dymitruk Sep 29 '11 at 01:51
  • Given your last comment, I've added a link to a tool I wrote that can do this; simply rebasing and sorting hasn't been sufficient for me when dealing with lots of branches and doing this incrementally – David Fraser Jun 26 '14 at 11:03

3 Answers3

1

splice_repos is a tool I wrote that interleaves commits from different repositories into a new repository, so that same-named branches get merged histories (as though they were committed to in historical order), rather than just being merged at the end with separate histories on different branches. There's a blog entry describing the rationale behind it.

David Fraser
  • 6,475
  • 1
  • 40
  • 56
1

You don't want submodules as you will pull your hair out with all the git submodule update commands you will be issuing. You will also have to issue 3 git log commands instead of one to see what has happened in a certain amount of time.

Bring all of the histories into one repo. Use filter-branch to reset the directories that each repos history resides in. There is no need to stitch. You can simply merge at any point once you do the filter branch.

Essentially repoA/master, repoB/master and repoC/master will exist in the new repo you make (although you can just start with one of them). After you apply filter branch, each tree in each commit will have a new root node that will be a directory (A for repoA branches, B for repoB branches, etc).

OR

git checkout -b newbranch --root
git log --all --format=%ad%H | sort | cut -c10- | xargs -n 1 git cherry-pick

adjust the cut so it only takes the hash. Haven't tried this but let me know how it works. You may need to flatten out history first with rebase. You can't interleave the different branches and merges from the 3 different histories.

hope this helps.

Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
  • 1
    hm, kind of...if we do so, we end up with 3 unrelated trees that merge to one at our current point. now when checking out an earlier revision which belongs to one of the former repos we only get files of this repository. as mentioned above we'd like other files that have been present at the time of that revision (even if of other original repos) to be there too. and git-stitch-repo does what we want, but is obviously bugged as some random files/commits are missing after the stitch.. – joreg Sep 28 '11 at 22:31
  • thanks for the 2nd option, but i have to say we didn't try it. we spent too much time on this already and it didn't sound too promising. we finally went with a simple merge of the unrelated branches meaning that when we go to a commit back in time we'll only see one branch. – joreg Oct 03 '11 at 23:52
  • It is possible but due to necessary flattening to make them intertwine properly you probably would be throwing away useful historic information. All the best to you. – Adam Dymitruk Oct 04 '11 at 06:12
-1

Probably the easiest way to do this is to use submodules. It doesn't exactly speak to the case you're looking to achieve, but it's darn close and not very headache prone.

Just create a new directory and git init it as your "super" repo. Then add in your A,B and C repos using the commands given on the link above.

brycemcd
  • 4,343
  • 3
  • 26
  • 29
  • thanks, we are aware of submodules but they are not an option. i added that info to my original question. – joreg Sep 27 '11 at 22:37