1

I have two repos. First repo (let's call it A) started a while ago; second repo (B) started very recently. Now we're thinking we would rather have just made B a subdirectory of A. So I'd like to do that, but keep B's commit history.

  • I want the full commit history. i.e. I don't want to just squash B's history into one patch and drop that as a new commit in A.
  • I do not care to preserve the exact SHA1s of B (I understand that that's probably impossible).
  • I do not care to preserve the timestamps of B's commits (though that would be nice to have).
  • I do not care to preserve authorship.
  • I just want to preserve the diffs/patches of each of B's commits.
  • I don't care to preserve any notion of two separate repositories. In fact, I want there only to be A going forward.
  • I don't need B to be a git submodule of A, with its own .git dir or anything like that.

At the end of whatever operations are done, I want three criteria satisfied:

  1. The files and directories as seen at the HEAD of B are seen in a subdirectory of A i.e. /path/to/repoB/somefile.js is found at /path/to/repoA/B/somefile.js
  2. All the commit messages of B are seen, in order, at the chronological end of the commits of A
  3. The diffs of each commit are available (viewable by git log, etc.)

Some examples may clarify what I intend:

  1. In repo B, commit 1 is to add file.txt
  2. commit 2 is to edit file.txt
  3. So in repo A, I want two new commits:
  4. repo A commit 98: add B/file.txt
  5. repo A commit 99: edit B/file.txt

EDIT:

Merge git repository in subdirectory has been proposed as a duplicate of my question. I'll admit that it is extremely close to what I'm asking, and has several fine answers. I tried the subtree answer there, as well as the rebase --onto answer. Both were very close, but were unsatisfactory: subtree didn't allow git log to see the history across the repository histories without referring to path/to/file/without/repo-subdir (where I moved B into repo-subdir); and rebase --onto didn't make B's history visible from A's HEAD.

Pistos
  • 23,070
  • 14
  • 64
  • 77
  • 1
    Possible duplicate of [Merge git repository in subdirectory](https://stackoverflow.com/questions/6426247/merge-git-repository-in-subdirectory) – phd Jan 10 '19 at 09:59
  • https://stackoverflow.com/search?q=%5Bgit%5D+make+one+repository+subdirectory+another – phd Jan 10 '19 at 09:59
  • 1
    In particular, see the `git subtree` answer to phd's suggested duplicate. – torek Jan 10 '19 at 13:12

1 Answers1

2

Here's what I ended up doing. Thanks to atrus from #git in Freenode (IRC) for steering me in the right direction.

  1. In repo B, make a new branch: git checkout -b indir
  2. In repo B, mkdir b-subdir, where b-subdir is the dir I intend for B to end up in the dir tree of A.
  3. In repo B, git mv [...] b-subdir to move everything (except .git/ and b-subdir/ itself) into b-subdir.
  4. Commit that move to repo B.
  5. Push to origin (push -u origin HEAD).
  6. In repo A: git remote add repo-b ssh://......../repo-b.git
  7. git fetch repo-b
  8. git merge --allow-unrelated-histories repo-b/indir

This allows me to see the full history of arbitrary files that came from repo B (using the --follow switch of git log) without needing to strip off the b-subdir/ prefix from the filepath. With git subtree, you only see the file's history in B if you strip that off (and you see the history in A if you don't).

Pistos
  • 23,070
  • 14
  • 64
  • 77