I had to start to use the git versioning system very quickly without having time to learn it in depth first. I was learning everything while working on a real project and thus I soon had to use advanced techniques. I hope that description of my beginnings may be useful for others.
1. | Subversion or git? |
2. | My first project |
3. | Easy sharing |
4. | My first repository |
5. | Unqualified certificate |
6. | Restoring the history |
7. | Lessons learned |
8. | Conclusion |
At the beginning I should write that I am fully satisfied with subversion. Nowadays its branching model is not such a nightmare as it used to be. The main advantage of git no longer comes from its branching facilities. However, what is the most important feature, is the ability to commit while being off-line. This is the reason why I decided to use git for my project.
My first project with git is a book written in Hindi using XeLaTeX. I started working on the book some time ago using subversion. Now I had to continue even on a notebook at places without internet connectivity. For now I gave up copying the history from subversion and just created a new repository on my desktop computer:
cd mkdir MyBook cd MyBook git init |
I have copied source files from the subversion working copy into it and executed:
git add * git commit -m 'Files copied from the subversion working copy.' |
Originally I thought that I would just transfer the MyBook
directory to the notebook, would work on it and after return move the directory back to my
desktop. However, this is not the right way of using a versioning system because you never
know where the current version of the repository resides. In a comment to an article
describing the possibilities of repository hosting I found a note that Dropbox can be used.
I feel that this is not a good method for stable work but consider it elegant for fast
startup. I have thus created a repository on Dropbox, added it as a remote source and
published the current state:
cd ~/Dropbox mkdir MyBook cd MyBook git init --bare cd ~/MyBook git remote add origin ~/Dropbox/MyBook/ git push origin master |
At that time i did not know the
--set-upstream
switch.
Why is cloud in general inappropriate for hosting repositories? It is because
you can execute git push
even when being off-line. A conflicting copy will then
be created on the cloud which will cause serious problems, especially if yo do not notice its
existence.
I decided to implement my first repository via WebDAV because I already use it for subversion. I followed these instructions: Aquì estamos! Git repository with Apache (via WebDAV) and gitweb. The above mentioned document does not describe everything, especially taking into account that my project is not public and access must be encrypted and password protected. I know almost everything about the Apache server, therefore the setup was an easy task.
Now I could simply copy the repository from Dropbox to the correct directory and change the permissions. However, I planned to use the newly created system also for other project. It is better if the repository is created by the web server which ensures automatically correct permissions. I already have a similar PHP script for subversion. Its modification for use with git was a matter of a few minutes.
I transferred the project to the new repository and cancelled its connection to Dropbox.
git remote add web https://my.server.at.home/git/MyBook/ git push web master git remote remove origin git remote rename web origin |
The https protocol requires a certificate. For testing purposes I have installed Apache on my home computer and built my testing certification authority. This authority is unknown for all programs. I can instruct git to ignore the certificate but I do not want to do it. I want to have my private certificate verified. And since I want to host several repositories on my test server, I want to do it globally. Google search gave me a simple instruction:
git config --global http.sslcainfo /path/to/MyCAcertificate.pem |
I did it even before installation of my first repository as described in the previous section. Everything worked till I tried to contact a server with a qualified certificate. I such a configuration git verifies certificates of all servers against my certification authority. I could configure the certificate locally for each clone but this is not what I would like to do. Instead it is possible to assign a certificate to a server. The problem was thus solved by the following commands:
git config --global --unset http.sslcainfo git config --global http."https://my.server.at.home/".sslcainfo /path/to/MyCAcertificate.pem |
What I am missing is the functionality of web browsers and the subversion client. The certificate is first verified against built-in certification authorities and only if it fails, the user installed certificates are tried. Unfortunately the git documentation does not tell me clearly whether it is possible and if so, how to do it.
My project was now split to two parts. The beginning of its history was in
subversion, its continuation in git. It made me feel kind of unhappy so I
started thinking whether anything could be done. First I wanted to convert my old
subversion repository to git. The best recommendation seemed to be
svn2git.
Installation is easy, and since I was the only user of the repository, the
authors
file can be created by hand.
Conversion from subversion needs a new empty repository, so I ave created one. In this case the conversion was fast because the project is very small and its histroy short. All was acieved by the following commands:
cd mkdir BookFromSVN cd BookFromSVN git init svn2git https://my.server.at.home/svn/MyBook -v |
Now the idea was to fetch the current project from git, try to unite it
somehow and push it to a repository holding both histories. I already knew that I can pull
the contents from one repository and after some works to push it to another. I was afraid
that the first would not be successful, so it may be necessary to repeat it. And I liked the
URL of my git repository, I wanted to keep it. Therefore I first renamed the
MyBook
directory to OLD-MyBook
directly on the server and then
generated an empty repository MyBook
by the PHP script. Finally I created a new
branch in my project and pulled the current contents into it:
cd ~/BookFromSVN git checkout -b fromgit git remote add oldgit https://my.server.at.home/git/OLD-MyBook/ git pull oldgit master |
Maybe it would be better to use rebase
but I used
merge
. After it I can see a branch started from nowhere, it is the place where
git is added to subversion. I can use git diff
to see that the
first revision in git is identical to the last revision in subversion. I could
therefore remove the branch and push the contents to the new repository with the old name.
Here are all the commands used:
git checkout master git merge fromgit git branch -d fromgit git remote add origin https://my.server.at.home/git/MyBook/ git push --set-upstream origin master git remote remove oldgit |
Now I could continue working in this new clone. An interesting thing is that
after I worked here for some time and pushed the work, I could return to my old local clone
and git pull
fetched the united history without any problem.
I have not learned branching within this project because it makes no sense here. Later I will certainly use a tag. I tried working with remote repositories. And my feeling is that one of my favourite quotes holds:
It [Babbage's analytical engine] has no pretentions whatever to originate anything but it can do whatever we know how to order it to perform. (Ada Countess of Lovelace)
The strong features of git are also its weak points. In subversion
one command is sufficient to send modified files to a central repository, git requires
three commands. It may be difficult for a novice to get accustomed to it and not to make
mistakes. It is needed to read git status
often and carefully. In
subversion several developers may successfully commit to the trunk with a minimal
risk of a conflict. I am afraid it is not the case of git especially if developers
work off-line and use git push
after o longer period of time. I think that a
feature branch is a must in order to survive in a team work.
Taking into account the above mentioned notes I will continue to use subversion for quite a long time. On the contrary I foresee projects (even the one-man ones) in the near future where git will become a very important tool for me.
I am forced to sponsor musicians and other copyright organisations by my programming work because I store my software, input data as well as the results of calculation on CD and DVD media.