Version Control System
Version control is the only reasonable way to keep track of changes in code and documentation. It allows to step back to any previous version easily. But the really big advantage comes if multiple developers work together.
There are some different version control systems available but after the use of git since some time it was clear to go on with it. Not only because it is good but also because it has a lot of other advantages coupled with GitHub.
1. Git
Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.
Git is easy to learn and has a tiny footprint with features like cheap local branching, convenient staging areas, and multiple workflows.
Read more in the Git book
The general workflow is like:
1.1. Installation
At first install the repository software and CLI:
$ sudo apt-get install git-all
The setting of the default user will tell Git that you don’t want to type your user name and email every time your computer talks to Git.
# use the settings you use on the central origin repository (maybe GitHub)
$ git config --global user.name alinex
$ git config --global user.email [email protected]
Password caching
To also keep Git from asking for your password every time, you need to turn on the credential helper so that Git will save your password in memory for some time:
$ git config --global credential.helper cache
This will keep the password for 15 minutes in memory. But you can also have Git store your credentials permanently using the following:
$ git config --global credential.helper store
Note: While this is convenient, Git will store your credentials in clear text in a
local file .git-credentials
under your “home” directory
1.2. Basic work flow
The most common commands are shown in the following work flow. Here everything is shown using CLI calls but you may use with any Git tool or your editors integration for Git.
To work on a project you have to clone it first:
$ git clone <repository url>
$ cd <repo dir>
This will create a complete clone of the whole repository in a subdirectory with the last name of the repository url.
Now you may go into it and change something. Afterwards you have to add the changes:
$ git add -A <changed path>
If one change is done commit it with a short descriptive message (will be asked interactively):
$ git commit
Later if your whole work is done you can push your local changes to the origin server so that other developers will also get them.
$ git pull # first pull the changes of others and merge them (automatically)
$ git push # now send your own changes
If you reached a new major, minor or bug fix version or also a special state of the code you should add a tag to get this version easily later:
$ git tag -a v1.4.0 -m 'version 1.4.0 with ....'
Here a new version 1.4.0 is tagged.
1.3. Branching
The organization of branches may be differ on your needs, you may use Git here in different ways:
- Historical branching there the
master
branch stores the official release history, and thedevelop
branch serves as an integration branch for features. It's also convenient to tag all commits in themaster
branch with a version number. - Feature branches with each new feature residing in its own branch, which can
be pushed to the central repository for backup/collaboration. But, instead of
branching off of
master
, feature branches usedevelop
as their parent branch. When a feature is complete, it gets merged back intodevelop
. - Release branches there once
develop
has acquired enough features for a release
arelease
branch is forked off ofdevelop
. Only bug fixes, documentation generation, and other release-oriented tasks should go in this branch. Once it's ready to ship, therelease
gets merged intomaster
and tagged with a version number. In addition, it should be merged back intodevelop
, which may have progressed since the release was initiated. - Maintenance branches are used as
hotfix
branch to quickly patch production releases. This is the only branch that should fork directly off ofmaster
. As soon as the fix is complete, it should be merged into bothmaster
anddevelop
.master
should be tagged with an updated version number.
An full example of the different types of branches put together:
But that's only one possibility, every organization is free to use branching as they need but it is important to clearly decide and communicate the proper way used within the organization.
Create a new branch using:
$ git checkout -b <name>
Show the current branch:
$ git branch
Switch between branches:
$ git checkout <name>
To merge it with the master:
$ git checkout master
$ git merge <name>
To remove the branch after done:
$ git branch -d <name>
To sync the changes use (for all branches):
$ git pull --all
$ git push --all
1.4. Special use cases
Moving repository
First you have to fetch all remote branches:
$ git fetch origin
Now check if all branches are local:
$ git branch -a
If there are some branches listed as remote which didn’t exist as local ones you have to check them out:
$ git checkout -b <name> origin/<name>
Now define a new remote repository:
$ git remote add new-origin <url>
Everything set up so you may transfer the repository:
$ git push --all new-origin
$ git push --tags new-origin
At last you may delete the old origin and rename it:
$ git remote rm origin
$ git remote rename new-origin origin
Pull/push to origin
Use the preset names:
$ git pull origin master
$ git push origin master
Subversion Integration
If you have a subversion server as master you may also use git for your work and sync the changes back to subversion as the master repository.
To use this you have to install the extension:
$ apt-get install git-svn
To do so you first init your git repository from the subversion master and load the initial data:
$ git svn clone -s https://github.com/alinex/my-repo
# -s is for --stdlayout which presumes the svn recommended layout for tags, trunk, and branches
If you don’t want the complete history you may use:
$ git svn clone -s -r 40000:HEAD https://github.com/alinex/my-repo
# -r is for the revision to start taking history from
To update your repository to HEAD of subversion master run:
$ git svn rebase
And to push your commits further to subversion:
$ git svn dcommit
Working with forks
If you have a fork you may add an additional remote repository:
$ git remote add upstream
To sync this you have to:
$ git fetch upstream
$ git checkout master
$ git merge upstream/master
1.5. Server Setup
If you want to use your own central repository you have to setup a git server:
Install the required package
$ sudo apt-get install -y git-core
Authenticated ssh access
Next you create a local user to access git using ssh:
$ sudo adduser git
$ su git
$ cd
$ mkdir .ssh && chmod 700 .ssh
$ touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys
Next you need to add each developer SSH public keys to the authorized_keys file for the git user.
$ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys
Now, you can set up an empty repository for them as described below.
The address will be git@gitserver:/var/git/project.git
You can easily restrict the git user to only doing Git activities with a limited shell tool called git-shell that comes with Git.
$ cat /etc/shells # see if `git-shell` is already in there. If not...
$ which git-shell # make sure git-shell is installed on your system.
$ sudo vim /etc/shells # and add the path to git-shell from last command
$ sudo chsh git # and enter the path to git-shell, usually: /usr/bin/git-shell
Now, the git user can only use the SSH connection to push and pull Git repositories and can’t shell onto the machine. If you try, you’ll see a login rejection like this:
$ ssh git@gitserver
fatal: Interactive git shell is not enabled.
Connection to gitserver closed.
Http Access
This is done using the apache webserver with its possibilities.
Add the following to the apache site configuration:
SetEnv GIT_PROJECT_ROOT /var/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/
<Directory "/usr/lib/git-core*">
Options ExecCGI Indexes
Order allow,deny
Allow from all
Require all granted
</Directory>
<LocationMatch "^/git/">
AuthType Basic
AuthName "Git Access"
AuthUserFile /etc/apache2/git.passwd
AuthGroupFile /etc/apache2/git.groups
Require valid-user
</LocationMatch>
Now you may access the server.
Web Interface gitweb
$ apt-get install -y gitweb
Create a new server repository
First create a bare repository:
$ git --bare init <myrepo>
$ cd <myrepo>
$ git --bare update-server-info
$ cd ..
$ chown -R www-data:www-data <myrepo>
Now make a new local repository:
$ git init <path>
After you have everything committed add the remote and push the repository:
$ git remote add origin <url>
$ git push --all origin
$ git push --tags origin
Add the login credentials in the .netrc file which is used by curl:
$ cat ~/.netrc
machine <git.yourdomain.com>
login reader
password reader
2. GitHub
GitHub is a free code hosting platform for version control and collaboration with open source. It lets you and others work together on projects from anywhere. On top of the Git repository management it supports further services like
- Git viewer
- Integrated CDN
- Issue reporting and management
- Wiki pages
- Static site
- Easy collaboration
If you use GitHub there is no need to setup your own Git server anymore. It’s surprisingly easy to get things set up and most tasks can be done directly by clicking view the web front end.
You can also use a badge on your README.md
like:
[![GitHub watchers](
https://img.shields.io/github/watchers/alinex/node-rest.svg?style=social&label=Watch&maxAge=86400)](
https://github.com/alinex/node-rest/subscription)
[![GitHub stars](
https://img.shields.io/github/stars/alinex/node-rest.svg?style=social&label=Star&maxAge=86400)](
https://github.com/alinex/node-rest)
[![GitHub forks](
https://img.shields.io/github/forks/alinex/node-rest.svg?style=social&label=Fork&maxAge=86400)](
https://github.com/alinex/node-rest)
[![GitHub issues](
https://img.shields.io/github/issues/alinex/node-rest.svg?maxAge=86400)](
https://github.com/alinex/node-rest/issues)