Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two git remotes with different history

Tags:

git

github

We have an internal corporate github repository that we want to open-source to github.com soon. In order to do so safely we want to remove the git history upon the initial push to the public repo. Therefore we need to:

  1. Create a public repo that we add as 2nd remote to our local github repo
  2. Push a history-truncated version of our local code to the public repo
  3. Ensure that all follow-up commits end up in both the local repo and the public repo

As an example, if the local history at the time of the initial public push is:

A -> B -> C -> D

then the public repo after the initial push should look like:

D

After adding two new commits, E and F, the two repos should looks like this respectively:

Local:

A -> B -> C -> D -> E -> F

Public:

D -> E -> F

How can we achieve all of that simultaneously as easily as possible? I realize that there are lots of questions/answers regarding truncating history or having more than one remote, but I haven't found anything about both of those features simultaneously.

like image 616
snooper77 Avatar asked Oct 28 '25 03:10

snooper77


1 Answers

One solution is to create a initial commit for your public repo, and use git replace --graft to sort of bind your internal and public histories together. I have personally found this solution to be great in a similar situation as you described in your question. In this case the histories will look like this:

History in your internal Github repo:

A -> B -> C -> D -> I (replaced) -> E -> F

History in your public Github repo:

I -> E -> F

where commits E and F are new development and I is the initial commit for public repo.

Steps to achieve this (assuming master is the main branch in all repos):

  • At your stating point you are in commit D
  • Copy the files to a new folder and create the initial commit I for you public repo
  • Push the initial commit to your (empty) public repo
  • Go back to your old local repo and add the new public remote
  • Pull the initial commit from public repo to a new branch
  • Check the hashes of commits D and I
  • On the new branch, run git replace --graft hash_of_commit_I hash_of_commit_D
  • When you run git show-ref you'll see ref refs/replace/*
  • git log will show replaced mark on commit I
  • Merge new branch to master (I to master)
  • Push new reference to your internal repo git push internal_remote 'refs/replace/*'
  • Push initial commit to your internal repo git push internal_remote HEAD:master
  • At this point you can delete the new branch
  • Pushing to public repo should not do anything git push public_remote master, there should only be the initial commit I and no previous history
  • Now you can make new development and push to both remotes without messing up the history!
  • git commit
  • git push internal_remote master
  • git push public_remote master
like image 67
xXxSniper666xXx Avatar answered Oct 29 '25 19:10

xXxSniper666xXx