Forking GIT project to Gerrit

Going through your own changes before you decide to carry on is a pretty good idea. I treat it myself as a form of checkpoint: I can approve my changes at any time, but the more important thing is: I can find all the hacks I made along the way.

It turns out to be a pretty good idea to use Gerrit even when you contribute your changes to other repositories, or even when you want to keep your custom changes to yourself and at the same time be able to stay up to date with remote changes.

So how does that work, in short?

  1. Open up Gerrit website and navigate to Projects. Create a new project, that will be a fork of another repository. Create initial commit, it may make things easier;
  2. Open Access configuration for this project. Create new reference refs/* and add 
    1. permission Push merge commits to project owners group (that will allow you to invoke git push);
    2. permission Forge commiter identity - this will be required by Gerrit to accept the changes you are not an author of.
  3. Clone this repository;
  4. Branch off the master branch;
  5. Add new upstream: git remote add upstream ;
  6. Merge the upstream's master branch to your local master branch
  7. Push changes to gerrit using git push origin master.

That's pretty much it. Good thing about mixture like the above is: you can - at any time in the future - recreate this exact configuration. It will work. You will also be able to push changes - once reviewed - to your upstream repository.

Good luck!

Gerrit Code Review - setup

Gerrit Code Review has given me a hard time when I first tried it out.

It wasn't such a big problem to have it installed, as it was to have it configured. Whenever I was done with initial setup, it kept failing on attempt to register first user, and the problem re-emerged some time later, when I decided to upgrade the system.

My biggest fail back then was to set things up manually. I added user to specific groups by hand, thinking that the setup script was not mature enough to handle it for me. While searching around for how i did this last time i stumbled upon a short [ticket](, which helped me realize, that it was all so much out of sync, it just couldn't handle the upgrade.

Ultimately, every time I set up the review site from scratch, the attempt to register first user ended up with the following message:

[2012-12-22 18:58:24,835] WARN / : Unexpected error during authentication
 at java.util.ArrayList$Itr.next(ArrayList.java:794)
 at com.google.gerrit.server.account.AccountManager.create(AccountManager.java:291)
 at com.google.gerrit.server.account.AccountManager.authenticate(AccountManager.java:122)
 at com.google.gerrit.httpd.auth.openid.OpenIdServiceImpl.doAuth(OpenIdServiceImpl.java:409)
 at com.google.gerrit.httpd.auth.openid.OpenIdLoginServlet.doPost(OpenIdLoginServlet.java:50)
 at com.google.gerrit.httpd.auth.openid.OpenIdLoginServlet.doGet(OpenIdLoginServlet.java:40)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)

Here's a step-by-step procedure that will help you set things up right the first time you try.


  • Linux box, 
  • Sun JAVA virtual machine - version 1.6 or later, 
  • PostgreSQL installed and running

Here's what you do:

  1. As root: Prepare Gerrit repository folder, say
    mkdir /var/repositories

  2. As root: Change permissions on this folder, allowing your gerrit2 user full access:
    chown -R gerrit2 /var/repositories
  3. As gerrit2: Initialize a new repository:
    git init --bare /var/repositories/All-Projects.git
  4. As gerrit2: Create new PostgreSQL user:
    createuser -A -D -P -E gerrit2
  5. As gerrit2: Create new PostgreSQL database:
    createdb -E UTF-8 -O gerrit2 reviewdb
  6. As gerrit2: Download the latest gerrit2 installation package and launch the setup:
    java -jar gerrit-full-2.5.1.war init \
        -d /home/gerrit2/review_site
  7. Finally, navigate to Gerrit web site and register your new user:
    xdg-open http://localhost:8080/#/admin/projects
Now, if you are facing complete reinstallation of your system, and upgrading is simply not possible (say, you did the same thing I did previously), here's what you need to do:
  1. As gerrit2: stop the review site:
    cd ~/review_site bin/gerrit.sh stop
  2. As postgres: drop the database:
    dropdb reviewdb
  3. As gerrit2: remove the All-Projects repo:
    rm -rf /var/repositories/All-Projects.git
Yes, this will purge the history of your reviews. It sucks - well, kind of. Ultimately you will get fully functional review site, which is pretty much what counts more.

Next step is usually to trim the approval categories. It feels kind-of wrong to manipulate the database directly, but then, at the same time, it feels stupid to go through verification of own changes.

Typically, one could do this by invoking:

ssh server gerrit gsql
delete from approval_categories \
    [where category_id="VRIF" or category_id="CRVW"]
delete from approval_category_values \
    [where category_id ...]

The contents of these two tables are:

gerrit> select * from approval_categories;
 name        | abbreviated_name | position | function_name | copy_min_score | category_id
 Verified    | V                | 0        | MaxWithBlock  | N              | VRIF
 Code Review | R                | 1        | MaxWithBlock  | Y              | CRVW
(2 rows; 14 ms)

gerrit> select * from approval_category_values; name                                            | category_id | value
 Verified                                        | VRIF        | 1
 No score                                        | VRIF        | 0
 Fails                                           | VRIF        | -1
 Looks good to me, approved                      | CRVW        | 2
 Looks good to me, but someone else must approve | CRVW        | 1
 No score                                        | CRVW        | 0
 I would prefer that you didn't submit this      | CRVW        | -1
 Do not submit                                   | CRVW        | -2
(8 rows; 7 ms)

so, nothing's lost - just delete the contents. Gerrit still does need an approval category. To add them, execute:

ssh server gerrit gsql

insert into approval_categories values \
    ("Approved", 'A', 0, MaxNoBlock, 'Y', "APRV");
insert into approval_category_values values \
    ('No Score', 'APRV', 0);
insert into approval_category_values values \
    ('Approved', 'APRV', 1);

and restart the server (for some, invoking flush-caches would work, too).


Import bookmarks from XMarks to Chrome

I love xmarks. I don't think there's anything even a little close to this service. I have my bookmarks everywhere and even if something goes wrong I can restore it - always.

Yet I do love android and chrome, too. Let's face it, xmarks for chrome is waay better than xmarks for android. And what happens if you accidentally enable syncing your bookmarks with chrome, while using xmarks? well, it all multiplies. In hundreds.

Here's a little trick you can do to propagate your xmarks to google chrome. It's pretty straight forward, but it requires a little bit of tweaking. That said, you can do that even if you're a total noob. Ready?

  1. Disable syncing your bookmarks with XMarks: click on the xmarks icon, open settings and select Sign Out,
  2. Navigate to your bookmarks management site,
  3. From the Tools menu select Export Bookmarks to HTML,
  4. Open text editor - any one will do - and replace all occurences of ":" with a colon (":"); save modified file,
  5. Open Chrome Settings (navigate to chrome://settings) and in Advanced Sync Options enable Bookmarks
  6. Close settings, open Chrome Bookmark Manager (navigate to chrome://bookmarks),
  7. From Organize menu select Import bookmarks from HTML,
  8. Select the file.
That will push your bookmarks to google and later synchronize with your android device.

Remember to turn off chrome bookmark sync before signing back into xmarks!


Synology: tweaking @eaDir

Thumbnails and indexes on Synology NAS are a pain. Not because they serve little purpose; the problem is that these folders are actually externally visible, especially when you don't want them. Every other multimedia manager would then list all these thumbnails again. Now this sucks a lot.

Good thing is, there is a way to tweak it. Here's how you do it.

In order to execute any of these steps, you need to open a SSH connection as root user to your synology NAS.

To completely disable indexing:

cd /usr/syno/etc.defaults/rc.d
# Disable restarting service on next boot-up.

chmod a-x S66fileindexd.sh
# Stop currently running index service.

. ./S66fileindexd.sh stop
# Remove entirely all index folders.

find /volume1 -type d -name '@eaDir' -print -exec rm -rf '{}' \;

I've been trying to look up alternative way to disable it. There is a possibility to query current status of shares to see which ones have indexing enabled.

synoshare is a tool that was created to report status of the shares. Usually, you can alter indexing settings of your custom shares using indexing application available through synology web interface. This is true for every folder, except for music, photo and video.

If  you invoke:

synoshare --enum ALL

you will see all your shared folders listed. Among them you will see the three above mentioned folders (unless you selected some other folders to host your multimedia). Now, when you invoke

synoshare --get photo
synoshare --get music
synoshare --get video

you will notice, that the status reported for these three is non-zero. A hint for programmers:
0x10 = locked
0x20 = indexing enabled
0x40 = indexing required
now the only question standing is - how to modify the share database located under /tmp/.db.synoshare.{BUILD}. Synology libraries allow to alter  these settings, but messing with them does not feel right - actually it requires more tweaking than just turning off one script, so i believe - until Synology offers possibility to turn off indexing of media folders  - there is no better solution, sorry.


ZSH: easy history navigation

Here's a quick help for all of you who want to be able to navigate through history much easier with ZSH.

Paste the following to your ~/.zshrc:

bindkey "\e[A" up-line-or-search
bindkey "\e[B" down-line-or-search

These changes will switch the way history navigation works in zsh; what these do is: whenever you are typing a command at shell prompt, arrow keys will navigate through history for you to find matches for the text you already entered.


Vim: forgot sudo?

Has it ever happened to you that you were modifying file that you had no permission to write in VIm? Most of us quit the editor, sometimes save the file to a temp location, then edit it again as root. The thing is - you don't really have to!

Once you open your file, you can save it as an input to external command. To do that, simply call:

:w !<command>

in this particular case, it's:

:w !sudo tee %

good luck!


Disabling ZSH user completion

ZSH has proven to be one of the most powerful shells i've used so far. It has really surprised me dozens of times and I started to love it much more than bash or anything else.

Unfortunately, ZSH can also suffer from the fact that it's so powerful. Among the things that made me almost cry was the user completion, enabled by default, that made the whole console freeze for long time before it finally resumed, giving me a list of hundreds LDAP users when all I wanted is a completion of local directory.

After longer search I finally mastered the query to get the right solution to the problem:

unsetopt cdablevars

This short line turns off auto-completion based on user names and variables. Once in place you will no longer be able to type:

cd user_name
cd var_name

instead, you're back to standard

cd ~user_name
cd $var_name

but, the upside is, the directory completion (when you press TAB key) is again working smoothly, even when you're completing commands (git etc).

Among available alternatives you can find a solution that would disable completion for a particular command, such as:

zstyle ':completion:*:complete:(cd|pushd):*' tag-order \
    'local-directories path-directories directory-stack' '*'
which will complete cd and pushd commands with directories only (so, no variables and no users for you). You can try to tweak this completion pattern to actually give you some of these mechanisms back to these commands.