|
|
|
@ -10,6 +10,7 @@ copy of repo in the checkout.
|
|
|
|
|
|
|
|
|
|
from __future__ import print_function
|
|
|
|
|
|
|
|
|
|
import datetime
|
|
|
|
|
import os
|
|
|
|
|
import platform
|
|
|
|
|
import subprocess
|
|
|
|
@ -24,7 +25,7 @@ def exec_command(cmd):
|
|
|
|
|
sys.exit(ret)
|
|
|
|
|
else:
|
|
|
|
|
os.execvp(cmd[0], cmd)
|
|
|
|
|
except:
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -113,7 +114,7 @@ if not REPO_REV:
|
|
|
|
|
# limitations under the License.
|
|
|
|
|
|
|
|
|
|
# increment this whenever we make important changes to this script
|
|
|
|
|
VERSION = (2, 0)
|
|
|
|
|
VERSION = (2, 3)
|
|
|
|
|
|
|
|
|
|
# increment this if the MAINTAINER_KEYS block is modified
|
|
|
|
|
KEYRING_VERSION = (2, 0)
|
|
|
|
@ -166,7 +167,12 @@ TACbBS+Up3RpfYVfd63c1cDdlru13pQAn3NQy/SN858MkxN+zym86UBgOad2
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
GIT = 'git' # our git command
|
|
|
|
|
MIN_GIT_VERSION = (2, 10, 2) # minimum supported git version
|
|
|
|
|
# NB: The version of git that the repo launcher requires may be much older than
|
|
|
|
|
# the version of git that the main repo source tree requires. Keeping this at
|
|
|
|
|
# an older version also makes it easier for users to upgrade/rollback as needed.
|
|
|
|
|
#
|
|
|
|
|
# git-1.7 is in (EOL) Ubuntu Precise.
|
|
|
|
|
MIN_GIT_VERSION = (1, 7, 2) # minimum supported git version
|
|
|
|
|
repodir = '.repo' # name of repo's private directory
|
|
|
|
|
S_repo = 'repo' # special repo repository
|
|
|
|
|
S_manifests = 'manifests' # special manifest repository
|
|
|
|
@ -199,88 +205,73 @@ gpg_dir = os.path.join(home_dot_repo, 'gnupg')
|
|
|
|
|
extra_args = []
|
|
|
|
|
init_optparse = optparse.OptionParser(usage="repo init -u url [options]")
|
|
|
|
|
|
|
|
|
|
# Logging
|
|
|
|
|
group = init_optparse.add_option_group('Logging options')
|
|
|
|
|
group.add_option('-q', '--quiet',
|
|
|
|
|
dest="quiet", action="store_true", default=False,
|
|
|
|
|
help="be quiet")
|
|
|
|
|
|
|
|
|
|
# Manifest
|
|
|
|
|
group = init_optparse.add_option_group('Manifest options')
|
|
|
|
|
group.add_option('-u', '--manifest-url',
|
|
|
|
|
dest='manifest_url',
|
|
|
|
|
help='manifest repository location', metavar='URL')
|
|
|
|
|
group.add_option('-b', '--manifest-branch',
|
|
|
|
|
dest='manifest_branch',
|
|
|
|
|
help='manifest branch or revision', metavar='REVISION')
|
|
|
|
|
group.add_option('-m', '--manifest-name',
|
|
|
|
|
dest='manifest_name',
|
|
|
|
|
help='initial manifest file', metavar='NAME.xml')
|
|
|
|
|
group.add_option('--current-branch',
|
|
|
|
|
dest='current_branch_only', action='store_true',
|
|
|
|
|
help='fetch only current manifest branch from server')
|
|
|
|
|
group.add_option('--mirror',
|
|
|
|
|
dest='mirror', action='store_true',
|
|
|
|
|
help='create a replica of the remote repositories '
|
|
|
|
|
'rather than a client working directory')
|
|
|
|
|
group.add_option('--reference',
|
|
|
|
|
dest='reference',
|
|
|
|
|
help='location of mirror directory', metavar='DIR')
|
|
|
|
|
group.add_option('--dissociate',
|
|
|
|
|
dest='dissociate', action='store_true',
|
|
|
|
|
help='dissociate from reference mirrors after clone')
|
|
|
|
|
group.add_option('--depth', type='int', default=None,
|
|
|
|
|
dest='depth',
|
|
|
|
|
help='create a shallow clone with given depth; see git clone')
|
|
|
|
|
group.add_option('--partial-clone', action='store_true',
|
|
|
|
|
dest='partial_clone',
|
|
|
|
|
help='perform partial clone (https://git-scm.com/'
|
|
|
|
|
'docs/gitrepository-layout#_code_partialclone_code)')
|
|
|
|
|
group.add_option('--clone-filter', action='store', default='blob:none',
|
|
|
|
|
dest='clone_filter',
|
|
|
|
|
help='filter for use with --partial-clone [default: %default]')
|
|
|
|
|
group.add_option('--archive',
|
|
|
|
|
dest='archive', action='store_true',
|
|
|
|
|
help='checkout an archive instead of a git repository for '
|
|
|
|
|
'each project. See git archive.')
|
|
|
|
|
group.add_option('--submodules',
|
|
|
|
|
dest='submodules', action='store_true',
|
|
|
|
|
help='sync any submodules associated with the manifest repo')
|
|
|
|
|
group.add_option('-g', '--groups',
|
|
|
|
|
dest='groups', default='default',
|
|
|
|
|
help='restrict manifest projects to ones with specified '
|
|
|
|
|
'group(s) [default|all|G1,G2,G3|G4,-G5,-G6]',
|
|
|
|
|
metavar='GROUP')
|
|
|
|
|
group.add_option('-p', '--platform',
|
|
|
|
|
dest='platform', default="auto",
|
|
|
|
|
help='restrict manifest projects to ones with a specified '
|
|
|
|
|
'platform group [auto|all|none|linux|darwin|...]',
|
|
|
|
|
metavar='PLATFORM')
|
|
|
|
|
group.add_option('--no-clone-bundle',
|
|
|
|
|
dest='no_clone_bundle', action='store_true',
|
|
|
|
|
help='disable use of /clone.bundle on HTTP/HTTPS')
|
|
|
|
|
group.add_option('--no-tags',
|
|
|
|
|
dest='no_tags', action='store_true',
|
|
|
|
|
help="don't fetch tags in the manifest")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Tool
|
|
|
|
|
group = init_optparse.add_option_group('repo Version options')
|
|
|
|
|
group.add_option('--repo-url',
|
|
|
|
|
dest='repo_url',
|
|
|
|
|
help='repo repository location ($REPO_URL)', metavar='URL')
|
|
|
|
|
group.add_option('--repo-branch',
|
|
|
|
|
dest='repo_branch',
|
|
|
|
|
help='repo branch or revision ($REPO_REV)', metavar='REVISION')
|
|
|
|
|
group.add_option('--no-repo-verify',
|
|
|
|
|
dest='no_repo_verify', action='store_true',
|
|
|
|
|
help='do not verify repo source code')
|
|
|
|
|
|
|
|
|
|
# Other
|
|
|
|
|
group = init_optparse.add_option_group('Other options')
|
|
|
|
|
group.add_option('--config-name',
|
|
|
|
|
dest='config_name', action="store_true", default=False,
|
|
|
|
|
help='Always prompt for name/e-mail')
|
|
|
|
|
def _InitParser():
|
|
|
|
|
"""Setup the init subcommand parser."""
|
|
|
|
|
# Logging.
|
|
|
|
|
group = init_optparse.add_option_group('Logging options')
|
|
|
|
|
group.add_option('-q', '--quiet',
|
|
|
|
|
action='store_true', default=False,
|
|
|
|
|
help='be quiet')
|
|
|
|
|
|
|
|
|
|
# Manifest.
|
|
|
|
|
group = init_optparse.add_option_group('Manifest options')
|
|
|
|
|
group.add_option('-u', '--manifest-url',
|
|
|
|
|
help='manifest repository location', metavar='URL')
|
|
|
|
|
group.add_option('-b', '--manifest-branch',
|
|
|
|
|
help='manifest branch or revision', metavar='REVISION')
|
|
|
|
|
group.add_option('-m', '--manifest-name',
|
|
|
|
|
help='initial manifest file', metavar='NAME.xml')
|
|
|
|
|
group.add_option('--current-branch',
|
|
|
|
|
dest='current_branch_only', action='store_true',
|
|
|
|
|
help='fetch only current manifest branch from server')
|
|
|
|
|
group.add_option('--mirror', action='store_true',
|
|
|
|
|
help='create a replica of the remote repositories '
|
|
|
|
|
'rather than a client working directory')
|
|
|
|
|
group.add_option('--reference',
|
|
|
|
|
help='location of mirror directory', metavar='DIR')
|
|
|
|
|
group.add_option('--dissociate', action='store_true',
|
|
|
|
|
help='dissociate from reference mirrors after clone')
|
|
|
|
|
group.add_option('--depth', type='int', default=None,
|
|
|
|
|
help='create a shallow clone with given depth; '
|
|
|
|
|
'see git clone')
|
|
|
|
|
group.add_option('--partial-clone', action='store_true',
|
|
|
|
|
help='perform partial clone (https://git-scm.com/'
|
|
|
|
|
'docs/gitrepository-layout#_code_partialclone_code)')
|
|
|
|
|
group.add_option('--clone-filter', action='store', default='blob:none',
|
|
|
|
|
help='filter for use with --partial-clone '
|
|
|
|
|
'[default: %default]')
|
|
|
|
|
group.add_option('--archive', action='store_true',
|
|
|
|
|
help='checkout an archive instead of a git repository for '
|
|
|
|
|
'each project. See git archive.')
|
|
|
|
|
group.add_option('--submodules', action='store_true',
|
|
|
|
|
help='sync any submodules associated with the manifest repo')
|
|
|
|
|
group.add_option('-g', '--groups', default='default',
|
|
|
|
|
help='restrict manifest projects to ones with specified '
|
|
|
|
|
'group(s) [default|all|G1,G2,G3|G4,-G5,-G6]',
|
|
|
|
|
metavar='GROUP')
|
|
|
|
|
group.add_option('-p', '--platform', default='auto',
|
|
|
|
|
help='restrict manifest projects to ones with a specified '
|
|
|
|
|
'platform group [auto|all|none|linux|darwin|...]',
|
|
|
|
|
metavar='PLATFORM')
|
|
|
|
|
group.add_option('--no-clone-bundle', action='store_true',
|
|
|
|
|
help='disable use of /clone.bundle on HTTP/HTTPS')
|
|
|
|
|
group.add_option('--no-tags', action='store_true',
|
|
|
|
|
help="don't fetch tags in the manifest")
|
|
|
|
|
|
|
|
|
|
# Tool.
|
|
|
|
|
group = init_optparse.add_option_group('repo Version options')
|
|
|
|
|
group.add_option('--repo-url', metavar='URL',
|
|
|
|
|
help='repo repository location ($REPO_URL)')
|
|
|
|
|
group.add_option('--repo-branch', metavar='REVISION',
|
|
|
|
|
help='repo branch or revision ($REPO_REV)')
|
|
|
|
|
group.add_option('--no-repo-verify', action='store_true',
|
|
|
|
|
help='do not verify repo source code')
|
|
|
|
|
|
|
|
|
|
# Other.
|
|
|
|
|
group = init_optparse.add_option_group('Other options')
|
|
|
|
|
group.add_option('--config-name',
|
|
|
|
|
action='store_true', default=False,
|
|
|
|
|
help='Always prompt for name/e-mail')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _GitcInitOptions(init_optparse_arg):
|
|
|
|
@ -488,6 +479,39 @@ def _CheckGitVersion():
|
|
|
|
|
raise CloneFailure()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def SetGitTrace2ParentSid(env=None):
|
|
|
|
|
"""Set up GIT_TRACE2_PARENT_SID for git tracing."""
|
|
|
|
|
# We roughly follow the format git itself uses in trace2/tr2_sid.c.
|
|
|
|
|
# (1) Be unique (2) be valid filename (3) be fixed length.
|
|
|
|
|
#
|
|
|
|
|
# Since we always export this variable, we try to avoid more expensive calls.
|
|
|
|
|
# e.g. We don't attempt hostname lookups or hashing the results.
|
|
|
|
|
if env is None:
|
|
|
|
|
env = os.environ
|
|
|
|
|
|
|
|
|
|
KEY = 'GIT_TRACE2_PARENT_SID'
|
|
|
|
|
|
|
|
|
|
now = datetime.datetime.utcnow()
|
|
|
|
|
value = 'repo-%s-P%08x' % (now.strftime('%Y%m%dT%H%M%SZ'), os.getpid())
|
|
|
|
|
|
|
|
|
|
# If it's already set, then append ourselves.
|
|
|
|
|
if KEY in env:
|
|
|
|
|
value = env[KEY] + '/' + value
|
|
|
|
|
|
|
|
|
|
_setenv(KEY, value, env=env)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _setenv(key, value, env=None):
|
|
|
|
|
"""Set |key| in the OS environment |env| to |value|."""
|
|
|
|
|
if env is None:
|
|
|
|
|
env = os.environ
|
|
|
|
|
# Environment handling across systems is messy.
|
|
|
|
|
try:
|
|
|
|
|
env[key] = value
|
|
|
|
|
except UnicodeEncodeError:
|
|
|
|
|
env[key] = value.encode()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def NeedSetupGnuPG():
|
|
|
|
|
if not os.path.isdir(home_dot_repo):
|
|
|
|
|
return True
|
|
|
|
@ -524,10 +548,7 @@ def SetupGnuPG(quiet):
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
env = os.environ.copy()
|
|
|
|
|
try:
|
|
|
|
|
env['GNUPGHOME'] = gpg_dir
|
|
|
|
|
except UnicodeEncodeError:
|
|
|
|
|
env['GNUPGHOME'] = gpg_dir.encode()
|
|
|
|
|
_setenv('GNUPGHOME', gpg_dir, env)
|
|
|
|
|
|
|
|
|
|
cmd = ['gpg', '--import']
|
|
|
|
|
try:
|
|
|
|
@ -733,10 +754,7 @@ def _Verify(cwd, branch, quiet):
|
|
|
|
|
print(file=sys.stderr)
|
|
|
|
|
|
|
|
|
|
env = os.environ.copy()
|
|
|
|
|
try:
|
|
|
|
|
env['GNUPGHOME'] = gpg_dir
|
|
|
|
|
except UnicodeEncodeError:
|
|
|
|
|
env['GNUPGHOME'] = gpg_dir.encode()
|
|
|
|
|
_setenv('GNUPGHOME', gpg_dir, env)
|
|
|
|
|
|
|
|
|
|
cmd = [GIT, 'tag', '-v', cur]
|
|
|
|
|
proc = subprocess.Popen(cmd,
|
|
|
|
@ -801,6 +819,7 @@ def _FindRepo():
|
|
|
|
|
|
|
|
|
|
class _Options(object):
|
|
|
|
|
help = False
|
|
|
|
|
version = False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _ParseArguments(args):
|
|
|
|
@ -812,7 +831,8 @@ def _ParseArguments(args):
|
|
|
|
|
a = args[i]
|
|
|
|
|
if a == '-h' or a == '--help':
|
|
|
|
|
opt.help = True
|
|
|
|
|
|
|
|
|
|
elif a == '--version':
|
|
|
|
|
opt.version = True
|
|
|
|
|
elif not a.startswith('-'):
|
|
|
|
|
cmd = a
|
|
|
|
|
arg = args[i + 1:]
|
|
|
|
@ -859,6 +879,16 @@ def _Help(args):
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _Version():
|
|
|
|
|
"""Show version information."""
|
|
|
|
|
print('<repo not installed>')
|
|
|
|
|
print('repo launcher version %s' % ('.'.join(str(x) for x in VERSION),))
|
|
|
|
|
print(' (from %s)' % (__file__,))
|
|
|
|
|
print('git %s' % (ParseGitVersion().full,))
|
|
|
|
|
print('Python %s' % sys.version)
|
|
|
|
|
sys.exit(0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _NotInstalled():
|
|
|
|
|
print('error: repo is not installed. Use "repo init" to install it here.',
|
|
|
|
|
file=sys.stderr)
|
|
|
|
@ -911,6 +941,9 @@ def _SetDefaultsTo(gitdir):
|
|
|
|
|
def main(orig_args):
|
|
|
|
|
cmd, opt, args = _ParseArguments(orig_args)
|
|
|
|
|
|
|
|
|
|
# We run this early as we run some git commands ourselves.
|
|
|
|
|
SetGitTrace2ParentSid()
|
|
|
|
|
|
|
|
|
|
repo_main, rel_repo_dir = None, None
|
|
|
|
|
# Don't use the local repo copy, make sure to switch to the gitc client first.
|
|
|
|
|
if cmd != 'gitc-init':
|
|
|
|
@ -926,11 +959,14 @@ def main(orig_args):
|
|
|
|
|
'command from the corresponding client under /gitc/',
|
|
|
|
|
file=sys.stderr)
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
_InitParser()
|
|
|
|
|
if not repo_main:
|
|
|
|
|
if opt.help:
|
|
|
|
|
_Usage()
|
|
|
|
|
if cmd == 'help':
|
|
|
|
|
_Help(args)
|
|
|
|
|
if opt.version or cmd == 'version':
|
|
|
|
|
_Version()
|
|
|
|
|
if not cmd:
|
|
|
|
|
_NotInstalled()
|
|
|
|
|
if cmd == 'init' or cmd == 'gitc-init':
|
|
|
|
|