Loading...
Random Pearls Random Pearls New Menu
  • All Pearls
    • Random Pearls
  • Coding and Development - Reference …
    • Coding and Development - Reference …  (parent page)
    • Information Technology  (parent page of Coding and Development - Reference …)
  • New Menu
  • Authors
  •  
  • Contact Us
  • Sign up
  • Login
    Forgot Password?
  • Follow us on
Image Back to Top Back to top
Language Preference
This website has language specific content. Here you can set the language(s) of your preference.

This setting does not affect the current page. It is used only for filtering pages in menus, preview tiles and search results.

It can be changed any time by using the login menu (if you are logged in) or by clicking the Language button on the left bottom of the page.
Log in to save your preference permanently.



If you do not set this preference, you may see a header like This page has 'language_name' content in page preview tiles.
Search
  • Navigation
  • Similar
  • Author
  • More...
You are here:
All Content / Science and Technology / Information Technology / Coding and Development - Reference … / How to Make Private Updateable Clone in Git
Table of Contents

Subscribe to Our Newsletter
Follow us by subscribing to our newsletter and navigate to the newly added content on this website directly from your inbox!
Login to subscribe to this page.
Categories  
Tags  
Author  
manisar
Author's Display Image

"Whenever you can, share. You never know who all will be able to see far away standing upon your shoulders!"

I write mainly on topics related to science and technology.

Sometimes, I create tools and animation.


How to Make Private Updateable Clone in Git

July 4, 2021

Author - manisar

Create private equivalent of a fork of a public repo on github


git clone will get you the code from a repo so that you can work on it locally, and if you have the push rights, you can even push your changes using git push.

When working on third-party public repos, if you do not intend to change the code, or do not wish to have your changes synced to github, git clone is sufficient. But if you have made changes (let's say you have added comments, if nothing else, for your reference), you'll not be able to have the online (github) version of your changed code, because git push is disabled for others in public repos.

One way is to fork the public repo into your personal workspace on github, and then clone it, but then github doesn't allow forks of public repos to be private. Also, if you are not going to be contributing, you may not want to fork the repo.

The next best deal is to do clone + mirror operations - the former from the public repo to your machine, and the latter from your machine to a newly created repo in your personal workspace. This will, at least, allow back and forth syncing of your code. Let's look at how to do this, and later we'll see how to improve this setup even further.

Case A - You Haven't Cloned the Public Repo Yet

  1. bare clone the public repo on your machine. This clone will later be pushed to github into your private repo.
    git clone --bare <public_repo.git>

    The reason for using --bare is threefold:

    a. no tracking is set up - we'll not be dealing with the public repo after this one-time cloning operation, so we do not need tracking

    b. the branches next, pu, and maint are cloned locally as well, along with master (unlike normal clone in which they remain remote and are tracked)

    c. branches other than the ones mentioned above (such as developer1/feature1) etc. are not copied or tracked either. This is in contrast with --mirror with in which all the branches are cloned.
    This is a good link on stackoverflow.com for learning the difference between git clone, --bare and --master.

  2. On your github, create a private (or public if you want) repo, and you may name it the same as public repo. For discretion, I'll use the term private repo here.
    Now, 1. above would have created a directory on your machine. cd to this directory and then fire:
    git push --mirror <private_repo.git>
    This will copy everything (not just the code, but all the refs etc. as well) to your private repo.

  3. Get out of the directory, delete it, and fire:
    git clone <private_repo.git>
    This will now get the code from your own repo, with all the tracking set up so that git pull, push etc. will work.

Case B - You Cloned the Public Repo Some Time Back

And now you realize the need to have it on github as your own repo.

  1. When you had used git clone <public_repo.git> you got a local master branch, along with remote tracking for all the other branches (since you had not used --bare). Branches keep on getting added and deleted. Before moving our local code to our personal repo, it will be a good idea to remove the references to outdated branches. Remote branches can be seen by firing git branch -r. We remove the obsolete references by using (inside the cloned repo on your machine):
    git fetch --prune
    A slightly modified version is:
    git remote prune origin # origin can be replaced by any remote path
    This version can be used if you have branches from some remote other than origin.

  2. On your github, create a private (or public) repo, and you may name it the same as public repo. For discretion, I'll use the term private repo here.

  3. There are couple of options here:
    a. use set-url as follows:
    git remote set-url origin <private_repo.git>
    git push
    # this pushes to the new origin code from the only local branch you have - master

    b. use git push with --prune
    git push --prune <private_repo.git> +refs/remotes/origin/*:refs/heads/* +refs/tags/*:refs/tags/*
    This pushes all the remote branches to the new repo.
    The push and fetch locations for origin in your local git are still pointing to the original public repo. Let's fix them by running:
    git remote set-url origin <private_repo.git>
    You get an unwanted guest - github creates a real branch named HEAD in your private repo. This branch is a copy of the branch your current local HEAD is pointing to (generally master or main).
    If you see this new HEAD branch in your private repo, what you need to do is just go to your private repo settings (on github), change the default branch to any other branch (if needed), and delete the HEAD branch.

    There is a difference between the a. and b. above.
    With a. only the master gets pushed from local to your newly created private repo, and you can simply keep on updating it by using git push. If you now go to your private repo on github, it will show no other branch than master. The local git on your machine will continue to have those other refs.

    With b. it's not just the master, but all other branches as well that get pushed (I mean the refs for other branches from the local clone). What this does is that it creates a more faithful (like mirrored) version of the public repo. You'll be able to see in github all the branches that came with the public repo originally. All these branches will be visible in your repo now (like the master branch), and you can merge them with the master if and when you want.

    Unless you are interested in looking into and merging any of the current branches, a. should be a good enough option.

Set Upstream (to public repo)

We do not need to do anything else if we don't care about what's happening in the original public repo after we have moved to our private repo. We now work with our own private repo in both github and locally.

But if you do care about the updates in the public repo, and wish to have them synced to your private repo whenever you wanted, these are the steps to be followed.

git remote add upstream <public_repo.git>
git remote set-url --push upstream DISABLE

This will add the public repo as a remote ref named upstream, and will also disable push to this remote ref (not mandatory, but good practice).

Check your remote refs by using git remote -v. You should see something like:

origin <private_repo.git> (fetch)
origin <private_repo.git> (push)
upstream <public_repo.git> (fetch)
upstream DISABLE (push)

After this, whenever needed, you can use these commands to update your local code from upstream (public repo), after resolving conflicts, if any:

git fetch upstream # to be followed by git merge upstream/master # if needed
git rebase upstream/master

Note that on running git branch -r, you'll see remote refs to both origin (private repo on github) and upstream (public repo on github) branches, but there will actually be no remote origin branches if you implemented Case B above, and did not use the git push --prune method. This can be confirmed by looking at the branches in your private repo on github.

This means that if you now checkout a remote branch using git checkout -b <remote_branch_name> origin/<remote_branch_name>, and do a subsequent push (to origin), it will only then push the code and create an actual branch on origin. Not a problem, just something to be aware of.

Or, conversely, if (in Case B), you have not used the git push --prune method above so that your origin does not have other branches, and now you want to have references to those branches removed from your local git as well, use git branch -rd origin/<remote_branch_name>.

In either case, on doing git fetch upstream, your local git will get references to all the upstream branches.

Advertisement
Advertisement
Close ad Ad

Advertisement
Close ad Ad

Advertisement
Close ad Ad

Return to Coding and Development - Reference and Tools

Tell us what you think (select text for formatting, or click )

Copyright © randompearls.com 2020

Privacy Policy