diff --git a/build/tools/repopick.py b/build/tools/repopick.py
index aa1d07b..135f475 100755
--- a/build/tools/repopick.py
+++ b/build/tools/repopick.py
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 #
-# Copyright (C) 2013 The CyanogenMod Project
+# Copyright (C) 2013-15 The CyanogenMod Project
+#           (C) 2017    The LineageOS Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -28,303 +29,414 @@
 import re
 import argparse
 import textwrap
+from xml.etree import ElementTree
 
 try:
-  # For python3
-  import urllib.request
+    import requests
 except ImportError:
-  # For python2
-  import imp
-  import urllib2
-  urllib = imp.new_module('urllib')
-  urllib.request = urllib2
+    try:
+        # For python3
+        import urllib.error
+        import urllib.request
+    except ImportError:
+        # For python2
+        import imp
+        import urllib2
+        urllib = imp.new_module('urllib')
+        urllib.error = urllib2
+        urllib.request = urllib2
 
-# Parse the command line
-parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, description=textwrap.dedent('''\
-    repopick.py is a utility to simplify the process of cherry picking
-    patches from OmniROM's Gerrit instance.
-
-    Given a list of change numbers, repopick will cd into the project path
-    and cherry pick the latest patch available.
-
-    With the --start-branch argument, the user can specify that a branch
-    should be created before cherry picking. This is useful for
-    cherry-picking many patches into a common branch which can be easily
-    abandoned later (good for testing other's changes.)
-
-    The --abandon-first argument, when used in conjuction with the
-    --start-branch option, will cause repopick to abandon the specified
-    branch in all repos first before performing any cherry picks.'''))
-parser.add_argument('change_number', nargs='*', help='change number to cherry pick')
-parser.add_argument('-i', '--ignore-missing', action='store_true', help='do not error out if a patch applies to a missing directory')
-parser.add_argument('-c', '--checkout', action='store_true', help='checkout instead of cherry pick')
-parser.add_argument('-s', '--start-branch', nargs=1, help='start the specified branch before cherry picking')
-parser.add_argument('-a', '--abandon-first', action='store_true', help='before cherry picking, abandon the branch specified in --start-branch')
-parser.add_argument('-b', '--auto-branch', action='store_true', help='shortcut to "--start-branch auto --abandon-first --ignore-missing"')
-parser.add_argument('-q', '--quiet', action='store_true', help='print as little as possible')
-parser.add_argument('-v', '--verbose', action='store_true', help='print extra information to aid in debug')
-parser.add_argument('-t', '--topic', help='pick all commits from a specified topic')
-args = parser.parse_args()
-if args.start_branch == None and args.abandon_first:
-    parser.error('if --abandon-first is set, you must also give the branch name with --start-branch')
-if args.auto_branch:
-    args.abandon_first = True
-    args.ignore_missing = True
-    if not args.start_branch:
-        args.start_branch = ['auto']
-if args.quiet and args.verbose:
-    parser.error('--quiet and --verbose cannot be specified together')
-if len(args.change_number) > 0 and args.topic:
-    parser.error('cannot specify a topic and change number(s) together')
-if len(args.change_number) == 0 and not args.topic:
-    parser.error('must specify at least one commit id or a topic')
-
-# Helper function to determine whether a path is an executable file
-def is_exe(fpath):
-    return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
-
-# Implementation of Unix 'which' in Python
-#
-# From: http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python
-def which(program):
-    fpath, fname = os.path.split(program)
-    if fpath:
-        if is_exe(program):
-            return program
-    else:
-        for path in os.environ["PATH"].split(os.pathsep):
-            path = path.strip('"')
-            exe_file = os.path.join(path, program)
-            if is_exe(exe_file):
-                return exe_file
-    sys.stderr.write('ERROR: Could not find the %s program in $PATH\n' % program)
-    sys.exit(1)
-
-# Simple wrapper for os.system() that:
-#   - exits on error
-#   - prints out the command if --verbose
-#   - suppresses all output if --quiet
-def execute_cmd(cmd, exit_on_fail=True):
-    if args.verbose:
-        print('Executing: %s' % cmd)
-    if args.quiet:
-        cmd = cmd.replace(' && ', ' &> /dev/null && ')
-        cmd = cmd + " &> /dev/null"
-    ret = os.system(cmd)
-    if ret and exit_on_fail:
-        if not args.verbose:
-            sys.stderr.write('\nERROR: Command that failed:\n%s' % cmd)
-        sys.exit(1)
-    return ret
 
 # Verifies whether pathA is a subdirectory (or the same) as pathB
