14

After rewriting the history of a repository with git filter-branch, all the SHAs change.

Now, if that repository (let's call it X) is used as a git submodule in another repository (let's call it Y), we have a problem.
Indeed, Y knows what version of the submodule X to load based on the SHA of the commit in that submodule. Since all the SHAs in X have now changed, Y points to SHAs that no longer exist.

Is there a way to rewrite the history of Y such that it points to the new commit SHAs of the submodule X (both in current and past commits)?

I would guess that given a correspondence between old SHAs and new ones, this is possible in principle, but I am afraid it would involve nasty bash scripts.
Is there anything easier?

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
Enzo
  • 964
  • 1
  • 9
  • 20

1 Answers1

8

but I am afraid it would involve nasty bash scripts.

I am afraid it does.

Is there anything easier?

Not that I know of.
Here are some clues (not a full-fledged script) of what you would need for that script to work:

If you still have access to the rewritten repo, its original history (before the filter-branch) is kept in .git/refs/original.

That means you can loop for that old history SHA1:

 git -C /path/to/rewritten/repo for-each-ref --format="%(refname)" refs/original

If the changes were limited to one branch, you can match easily the new SHA1 with the old one (the first old one matches the first commit of the rewritten branch, the second old one... and so on)

If not, you would have to look for a revs in order to find a match (same date, sane commit message)

git rev-list --all \
  | while read commit
 do
 ...

Make sure the parent repo updates its refs for the submodule:

cd parent/repo
cd asubmodule
git fetch

That way, the new SHA1 are available.

Finally, you can do a filter-branch in the parent repo, looking for a gitlink, special entry in the index, matching one of the old SHA1.

For each match, you checkout the new SHA1 in the submodule folder, get back one level up to the parent repo, add and commit: that will record a new gitlink SHA1.

cd parent/repo/asubmodule
git checkout <new SHA1>
cd ..
git add .
git commit -m "Record new SHA1 for asubmodule"
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250