Version control

Git

Git is used as version control system of the Linux kernel source. One really nice feature is that it needs no tricky server setup. The software can be developed in a directory not be worried about version control. Once when the need having a version control system pops up, the program git needs to be installed the usual way as any other program on your Linux distribution. Using git the hidden directory .git (the repository) will be added there where the source code is developed. A bare repository is kept inside this hidden directory .git that holds everything a version control system needs. The code being developed in the above directory becomes the working tree. In case of putting it on a server to have a master for different persons, just the content of the bare repository is required and no working tree makes sense to have on the server. A Git repository can be easily put on a server, however if the server is on the Internet then some security settings of the server make the setup difficult.

Instead of setting up a server https://github.com/ and it many ready and easy to go features can be used. Github allows easily to start a new repository, however it might be better to start with a local repository first and when convinced that the project will have some live time then move it to github.

For git see:https://git-scm.com/. To get help type:

git <git command> --help

man git-<git command>

git help<git command>

Before you start the first time with a fresh git installation let git know who you are, so it will know in the future who has done what when you work in a team:

git config --global user.name "<your name>"

git config --global user.email "<your@email>"

git config --list

To put a project under git clean up the directory first, it is recommended that object files, backup files and executables are not in the same directory (however a file .gitignore can be added that controls what will be checked). To put all files in the directory under git do:

cd <working directory>

git init to create and initialize the .git directory

git add . or git add -A to add all untracked files to the staging area.

git status

git commit -m 'Initial commit'

To add individual files (git add . adds all files) under git (or use wildcards as git add *.c), do:

git add<new file1><new file2>

Note

Git uses two steps to put the files in its archive. First you add them to the staging area, so the files change from untracked files to tracked files. Then the tracked files can be committed.

git reset <file name> to remove from the staging area. Alternatively the file can just be deleted and then commit will take care about the removal.

git reset removes all files from the staging area.

After that you can work normally. When you think it is time to have a good status of you work type:

git status

to see what you have done. You will see what files you modified and what files you created new, plus what new steps you can do with git.

After that do a:

git commit

If you have a clean directory (no backup files, no objects and runnable executables), you could do this faster by:

git commit -a

To see what you have done (key Q brings you back):

git log or the more compact version git log --oneline important is the commit id or just the first 10 characters of the commit id as git log --oneline shows

Ignoring files and directories

Inside the directory that git observes, there might be files and directories that should not be version controlled. Such directories and files might contain files automatically produced be integrated project environments.

To ignore files and directories, put the file .gitignore inside the directory. It is a text file that could contain something as:

