skey - web developer

Setting up a Git Repository

by on

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 basicaly holds 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 setup your own git repository in your local company infrastructure.

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, 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 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

What we need?

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. Lets 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. We can check what it is.


    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

Yes it's nothing else, just a directory and when we go into 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 setting. The hooks are stored in Hooks directory. Probably 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, thats not the 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 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 give you now 2 minute break to check your twitter and facebook feeds. ... Another funny cat on social media and we can carry on.

2.a Cloning local copy of Git Repository

Now that we are back in our computer, lets go to our project. Your project may be in different folder. Mine are 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 in central repository to our local copy. It's empty now, because we just created it and didn't commit anything. 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 thee dot . to the end of the 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 : after IP address means relative path, so you would need to remove that to use absolute path. Something like this: git clone ssh://user@192.168.1.26/Users/user/Repositories/myproject.git .

2.b Initialize local and setup remote tracking

By cloning the repository we download the files from the repository. 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 also 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. 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 for git about the repository.


    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 and pulled from repostory 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.

Let's new create 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 * to add to git all files in current folder or any other modificators. 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 finished 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 new branch was created in central repository, the master branch. We can see this only when 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 or hostname. We could even create a subdomain to hold 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. If you spot any error please, let me know.