gerrit account merge

Posted on 28.06.2014

⚠️ updated version available

As mentioned before I’m the admin of coreboot’s code review system which uses the fine Gerrit tool.

One recurring issue is that its user registration is automatic, so when you login with some OpenID provider (like Yahoo, Google, or your own) that you haven’t used before, you get a new account, with no self-service option to fix that.

There’s a complex SQL routine out there that allows for mass merges, but it’s written for Postgres while we use the built-in H2 database (coreboot is really a tiny project in comparison to what’s out there, and so H2 is good enough for us).

So here’s my attempt at automating things, a shell script calling into gerrit’s “gsql” interface, using only the most basic and compatible SQL calls. It uses the internal account ids which can be found in various places across the gerrit user interface and merges exactly one pair of accounts. Larger jobs require multiple invocations (eg. merge A B; merge A C; merge A D to make A, B, C, D all merge to a single account ‘A’).

#!/bin/sh
# Copyright (C) 2014 Patrick Georgi <patrick@georgi-clan.de>
# licensing: ISC license terms
#
# usage: $0 id-to-keep id-to-merge
HOST=review.coreboot.org
PORT=29418
if [ $# -ne 2 ]; then
	echo "usage: $0 id-to-keep id-to-merge"
	exit 1
fi
KEEP=$1
MERGE=$2
if [ `expr $KEEP + 0` -eq 0 ]; then
	echo "$KEEP is not an id"
	exit 1
fi
if [ `expr $MERGE + 0` -eq 0 ]; then
	echo "$MERGE is not an id"
	exit 1
fi
ssh -p $PORT $HOST gerrit gsql << _EOF
BEGIN TRANSACTION;
UPDATE account_external_ids SET account_id=$KEEP WHERE account_id=$MERGE;
UPDATE account_ssh_keys SET account_id=$KEEP WHERE account_id=$MERGE;
UPDATE starred_changes SET account_id=$KEEP WHERE account_id=$MERGE;
UPDATE account_patch_reviews SET account_id=$KEEP WHERE account_id=$MERGE;
UPDATE account_project_watches SET account_id=$KEEP WHERE account_id=$MERGE;
UPDATE account_group_members SET account_id=$KEEP WHERE account_id=$MERGE;
UPDATE patch_set_approvals SET account_id=$KEEP WHERE account_id=$MERGE;
UPDATE account_patch_reviews SET account_id=$KEEP WHERE account_id=$MERGE;
UPDATE changes SET owner_account_id=$KEEP WHERE owner_account_id=$MERGE;
UPDATE patch_sets SET uploader_account_id=$KEEP WHERE uploader_account_id=$MERGE;
UPDATE change_messages SET author_id=$KEEP WHERE author_id=$MERGE;
UPDATE patch_comments SET author_id=$KEEP WHERE author_id=$MERGE;
DELETE FROM accounts WHERE account_id=$MERGE;
DELETE FROM account_diff_preferences WHERE id=$MERGE;
COMMIT;
_EOF
ssh -p $PORT $HOST gerrit flush-caches