This is just an arbitrary collection of Git things I felt like documenting, mostly so I don’t forget how I did them.

Table of Contents [Back to top]

SSH setup

On your local system, create an RSA keypair using:

ssh-keygen -b 2048 -t rsa -f ~/.ssh/account.github.id_rsa

Pick a memorable passphrase; occasionally you will get requests to supply it.

Now add the public SSH key to your GitHub account. It might be helpful to make the title the same as the file name.

Setup ssh-agent

Whenever you interact with GitHub from the command line, you’ll be prompted to supply the passphrase. This quickly gets tedious.

Happily, there is a way around this; the openssh project has provided ssh-agent which can remember the passphrase for you.

ssh-agent may already be running on your system. Check this with the command:

ssh-add -l

If this responds with something like “Could not open a connection to your authentication agent” then ssh-agent is not running; if it responds with “The agent has no identities” then the agent is running but not configured to supply the passphrase for any identities.

To start the agent on a BASH or Bourne shell system, use the command

eval `ssh-agent -s`

Those are back-ticks, not single-quotes.

Then you can add your GitHub identity using:

ssh-add ~/.ssh/account.github.id_rsa

Setup SSH config file

To make sure the connection to GitHub uses the identity you created, it is best to create an alias in the ~/.ssh/config file. The following entry should work; modify the name and the identity file to match your identity and preference.

Host mygithub
	User git
	HostName github.com
	PreferredAuthentications publickey
	IdentityFile ~/.ssh/account.github.id_rsa

In fact, this is the only way to get the command line git to connect with the identity you’ve associated with the GitHub account. So instead of:

git clone git@github.com:account/myrepo.git

you enter:

git clone mygithub:account/myrepo.git

Now, if you cd into the local repo and enter the command “git remote -v”, you should see something like:

origin	mygithub:account/myrepo (fetch)
origin	mygithub:account/myrepo (push)

So all your push requests should use the correct identity when communicating with GitHub.

Cloning to a local Git repository from one of your GitHub repositories

This is pretty straightforward; especially so if you’ve followed the SSH setup advice given in a previous section.

git clone mygithub:account/myrepo.git

where mygithub matches an alias in the ~/.ssh/config file, account is your GitHub account, and myrepo is the name of your repository (the one you want to clone to the local system).

Have one remote at GitHub and another in Gitolite

I have all my repositories hosted on a server running gitolite. Some of the projects I also publish on GitHub.

Scenario: starting with a forked GitHub project.

In this scenario, I’m going to take the peg- multimarkdown project, fork it, import it into gitolite, and then setup all the remotes needed to keep in sync with the two remote repositorites.

I forked peg-multimarkdown some time ago. I just did this interactively using the GitHub website. So I can proceed with cloning a local repo and the adding it to gitolite.

I have a host alias github-je for my GitHub account in my ~/.ssh/config, so I clone the repo using:

cd ~/git-repos
git clone github-je:JeNeSuisPasDave/peg-multimarkdown.git

When I show all the branches, I see many remote branches other than just the master.

~/git-repos$ cd peg-multimarkdown/
~/git-repos/peg-multimarkdown$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/cocoa
  remotes/origin/development
  remotes/origin/gh-pages
  remotes/origin/glibfree
  remotes/origin/glibfree-unix
  remotes/origin/html5
  remotes/origin/mac-compatibility
  remotes/origin/mac-installer
  remotes/origin/master
  remotes/origin/original
  remotes/origin/windows-installer
~/git-repos/peg-multimarkdown$

If I create a bare repo from what I have now, I’ll loose all those remote branches. So, I need to capture each branch, and then switch back to the master, as follows:

git checkout -t origin/cocoa
git checkout -t origin/development
git checkout -t origin/gh-pages
git checkout -t origin/glibfree
git checkout -t origin/glibfree-unix
git checkout -t origin/html5
git checkout -t origin/mac-compatibility
git checkout -t origin/mac-installer
git checkout -t origin/master
git checkout -t origin/original
git checkout -t origin/windows-installer
git checkout master

