Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A simple python script to mass pick open changes from gerrit in order based on dependencies.
#!/bin/sh
""":"
exec python $0 ${1+"$@"}
"""
# Author: Clark Scheff
#
# Picks all open commits for a given project in the correct
# order based on their dependencies. There is plenty of
# room for improvments but this does work as intended.
#
# Note: make sure you are in the correct project directory before running this.
#
# An example of picking all open commits for android_frameworks_base
# mass_gerrit_pick.py -p ChameleonOS/android_frameworks_base -u d34d -b jellybean-mr2.1 -s review.chameleonos.org
import sys
import subprocess
import json
import getopt
# change these if you don't feel like supplying it at the command line
USERNAME = 'd34d'
BRANCH = 'kitkat'
SITE = 'review.chameleonos.org'
PROJECT = ''
LIMIT = 1000
STATUS = 'open'
COMMITTER = None
def usage():
print 'usage %s -p project [-b branch][-u username][-s site]' % sys.argv[0]
if len(sys.argv) < 2:
usage()
sys.exit(2)
try:
opts, args = getopt.getopt(sys.argv[1:], 'mp:b:u:s:l:c:', ['merged', 'project', 'branch', 'username', 'site', 'limit', 'committer'])
except getopt.GetoptError as err:
print str(err)
usage()
sys.exit(3)
has_project = False
for o, a in opts:
if o in ('-p', 'project'):
PROJECT = a
has_project = True
elif o in ('-b', 'branch'):
BRANCH = a
elif o in ('-u', 'username'):
USERNAME = a
elif o in ('-s', 'site'):
SITE = a
elif o in ('-l', 'limit'):
try:
LIMIT = int(a)
except:
pass
elif o in ('-m', 'merged'):
STATUS = 'merged'
elif o in ('-c', 'committer'):
COMMITTER = a
else:
assert False, 'unhandled option!'
if not has_project:
print 'Missing project'
usage()
sys.exit(4)
LOGIN = '%s@%s' % (USERNAME, SITE)
data = subprocess.check_output(
[
'ssh',
'-p',
'29418',
LOGIN,
'gerrit',
'query',
'status:' + STATUS, 'project:' + PROJECT,
'limit:%d' % LIMIT,
'--dependencies',
'--current-patch-set',
'--format', 'JSON'
])
# there is a \n at the very end so omit that from the list
listdata = data.split('\n')[:-1]
picks = []
for i in range(len(listdata) - 1):
jsondata = json.loads(listdata[i])
commitId = int(jsondata['number'])
try:
dependsOn = jsondata['dependsOn'][0]
dependencyId = int(dependsOn['number'])
except:
dependencyId = 0
patchset = int(jsondata['currentPatchSet']['number'])
branch = jsondata['branch']
if COMMITTER is None or COMMITTER == jsondata['owner']['username']:
if branch == BRANCH:
picks.append((commitId, dependencyId, patchset))
# pre-sort the list based on dependency id
picks = sorted(picks, key=lambda x: x[1])
# sort picks so dependencies come before the pick that depends on them
for i in range(len(picks)):
commitId, dependencyId, patchset = picks[i]
if dependencyId > 0:
for j in range(len(picks)):
if picks[j][0] == dependencyId:
tmp = picks[i]
del picks[i]
if i < j:
picks.insert(j, tmp)
else:
picks.insert(j+1, tmp)
break
# now go through and pick these bad boys
# template requires a tuple of (SITE, PROJECT, commitId % 100, commitId, patchset)
COMMAND_TEMPLATE='git fetch http://%s/%s refs/changes/%02d/%d/%d && git cherry-pick FETCH_HEAD'
for i in range(len(picks)):
commitId = picks[i][0]
change = commitId % 100
command = COMMAND_TEMPLATE % (SITE, PROJECT, change, commitId, picks[i][2])
subprocess.call(command, shell=True)
@ishan-12
Copy link

ishan-12 commented Sep 27, 2019

This doesn't order correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment