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.
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 email@example.com 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
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 firstname.lastname@example.org: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 email@example.com:Repositories/myproject.git
: after IP address means relative path, so you would need to remove that to use absolute path. Something like this:
git clone ssh://firstname.lastname@example.org/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 email@example.com: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
Stefans-iMac:myproject.dev stefan$ git remote -v origin firstname.lastname@example.org:Repositories/myproject.git (fetch) origin email@example.com: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 firstname.lastname@example.org: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.
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.