-def is_pathA_subdir_of_pathB(pathA, pathB):
-    pathA = os.path.realpath(pathA) + '/'
-    pathB = os.path.realpath(pathB) + '/'
-    return(pathB == pathA[:len(pathB)])
+def is_subdir(a, b):
+    a = os.path.realpath(a) + '/'
+    b = os.path.realpath(b) + '/'
+    return b == a[:len(b)]
 
-# Find the necessary bins - repo
-repo_bin = which('repo')
 
-# Find the necessary bins - git
-git_bin = which('git')
-
-# Change current directory to the top of the tree
-if os.environ.get('ANDROID_BUILD_TOP', None):
-    top = os.environ['ANDROID_BUILD_TOP']
-    if not is_pathA_subdir_of_pathB(os.getcwd(), top):
-        sys.stderr.write('ERROR: You must run this tool from within $ANDROID_BUILD_TOP!\n')
-        sys.exit(1)
-    os.chdir(os.environ['ANDROID_BUILD_TOP'])
-else:
-    sys.stderr.write('ERROR: $ANDROID_BUILD_TOP is not defined. please check build/envsetup.sh\n')
-    sys.exit(1)
-
-# Sanity check that we are being run from the top level of the tree
-if not os.path.isdir('.repo'):
-    sys.stderr.write('ERROR: No .repo directory found. Please run this from the top of your tree.\n')
-    sys.exit(1)
-
-# If --abandon-first is given, abandon the branch before starting
-if args.abandon_first:
-    # Determine if the branch already exists; skip the abandon if it does not
-    plist = subprocess.Popen([repo_bin,"info"], stdout=subprocess.PIPE)
-    needs_abandon = False
-    while(True):
-        pline = plist.stdout.readline().rstrip()
-        if not pline:
-            break
-        matchObj = re.match(r'Local Branches.*\[(.*)\]', pline.decode())
-        if matchObj:
-            local_branches = re.split('\s*,\s*', matchObj.group(1))
-            if any(args.start_branch[0] in s for s in local_branches):
-                needs_abandon = True
-
-    if needs_abandon:
-        # Perform the abandon only if the branch already exists
-        if not args.quiet:
-            print('Abandoning branch: %s' % args.start_branch[0])
-        cmd = '%s abandon %s' % (repo_bin, args.start_branch[0])
-        execute_cmd(cmd)
-        if not args.quiet:
-            print('')
-
-# Get the list of projects that repo knows about
-#   - convert the project name to a project path
-project_name_to_path = {}
-plist = subprocess.Popen([repo_bin,"list"], stdout=subprocess.PIPE)
-project_path = None
-while(True):
-    pline = plist.stdout.readline().rstrip()
-    if not pline:
-        break
-    ppaths = re.split('\s*:\s*', pline.decode())
-    project_name_to_path[ppaths[1]] = ppaths[0]
-
-# Get all commits for a specified topic
-if args.topic:
-    url = 'http://gerrit.omnirom.org/changes/?q=topic:%s' % args.topic
-    if args.verbose:
-        print('Fetching all commits from topic: %s\n' % args.topic)
-    f = urllib.request.urlopen(url)
-    d = f.read().decode("utf-8")
-    if args.verbose:
-        print('Result from request:\n' + d)
-
-    # Clean up the result
-    d = d.lstrip(")]}'\n")
-    if re.match(r'\[\s*\]', d):
-        sys.stderr.write('ERROR: Topic %s was not found on the server\n' % args.topic)
-        sys.exit(1)
-    if args.verbose:
-        print('Result from request:\n' + d)
-
-    try:
-        data = json.loads(d)
-    except ValueError:
-        sys.stderr.write('ERROR: Could not load json')
-        sys.exit(1)
-
-    args.change_number = sorted(d['_number'] for d in data)
-
-# Check for range of commits and rebuild array
-changelist = []
-for change in args.change_number:
-    c=str(change)
-    if '-' in c:
-        templist = c.split('-')
-        for i in range(int(templist[0]), int(templist[1]) + 1):
-            changelist.append(str(i))
+def fetch_query_via_ssh(remote_url, query):
+    """Given a remote_url and a query, return the list of changes that fit it
+       This function is slightly messy - the ssh api does not return data in the same structure as the HTTP REST API
+       We have to get the data, then transform it to match what we're expecting from the HTTP RESET API"""
+    if remote_url.count(':') == 2:
+        (uri, userhost, port) = remote_url.split(':')
+        userhost = userhost[2:]
+    elif remote_url.count(':') == 1:
+        (uri, userhost) = remote_url.split(':')
+        userhost = userhost[2:]
+        port = 29418
     else:
