Category Archives: git

git send-email: Can’t locate Net/SMTP/SSL.pm

While trying to send a patch with git (installed over macports) over GMail I came across the following error on Mac OS X 10.8:

Can't locate Net/SMTP/SSL.pm in @INC (@INC contains: /usr/../Library/Perl/5.12/darwin-
thread-multi-2level /usr/share/git-core/perl /Library/Perl/5.12/darwin-thread-multi-2l
evel /Library/Perl/5.12 /Network/Library/Perl/5.12/darwin-thread-multi-2level /Network
/Library/Perl/5.12 /Library/Perl/Updates/5.12.4 /System/Library/Perl/5.12/darwin-threa
d-multi-2level /System/Library/Perl/5.12 /System/Library/Perl/Extras/5.12/darwin-threa
d-multi-2level /System/Library/Perl/Extras/5.12 .) at /usr/libexec/git-core/git-send-e
mail line 1124.

Which also seems to be the problem filed in the macports bugtracker.

The solution however is pretty easy — except if you don’t read like I did — and requires you just a few commands:

$ sudo port install p5.12-net-smtp-ssl
$ sudo mkdir -p /usr/share/git-core/perl/Net/SMTP
$ sudo ln /opt/local/lib/perl5/vendor_perl/5.12.4/Net/SMTP/SSL.pm \
 /usr/share/git-core/perl/Net/SMTP/SSL.pm

And suddenly: It works!

Redmine does not give read-only access to the git-repo

The problem

I wrote how to install redmine on a debian server with mysql and everything went fine so far, until one day somebody wanted to clone a repo.

fatal: http://domain.tld/git/example.git/info/refs not found:
did you run git update-server-info on the server?

The analysis

So I thought it would solve the problem to run the command in the according git-repo. Nope, it didn’t. But accessing it via gitosis@domain.tld/git/example.git did actually work fine. That’s what puzzled me. Long story short: The apache tried to deliver a directory respectively a file that simply didn’t exist in the path. My redmine is located in /var/www/redmine and there is simply no directory git/ in there. But the gitosis@domain.tld/git/example.git was delivered by the gitosis daemon! So one could easily work while the other not.

The solution

So as soon I understood that I struggled with a totally different problem than git told me (the apache simply didn’t find the file), it was quite easy to fix it. Just add the following line to your redmine apache config, restart apache and everything should be fine.

Alias /git /srv/gitosis/repositories

git tips and tricks: I told you not to touch my file!

Table of contents for git tips and tricks

  1. git tips and tricks: getting the overview
  2. git tips and tricks: fsck, I forgot commit something!
  3. git tips and tricks: I told you not to touch my file!

What’s wrong?

I told my co-dev not to edit my bibliography bib-file for our LaTeX documentation since I use a tool that saves every source in a database and then exports it to a bib-file, which will be overwritten and by this his entries will be lost. I even put my acronym in the file name. And I told him not to touch this file.

Guess what happened? Exactly, he made some changes to this file.

So what now? Just revert the commit? Revert partially and then add the changes manually to an other file? Hmm … would be the easiest way to do it, but I was not sure how well this would work since git does content based revision. Finally I asked again René Nussbaumer to help my out of this dilemma.

How to fix it?

Pretty easy but not so obvious!

I’ll try to explain it in my own words:

  • I partially checkout the file before it got changed. So now I have a sane file on my harddisk.
  • Then I look in the Index to see what will be done in the next commit.
  • This change is what I want to apply to an other new file. But not remove it, add it somewhere else.
$ git log --oneline
abcde some other stuff
12345 changed MY_file.txt
a1b2c initial commit

$ git checkout -p a1b2c

just select the affected file with 'y' and
then to drop the rest, hit 'd'

$ git diff --cached

copy the WHOLE output to your clipboard
paste it in your editor and edit the 3rd
and 4th line. One starts with --- the other
with +++, change BOTH filenames to what you
like. Be carful about existing files. Copy
the diff again in your clipboard

$ touch your_colleagues_filename
$ git apply -R -C0 --recount

-R makes from those - (removed lines)
+ and those line will be added

-C0 is to ignore the non-existant surroundings

--recount is to 'recalculate' the line counts
(this @@ line)

paste the diff and hit ctrl+d

$ git status

