How to Duplicate a Git Repo and Copy Git History

Laptop and desk on top floor of New York apartment building office

There are situations where we want to duplicate a git repo in a separate project with different Git history. However, when we clone the repo, we want to bring with us the git history of the previous repo.

This can be done with a few simple commands. Documentation on this can be seen at GitHub.com.

Summary

The process can be summed up in 4 main steps:

1. Create a blank remote repo via GitHub.com (or the command line)

2. Create a bare clone of the origin repo with the command:

$ git clone --bare "https://github.com/username/git-repo-name"

3. Push mirror the cloned origin repo to the remote target repo with the command:

$ git push --mirror https://github.com/exampleuser/new-repository.git

4. Clone the new target repo onto your local machine with the standard cloning command to work on it:

$ git clone 'https://github.com/omartheman/Omars-New-Project.git'

Step 1: Create a blank remote repo (our target repo)

We want to create a blank remote repo. This is going to be our duplicate repo when we are finished. We can go to https://github.com and log in to our account to create the blank repo. This can also be done with commands in the terminal on our machine.

In the top right corner of your GitHub account, click the “+” to add a new repository, then follow the on-screen instructions.

When we click “Create”, we will be taken to the blank repo’s page. From here we can copy the URL of the repo, as we will be using it in the next step.

Step 2: Create a bare clone of the repo

Next we want to do is create a bare copy of the repository we want to duplicate. We can do this with the command:

git clone --bare "https://github.com/username/git-repo-name"

The bare repo we create won’t contain any project files. This will allow us to push only the git history from our origin project to our target project. If we take a look inside of the created folder, “GasGuide.git”, we will see only .git files:

We can go into our GitHub account, and find our remote repo’s URL:

Info about a bare git repo, for those who want to know

A bare git repo is a folder that contains only information about the git history of the repo being cloned. The folder doesn’t contain any of the working files from the repo. Additionally, bare git repos place the git history files and folders into the parent folder, instead of into a “.git” subfolder. (Source: Jon Saints)

Step 3: Push a mirror of the bare clone to the remote repo

Once we’ve created our bare clone on our machine, we can change directories into our cloned repo, and push this repo into our remote target repo. We use the command:

$ cd old-repository.git
$ git push --mirror https://github.com/exampleuser/new-repository.git

When we mirror push to the target repo, we get all of the files from our origin repo into our target repo, as well as the git history. However, when we use the process above, we will have a separate working repo for our future changes to each project. This means that, although up to this point the git history is identical for both projects, any future changes to one of these repos will only register in that respective repo’s git history. This accomplishes our objective of cloning our repo but giving it it’s own duplicated working repository.

Step 4: Clone new remote repo into local machine

Once we have mirror pushed to the remote repo, we can go back to our new remote repo and clone it into our local machine with the standard clone command, which will allow us to start working there:

Going back to our new remote repo, we should see that the project files have now been added, if we refresh the page.

We can use the following command to clone our remote repo to our local machine:

$ cd 'our-destination-parent-folder'
$ git clone 'https://github.com/omartheman/Omars-New-Project.git'
Command git clone running in the terminal

Step 5 (optional): Add new repo to GitHub Desktop

If we are using GitHub Desktop, we can add the new repo there as well. We should be able to easily test there to make sure that the old and new repos’ commits are not affecting each other. We can make a test commit in one repo, switch to the other repo, and pull from the remote origin to make sure that the changes in one are not affecting the other.

That’s it!

Good luck! 🙂

Subscribe to new blog posts