-        changelist.append(c)
+        raise Exception('Malformed URI: Expecting ssh://[user@]host[:port]')
 
-args.change_number = changelist
 
-# Iterate through the requested change numbers
-for change in args.change_number:
-    if not args.quiet:
-        print('Applying change number %s ...' % change)
+    out = subprocess.check_output(['ssh', '-x', '-p{0}'.format(port), userhost, 'gerrit', 'query', '--format=JSON --patch-sets --current-patch-set', query])
+    if not hasattr(out, 'encode'):
+        out = out.decode()
+    reviews = []
+    for line in out.split('\n'):
+        try:
+            data = json.loads(line)
+            # make our data look like the http rest api data
+            review = {
+                'branch': data['branch'],
+                'change_id': data['id'],
+                'current_revision': data['currentPatchSet']['revision'],
+                'number': int(data['number']),
+                'revisions': {patch_set['revision']: {
+                    'number': int(patch_set['number']),
+                    'fetch': {
+                        'ssh': {
+                            'ref': patch_set['ref'],
+                            'url': 'ssh://{0}:{1}/{2}'.format(userhost, port, data['project'])
+                        }
+                    }
+                } for patch_set in data['patchSets']},
+                'subject': data['subject'],
+                'project': data['project'],
+                'status': data['status']
+            }
+            reviews.append(review)
+        except:
+            pass
+    args.quiet or print('Found {0} reviews'.format(len(reviews)))
+    return reviews
 
-    # Fetch information about the change from Gerrit's REST API
-    #
-    # gerrit returns two lines, a magic string and then valid JSON:
-    #   )]}'
-    #   [ ... valid JSON ... ]
-    url = 'https://gerrit.omnirom.org/changes/?q=%s&o=CURRENT_REVISION&o=CURRENT_COMMIT&pp=0' % change
-    if args.verbose:
-        print('Fetching from: %s\n' % url)
-    f = urllib.request.urlopen(url)
-    d = f.read().decode("utf-8")
-    if args.verbose:
-        print('Result from request:\n' + d)
 
