Creating a Git repository and making it public
The standard Git documentation is pretty damn good, but a bit long-winded when it comes to this, so I thought I would create a more succinct HOWTO here.
Our Goal
Or goal is simple. We have some code that we’ve written and we’d like to turn it into a Git repository that is stored on our Git server. In this example I will be using the procedure I used to add Snippy:http://dev.funkynerd.com/projects/snippy to my public Git server.
Housekeeping
Before we do anything here, there are a few things you may need to get setup first. You only need to do these once so if you have already done them you can just skip this section
User-based Git Config
It is ALWAYS a good idea to have a .gitconfig file in your home directory (for Linux workstations, obviously). So, create the file ~/.gitconfig and add at least the following to it.
[user]
name = {your name}
email = you@yourdomain.com
This is used by Git when you commit stuff and makes sure that your commit identity is consistent. May I also suggest that you do this for everything computer that you expect to commit to git from, regardless of platfrom, and make sure the parameters are consistant. This will save on some ugliness later.
If you are on Windows, then sorry, I can’t help you right now, but I’m sure you can figure it out.
Create the repository root directory
I keep all my code repositories in /var/local/git. Here is a listing of how it looks:
drwxr-sr-x 7 root staff 4096 2011-02-01 11:41 git
As you can see, I have added the directory to the _staff_ group and make the group sticky. This means that anything created under that directory will have the default group of staff. Make sure your Git repository directory is setup like this.
To get the directory created just do the following:
$ sudo mkdir /var/local/git $ sudo chgrp staff /var/local/git $ sudo chmod g+ws /var/local/git
That’s all there is to it. Now we have a nice place to start adding our repositories.
Initialise the local repository
Basically all we need to do is change to the directory where our code is, create an empty Git repository and make our initial commit.
$ cd /usr/src/snippy $ git init Initialized empty Git repository in /usr/src/snippy/.git/ $ git add * $ git commit
When prompted, add your initial commit message (I usually just put “Initial commit of {project name}”). You now have a populated local repository that you can use “as is” to manage your code. Even if you choose not to make it public now, you can do so later at any time by just continuing on with the below steps.
Create a public repository
This bit is the most complicated part due to the permissions required to allow write access to certain users. Hopefully the steps below make it a bit easier to follow.
Here’s how you create the repository and set the permissions up to allow write access.
$ sudo git init --bare /var/local/git/snippy.git Initialized empty Git repository in /var/local/git/snippy.git/ $ sudo chmod -R g+w /var/local/git/snippy.git $ sudo touch /var/local/git/snippy.git/git-daemon-export-ok
Note: The git-daemon-export-ok is required to allow the git-daemon to export the repository. If this file does not exist, the git-daemon will not export it.
That’s it. Now you just need to make sure that anyone you want to allow access to write to your repository is a member of the staff group.
Making our repository public
This step involves setting up our local repository with the location of our previously created public repository and pushing our commit out to it.
Setting up
When we initialised the local repository, Git created a hidden sub-directory called .git. In there is a file called config that we need to edit.
Mine looks like this:
[core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = git://dev.funkynerd.com/snippy.git [branch "master"] remote = origin merge = refs/heads/master [remote "pub"] fetch = +refs/heads/*:refs/remotes/origin/* url = ssh://dev.funkynerd.com/var/local/git/snippy.git push = refs/heads/master:refs/heads/master
The [remote "origin"] section defines a remote repository that we can fetch from. The [branch "master"] section tells git that master is a remote branch located on the *origin* server which is where we want to get our sourcecode from when we issue a *pull* command with no repository specified. Finally, [remote "pub"] defines a remote repository that we can write to for push commands. Notice that this uses ssh instead of git. This is because git does not allow writing. This is also so that git can make use of ssh’s security functions. So if you can ssh to the server with a shared key, then you can push your git repository. If you don’t use a shared key then you can still use a password if your ssh server allows it.
Making the push
Lastly, all we need to do is push our local repository to the public one.
$ git pull $ git push pub Counting objects: 160, done. Delta compression using up to 2 threads. Compressing objects: 100% (152/152), done. Writing objects: 100% (160/160), 293.01 KiB, done. Total 160 (delta 26), reused 0 (delta 0) To ssh://dev.funkynerd.com/var/local/git/snippy.git * [new branch] master -> master
If you see something like the above then you’re good to go. For good measure it always recommended that you issue a git pull once you’ve done a push, just to make sure everything is in sync.
This time, you should get the following:
$ git pull Already up-to-date.
You’re now good to go.
On-going usage
While you continue to develop just be aware that there may be others pushing changes to the public repository. Git is pretty good at getting the right changes in without messing up things but there are some good practices to keep in mind that help minimise the chance of something getting screwed up.
Before you push, do a pull.
$git add $git commit $ git pull Already up-to-date. $ git push pub
You may not always be up to date and some changed may come down. Most of the time they will just get merged in without a problem. Sometimes there will be conflicts which Git will guide you through resolving at this point.
When you’ve pushed, do another pull
$ git push $ git pull Already up-to-date.
This just keeps everything in sync. See, when you push stuff to the remote repository that push is also tracked as a commit and has a commit ID. It’s wise to do a pull straight away so that those commits are also known in your local respository. Really, it would be nice if a push implied a pull because 99.9% of the time you do this. But the coolness of Git is that it caters for all situation, including the 0.01% of the time you don’t want to pull straight away.