Checking out an open-source git project: the right way
(Paraphrased from Long Nguyen’s guide to checking out projects from GitHub — which is excellent, except that Long uses the name “long” for too many different things, making the code hard for mere mortals to read.)
Suppose you would like to work on the open-source Insoshi project. You have the URL of its official git repository:
git://github.com/insoshi/insoshi.git
You could simply clone this URL to your own machine:
$ git clone git://github.com/insoshi/insoshi.git
after which you could mess around with your local copy as much as you like. But it’s hard to share a local repository with your friends, or among several machines, so perhaps you’d rather create a private fork on a server somewhere. It’s easy to do this with a GitHub-hosted project like Insoshi — you get a GitHub account, then press GitHub’s “fork” button, and you rewarded with the URL for your own personal GitHub-hosted fork:
git@github.com:mechfish/insoshi.git
Now you could make a local clone of that remote fork:
$ git clone git@github.com:mechfish/insoshi.git
but there are disadvantages to that. One is that the local clone will have a different parent: its origin will be remote fork, while the remote fork’s origin is the official project repository. Ideally, you would want the two repositories to be interchangeable, so that you won’t get confused when comparing them, and so you can upload the local version to replace the remote version if it gets lost or corrupted.
You’d also like to be able to pull changes from the official repository directly into your local copy, then push them up to the remote fork, rather than having to pull every change forward through the chain: official → remote fork → local copy. That’s painful.
So here’s what to do:
$ git clone git://github.com/insoshi/insoshi.git
$ cd insoshi
$ git branch devel master
$ git checkout devel
$ git remote add fork git@github.com:mechfish/insoshi.git
$ git fetch fork
$ git push fork devel:refs/heads/devel
$ git config branch.devel.remote fork
$ git config branch.devel.merge refs/heads/devel
Here’s what these commands accomplish:
- Clone the official repository and
cdinto the local copy. - Create a
develbranch to develop on. Note that if we want to base our development branch on the “edge” version of the project instead of the stable version we should do this instead:$ git branch --track edge origin/edge; git branch devel edge - Checkout our new
develbranch. - Add a remote named “fork” that points to our private fork on the remote server.
- Fetch the remote fork’s contents.
- Push our new
develbranch to the remote fork, where it should have the same name. - Set the
configfor thedevelbranch so that it automatically pushes changes to thedevelbranch on the remote fork when we do a plaingit push, and automatically pulls from thedevelbranch on the remote fork when we do a plaingit pull.
Note that with this setup you automatically get the feature that a git push will push up all changes to all branches, including the master branch. (That’s because the default refspec for remotes is refs/heads/*:refs/heads/*.) So you can pull changes from origin directly to your local copy, with the assurance that those changes will be automatically migrated to your remote fork repository when you push.
Comments
This code is much clearer for a git/github newbie. Thanks for the disambiguation of names.
Post new comment