should show that MY_file.txt and your colleagues
file have been changed.

$ git commit

git tips and tricks: fsck, I forgot commit something!

Table of contents for git tips and tricks

  1. git tips and tricks: getting the overview
  2. git tips and tricks: fsck, I forgot commit something!
  3. git tips and tricks: I told you not to touch my file!

You add the latest changes to your index and happily commit it to then notice “Drat, I forgot something!” or “Noez, there is a typo!” Well, as long as you didn’t push your commits to a remote host you have a chance to fix this.

Fixing Typos

Let’s say you committed some changes of the file foobar.txt to the notice you wrote a single word wrong, typo. Committing a new version would be pretty much uncool. So let’s do some magic:

vim foobar.txt
[Write some stuff]
git add foobar.txt
git commit -m "Added new stuff"
[You note a typo and fix it]
vim foobar.txt
git add foobar.txt
git commit -m "fixup! $(git log -1 --format='%s' HEAD)"
git rebase --interactive --autosquash HEAD~2
[Approve the fixup]
git log --oneline --decorate

And the magic shows: No new commit in the log! But only do this on commits you didn’t push yet, otherwise this could break others git repo!

Squashing commits together

Let’s imagine you worked on a function, committed it and later you wrote a similar function that does nearly the same but is a little bit different. Or more general: You just want to merge to commits into one.

vim foobar.txt
[Write some stuff]
git add foobar.txt
git commit -m "function foobar()"
[You make a similar function or so]
vim foobar.txt
git add foobar.txt
git commit -m "squash! $(git log -1 --format='%s' HEAD)"
git rebase --interactive --autosquash HEAD~2
[Approve the squash]
[Write new commit message, probably you want \
to state that you committed foobar() and foobar2()]
git log --oneline --decorate

This is not something a function I use often when writing some documentation. You should think before using it. Maybe you want to be able to distinguish the revision from the first written down version. I suggest to only use this version when you actually merge two commits.

Sources, References

This time I have to thank René Nussbaumer who took much time to break this stuff in understandable pieces for me.

git tips and tricks: getting the overview

Table of contents for git tips and tricks

  1. git tips and tricks: getting the overview
  2. git tips and tricks: fsck, I forgot commit something!
  3. git tips and tricks: I told you not to touch my file!

When working with git I felt the urge to have a GUI because I quickly lost the overview over the commits, diffs and everything. Well, not always you have the luxury of being able to install a GUI (maybe you’re working remotely on a linux server or similar) and frankly why install something separate when the git CLI brings more or less everything I need?

git log

git log --oneline --decorate

Mac OS X terminal showing git log --oneline --decorate

And one more for git log which also makes so pretty looking branch treeviews.

git log --graph --full-history --all --color \
--pretty=format:"%x1b[33m%h%x09%x1b[32m%d%x1b[0m%x20%s"

git log for the more visually minded

git diff

When using git diff to see what other changed in a LaTeX document this can be pretty frustrating when they don’t do hard line breaks every 80 or so chars. Then the git pager will not break the lines but show it on one line. Happy scrolling! But there’s a solution to restrict the diff to word level (and not the whole line) and to enforce the pager to make newlines when the output is larger than your terminal.

GIT_PAGER='less -r' git diff --word-diff

GIT_PAGER='less -r' git diff --word-diff enables you to have a easier to read output

Sources

http://mislav.uniqpath.com/2010/07/git-tips/

http://stackoverflow.com/questions/1838873/visualizing-branch-topology-in-git

SCM with git, for the graphically minded

SCM means Source Code Management and is not much of a magic when I tell you that basically it’s not much more than using CVS, SVN, git or mercurial for instance. These are very powerful tools indeed and sometimes a CLI just doesn’t feel intuitive in world where we judge the tools by their look&feel and sincerly a visual diff is easier to understand. Also I wanted to make a translation of my post over at G+.

Mac OS X

Free/FOSS

Gity App

It is FOSS (GPLv3) and runs 10.6 and 10.7. Frankly I didn’t run into any limitations but probably because I’m not using all git’s power and complexity. I think this is a good tool for daily use.

Gity App

http://gityapp.com/

Gitx

Also FOSS (GPLv2) but with a very simple interface, in my opinion a bit too simple so I can only recommend it for the very very beginner, though a very good app.

