Nadira Fathima
Nadira Fathima

Reputation: 1

Synchronize two remote git repositories with different commit histories

I have two git remote repositories in two unrelated cloud locations. These repositories contain different commit histories.

We ended up having some new code in both Repo2 and other new code in Repo1. But now we want to push code in parallel to both the repositories.

So, my question is:

Upvotes: 0

Views: 3357

Answers (1)

LightCC
LightCC

Reputation: 11649

There are three repos involved:

  1. The first remote repo
  2. The second remote repo
  3. Your local copy of the repo

Since you may have a mix of both repos on your local pc, I recommend renaming that repo directory name to myrepo.backup or similar and starting fresh by doing the following:

  1. Clone from Repo1 into new local directory (clone all branches, not just master)
  2. Add Repo2 as a new remote, so the local repo has two remotes
  3. Fetch all from Repo2.

When you fetch all, make sure you create tracking branches for all the remote repos, which should look something like this:

  1. master - your local tracking reference
  2. Repo1/master - the tracking reference of the remote master branch on Repo1
  3. Repo2/master - the tracking reference of the remote master branch on Repo2

If the master branch diverged between the two repos, it might look something like this:

o-o-o-o-o-o-o-o-o-o-o
       \   \-master  \- Repo1/master  
        \
         \o-o-o-o
                 \- Repo2/master

Note: you may have more than just a master branch. This is intended to show an example with just one branch, but the same decisions would need to be made for every branch.

At this point you will have all of the history showing up in your local repo from both repos. All you need to do is decide how to deal with any divergences between branches.

Option 1: Rename or tag the branch from the second repo

For example, you could fast-forward the local master branch to match Repo1/master, and then create a local branch at the same commit as the Repo2/master that has a different name, such as master2 if you wanted both histories to continue to exist separately.

Alternately, if you want the alternate branch to stop and not be worked further, just add a tag instead of making it a branch. It will still push to the repo with the correct command, but tagging it can be used to indicate it is not a live branch that should be added to (especially if the tag is something like END_OF_DUPLICATE_master)

Option 2: Merge the diverging branches

Alternatively, you could merge Repo2/master into Repo1/master, creating a new commit that consolidates all the changes from Repo2 into the Repo1 master branch, but leaving all the history intact, and now have a consolidated master branch.

Option 3: Rebase the diverging branches

Another way to resolve this would be to rebase the Repo2 master branch onto the Repo1 master branch - with or without squashing, depending whether you want to keep that particular history.

Rinse and repeat

Then just repeat the same decision for all other branches that exist. Finally, make sure that you have local branches or tags moved forward to the latest commits and present for all existing branches, and then push all local branches and tags back up to both repos and they will be sync'd up.

Now, all this said, I really strongly recommend just having one main repo. However, if you need a separate repo due to permission differences in who can access each repo or something like that, I would look into using the forking mechanism (available on Github, Gitlab, and I think also on Bitbucket).

Also, if this description isn't clear enough, do a search on how to manage working in forked repos and how to sync up origin (the fork) with the upstream (the original repo), as this is more or less that same as what you are trying to do.

Upvotes: 1

Related Questions