The -t is so that the local branch tracks the remote branch.

Now I can create a bare repo:

cd ~/trash
git clone --bare ~/git-repos/peg-multimarkdown

and archive and compress the bare repo so that I can easily transfer it to the gitolite server:

tar -czf peg-multimarkdown.git.tgz peg-multimarkdown.git

sftp that to the gitolite server and unarchive it into the repositories folder:

cd ./repositories
tar -xzf peg-multimarkdown.git.tgz

Make sure the ownership and permissions is correct for all folders and files in the tree.

Now back on the local system, I clone the repo from gitolite (using my host alias gitolite):

git clone gitolite:peg-multimarkdown

And if I look at the branches and remotes I see:

$ cd peg-multimarkdown
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/cocoa
  remotes/origin/development
  remotes/origin/gh-pages
  remotes/origin/glibfree
  remotes/origin/glibfree-unix
  remotes/origin/html5
  remotes/origin/mac-compatibility
  remotes/origin/mac-installer
  remotes/origin/master
  remotes/origin/original
  remotes/origin/windows-installer
$ git remote -v
origin	gitolite:peg-multimarkdown (fetch)
origin	gitolite:peg-multimarkdown (push)

Now we need to add remotes for my GitHub repo and the original repo that I forked. The way to do that is:

git remote add upstream github-je:fletcher/peg-multimarkdown.git
git remote add myupstream github-je:JeNeSuisPasDave/peg-multimarkdown.git

Now the remotes look like:

$ git remote -v
myupstream	github-je:JeNeSuisPasDave/peg-multimarkdown.git (fetch)
myupstream	github-je:JeNeSuisPasDave/peg-multimarkdown.git (push)
origin	gitolite:private/datihein/peg-multimarkdown (fetch)
origin	gitolite:private/datihein/peg-multimarkdown (push)
upstream	github-je:fletcher/peg-multimarkdown.git (fetch)
upstream	github-je:fletcher/peg-multimarkdown.git (push)

And fetch from each, then show the branches

$ git fetch upstream
$ git fetch myupstream
$ git branch -a
$ git branch -a
* master
  remotes/myupstream/cocoa
  remotes/myupstream/development
  remotes/myupstream/gh-pages
  remotes/myupstream/glibfree
  remotes/myupstream/glibfree-unix
  remotes/myupstream/html5
  remotes/myupstream/mac-compatibility
  remotes/myupstream/mac-installer
  remotes/myupstream/master
  remotes/myupstream/original
  remotes/myupstream/windows-installer
  remotes/origin/HEAD -> origin/master
  remotes/origin/cocoa
  remotes/origin/development
  remotes/origin/gh-pages
  remotes/origin/glibfree
  remotes/origin/glibfree-unix
  remotes/origin/html5
  remotes/origin/mac-compatibility
  remotes/origin/mac-installer
  remotes/origin/master
  remotes/origin/original
  remotes/origin/windows-installer
  remotes/upstream/cocoa
  remotes/upstream/development
  remotes/upstream/gh-pages
  remotes/upstream/glibfree
  remotes/upstream/glibfree-unix
  remotes/upstream/greg
  remotes/upstream/html5
  remotes/upstream/mac-compatibility
  remotes/upstream/mac-installer
  remotes/upstream/master
  remotes/upstream/original
  remotes/upstream/windows-installer
  remotes/upstream/xcode

Moving a local Git repository into GitHub

This is a nearly exact pull from the GitHub online documentation.

If you have a repo on an external server that you wish to move to GitHub, you can move it with a special clone and push. This method will create an exact mirror of the repo into the new repo.

First, create a new repo on the target account. Next, create a mirror that includes all branches and tags. To do this you need to do a bare-clone followed by a mirror-push:

git clone --bare url/for/my-old-repo.git
cd my-old-repo.git
git push --mirror git@github.com:mycompany/my-new-repo.git
cd ..
rm -rf my-old-repo.git