How to move changes to another repo while avoiding conflicts
Asked Answered
S

1

0

I have two GitHub repos of the same application (one is forked from the other). However, due to the forked one being public I had to strip out secrets from it, so I had to change the commit history completely on that one.

Development continued on both repos and they kinda diverged from each other a bit. Later, it was agreed that we want to move a range of 70 commits from one repo to the other. Since the changes touch so many files, this will cause a lot of conflicts and i want to minimize this. Here is a diagram that explains the current state:

Current commit history

To solve this, I am thinking of doing the following:

  • Copy the public repo (repo2) into a branch into the private repo (repo1)
  • Create a PR against that branch
  • The team works on resolving the conflicts on by one
  • Squash (D => Z + new change to fixed the conflicts)
  • Cherry-pick the squashed commit into "repo 2" (public repo)

However, if I do this, I will lose the commit history.

What is the best approach here? Are there any other way to go around this?

Thanks

Sublimate answered 30/7 at 15:54 Comment(2)
So, C and D are the same (content) except for the secrets?Gearard
No they are different. Only A & B are the sameSublimate
H
0

Having done this before, I'll offer two solutions. Note that #1 is typically the better long term solution, but it has more pre-work to implement.

Solution #1: One repo instead of two

There are many different ways to implement this, but they all converge down to having only a single repository to maintain, instead of two with completely different histories. Some people use a private submodule to contain the secrets, or different branches that only exist in the private repo that they keep rebasing, or environmental variables, or my personal preference which is untracked (using .gitignore'd) config files that contain the secrets with example templates so each developer can populate their own configs. See questions like this one for more details.

Solution #2: Automate creating repo 2 from repo 1

The idea here is to write a script (typically using git filter-repo) which makes all the changes you need to your repo, and is repeatable. Once you've perfected the script, you run it the first time and all of the commit IDs will change, but as long as you don't change the script and don't rewrite the source repo, all subsequent passes will recreate the same commit hashes1 and simply add more commits from your source repo starting from the same previous HEAD commit ID. This enables you to merge in new changes cleanly across repos without conflicts.

Note both of these solutions have some downsides:

With #1 you'll need to also rewrite your private repo, and reorganize the structure a bit to get your secrets working.

With #2 you'll likely have to rewrite your public repo again one final time while you perfect your script. This may not be a problem if it doesn't have many contributors yet.


1git-filter-repo will only recreate the same commit hashes in subsequent passes if nothing about the commits needs to change. This is normally the case since author and committer dates from existing commits are preserved by git-filter-repo. If your script does something outside of git-filter-repo or uses an option that will change a committer date to "now", consider hard-coding it to a specific date so the hash IDs are predictable and constant.

Husk answered 5/8 at 19:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.