Setting up a Git Repository

Posted by Stefan Kecskes on Friday, September 18, 2015

Code repositories

Repositories these days are one of the basic stones of any software development. It allows teams of people to work together on one piece of software and allow every team member to see who made what changes, when and why. Repositories basically hold the copy of all changes made to code and also gives you the latest, most recent version. I don’t want to go deeply into why is it good and why we (developers) can’t live without it. There are great articles on this topic on internet here or here. Today, I want to show you how you can set up your own git repository in your local company infrastructure. Although, there are other solutions like SVN, CVS, Mercurial, they are marginal these days as git has become de facto only standard used globally across industry.

Why should I use local Git Repository?

Well, that’s great question. I know, there are many great services like bitbucket, sourceforge, github or google code ( the last one has ended its existence :) but sometimes you just want to learn how this stuff works behind the nice IO, how you could replicate their functionality with your own solution or in my case manager is afraid of data security and doesn’t want to pay for the service. In my case, I could end up with 10+ codebases of our clients, without any revisions, history checking etc. Actually when I joined this employer, we had a server where we stored copies of codebases in folders. Many copies of one project, some of them called, latest_backup or new_backup. Yes, I said to myself same - WTF? and then started to think how to solve this and come up with this simple solution.

What are we going to achieve?

We want to have a place on server, I mean a folder, where we will store all our repositories. We want to be able to connect to this server with git and download (pull) or upload (push) our changes to repository. This place will serve as master remote place and everybody will pull from and push to this place. We will also have our local copy of repository on our development machine and that will be the folder on which we will work on daily basis.

Central repository

Prerequisites

As this solution uses open source tools and the infrastructure of your company is already in place all you need is only:

  • About an hour of time
  • server, where you can SSH (for remote master repository)
  • server will have git installed on it.
  • your computer with terminal on it

1. Creating Git repository

Use terminal to log into your server through SSH. I already explained how to make SSH connection so just log in. Your username and IP will be probably different from mine example. Git will track the remote repository by hostname, in our case it will be IP address. Therefore, this server will need to have same IP address all the time, so if its on wifi or your company router uses DHCP, then please make sure that this server will have static IP.

	Stefans-iMac:~ stefan$ ssh user@192.168.1.26
	Last login: Thu Sep 10 16:21:57 2015
    delta:~ user$

Now we are in home directory of user user on our server. We can see it as ~ after the machine name or check it by pwd

	delta:~ user$ pwd
    /Users/user

I decided that we can make here folder Repositories, but you can make it anywhere you want.

	delta:~ user$ mkdir Repositories
	delta:~ user$ cd Repositories

We will create all of our central repositories in this folder. We will use command git init which creates an empty repository, but because we want to create shared repository instead of working directory we will use the --bare flag. Let’s start with the first repository called myproject. It’s good practice to add .git to the project name so that we will know that it contains the git repository.

	delta:~ user$ git init --bare myproject.git
	Initialized empty Git repository in /Users/user/Repositories/myproject.git/

That’s it. The empty bare repository was created and this will act as remote central repository for all users. We can check how it looks like in linux file system:

	delta:Repositories user$ ls -la
    total 3
    drwxr-xr-x  19 user  staff   646 17 Sep 11:08 .
    drwxr-xr-x+ 25 user  staff   850 10 Sep 16:22 ..
    drwxr-xr-x  10 user  staff   340 17 Sep 11:08 myproject.git

Yep, it’s nothing else, just a directory and when we go inside it we can see what it contains:

	delta:Repositories user$ cd myproject.git/
    delta:myproject.git user$ ls -la
    total 24
    drwxr-xr-x  10 user  staff  340 17 Sep 11:08 .
    drwxr-xr-x  19 user  staff  646 17 Sep 11:08 ..
    -rw-r--r--   1 user  staff   23 17 Sep 11:08 HEAD
    drwxr-xr-x   2 user  staff   68 17 Sep 11:08 branches
    -rw-r--r--   1 user  staff  112 17 Sep 11:08 config
    -rw-r--r--   1 user  staff   73 17 Sep 11:08 description
    drwxr-xr-x  11 user  staff  374 17 Sep 11:08 hooks
    drwxr-xr-x   3 user  staff  102 17 Sep 11:08 info
    drwxr-xr-x   4 user  staff  136 17 Sep 11:08 objects
    drwxr-xr-x   4 user  staff  136 17 Sep 11:08 refs

We can see that the branches are stored in branches directory. It contains HEAD, config and description files, which hold settings. The hooks are stored in Hooks directory. You will never need to make any changes here, but it is good to know that such things can be found inside repository folder. We never work directly in this directory, that’s not a good practice, that means that we never make commits here, we should only pull and push from here. We are done on server side of repository and can log out from our server’s SSH instance.

	delta:myproject.git user$ exit
	logout
	Connection to 192.168.1.26 closed.
	Stefans-iMac:~ stefan$ 

