4

I have two repos (let's call them oldrepo1 and oldrepo2). These two repos have 20k and 21k commits respectively in their current history. I'm merging them together in a new repo, each one under a subdir:

newrepo/oldrepo1

newrepo/oldrepo2

I've used these commands to populate the new repo

git subtree add --message="Migrate oldrepo1" --prefix=oldrepo1 <oldrepo1 url> master

git subtree add --message="Migrate oldrepo2" --prefix=oldrepo2 <oldrepo2 url> master

when I go into the root of newrepo, and run "git --no-pager log --graph --oneline" I get 41k commits, as expected, but if I drill down to any level underneath and run git log all I get is the "Migrate oldrepoX" commit:

For instance, I have a file that has had 60 changes in the original repo, but when I run git log on that same file in the new repo, all I get is:

commit <commitid>
  Author: Me <me@myselfandi.com>
  Date:   Fri Sep 18 23:17:28 2020 -0700

      Migrate oldrepo1

      git-subtree-dir: oldrepo1
      git-subtree-mainline: <somecommitid>
      git-subtree-split: <somecommitid>

I didn't squash any history when I migrated, so why can't I see the 60 commits to this file in the new repo?

Rusty Morris
  • 121
  • 2
  • 4

3 Answers3

0

when I run git log on that same file ...

You did not show the actual command that you used, but let's suppose, for instance, that it is:

git log path/to/file.ext

or:

(cd path; git log to/file.ext)

which both do the same thing. More generally any git log command that includes a path will do this.

The this in question is called History Simplification (see Git log history simplification, elaborations example in git log's manual). The git log documentation has been improved recently (in commit 8d049e182e2e...), so see that as well. This history simplification can only follow a single file or path through renames, will miss some cases, and generally requires using the --follow option.

Edit: I forgot to mention that git subtree add is a particularly difficult case, for which even --follow doesn't help (usually). The existing --follow option is a horrible hack that really needs to be replaced, but this has been true for more than a decade and a good replacement is hard.

torek
  • 448,244
  • 59
  • 642
  • 775
  • I'm moving deep into the tree and running git log on a specific file: cd some/deeper/path git log file.ext which only gives me the subtree commit I tried with the --follow option and got no output at all – Rusty Morris Oct 13 '20 at 18:28
  • It all comes out the same: `git log file.ext` resolves the path relative to the repository root, so from that point on it is looking for a file named `some/deeper/path/file.ext`. Because `git subtree` reads the file in at that path, but earlier commits have a *different path*, the file name isn't the same. Remember that in Git, the file isn't named `file.ext`, it's named `some/deeper/path/file.ext`, complete with slashes. The `--follow` will detect if its name changes from one commit to another, and try to follow the new name. This won't catch all cases. – torek Oct 13 '20 at 18:35
  • I also tried `git log --full-history file.ext`, and got the same single commit for the subtree add. – Rusty Morris Oct 13 '20 at 18:36
  • The case from `git subtree add` is particularly difficult here so in general you won't be able to see the file in earlier commits. To fix this, modify the `git log` source code so that it can detect this kind of case, and then you'll be able to see the file in earlier commits. (This is extremely non-trivial!) – torek Oct 13 '20 at 18:36
  • In the original repository—whose commits are now in the combined repository—the file had the path name without the prefix. If you ask `git log` to look for *that* path, it should find the file, but you'll only see those commits that modify the file under its *old name*. – torek Oct 13 '20 at 18:40
  • There's surely got to be some way of seeing this history without hacking git itself. These are repos in Azure, so I can't control anything about how Azure itself is showing history. – Rusty Morris Oct 13 '20 at 18:44
  • How to ask git log for that path? if I give git log any path, it tries to find that path in the local file system, so asking it for a path that is not the actual file path errors out with "unknown revision or path not in the working tree" – Rusty Morris Oct 13 '20 at 18:47
  • 1
    *How to ask git log for that path?* That's the $64,000 ($1 million?) question. There isn't a way to do it today. The history in a Git repository is the set of commits in the repository. The answer is in there. There's just no way to *ask for it*. If you *know* the answer, though, use `git log -- `. The `--` tells Git: *the rest of these are path names*. Otherwise Git tries to guess whether that's a revision or a path, and it doesn't work as either one *based on the current commit*. – torek Oct 13 '20 at 18:51
0

I opted for a different approach, using git-filter-repo to remap each repo into subfolders and merge those modified repos into the new repo, as described by x-yuri in this discussion:

How to import existing Git repository into another?

with the details further spelled out here:

https://gist.github.com/x-yuri/6161d90d1af8ebac6e560bcef548c1c3

Rusty Morris
  • 121
  • 2
  • 4
-1

Just add --pretty="full" to your log command: git log --pretty="full" path/to/file.ext

hajer
  • 1