0

What I've got

I have read many SO questions about combining repositories. I'm almost there, but I'm missing something.

I have two repositories current-repo, which published and shared, and old-repo which is not. I have the only copy. Their histories look something like

                         1--2--3--4--5  <= current-repo
                         =
                content is the same
                         =
old-repo =>  a--b--c--d--e

What I want

Ideally, by combining the two repos, I'd get a repo with a history like

1. a--b--c--d--1--2--3--4--5  <= notice, duplicate old entry "e" is dropped"

I'd also settle for the following:

2. a--b--c--d--e--1--2--3--4--5            <= duplicate content in "e" and "1"
3. foo--bar--baz--buz--1--2--3--4--5       <= like #1 above, but rehashed "old" history
4. foo--bar--baz--buz--bif--1--2--3--4--5  <= like #4, but "bif" and "1" have duplicate content

What I've tried

I can get to this point (locally) with

cd ~/current-repo
git remote add -f old-repo ~/old-repo
git replace -f --graft 1 d

Now, it's my understanding that at this point I have to push/pull refs/replace/*. I don't want my users to have to do this step.

The git graft (and maybe some git replace) solutions that I saw, had a git filter-branch step. I tried this, and also git rebase-ing, but only the hashes from the current-repo history were re-written. I also, don't want this. I don't care if the history from the old-repo get's re-hashed. As I mentioned, that repo isn't published and shared. Basically, the next time my users did a git fetch, they'd get a bunch of old history, in addition to whatever "new" history they were missing.

tl;dr

I want to combine two git repos, maintaining a linear history, and maintaining the hashes of the "newer" repository. How do I get to a repository with my chosen history (above) or something similar?

nega
  • 2,526
  • 20
  • 25

1 Answers1

3

tl;dr

No, it cannot be done.

Details

Preserving the hashing while adding more history at the beginning is not possible, by design.

The sha1 hash of a commit is based on the idea of a cryptographic signature: it hashes not only the commit and its contents, date, committer and all that, but it also hashes the parents in, which means that it hashes the entire history leading to that commit.

Thus, there is no way to change the history without changing the hash of every commit whose history was extended (or modified in any other way).

joanis
  • 10,635
  • 14
  • 30
  • 40