Great, we have made almost all the hard work.

I’ll give you now a 2-minute break to check your social feeds and let’s meet here soon again.


You just checked all your successful friends that you don’t care about anyway, and we can carry on with code repositories.

2a Cloning local copy of Git Repository

Your projects may be in different folders. Mine are usually in my home directory in ~/Projects/myproject.dev/.

	Stefans-iMac:~ stefan$ cd Projects/myproject.dev/
    Stefans-iMac:myproject.dev stefan$ 

We are going to clone the stuff from the central repository into our local repository. The central repo is now empty, because we just created it, and we didn’t commit anything yet. Anyway we have to do this step, so that the git will now which remote repo to track.

	Stefans-iMac:myproject.dev stefan$ git clone user@192.168.1.26:Repositories/myproject.git .
	Cloning into '.'
	warning: You appear to have cloned an empty repository.
	Checking connectivity... done.

I added a dot . to the end of the clone command, to tell git to clone inside current directory. If we wouldn’t have folder myproject.dev, the git would create it for us. The command would then look like this git clone user@192.168.1.26:Repositories/myproject.git. The colon : after IP address means relative path, so you would need to remove that to use absolute path. For absolute paths it would look something like this: git clone ssh://user@192.168.1.26/Users/user/Repositories/myproject.git .

2b Initialize local and setup remote tracking

By cloning the repository we actually download the files from the repository (2a). This is cool as git gets everything for us with one command. There may be problem to clone into non-empty folder as clone command is not capable of merging, it just gets the clean copy of remote repository. There is no point in cloning empty repositories like our, which we just created. Therefore, the other solution is to initialize the local git working directory and then set up the tracking to some remote bare repository. Let’s do it now in 2b approach. We will create folder for our new project and go inside, initialize git inside it and then set up our local git to track the remote bare repository.

	Stefans-iMac:Projects stefan$ mkdir myproject.dev
    Stefans-iMac:Projects stefan$ cd myproject.dev/
    Stefans-iMac:myproject.dev stefan$ git init
    Initialized empty Git repository in /Users/stefan/Projects/myproject.dev/.git/
    Stefans-iMac:myproject.dev stefan$ git remote add origin user@192.168.1.26:Repositories/myproject.git

By checking the folder content, we can see that git created folder named .git which is hidden and holds all the information about the repository for git.

	Stefans-iMac:myproject.dev stefan$ ls -la
    total 0
    drwxr-xr-x   3 stefan  staff   102 17 Sep 12:05 .
    drwxr-xr-x  30 stefan  staff  1020 17 Sep 12:05 ..
    drwxr-xr-x   9 stefan  staff   306 17 Sep 12:06 .git

We can also check what is the remote repository by simple command remote -v

	Stefans-iMac:myproject.dev stefan$ git remote -v
    origin	user@192.168.1.26:Repositories/myproject.git (fetch)
    origin	user@192.168.1.26:Repositories/myproject.git (push)

3. Send changes to repository

Making the changes to repository are called commits, and sending to bare repository server is called pushing. We can make more commits to code and push them at once. Our colleagues will not know about our changes, until they are pushed by us to central repository and pulled from central repository by them. If you pull changes from repo, it will download all the commits, so you don’t have to pull commits one by one.

Lets create new file:

    Stefans-iMac:myproject.dev stefan$ echo "Hello world" >> index.html

Now we have to tell to git that we want this file to be added to git repository. We can use * wildcard to add to git all files in current folder or any other modification. We do this step only when adding new files to repository. Git will automatically check changes in files added before.

	Stefans-iMac:myproject.dev stefan$ git add index.html

Next we want to tell git that changes are finalized, and we want git to save the changes - commit the changes. Good practice is to add some message about the changes, so that our colleagues will now why are we making changes to code.

	Stefans-iMac:myproject.dev stefan$ git commit -m "created index file"
    [master (root-commit) e74a749] created index file
     1 file changed, 1 insertion(+)
     create mode 100644 index.html

And finally we want to send this information to central repository, so that our colleagues can pull changes made by us. We can remove commits or change them before pushing them. Once the changes are pushed to central repository, they will become its part and can’t be removed from the history. Make sure that you don’t push bugs to repository, as some teams may practice to The Board of Shame, where nobody wants to see their name.

	Stefans-iMac:myproject.dev stefan$ git push -u origin master
    Counting objects: 3, done.
    Writing objects: 100% (3/3), 235 bytes | 0 bytes/s, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To user@192.168.1.26:Repositories/myproject.git
     * [new branch]      master -> master
    Branch master set up to track remote branch master from origin.

We see also information that the new branch was created in central repository, the master branch. We can see this only after the new branch is created, but branches are not in scope of this post.

Conclusion

We created bare central repository on the local server, but we could do the same on any server with static IP address, hostname or a subdomain that holds our repositories. Then learned how to create our local working repository. One way for cloning the existing project and second for creating first commits and pushing it into repository.