mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
cf7c0834cf
When someone does "repo download -c <project> <change>" without specifying a patch number, by default patch 1 is downloaded. An alternative is to look for the latest patch and download the same when no explicit patch is given. This commit does the same by identifying the latest patch using "git ls-remote". Change-Id: Ia5fa7364415f53a3d9436df4643e38f3c90ded58
113 lines
3.6 KiB
Python
Executable File
113 lines
3.6 KiB
Python
Executable File
#
|
|
# Copyright (C) 2008 The Android Open Source Project
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
from __future__ import print_function
|
|
import re
|
|
import sys
|
|
|
|
from command import Command
|
|
from error import GitError
|
|
|
|
CHANGE_RE = re.compile(r'^([1-9][0-9]*)(?:[/\.-]([1-9][0-9]*))?$')
|
|
|
|
class Download(Command):
|
|
common = True
|
|
helpSummary = "Download and checkout a change"
|
|
helpUsage = """
|
|
%prog {[project] change[/patchset]}...
|
|
"""
|
|
helpDescription = """
|
|
The '%prog' command downloads a change from the review system and
|
|
makes it available in your project's local working directory.
|
|
If no project is specified try to use current directory as a project.
|
|
"""
|
|
|
|
def _Options(self, p):
|
|
p.add_option('-c', '--cherry-pick',
|
|
dest='cherrypick', action='store_true',
|
|
help="cherry-pick instead of checkout")
|
|
p.add_option('-r', '--revert',
|
|
dest='revert', action='store_true',
|
|
help="revert instead of checkout")
|
|
p.add_option('-f', '--ff-only',
|
|
dest='ffonly', action='store_true',
|
|
help="force fast-forward merge")
|
|
|
|
def _ParseChangeIds(self, args):
|
|
if not args:
|
|
self.Usage()
|
|
|
|
to_get = []
|
|
project = None
|
|
|
|
for a in args:
|
|
m = CHANGE_RE.match(a)
|
|
if m:
|
|
if not project:
|
|
project = self.GetProjects(".")[0]
|
|
chg_id = int(m.group(1))
|
|
if m.group(2):
|
|
ps_id = int(m.group(2))
|
|
else:
|
|
ps_id = 1
|
|
regex = r'refs/changes/%2.2d/%d/(\d+)' % (chg_id % 100, chg_id)
|
|
output = project._LsRemote()
|
|
if output:
|
|
rcomp = re.compile(regex, re.I)
|
|
for line in output.splitlines():
|
|
match = rcomp.search(line)
|
|
if match:
|
|
ps_id = max(int(match.group(1)), ps_id)
|
|
to_get.append((project, chg_id, ps_id))
|
|
else:
|
|
project = self.GetProjects([a])[0]
|
|
return to_get
|
|
|
|
def Execute(self, opt, args):
|
|
for project, change_id, ps_id in self._ParseChangeIds(args):
|
|
dl = project.DownloadPatchSet(change_id, ps_id)
|
|
if not dl:
|
|
print('[%s] change %d/%d not found'
|
|
% (project.name, change_id, ps_id),
|
|
file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
if not opt.revert and not dl.commits:
|
|
print('[%s] change %d/%d has already been merged'
|
|
% (project.name, change_id, ps_id),
|
|
file=sys.stderr)
|
|
continue
|
|
|
|
if len(dl.commits) > 1:
|
|
print('[%s] %d/%d depends on %d unmerged changes:' \
|
|
% (project.name, change_id, ps_id, len(dl.commits)),
|
|
file=sys.stderr)
|
|
for c in dl.commits:
|
|
print(' %s' % (c), file=sys.stderr)
|
|
if opt.cherrypick:
|
|
try:
|
|
project._CherryPick(dl.commit)
|
|
except GitError:
|
|
print('[%s] Could not complete the cherry-pick of %s' \
|
|
% (project.name, dl.commit), file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
elif opt.revert:
|
|
project._Revert(dl.commit)
|
|
elif opt.ffonly:
|
|
project._FastForward(dl.commit, ffonly=True)
|
|
else:
|
|
project._Checkout(dl.commit)
|