-    # Clean up the result
-    d = d.split('\n')[1]
-    if re.match(r'\[\s*\]', d):
-        sys.stderr.write('ERROR: Change number %s was not found on the server\n' % change)
+def fetch_query_via_http(remote_url, query):
+    if "requests" in sys.modules:
+        auth = None
+        if os.path.isfile(os.getenv("HOME") + "/.gerritrc"):
+            f = open(os.getenv("HOME") + "/.gerritrc", "r")
+            for line in f:
+                parts = line.rstrip().split("|")
+                if parts[0] in remote_url:
+                    auth = requests.auth.HTTPBasicAuth(username=parts[1], password=parts[2])
+        statusCode = '-1'
+        if auth:
+            url = '{0}/a/changes/?q={1}&o=CURRENT_REVISION&o=ALL_REVISIONS'.format(remote_url, query)
+            data = requests.get(url, auth=auth)
+            statusCode = str(data.status_code)
+        if statusCode != '200':
+            #They didn't get good authorization or data, Let's try the old way
+            url = '{0}/changes/?q={1}&o=CURRENT_REVISION&o=ALL_REVISIONS'.format(remote_url, query)
+            data = requests.get(url)
+        reviews = json.loads(data.text[5:])
+    else:
+        """Given a query, fetch the change numbers via http"""
+        url = '{0}/changes/?q={1}&o=CURRENT_REVISION&o=ALL_REVISIONS'.format(remote_url, query)
+        data = urllib.request.urlopen(url).read().decode('utf-8')
+        reviews = json.loads(data[5:])
+
+    for review in reviews:
+        review['number'] = review.pop('_number')
+
+    return reviews
+
+
+def fetch_query(remote_url, query):
+    """Wrapper for fetch_query_via_proto functions"""
+    if remote_url[0:3] == 'ssh':
+        return fetch_query_via_ssh(remote_url, query)
+    elif remote_url[0:4] == 'http':
+        return fetch_query_via_http(remote_url, query.replace(' ', '+'))
+    else:
+        raise Exception('Gerrit URL should be in the form http[s]://hostname/ or ssh://[user@]host[:port]')
+
+if __name__ == '__main__':
+    # Default to OmniRom Gerrit
+    default_gerrit = 'https://gerrit.omnirom.org'
+
+    parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, description=textwrap.dedent('''\
+        repopick.py is a utility to simplify the process of cherry picking
+        patches from OmniRom's Gerrit instance (or any gerrit instance of your choosing)
+
+        Given a list of change numbers, repopick will cd into the project path
+        and cherry pick the latest patch available.
+
+        With the --start-branch argument, the user can specify that a branch
+        should be created before cherry picking. This is useful for
+        cherry-picking many patches into a common branch which can be easily
+        abandoned later (good for testing other's changes.)
+
+        The --abandon-first argument, when used in conjunction with the
+        --start-branch option, will cause repopick to abandon the specified
+        branch in all repos first before performing any cherry picks.'''))
+    parser.add_argument('change_number', nargs='*', help='change number to cherry pick.  Use {change number}/{patchset number} to get a specific revision.')
+    parser.add_argument('-i', '--ignore-missing', action='store_true', help='do not error out if a patch applies to a missing directory')
+    parser.add_argument('-s', '--start-branch', nargs=1, help='start the specified branch before cherry picking')
+    parser.add_argument('-r', '--reset', action='store_true', help='reset to initial state (abort cherry-pick) if there is a conflict')
+    parser.add_argument('-a', '--abandon-first', action='store_true', help='before cherry picking, abandon the branch specified in --start-branch')
+    parser.add_argument('-b', '--auto-branch', action='store_true', help='shortcut to "--start-branch auto --abandon-first --ignore-missing"')
+    parser.add_argument('-q', '--quiet', action='store_true', help='print as little as possible')
+    parser.add_argument('-v', '--verbose', action='store_true', help='print extra information to aid in debug')
+    parser.add_argument('-f', '--force', action='store_true', help='force cherry pick even if change is closed')
+    parser.add_argument('-p', '--pull', action='store_true', help='execute pull instead of cherry-pick')
+    parser.add_argument('-P', '--path', help='use the specified path for the change')
+    parser.add_argument('-t', '--topic', help='pick all commits from a specified topic')
+    parser.add_argument('-Q', '--query', help='pick all commits using the specified query')
+    parser.add_argument('-g', '--gerrit', default=default_gerrit, help='Gerrit Instance to use. Form proto://[user@]host[:port]')
+    parser.add_argument('-e', '--exclude', nargs=1, help='exclude a list of commit numbers separated by a ,')
+    parser.add_argument('-c', '--check-picked', type=int, default=10, help='pass the amount of commits to check for already picked changes')
+    args = parser.parse_args()
+    if not args.start_branch and args.abandon_first:
+        parser.error('if --abandon-first is set, you must also give the branch name with --start-branch')
+    if args.auto_branch:
+        args.abandon_first = True
+        args.ignore_missing = True
+        if not args.start_branch:
+            args.start_branch = ['auto']
+    if args.quiet and args.verbose:
+        parser.error('--quiet and --verbose cannot be specified together')
+
+    if (1 << bool(args.change_number) << bool(args.topic) << bool(args.query)) != 2:
+        parser.error('One (and only one) of change_number, topic, and query are allowed')
+
+    # Change current directory to the top of the tree
+    if 'ANDROID_BUILD_TOP' in os.environ:
+        top = os.environ['ANDROID_BUILD_TOP']
+
+        if not is_subdir(os.getcwd(), top):
+            sys.stderr.write('ERROR: You must run this tool from within $ANDROID_BUILD_TOP!\n')
+            sys.exit(1)
+        os.chdir(os.environ['ANDROID_BUILD_TOP'])
+
+    # Sanity check that we are being run from the top level of the tree
+    if not os.path.isdir('.repo'):
+        sys.stderr.write('ERROR: No .repo directory found. Please run this from the top of your tree.\n')
         sys.exit(1)
 