Gitx App

http://gitx.frim.nl/

Gitti

Gitti is free of charge, but I’m not sure how the development is going on. It is noted as ‘Beta’ which could mean that the final version may be shareware. However I found the interface a bit disturbing: I don’t see the changes in the commit area which makes it hard to know what to write in the commit message. On the other hand I found the Configuration area quite interesting.

Gitti App

http://www.gittiapp.com/

SmartGit

SmartGit is also free and provides also clients for Windows and Linux. You may use it free for non-commercial use, but the interface looks more like a tool from a few years ago. Oh, and the log buttons opens a new window. Probably not the worst client for code review but … no, I’m not convinced.

SmartGit

http://www.syntevo.com/smartgit/

Gitbox

Well, it’s not exactly shareware though $39.00 (50% discount for students), it just restricts you to three projects in the sidebar, but if you remove a project from the sidebar and add a other one, it works. Unfortunately it lacks of an integrated diff view.

Gitbox

http://gitboxapp.com/

Shareware

Tower

Unfortunately it is shareware and costs €49.00 but on the other side you can test it for 30 days. You get 50% discount as a student. The earlier beta versions were free of charge, but you were forced to update every 30 days or so.

Tower App (git-tower)

http://git-tower.com

SourceTree

SourceTree (€45.00, 21 days trial) brings the most complicated interface I think but also feels like it uses the whole power git provides. It also supports mercurial, so if you ever happen to use both, you should consider this GUI. Oh, but I don’t like the icons, the look too candy to me.

SourceTree

http://www.sourcetreeapp.com/

Sprout

Sprout is only sold via the Apple App Store for $35.00 but doesn’t make a good figure. The log doesn’t show any changes in the code which disappoints. In my opinion it’s not worth testing, but the low version number indicates there might be some changes in the future.

Sprout
http://gitmacapp.com/sprout

Windows

Since I no longer use Windows I just googled a bit.

Free/FOSS

tortoisegit

When you know tortoisesvn, you’ll know your way around tortoisegit. It’s FOSS and brings a redmine bugtracker plugin.

Linux

Well, I never used any GUI for git under Linux, but I’d like to point out to two good looking: qgit and gitg. You should find them in your distros repo.

Android

FOSS

agit

Yes, there is a git client for android! But it costs you something like CHF 2.20. I didn’t try it out, I followed the instruction to build your own agit and I didn’t managed to get it work. Maybe you are more lucky than I am.

Crash course!

Well, finally we got some tools to work with but the code also should find its way to a centralized place. I suggest to have a look at setting up your own server and then setting tortoisegit if you use windows and github.

There’s also my tutorial for setting up redmine (a bugtracker with git support) on debian or you can take a look at gitorious which provides hosting for code for free. And if you’re still thinking that this is soooo complicated, have a look here.

Finally I’d like to point you to the most valuable document for entry level git user: Everyday GIT With 20 Commands Or So

Final words

If you happen to use a GUI I didn’t mention or found other good or interesting stuff, let me know. I acknowledge that this post is a bit long on Mac OS X apps due I use this daily, I’d be really happy if you write a post about linux GUIs and I’ll link to your post, I promise!

Personally I use Gity and maybe I’ll buy Tower one day, depending how much I’ll use git. I also like to thank my friends over at NGAS for their support!

Installing Redmine and gitosis on a Debian root-server with MySQL

So I wanted a bugtracker with a little of everything and git integration. First of all I must admit that this wasn’t easy and I wasted some time figuring out how to get this stuff working. Since I love to see tutorials and manuals myself, I’ll share my experience.

Be aware though that Ruby on Rails consumes a lot of RAM and will not run on 128MB RAM. I had to upgrade my VPS which now runs fine with 512MB RAM. I installed Redmine 1.0.1-stable on my Debian Squeeze 6 with the MySQL backend, but not without getting serious trouble when enabling the gitosis plugin: Whenever a username in git contained a umlaut, it just threw a server error. Finally I was able to tackle down the problem with a lot of help from friends over at #bsdprojects.

WARNING: This post is not intended to provide a foolproof guide or a newbie tutorial. This is meant for someone being able to handle a full root server.

INSTALLING PACKAGES

Install the needed debian packages:

