4

I have a repository ("repo") that needs to be gradually migrated to a new repository ("repo-lfs"). repo-lfs uses LFS to store large files, while repo did not.

The intermediate state looks as follows:

repo-lfs: ---------------> main

repo:     ---------------> main
              \_________ release-1.0

Now I want to migrate the "release-1.0" branch to repo-lfs, which requires rebasing repo:release-1.0 onto repo-lfs:main. I have already added repo as a remote on repo-lfs, but a naïve rebase produces conflicts for every change to every file that was migrated to Git LFS:

$ git rebase --onto <correct commit on main> repo/main repo/release-1.0
Auto-merging xy.zip
CONFLICT (content): Merge conflict in xy.zip
[...]
Could not apply 96639f9... Edited xy.zip
Encountered 1 file(s) that should have been pointers, but weren't:
        xy.zip

How do I automatically resolve these "conflicts" in the obvious manner, i.e. by applying the change to the file in git LFS?

mb-lang
  • 73
  • 5
  • Did you try the strategy "ours" or "theirs" like `git rebase -s recursive -X ours --onto repo/main repo/release-1.0` ? – Reynadan Mar 22 '22 at 16:22
  • If repo/release-1.0 is made from an intermediate commit from repo/main, the rebase would need to be `git rebase --onto main $(git merge-base repo/main repo/release-1.0) repo/release-1.0` – VonC Mar 22 '22 at 22:06
  • @Reynadan Using the "ours" strategy will throw away all changes made to LFS-migrated files in the release-1.0 branch. What I want to achieve instead is that the changes are applied to the corresponding files in LFS. – mb-lang Mar 23 '22 at 06:16
  • @VonC I think you misunderstood what I was trying to achieve. The migrated repository should eventually mirror the original state. With your version, I would rebase the release branch on the latest commit on main, while I actually want it to start at the (equivalent of) the same commit it originally started from. – mb-lang Mar 23 '22 at 06:22
  • 1
    @mb-lang Got it, but the last two params seem fishy: In your question "`git rebase --onto repo/main repo/release-1.0`". A `rebase --onto B X Y` means "rebase all commits from *after* `X` up to `Y` onto `B`". In your case, you rebase onto ``, which is correct, as you explained. But I struggle to see on your graph "all commits *after* `repo/main` (?), up to "`repo/release-1.0`". Hence, my `$(git merge-base)` proposal. To start from the right commit to migrate the `repo/release-1.0` branch. – VonC Mar 23 '22 at 06:43
  • @VonC Ah, now I see what you were getting at. I just did a quick test: `git rebase --onto branch1 branch2` and `git rebase --onto $(git merge-base branch1 branch2) branch2` seem to be doing the same thing on my test repository. Not sure if this is an accident or intended, as I cannot find any description of this behavior in the git-rebase documentation. – mb-lang Mar 23 '22 at 07:09
  • OK, there's at least a little hint in the documentation of `git rebase`: The description of the `--fork-point` option mentions that it affects `git merge-base`, so even though the documentation does not state it explicitly, I think the implicit call to merge-base is intended and both versions of the command are correct. – mb-lang Mar 23 '22 at 07:18
  • @mb-lang I have written on fork-point before: https://stackoverflow.com/a/20423029/6309 – VonC Mar 23 '22 at 07:27

1 Answers1

0

I can answer my own question now:

You do not need to use git rebase and resolve the resulting conflicts at all. git lfs migrate import is completely deterministic, which allows you to avoid the problem altogether.

As long as you do not rewrite the history of repo, you can migrate new branches to repo-lfs by simply checking them out as a local branch in repo-lfs and running the exact same git lfs migrate import command that was originally used to migrate the main branch. Git LFS will produce the exact same commit hashes it previously produced for all commits shared between the release branch and main, which means the new branch will automatically be attached to the correct parent commit and the resulting history will match the history from the non-LFS repository perfectly.

mb-lang
  • 73
  • 5