Tuesday, August 31, 2010

How to run git daemon (quick 'n dirty)

First, I assume you have installed git and know how to clone a project from a repository.

Create a directory where you'll keep all your projects to be cloned and go into that directory. For example, we could call our repository trunk "MyRepoFolder".
#mkdir MyRepoFolder

Now, the first thing to do is clone a bare git repository. With bare I mean a clean repo without a working tree like modified files, staged files etc. To get this, we do as follows:
# git clone --bare ~/Development/CProject/myproject/ myproject.git

Next, we create a magic file "git-daemon-export-ok" in the project's directory.
# touch myproject.git/git-daemon-export-ok

Finally you can start the daemon, in my case it would be:
#git daemon --verbose --base-path=/home/nordin/MyRepoFolder

With the --verbose option you activate some loggings to stdout, so you can see if it works when you clone myproject from another pc.

If you want to clone "myporject.git" from another Linux pc, you should do as follows:
#git clone git://my.machine.ip.address/myproject.git

If this works, you can focus on the tweakings and other detailed stuff. But that's up to you :)

Saturday, August 28, 2010

Quick 'n dirty Vim for C developers part 1.

This will be updated as soon as possible.

A quick Git tutorial part 1, basics.

Git basics


Git basic commands

Git init or clone
To initialize your current project with Git, you first go to your root project folder. For example, below is your project:
MyProject
    |_ sources (directory)
    |    |_ main.c
    |    |_ foo.c
    |    |_ foo.h
    |
    |_ readme.txt (file)

Your root project folder is MyProject, in this folder you execute the following command:
# git init .


This means, initialize Git in this folder to result in a Git repository.
Next, is to add all folder and files to the newly created git repository:
# git add .


Finally, check in all the files as an official commit, which means the changes are really saved:
# git commit -m "The files are offically commited in the Git repo."


The argument -m means message, because for each commit, Git wants (or even forces) you to add a comment, so afterwards you can easily read why the changes are added to this commit.

Another way is to clone a git project from a remote machine (like projects from github), use this command:
# git clone http://url.of.the.server/project.git


Once you've done that, you get a complete project with all its history, without adding or committing. From now on, you can can create new branches, add modifications and issue new commits.


Git stages
In git you have several stages. In the beginning, if you add a file in your project, the file is considered as untracked by Git. This means, that although you perform a Git commit, the untracked file is not included to the final commit! To make the newly created file trackable by Git, you issue the command "git add filename". This brings the file into the tracked stage. If we modify this same file, it is than to be considered as modified by Git. So to include the modification in Git (meaning bring the modification in the Git index), we AGAIN issue "git add filename". Now the changes are in the 'Index' stage and is ready to commit (ready to make a new snapshot for this particular version). Finally, if we (git) added all the changes, we than issue the commit command "git commit -m 'message'". Now we've walked through all the workflow processes, these are the steps you often will perform.
So the workflow is like this:

step                            status
1 new file abc.txt    : untracked
2 git add abc.txt      : tracking
3 edit abc.txt            : modified
4 git add abc.txt      : indexed (meaning ready to be committed)
5 git commit             : commit the new changes (create new snapshot)

The place where you do changes and edits on files is called the "Working tree". When you (git) add those modifications, they're put on the index stage. When committing, those modifications in the index stage are than committed for a new snapshot.


Display the commits
If you want to see all the commits of a project, you can do as follows:
# git log

This will result in a list of all  commits, the picture below gives you a portion of the output of this command:


git-log output

We see in the above picture 4 items:
  • Commit: This is the hash value of the changes that has been added, also called a revision. The hash value is a checksum for validity of the changed data. If somehow the data got corrupted, we would get an error from Git that something wrong is going on.
    In the .git folder special objects are saved for each commit which contains the changes, of course protected by sha-1.
  • Author: The one who made the changes
  • Date: date of commit
  • message: additonal note/information about this commit
You can format this output with the available arguments, like:
# git log --pretty=oneline

A nicer one is:
 # git log --graph --pretty=oneline --abbrev-commit

Concerning the hash value, it's not so important to us, it's more important for Git. You don't need to look at it all the time, except when you want to go back to some previous revision and create a release out of it, or you want to perform a git diff, to see the difference in a certain file.

git-status
If you made some changes, you can check the current status. This way you can see what files are modified before committing.
# git status


git reset
With git reset you can revert back to its original state, meaning before you made some changes to files. It may happen you made a mess and you get panic. Be relax and do the following command:
#git reset --hard

This will remove all the changes (not the changes from previous commits) and go back to its latest commit (which is also called HEAD).
(More explanation needed here...)


git tag
git tag command is very useful too if you want to give a revision a tag name for a release. We can give a tag like this:
# git tag v1.0.2 -m "bug fix"

To tag a certain commit, you can do this:
# git tag v1.0.1 -m "update" 56ae0a9

This way you give a tag name for a commit, the first 7 character of the hash are enough.
Another very cool command is to get the sources from a certain tag. It's also much easier to remember if you want to go back to the last release of your software:
# git checkout v1.0.1


git branch
A very cool feature of git is you can make a copy of your complete source for editing, while you're still in the same repository. This is called branching. Without making a copy of all your sources in your repository to another directory, you can do the some editing in another copy which is called a branch. Normally you're already in a branch, called master, which is by default. By branching, you can make a complete copy of your project but under a different name. To make a new branch, you have to specify a name, for example:
# git branch -b mynewbranch

Now you're on a copy of your complete project and do some edits. To switch back to your original branch, you do:
# git checkout master

To get a list of branches:
# git branch

The one that is marked with an asterisk (*) is the current branch you're on.
Now we go back to the newly created branch:
# git checkout mynewbranch

If we added some changes and did some commits, we would like to add the changes to our master branch. To do that, we first go back to our master branch:
# git checkout master

And than merge the changes from mynewbranch to master:
# git merge mynewbranch

To delete 'mynewbranch' as we don't use it anymore:
# git branch -d mynewbranch

Thursday, August 5, 2010

C/C++ development basics on Linux

To develop C/C++ applications under Linux (and other OSs as well) there are some basic steps you need to do to write reliable applications.

When compiling your sources, it's very important to set the -Wall option. This will show all the possible warnings and errors during compiling. The errors should be fixed first, otherwise there will be no executable generated.
It's also important to fix all the warnings, normally you can ignore them, but be aware, there can be hidden bugs which come out when running a release version. So it's a good habit to fix all the warnings and errors before continuing. If you don't, you'll end up with too many warnings and because you're so lazy, you'll never fix them.

Another important note is to test your code a few times before adding a new feature. This makes your code stable and less sensitive for crashes. Also it's much easier to work this way, if you don't you'll end up with a lot of debugging.

What's also important is to use valgrind checking your memory usage. If you do a lot of memory allocations, there's a good chance you forget to free an unused allocated memory. This can result in a memory leak.

Another tip is before writing a functionality like a serial port or bluetooth communication, it's better to do this in a seperate mini project, just to focus on that functionality. If it all works well, you can simply import the code to your big project. This is much more efficient than writing it directly in your main project.

NSNotification example