# ignore backup files
*.h~
*.c~
# ignore compilation results
default/*

Going back

If not yet committed, getting rid of recently done modifications is easy. git status shows what has been modified since the last commit. git checkout -- <filename> will then get last version. -- seems to be there to mark the name as filename. If -- is missing then a commit name with the same name as the file might be taken. git checkout -- . will do it with all files not committed.

Release

If it comes to release, you should give your release a tag. Commits are identified by a commit number as af8dad733ecf500a859a09357576cbb5605cf543 that can be obtained by git show, git log or git log --oneline. Instead of dealing with those numbers or descriptions.

Commits can be tagged either annotated git tag -a <version> or lightweight (not recommended) git tag <version>.

Important

<version> is just a string that can be everything. It needs therefore some discipline to not end up messy. Examples are:

1.0

1.0-rc0 (release candidate 0)

Links how to do it:https://en.wikipedia.org/wiki/Software_versioning and https://www.python.org/dev/peps/pep-0440/.

An other issue is if V, v, Ver, ver , version, Version, ... should be put in front of the number. To keep it simple this can also be omitted, since people dealing with it know what 1.0-rc0 mean.

If something other than the head is tagged, the commit number can be passed git tag -a 1.0 af8dad733ecf500.

Note

The commit number does not have to be inserted completely, It just needs enough characters to be unique.

To see what tags there are type git tag

To delete tags git tag -d <tag name>

To create a zipped tarball of the latest version (HEAD)in the working directory (make sure you have committed everything):

git archive -o<name of the archive>.tar HEAD && gzip <name of the archive>.tar

Branch

If a well working version gets larger risky modifications or if a second programmer starts doing something, it is worth to make a branch, this means a new version that exists in parallel to the stable version the master. If everything goes well the branch can be merged with the stable version at some future moment, if not the branch can be deleted. To see what branch you have the type:

git branch

Note

More important * shows you what branch you work on

To create new branches type:

git branch<name of new branch> <tag from where it branches>

To checkout the branch (creating does not checkout):

git checkout<name of new branch>

To create and checkout

git checkout -b <name of new branch>

To merge the branch to the master:

git merge<name of new branch>

To delete a branch

git branch -d<name of new branch>

Cloning

git clone <uri><path to local directory>.git creates a clone of the git repository from the Internet on the local computer. It is a good habit to put .git to such directpry names.

On local filesystem the directory containing git (the git repository) could be simply copied but the clean way is git clone file://<path to local source directory><path to destination directory>

Note

git clone <path to local source directory><path to destination directory> will try to create hard links between source and destination. so use file:// do have a real copy.

When created a clone a complete copy is created changes will affect just one of them. To see where the local repository fetches and pushes its changes git remote -v

Remote repository are bare repository that have no working directories (working tree) where the files are checked out. The purpose of a remote repository is that the files checked out are on a remote machine and not on the server. A remote bare repository is a .git directory with a visible (not hidden) directory with a name as <name>.git.

Such a remote bare repository can be created from a regular repository.

git supports different ways of communication. The following uses http and does not require to have git installed on the server. On the server machine run

cd /var/www/htdocs or where your server data is

git clone --bare <path to the source repository><name of remote repository>.git

Some magic work needs to be done

cd <name of remote repository>.git

mv hooks/post-update.sample hooks/post-update

chmod a+x hooks/post-update

git update-server-info

Now when the magic is done a user can clone it with git clone http://<server name>/<name of remote repository>.git

git diff will show the differences between the two repositories

Important

The remote repository might have been changed (as by other developers) since the cloning. To get this update git pull origin master

git push origin master will then move back the work

Branches

Instead of working always on the newest version (the head of the master branch), other branches are made. The work/changes are then made on those branches.

git log --oneline shows on single lines what commits have been done

git branch <my branch> creates a branch at the the head

git checkout -b <my-fork-branch><commit as e4f5g6h> branches at a specific commit and switches to this branch

git branch -a will show all the branches (lists local and remote branches) and marks selected branch with *

git switch <my branch> will switch between brnches

git branch will show just all local branches

Important

Creating a branch does not mean working on it. To work on it it must be switched to it: git checkout <my branch>

git push -u origin <my branch> copies the branch to the remote repository

Merging is the step to get the master branch all of the work done in <my branch>

Important

Merging starts with switching back from <my branch> to the master branch git checkout master. To make sure the local master branch matches the remote master branch git pull origin master

git merge <my branch> will finally merge it into the master branch

git push origin master will then put the change to the remote.

git push origin HEAD:master --force is the command to overwrite the head master on the remote in case something went wrong on the remote repository

git branch --merged will show what branches are merged with the master branch and might therefore be deleted on the local repository as git branch -d <my branch> and on the remote repository as git push origin --delete <my branch> to see that all branches are deleted git branch -a

Gui

Git has also its Gui:

git gui

or

gitk

Since this GUI is quite complex to support everything it is recommended to not loose focus and start first with the simple console commands.

GitHub

When a project has some success it is ready to share it with others so https://github.com/ is a way to go. Everything can be done very intuitive in a web browser as create repositories.

The way to work in GitHub is create a branch from the master, so the master stays intact and ready to be used by others. Then do the work (commits) on the branch, make a pull request and merge it with the branch.

https://codeberg.org/ is an alternative for github.

create a git repository

Sign up and sign in in https://github.com/

Create a new repository using the github gui, add all files and directory to github and commit them using the gui.

Create a local branch

mkdir ~/GitHub create a directory

cd ~/GitHub/ and go into this directory

git clone https://github.com/linurs/linursoverlay.git get the repository from the Internet to the local directory

cd linursoverlay go into the repository

git branch <my-branch> even being local create a branch to keep also the master branch intact. This is later important to merge your work with the master branch on the Internet (GitHub)

Important

git checkout <my-branch> now let git know that you are going to work with your branch and that you like to keep the master branch intact.

Now to all the work in the directory.

Upload

When coming to an end do git status, git add and git commit until the git repository is happy.

Important

Remember the login username and access token to do the following. The access token is a long number that is used instead of the password to get access. Access tokens will be required in the future. The access token can be created using a web browser accessing GitHub.https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token

Finally do git push --set-upstream origin <my-branch> to have it on GitHub

Now on https://github.com/ create a pull request and if having the privileges merge it. The branch does not need to be deleted when planing new activities.

CVS (Concurrent Version System)

It is a tool that allows multiple software developers work simultaneously on the same project and handles different versions and releases. An other version control systems is: subversion, snv

Two branches (working activities) are commonly used:

  1. stable branch (Base branch) => just bug fix work being done

  2. unstable branch (Head branch)=> work to add new features

The unstable branch gets frozen from time to time to make releases

Note:

  1. Major releases have new features, therefore when an unstable branch get frozen the major release number will be increased.

  2. Minor releases are bugfixes of the stable branch and the minor release number gets increased.

Examples:

myprogram-3.2 => 3rd major release with 2nd minor release.

kde-3.5.2 => 3.5th major release, 2nd minor release

The CVS repository (main repository) is usually on a server but can also be local (local repository) when you make local development. The actual work is done in a working folder (synonyms: working copy, sandbox). CVS is a client sever architecture, where the CVS server is on the net somewhere as https://sourceforge.net/ and a CVS client is on your computer. If you have a local CVS repository then client and sever is on your machine.

To get the files in the working folder you need to checkout the module (module is the word for a CVS project, e.g. the program being developed).

Having once the files on the computer they can be updated to receive the changes from the colleagues working on the same files.

Committing is the command to store your work done in the repository.

CVS Internals

Inside the CVS repository there is a subfolder CVSROOT and subfolders for each project (or module) that has been created.

The files in the repositories are not stored in the same form as in the working directory. To the filenames ,v is added and the text-files get a CVS header whereas the original text is moved in between two @ characters. Therefore no additional files are required in the module directory of the repository. This is also one reason why to take care how to use binary files with CVS.

The local working directory gets all the source files and has a CVS subdirectory containing internal CVS data.

The CVSROOT subfolder inside the repository holds CVS internal data.

Cervisia

CVS is a command line tool but Cervisia is a GUI (graphical user interface) frontend for CVS. Useful Cervisia configuration:

In the Settings menu, check the Create Folders on Update box, the Prune Empty Folders on Update box and the Update Recursively box, directly on the menu.

Now, still on the Settings menu, click the Configure Cervisia... menu item.

Click the advanced icon in the icon list and set the Default Compression Level drop down to three. Press OK.

Cervisia has two windows one containing the files of the repository and the other one showing the CVS text commands issued and the responses.

Exporting files is used for making a release and does not copy the CVS subfolder. Tags are used to mark releases snapshots that later can be recreated. An alternative is using the date for that. It is obviously that you can not change and commit to the same date and tag (unless the tag is a branch tag). Tags are usually given a name consisting of the project name and the version number.

Tags are usually linear except branch tags that can create a branch and therefor leave the trunk. The trunk points to the head branch that grows up.

Leaving branch empty means head branch.

Revision A and B in the browse log are just used to mark a range of versions from version A to B to e.g. to see differences or create patches between versions.

How to create a repository

It is worth to create an empty subfolder in the CVSROOT, then checkout it to the working directory. Copy all files to the working directory, add them to the repository.

Watch out for binary files! For binary files don't use the add icon or the file->add to repository since this adds the mentioned header to the files and might corrupt them. Use instead the file->add binary command.

Then you have to commit all files so they appear in the repository. An alternative would be the Cervisia import module command.

Creating a Local Repository

mkdir /home/user/cvsroot

cvs -d /home/user/cvsroot init

mkdir /home/user/cvsroot/myproject

Finding The Repository Location And The Retrieval Method

generic

[:method:][[user][:password]@]hostname[:[port]]/path/to/main/repository

Example for local

:local:/home/user/cvsroot

Setting The Repository Location And The Retrieval Method

Using Cervisia to set the location: Cervisia has the ability to store different repository locations.

To add a repository location, click the Repository menu then the Repositories... menu item.

The Configure Access to Repositories dialog box will pop up.

Press the Add... button. The Add Repository dialog should appear.

Type the repository location in the Repository text box. Press OK.

If your repository's retrieval method is pserver, you still have to log in. The Status column is probably showing Not logged in.

Press the Login button. If you are using an Anonymous CVS mirror just hit enter. Else, type your password. If everything went well, now the Status column should show: Logged in.

If you want, add another location. Cervisia will store as many locations as you like!

Other version control systems

subversion is supposed to be the successor of cvs see: http://svnbook.red-bean.com/

http://bazaar.canonical.com/


Linurs startpage