-    # Parse the JSON
-    try:
-        data_array = json.loads(d)
-    except ValueError:
-        sys.stderr.write('ERROR: The response from the server could not be parsed properly\n')
-        if args.verbose:
-            sys.stderr.write('The malformed response was: %s\n' % d)
-        sys.exit(1)
-    # Enumerate through JSON response
-    for (i, data) in enumerate(data_array):
-        date_fluff       = '.000000000'
-        project_name     = data['project']
-        change_number    = data['_number']
-        current_revision = data['revisions'][data['current_revision']]
-        status           = data['status']
-        patch_number     = current_revision['_number']
-        # Backwards compatibility
-        if 'http' in current_revision['fetch']:
-            fetch_url        = current_revision['fetch']['http']['url']
-            fetch_ref        = current_revision['fetch']['http']['ref']
-        else:
-            fetch_url        = current_revision['fetch']['anonymous http']['url']
-            fetch_ref        = current_revision['fetch']['anonymous http']['ref']
-        author_name      = current_revision['commit']['author']['name']
-        author_email     = current_revision['commit']['author']['email']
-        author_date      = current_revision['commit']['author']['date'].replace(date_fluff, '')
-        committer_name   = current_revision['commit']['committer']['name']
-        committer_email  = current_revision['commit']['committer']['email']
-        committer_date   = current_revision['commit']['committer']['date'].replace(date_fluff, '')
-        subject          = current_revision['commit']['subject']
+    # If --abandon-first is given, abandon the branch before starting
+    if args.abandon_first:
+        # Determine if the branch already exists; skip the abandon if it does not
+        plist = subprocess.check_output(['repo', 'info'])
+        if not hasattr(plist, 'encode'):
+            plist = plist.decode()
+        needs_abandon = False
+        for pline in plist.splitlines():
+            matchObj = re.match(r'Local Branches.*\[(.*)\]', pline)
+            if matchObj:
+                local_branches = re.split('\s*,\s*', matchObj.group(1))
+                if any(args.start_branch[0] in s for s in local_branches):
+                    needs_abandon = True
 
-        # remove symbols from committer name
-        # from http://stackoverflow.com/questions/9942594/unicodeencodeerror-ascii-codec-cant-encode-character-u-xa0-in-position-20?rq=1
-        author_name = author_name.encode('ascii', 'ignore').decode('ascii')
-        committer_name = committer_name.encode('ascii', 'ignore').decode('ascii')
+        if needs_abandon:
+            # Perform the abandon only if the branch already exists
+            if not args.quiet:
+                print('Abandoning branch: %s' % args.start_branch[0])
+            subprocess.check_output(['repo', 'abandon', args.start_branch[0]])
+            if not args.quiet:
+                print('')
 
-        # Check if commit is not open, skip it.
-        if (status != 'OPEN' and status != 'NEW'):
-            print("Change is not open. Skipping the cherry pick.")
-            continue;
+    # Get the master manifest from repo
+    #   - convert project name and revision to a path
+    project_name_to_data = {}
+    manifest = subprocess.check_output(['repo', 'manifest'])
+    xml_root = ElementTree.fromstring(manifest)
+    projects = xml_root.findall('project')
+    remotes = xml_root.findall('remote')
+    default_revision = xml_root.findall('default')[0].get('revision')
+
+    #dump project data into the a list of dicts with the following data:
+    #{project: {path, revision}}
+
+    for project in projects:
+        name = project.get('name')
+        path = project.get('path')
+        revision = project.get('revision')
+        if revision is None:
+            for remote in remotes:
+                if remote.get('name') == project.get('remote'):
+                    revision = remote.get('revision')
+            if revision is None:
+                revision = default_revision
+
+        if not name in project_name_to_data:
+            project_name_to_data[name] = {}
+        revision = revision.split('refs/heads/')[-1]
+        project_name_to_data[name][revision] = path
+
+    # get data on requested changes
+    reviews = []
+    change_numbers = []
+    if args.topic:
+        reviews = fetch_query(args.gerrit, 'topic:{0}'.format(args.topic))
+        change_numbers = sorted([str(r['number']) for r in reviews], key=int)
+    if args.query:
+        reviews = fetch_query(args.gerrit, args.query)
+        change_numbers = sorted([str(r['number']) for r in reviews], key=int)
+    if args.change_number:
+        for c in args.change_number:
+            if '-' in c:
+                templist = c.split('-')
+                for i in range(int(templist[0]), int(templist[1]) + 1):
+                    change_numbers.append(str(i))
+            else:
+                change_numbers.append(c)
+        reviews = fetch_query(args.gerrit, ' OR '.join('change:{0}'.format(x.split('/')[0]) for x in change_numbers))
+
+    # make list of things to actually merge
+    mergables = []
+
+    # If --exclude is given, create the list of commits to ignore
+    exclude = []
+    if args.exclude:
+        exclude = args.exclude[0].split(',')
+
+    for change in change_numbers:
+        patchset = None
+        if '/' in change:
+            (change, patchset) = change.split('/')
+
+        if change in exclude:
+            continue
+
+        change = int(change)
+
+        if patchset is not None:
+            patchset = int(patchset)
+
+        review = next((x for x in reviews if x['number'] == change), None)
+        if review is None:
+            print('Change %d not found, skipping' % change)
+            continue
+
+        mergables.append({
+            'subject': review['subject'],
+            'project': review['project'],
+            'branch': review['branch'],
+            'change_id': review['change_id'],
+            'change_number': review['number'],
+            'status': review['status'],
+            'fetch': None
+        })
+        mergables[-1]['fetch'] = review['revisions'][review['current_revision']]['fetch']
+        mergables[-1]['id'] = change
+        if patchset:
+            try:
+                mergables[-1]['fetch'] = [review['revisions'][x]['fetch'] for x in review['revisions'] if review['revisions'][x]['_number'] == patchset][0]
+                mergables[-1]['id'] = '{0}/{1}'.format(change, patchset)
+            except (IndexError, ValueError):
+                args.quiet or print('ERROR: The patch set {0}/{1} could not be found, using CURRENT_REVISION instead.'.format(change, patchset))
+
+    for item in mergables:
+        args.quiet or print('Applying change number {0}...'.format(item['id']))
+        # Check if change is open and exit if it's not, unless -f is specified
+        if (item['status'] != 'OPEN' and item['status'] != 'NEW' and item['status'] != 'DRAFT') and not args.query:
+            if args.force:
+                print('!! Force-picking a closed change !!\n')
+            else:
+                print('Change status is ' + item['status'] + '. Skipping the cherry pick.\nUse -f to force this pick.')
+                continue
 
         # Convert the project name to a project path
         #   - check that the project path exists
-        if project_name in project_name_to_path:
-            project_path = project_name_to_path[project_name];
+        project_path = None
+
+        if item['project'] in project_name_to_data and item['branch'] in project_name_to_data[item['project']]:
+            project_path = project_name_to_data[item['project']][item['branch']]
+        elif args.path:
+            project_path = args.path
         elif args.ignore_missing:
-            print('WARNING: Skipping %d since there is no project directory for: %s\n' % (change_number, project_name))
-            continue;
+            print('WARNING: Skipping {0} since there is no project directory for: {1}\n'.format(item['id'], item['project']))
+            continue
         else:
-            sys.stderr.write('ERROR: For %d, could not determine the project path for project %s\n' % (change_number, project_name))
-            continue;
+            sys.stderr.write('ERROR: For {0}, could not determine the project path for project {1}\n'.format(item['id'], item['project']))
+            sys.exit(1)
 
         # If --start-branch is given, create the branch (more than once per path is okay; repo ignores gracefully)
         if args.start_branch:
-            cmd = '%s start %s %s' % (repo_bin, args.start_branch[0], project_path)
-            execute_cmd(cmd)
+            subprocess.check_output(['repo', 'start', args.start_branch[0], project_path])
+
+        # Determine the maximum commits to check already picked changes
+        check_picked_count = args.check_picked
+        branch_commits_count = int(subprocess.check_output(['git', 'rev-list', '--count', 'HEAD'], cwd=project_path))
+        if branch_commits_count <= check_picked_count:
+            check_picked_count = branch_commits_count - 1
+
+        # Check if change is already picked to HEAD...HEAD~check_picked_count
+        found_change = False
+        for i in range(0, check_picked_count):
+            if subprocess.call(['git', 'cat-file', '-e', 'HEAD~{0}'.format(i)], cwd=project_path, stderr=open(os.devnull, 'wb')):
+                continue
+            output = subprocess.check_output(['git', 'show', '-q', 'HEAD~{0}'.format(i)], cwd=project_path).split()
+            if 'Change-Id:' in output:
+                head_change_id = ''
+                for j,t in enumerate(reversed(output)):
+                    if t == 'Change-Id:':
+                        head_change_id = output[len(output) - j]
+                        break
+                if head_change_id.strip() == item['change_id']:
+                    print('Skipping {0} - already picked in {1} as HEAD~{2}'.format(item['id'], project_path, i))
+                    found_change = True
+                    break
+        if found_change:
+            continue
 
         # Print out some useful info
         if not args.quiet:
-            print('--> Subject:       "%s"' % subject)
-            print('--> Project path:  %s' % project_path)
-            print('--> Change number: %d (Patch Set %d)' % (change_number, patch_number))
-            print('--> Author:        %s <%s> %s' % (author_name, author_email, author_date))
-            print('--> Committer:     %s <%s> %s' % (committer_name, committer_email, committer_date))
+            print('--> Subject:       "{0}"'.format(item['subject'].encode('utf-8')))
+            print('--> Project path:  {0}'.format(project_path))
+            print('--> Change number: {0} (Patch Set {0})'.format(item['id']))
 
-        if args.verbose:
-            print('Trying to fetch the change %d (Patch Set %d) from Gerrit')
-        cmd = 'cd %s && git fetch %s %s' % (project_path, fetch_url, fetch_ref)
-        execute_cmd(cmd)
-        # Check if it worked
-        FETCH_HEAD = '%s/.git/FETCH_HEAD' % project_path
-        if os.stat(FETCH_HEAD).st_size == 0:
-            # That didn't work, print error and exit
-            sys.stderr.write('ERROR: Fetching change from Gerrit failed. Exiting...')
-            continue;
-        # Perform the cherry-pick or checkout
-        if args.checkout:
-            cmd = 'cd %s && git checkout FETCH_HEAD' % (project_path)
+        if 'anonymous http' in item['fetch']:
+            method = 'anonymous http'
         else:
-            cmd = 'cd %s && git cherry-pick FETCH_HEAD' % (project_path)
+            method = 'ssh'
 
-        execute_cmd(cmd)
+        # Try fetching from GitHub first if using default gerrit
+        if args.gerrit == default_gerrit:
+            if args.verbose:
+                print('Trying to fetch the change from GitHub')
+
+            if args.pull:
+                cmd = ['git pull --no-edit omnirom', item['fetch'][method]['ref']]
+            else:
+                cmd = ['git fetch omnirom', item['fetch'][method]['ref']]
+            if args.quiet:
+                cmd.append('--quiet')
+            else:
+                print(cmd)
+            result = subprocess.call([' '.join(cmd)], cwd=project_path, shell=True)
+            FETCH_HEAD = '{0}/.git/FETCH_HEAD'.format(project_path)
+            if result != 0 and os.stat(FETCH_HEAD).st_size != 0:
+                print('ERROR: git command failed')
+                sys.exit(result)
+        # Check if it worked
+        if args.gerrit != default_gerrit or os.stat(FETCH_HEAD).st_size == 0:
+            # If not using the default gerrit or github failed, fetch from gerrit.
+            if args.verbose:
+                if args.gerrit == default_gerrit:
+                    print('Fetching from GitHub didn\'t work, trying to fetch the change from Gerrit')
+                else:
+                    print('Fetching from {0}'.format(args.gerrit))
+
+            if args.pull:
+                cmd = ['git pull --no-edit', item['fetch'][method]['url'], item['fetch'][method]['ref']]
+            else:
+                cmd = ['git fetch', item['fetch'][method]['url'], item['fetch'][method]['ref']]
+            if args.quiet:
+                cmd.append('--quiet')
+            else:
+                print(cmd)
+            result = subprocess.call([' '.join(cmd)], cwd=project_path, shell=True)
+            if result != 0:
+                print('ERROR: git command failed')
+                sys.exit(result)
+        # Perform the cherry-pick
+        if not args.pull:
+            cmd = ['git cherry-pick FETCH_HEAD']
+            if args.quiet:
+                cmd_out = open(os.devnull, 'wb')
+            else:
+                cmd_out = None
+            result = subprocess.call(cmd, cwd=project_path, shell=True, stdout=cmd_out, stderr=cmd_out)
+            if result != 0:
+                if args.reset:
+                    print('ERROR: git command failed, aborting cherry-pick')
+                    cmd = ['git cherry-pick --abort']
+                    subprocess.call(cmd, cwd=project_path, shell=True, stdout=cmd_out, stderr=cmd_out)
+                else:
+                    print('ERROR: git command failed')
+                sys.exit(result)
         if not args.quiet:
-            print('Change #%d (Patch Set %d) %s into %s' % (change_number, patch_number, 'checked out' if args.checkout else 'cherry-picked', project_path))
+            print('')
