3

I've got two related git repositories on GitHub that should really be one. How do I combine both projects into one project, in a way that satisfies the following context:

  • Each repo currently only has a master branch.
  • A is the older repo, B is the newer repo.
  • A is the canonical repo (ie: repo A has the name that I ultimately want this tool to be called, so I want all future work, after B has been appended to A, to be done in repo A).
  • After B has been appended to A, A should exist, B should be deleted.
  • I don't want to put one repo as a subdirectory of the other, I want to combine the two repos as if they were one repo all along.
  • I want this change to the git history of A to be permanent so that folks don't have to pull refs, but instead just clone the updated repo A and get everything as expected.
  • There are 3 similar files between the two repos: .gitignore, readme.md, and package.json.
Brian Zelip
  • 2,909
  • 4
  • 33
  • 45
  • 1
    Is there any reason you can't just copy the contents of B into A and overwrite/merge files manually? Does B's commit history need to be preserved? – Green Cloak Guy Apr 30 '19 at 01:47
  • 1
    @GreenCloakGuy - Yes, B's commit history needs to be reserved. – Brian Zelip Apr 30 '19 at 01:53
  • Is there a single commit `aaa` in A which should be mapped to a commit `bbb` in B ? – LeGEC Apr 30 '19 at 08:39
  • @LeGEC - not sure what you mean by 'mapped', but the point is to append repo B's initial commit after repo A's last commit. – Brian Zelip Apr 30 '19 at 15:08
  • Does this answer your question? [Concatenate two git repository histories](https://stackoverflow.com/questions/16056506/concatenate-two-git-repository-histories) – Inigo Jan 29 '23 at 02:29

2 Answers2

2

Here is a clean way to do it:

From your local A repository

git remote add b https://github.com/your-username/your-b-repo.git
git fetch b
git checkout -b b-master b/master
git rebase master
# fix conflicts if any
git checkout master
git merge b-master
git branch -d b-master

Explanation

  1. Add your secondary remote repository called b to the local primary repository
  2. Fetch everything from it
  3. Create a new local branch that matches the b/master called b-master and checkout to it
  4. Place everything you did in the B repository after everything you did in the A repository using the rebase command
    1. Fix the conflits during the rebase
  5. Checkout your master branch (on A)
  6. merge the master branch (A) to the b-master branch (B)
  7. Delete the now useless b-master branch
SteeveDroz
  • 6,006
  • 6
  • 33
  • 65
  • Holy smokes it worked!! I was surprised your method did not include `git replace --graft`, and `git filter-branch`, but it worked very well. Thanks very much for your input! – Brian Zelip Apr 30 '19 at 15:51
  • 1
    "My" method does exactly what you want to do: it literrally takes all the commits from `b` and puts them after the commits from `a`. This is the very definition of rebase. You're welcome! – SteeveDroz Apr 30 '19 at 15:53
1

You can:

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 1
    That only *displays* the two repositories interlaced, not merge them! – SteeveDroz Apr 30 '19 at 05:07
  • 1
    @SteeveDroz no, the goal is to rewrite with filter-branch the history of repo A by adding the commits from repo B. – VonC Apr 30 '19 at 05:08
  • 1
    Oh, nevermind, I understood that big `filter-branch` command the wrong way. – SteeveDroz Apr 30 '19 at 05:10
  • @VonC - your approach is more similar to what I thought I'd be doing than the @SteeveDroz solution since it uses `git filter-branch`. The context you linked to is different than mine though, and I'm not sure how to wield `git filter-branch` in my case. I don't want each repo in its own subdirectory, rather I'm after a linear history where the last commit of repo A is the parent of the initial commit of repo B. Any input? – Brian Zelip Apr 30 '19 at 15:33
  • 1
    @BrianZelip The approach I link do *not* put each repository in their own directory, provided you don't use the --prefix option (https://git-scm.com/docs/git-read-tree#Documentation/git-read-tree.txt---prefixltprefixgt) – VonC Apr 30 '19 at 17:51