1

This is what I have


RepoA: root ➊ → ⋯ [History A] ⋯ → ➌
RepoB: root ➋ → ⋯ [History B] ⋯ → ➌

where the files (➌) in each repo are now identical, but the histories and roots are entirely unrelated.

This is what I want, but both Git and related queries I've been here and elsewhere seem to be going out of their way to avoid this!


RepoA:
branchA root ➊ → ⋯ [History A] ⋯ → ➌ \ ∙ → ➌ / branchB root ➋ → ⋯ [History B] ⋯ → ➌

merged together into RepoA, keeping the root and history of RepoB separate from that of RepoA, so that when I look at the history of any file, after the merger, it will show separate histories from each branch, and not mangle the two sets of histories together.

It's a mash-up of two separate code-bases. I have many projects like this, not just one or two. Some may eventually come to have many different lines of ancestry, rather than just two. Yet, GitHub seems to be specifically blocking this very situation!

  • 1
    Just run `git merge --allow-unrelated-histories -s ours ` to build the new commit with the snapshot from the tip-most commit of one of the two histories (the one you're "on" when you run that), and you have the result you're asking for. Whether and when that's *useful* is a different question, but you've decided you want it so that's how to get it :-) – torek Jul 09 '22 at 02:00
  • Note that Git does not have *file* history. The `git log` command goes *commit-by-commit*. If you want to examine some particular trace of history, going all the way down one "leg" of a merge before starting down the other, use the `--topo-order` option to `git log`. – torek Jul 09 '22 at 02:02

2 Answers2

1

It's a mash-up of two separate code-bases. I have many projects like this, not just one or two.

Normally, each projects would be in its own repository.

But if not, assuming repoB has only one branch of interest (say main):

cd repoA
git switch main
git add repoB URL/repo/B
git fetch repoB
git merge --allow-unrelated-histories -s ours repoB/main

You can repeat that for others "repoB", but the end-result will be a giant repository whose entire codebase will be branches or tagged as "one".
That may, or may not be what you want/need.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • By "mash-up" I mean one project that has two or more independent lines of descent from different code-bases which, by a progressive serives of updates, have each been brought into common identical form. (1) - by a series of updates and commits (history A) - has become (3); (2) - also by series of updates and commits (history B) - has become (3); and both (3)'s are exactly the same. I want each set of histories kept separate, but in a single repository, so that looking at the history of any file will show 2 independent lines of ancestry of each. – Lydia Marie Williamson Jul 12 '22 at 06:08
  • @LydiaMarieWilliamson OK. What was the result of your tests with root rebase or (from my answer) `git merge --allow-unrelated-histories`? – VonC Jul 12 '22 at 06:10
  • Ultimately, I found a combination that worked and gave me the result I sought. I'll hunt down the command sequence in my logs and include it in an edit. – Lydia Marie Williamson Jan 22 '23 at 08:30
  • @LydiaMarieWilliamson well done, I look forward to seeing that sequence of commands. – VonC Jan 22 '23 at 09:05
0

I don't think there is an answer to your query. As far as I'm aware, no git repository can have more than one root - ever! (And this may not have always been the case.)

"git init" will create a new repository with one root. All commits, reversions, branches and merges will operate on the tree that has just that single root. All branch switches and commit navigations will navigate to other parts of the tree. All rebases will reattach one part of the tree to another part that tree.

So, it appears that under no circumstance, will the "there is only one root" condition ever be broken. It is an invariant, and GitHub (as you suggested) is literally going out of its way to prevent what you're asking for.

So, you may have to create a fake root, attach A's root and B's root to it (along with the rest of their respective trees) and then merge their respective heads. Since I don't think there's any way you can dig under A's root to rebase it onto the fake root, then you may have to do this all within a new repository, instead of keeping it all in A.

NinjaDarth
  • 287
  • 1
  • 3
  • I think you identified the root of my problem; but your conclusion may be premature. It is possible to do surgery on the root and rebase the root. I think I'll try that. – Lydia Marie Williamson Jul 09 '22 at 10:54