apt-get install acl apache2 apache2-mpm-prefork apache2-prefork-dev build-essential cron git-core gitosis git-daemon-run libapache-dbi-perl libapache2-mod-passenger libapache2-mod-perl2 libcurl4-openssl-dev libdigest-sha1-perl libgemplugin-ruby libgemplugin-ruby1.8 libmysqlclient15-dev libnet-ssh-ruby1.8 librmagick-ruby1.8 libruby-extras libruby1.8-extras mysql-server python-setuptools rake redmine redmine-mysql ruby ruby1.8-dev rubygems sudo wget

CONFIGURING & SETUP

MySQL

This is where I failed in the first attempt, MySQL obviously has severe problems with the encoding and a configuration change was the solution eventually. Be sure to add the following to  /etc/mysql/my.cnf before you do anything else:

[client]
default-character-set=utf8

[mysqld]
default-character-set = utf8
skip-character-set-client-handshake
character-set-server = utf8
collation-server = utf8_general_ci
init-connect = SET NAMES utf8

Now create the DB:

mysql -u root -p

CREATE DATABASE redmine CHARACTER SET utf8;
CREATE USER 'redmine'@'localhost' IDENTIFIED BY 'my_password';
GRANT ALL privileges ON redmine.* TO 'redmine'@'localhost';
quit;

Configure redmine:
vi /etc/redmine/default/database.yml

  production:
    adapter: mysql
    database: redmine
    host: localhost
    username: redmine
    password: my_password
    encoding: utf8

Installing the gems

Now comes the funny part, you need to exactly these versions or you’ll encounter strange errors:
gem install rails -v=2.3.11
gem install rack -v=1.1.0
gem install mysql
gem install -v=0.4.2 i18n
gem install inifile lockfile net-ssh

Get Redmine in place

ln -s /usr/share/redmine /var/www/redmine
chown -R www-data:www-data /var/www/redmine
chmod -R 755 /var/www/redmine
cd /var/www/redmine
rake generate_session_store
RAILS_ENV=production rake db:migrate
RAILS_ENV=production rake redmine:load_default_data

Apache

a2enmod passenger
vi /etc/apache2/sites-avaible/redmine

    <VirtualHost *:80>
        ServerName redmine.domain.tld
        DocumentRoot /usr/share/redmine/public
        <Directory /usr/share/redmine/public/>
                Options -MultiViews
        </Directory>
    </VirtualHost>


a2ensite redmine
/etc/init.d/apache2 reload
/etc/init.d/apache2 restart

Now your Apache should be able to handle the redmine bugtracker.

 Integrate gitosis

vi /etc/fstab

    …
    /dev/foo /  ext3  acl,errors=remount-ro 0 1
    …

reboot
sudo -H -u gitosis ssh-keygen -t dsa

Set no password, use standard path/file

sudo -u gitosis cat ~gitosis/.ssh/id_dsa.pub | sudo -H -u gitosis gitosis-init
sed -i.orig 's:/var/cache:/srv/gitosis:g' /etc/sv/git-daemon/run
sv restart git-daemon
setfacl -m user:www-data:r-x,mask:r-x ~gitosis/.ssh
setfacl -m user:www-data:r--,mask:r-- ~gitosis/.ssh/id_dsa
script/plugin install git://github.com/xdissent/redmine_gitosis.git
sudo -u www-data X_DEBIAN_SITEID=default RAILS_ENV=production rake db:migrate:plugins
/etc/init.d/apache2 restart

Point your browser to your installation, log in, go to Administration -> Plugins -> Configure Redmine Gitosis, change ‘localhost’ to your domain, change xdissent.com to your domain.

The repository

Now …

  • create a normal user
  • give him administrator access
  • logout as admin, login as user
  • create new project
  • give yourself at least ‘Developer’ role (Settings -> Members)
  • go to Settings -> Repository, choose git as SCM (this step was actually nowhere mentioned …)
  • now you’ll see a new menu (on the blue background) called ‘Repository’, click on it and follow the instruction written there.

You should be able to push your git repo to the redmine server finally.

SOURCES

MySQL + UTF-8 = Not So Obvious
TUTORIAL: REDMINE WITH GIT AND GITOSIS ON UBUNTU 11.04
GitHub Clone with Redmine