Git DVCS Server Setup and Use in a Team
It seems that all the software developers are using git DVCS these days. I haven’t done serious software development in many years, so I’ve been using RCS all this time for my system admin scripting needs. With my new development work, I need to upgrade my toolset to a DVCS – Distributed Version Control System. There are many reasons to do this even if you don’t want to publish all your code on the internet. Below I’ll show how to setup an internal git server that can be shared inside a company or just between friends on the internet.
I’ll assume:
- Your git server will be on a Linux/Unix system someplace where
- all the developers will have ssh connection access.
- You have git installed on the server and the clients already.
Those server connections may allow full shell access or be limited to support just git. Regardless, setting up ssh-keys – Ssh Config Setup – is a good idea between the client(s) and the server computers.
Keep reading to learn about Git setup.
Understanding GIT
Understanding GIT is beyond what we want to cover today. I found a few youtube videos which explained it well enough.
- Introduction to Version Control Systems – Part 1
He does a nice job explaining version control and distributed version control. The Part 2 video isn’t bad but the recording cut off the bottom of his terminal, so we didn’t see the commands. There are better videos with the actual commands or just read a little further.
Even if you don’t do software development, there are lots of other reasons to setup git and have repositories. For text files, git is extremely efficient and recommended, but for binary files, not so much.
For example, many people keep their Linux configuration files in a git repository. This means that doing an upgrade for 1 program doesn’t risk your other desktop settings. It also means you can get back whatever the prior settings were or completely mirror all your settings to another system. That’s pretty sweet in my book. It can have much finer levels of control when compared to daily backups. Of course, having that control means you manually need to take a snapshot, but doing that before and after any change is pretty easy.
There’s 1 key idea for git. Git repositories are based on the current directory in which you are working. For Linux/Unix people, this is second nature and goes without saying. On Windows, the actual directory you are working from is less clear. Pointing an clicking on directories seldom actually changes the POSIX cwd in Windows. That means you want to be
use a command prompt and be in the top level directory for your project when you perform git commands.This is critical. I suppose there are ways to force a directory with an environment variable or some programs may let you setup a top-level project directory, but if you work on multiple projects with different git repositories, that can be cumbersome to manage.
Server-side Repository
The server-side repository doesn’t need any source code to be setup. You won’t be working in the repository, no compiling or other development things there. It is a place to put code, other assets and code changes via the git command. It will be completely managed by the git tool, not you. Hands off.
I’ll assume you got ssh working between the client(s) and server systems previously.
$ ssh userid@server
We all know that ssh rocks and that it is secure, provided you have very strong passwords and/or use key-based authentication. All Git commands and transfers happen inside an ssh tunnel. Pretty sweet, again.
Step 1 – Groups
Login to the server and setup a different UNIX group for each project and place the individual accounts into the new groups as needed. You may not need a different group for every development project, but you’ll definitely want at least 1 group.
Adding userids to groups is pretty easy. I tend to just edit the /etc/group file and add users to the end of the grp line manually. There are newgrp and addgrp or grpadd commands if you’d like to do it that way. The grpadd/addgrp commands are for root only. The newgrp command lets each user make the new group primary for that shell ( I think it is shell instance dependent ). Anyway, that doesn’t matter, just that they are a member of the appropriate group does.
On my remote server that will be used for ‘git’, I created a dev group and added the development team to that group. You may need to setup user accounts or want to connect the git repo server to your LDAP server for user and group controls. It is a good idea to have centralized access control in an LDAP directory after all. System Admins think about this all the time, software developers, not so much.
Step 2 – Initialize
$ newgrp dev $ mkdir repo; cd repo $ git init --bare --shared=group
This changes my current, active group to the new “dev” group, creates a directory to be used as the git repository and initializes it to be used by multiple people. The group permissions should be read/write. Here’s the resulting directory structure:
TOP
├── branches
├── config
├── description
├── HEAD
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── post-commit.sample
│ ├── post-receive.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── prepare-commit-msg.sample
│ ├── pre-rebase.sample
│ └── update.sample
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
That’s it on the server-side.
Client-side Git
On the client-side, create a directory for your new project.
$ mkdir proj
$ cd proj
$ git init
That sets up a local git repo, ready to be used for your code and changes. Drop some code changes into it.
User Setup
It is a good idea to tell git about you on a system.
$ git config —global user.name “Firstname Lastname”
$ git config —global user.email “your_email@youremail.com”
You can override these settings on each project, if you like.
Block Some Files from Git Management
Before you add all the files to your new project, we want to tell git to ignore some files and directories. If you are like me, you’ve been editing files and finally got something worth saving beyond the automatic daily system backups. I do not want all the files in there to be managed by git. Git understands exclusion lists. Edit
$ vi .git/info/exclude
and add a few regex patterns.
.mp4
*.mov
public/tn
public/v
db/sqlite*
I’ll update development tool managed files like DBIx::Class generated Result and ResultSet classes manually, so I want those files stored inside the git repo.
Ok, now we can recursively add everything in our project.
$ git add .
Let’s check the current status of git to be certain the files we didn’t want included were not.
$ git status
Shows only the files we like. Guess our pattern matching was good.
Our code hasn’t been put into the local repository yet. For that to happen, you need to commit.
$ git commit
then edit the very first lines with the reason for your commit. In the RCS world, this commit is the same as a ci – check-in. There is no co -l command at this stage.
Edit one of your files – a trivial edit is fine. I did an web application config.yml file. Nothing will happen with that file at this point. A commit will not do anything. You must “add” it to the list of files to be checked in. There are many different ways to handle this part of git workflow. Some will manually deal with each file for a new feature or bug they are working. If you work only one feature or bug at a time and then commit the changes together, all the files can be added with the
$ git add .command. That is my intention. 1 feature per commit regardless of the number of files involved. That includes test cases to test the feature. We don’t do test driven development here, but we do lots of automatic testing as part of our process.
$ git status \# On branch master \# Changes to be committed: \# (use "git reset HEAD <file>..." to unstage) \# \# modified: config.yml \#
Ah, we have outstanding changes to be committed – assuming we are done with the necessary changes. Time for a commit.
$ git commit -m "minor comment" $ git status \# On branch master nothing to commit (working directory clean)
No changes to be made. Ok, that’s all working. time to bring in the remote server with a repository.
Set an Origin
We’re still on the client machine and in the top level directory for this project.
$ git remote add origin ssh://user@server/directory/path/to/repo
Don’t forget that since we are using ssh, you can use your ~/.ssh/config to make life easy. Ssh Config Setup
You don’t have to use a remote server for your git repository. Having it on the same machine just means your origin becomes:
$ git remote add origin /directory/path/to/repo
Push to the Server
The next step is to push our local repo to the remote server. Since we just setup our origin, it is easy.
$ git push origin —all
For my little project, there were 64 files of 116KiB total. That was the compressed size, I guess.
If we work in a team, some other developer may be editing files inside our project. That means we’ll need to pull from the server repository sometimes.
$ git pull
In this case, git tells us there aren’t any differences.
Now that the remote repository is setup with all our code, we may want to deploy it to a test server. As a developer, this is were the rubber meets the road, since we all know everything works perfectly on our systems, but tend to break on production and test systems. ;)
Clone a Project / Git Repo
On your test server, setup just like it was a client.
$ git init
Now we want to clone the repository to get everything setup on the new system.
$ git clone ssh://user@server/directory/path/to/repo
Pull from the Server
As others make changes to the code, the test server (and your personal) repo may be missing changes. It is time to pull from the remote repository from the server.
$ git pull ssh://user@server/directory/path/to/repo
When you are testing, you may find some issue and correct it on that machine. For me, this is usually configuration changes. Don’t forget to
- “add” those files,
- “commit” the changes, and
- “push” the updates to the git repository.
Back on your development system, you will want to “pull” those changes from the git repository.
Other Topics
There’s lots of other features to git, but these will get you working today. Learn the advanced topics later, when you need them. For now, just get started using Git and all the power it brings to your software development.
Some of the other topics to look up later
- Tagging
- Branching
- Merging
My intent is to create a branch for every new feature or bug in my software projects and work on that branch to completion. When the test cases are all working and code it completed, I’ll merge this feature-branch back into the master branch and set a tag for the entire codebase with the formal change-management authorization tag. This is because git makes doing it easy. It provides a way to commit/checkin all the changed files for a single defect or feature at once. That’s very powerful and worthy of our use. It also means that determining exactly which files were touched for a bug or feature will be easier. This assumes everyone does it this way.
Git in practice is a study in democracy. There is nothing that makes any repository any more important than any other repository except that users decide to make it so.
What Did I Miss?
I’m fairly new to Git, so I must have missed some pretty critical things. There could be problems with the commands too.
The steps above assume you want a central server and want multiple users to have access to it. It is just as possible to have a read-only repository for use by lackeys and have 1 or 2 gatekeepers with authority to write to the main repo.
This is how the Linux kernel works. Code is provided upstream through different, trusted people who have been working on the Linux kernel. It is like a pyramid with Linus at the time accepting changes from his trusted, inner circle. This model scales really well, since every person of every layer can support 5-10 trusted lieutenants to provide tested code. It also means that when a lieutenant accepts your code, his reputation is on the line up the chain. Imagine each node has 5 child-nodes. Linus is at the top and he has 5 lieutenants and each of them have 5 lieutenants and to the next level. In just 4 levels, that is 158 people all working to make the Linux kernel better. Here’s a picture for 4 levels:
Linus
|____1
| |____a
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____b
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____c
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____d
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____e
| |____1
| |____3
| |____2
| |____4
| |____5
|____2
| |____a
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____b
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____c
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____d
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____e
| |____1
| |____3
| |____2
| |____4
| |____5
|____3
| |____a
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____b
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____c
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____d
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____e
| |____1
| |____3
| |____2
| |____4
| |____5
|____4
| |____a
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____b
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____c
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____d
| | |____1
| | |____3
| | |____2
| | |____4
| | |____5
| |____e
| |____1
| |____3
| |____2
| |____4
| |____5
|___5
|____a
| |____1
| |____3
| |____2
| |____4
| |____5
|____b
| |____1
| |____3
| |____2
| |____4
| |____5
|____c
| |____1
| |____3
| |____2
| |____4
| |____5
|____d
| |____1
| |____3
| |____2
| |____4
| |____5
|____e
|____1
|____3
|____2
|____4
|____5
That’s scalability. It is actually the reason that Linux created git.
Videos on Git Server Setup
- Setup Git Server
- Another Setup Git Server
- Git Server Workflow for a Website This guy was so quick with his terminal that I had to pause the video a few times to catch up.