mirror of
https://gerrit.googlesource.com/git-repo
synced 2025-06-26 20:17:52 +00:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
0ec2029833 | |||
d8e8ae8990 | |||
6448a4f2af | |||
1328c35a4d | |||
7f8bd85184 | |||
c63328e5ff | |||
b55769a5c9 | |||
5637afcc60 | |||
df8b1cba47 |
10
command.py
10
command.py
@ -24,6 +24,10 @@ from error import InvalidProjectGroupsError
|
||||
import progress
|
||||
|
||||
|
||||
# Are we generating man-pages?
|
||||
GENERATE_MANPAGES = os.environ.get('_REPO_GENERATE_MANPAGES_') == ' indeed! '
|
||||
|
||||
|
||||
# Number of projects to submit to a single worker process at a time.
|
||||
# This number represents a tradeoff between the overhead of IPC and finer
|
||||
# grained opportunity for parallelism. This particular value was chosen by
|
||||
@ -122,10 +126,14 @@ class Command(object):
|
||||
help='only show errors')
|
||||
|
||||
if self.PARALLEL_JOBS is not None:
|
||||
default = 'based on number of CPU cores'
|
||||
if not GENERATE_MANPAGES:
|
||||
# Only include active cpu count if we aren't generating man pages.
|
||||
default = f'%default; {default}'
|
||||
p.add_option(
|
||||
'-j', '--jobs',
|
||||
type=int, default=self.PARALLEL_JOBS,
|
||||
help='number of jobs to run in parallel (default: %s)' % self.PARALLEL_JOBS)
|
||||
help=f'number of jobs to run in parallel (default: {default})')
|
||||
|
||||
def _Options(self, p):
|
||||
"""Initialize the option parser with subcommand-specific options."""
|
||||
|
@ -277,6 +277,11 @@ Things in italics are things we used to care about but probably don't anymore.
|
||||
| Nov 2019 | | 2.24.0 |
|
||||
| Jan 2020 | | 2.25.0 | | **20.04 Focal** |
|
||||
| Apr 2020 | **Apr 2030** | | | **20.04 Focal** | 2.25.0 | 2.7.17 3.7.5 |
|
||||
| Oct 2020 | **Oct 2025** | | 3.9.0 | 21.04 Hirsute / **Bullseye** |
|
||||
| Dec 2020 | | 2.30.0 | | 21.04 Hirsute / **Bullseye** |
|
||||
| Apr 2021 | *Jan 2022* | | | 21.04 Hirsute | 2.30.2 | 2.7.18 3.9.4 |
|
||||
| Aug 2021 | **Aug 2026** | | | **Debian 11 Bullseye** | 2.30.2 | 2.7.18 3.9.2 |
|
||||
| **Date** | **EOL** | **[Git][rel-g]** | **[Python][rel-p]** | **[Ubuntu][rel-u] / [Debian][rel-d]** | **Git** | **Python** |
|
||||
|
||||
|
||||
[contact]: ../README.md#contact
|
||||
|
@ -59,7 +59,7 @@ class CommitIdsResult(NamedTuple):
|
||||
class UpdateProjectsResult(NamedTuple):
|
||||
"""Return the overriding manifest file and whether caller should exit."""
|
||||
|
||||
# Path name of the overriding manfiest file if successful, otherwise None.
|
||||
# Path name of the overriding manifest file if successful, otherwise None.
|
||||
manifest_path: str
|
||||
# Whether the caller should exit.
|
||||
fatal: bool
|
||||
@ -73,7 +73,7 @@ class Superproject(object):
|
||||
is a dictionary with project/commit id entries.
|
||||
"""
|
||||
def __init__(self, manifest, repodir, git_event_log,
|
||||
superproject_dir='exp-superproject', quiet=False):
|
||||
superproject_dir='exp-superproject', quiet=False, print_messages=False):
|
||||
"""Initializes superproject.
|
||||
|
||||
Args:
|
||||
@ -83,11 +83,13 @@ class Superproject(object):
|
||||
git_event_log: A git trace2 event log to log events.
|
||||
superproject_dir: Relative path under |repodir| to checkout superproject.
|
||||
quiet: If True then only print the progress messages.
|
||||
print_messages: if True then print error/warning messages.
|
||||
"""
|
||||
self._project_commit_ids = None
|
||||
self._manifest = manifest
|
||||
self._git_event_log = git_event_log
|
||||
self._quiet = quiet
|
||||
self._print_messages = print_messages
|
||||
self._branch = self._GetBranch()
|
||||
self._repodir = os.path.abspath(repodir)
|
||||
self._superproject_dir = superproject_dir
|
||||
@ -96,8 +98,11 @@ class Superproject(object):
|
||||
_SUPERPROJECT_MANIFEST_NAME)
|
||||
git_name = ''
|
||||
if self._manifest.superproject:
|
||||
remote_name = self._manifest.superproject['remote'].name
|
||||
git_name = hashlib.md5(remote_name.encode('utf8')).hexdigest() + '-'
|
||||
remote = self._manifest.superproject['remote']
|
||||
git_name = hashlib.md5(remote.name.encode('utf8')).hexdigest() + '-'
|
||||
self._remote_url = remote.url
|
||||
else:
|
||||
self._remote_url = None
|
||||
self._work_git_name = git_name + _SUPERPROJECT_GIT_NAME
|
||||
self._work_git = os.path.join(self._superproject_path, self._work_git_name)
|
||||
|
||||
@ -122,10 +127,23 @@ class Superproject(object):
|
||||
branch = branch[len(R_HEADS):]
|
||||
return branch
|
||||
|
||||
def _LogError(self, message):
|
||||
def _LogMessage(self, message):
|
||||
"""Logs message to stderr and _git_event_log."""
|
||||
print(message, file=sys.stderr)
|
||||
self._git_event_log.ErrorEvent(message, '')
|
||||
if self._print_messages:
|
||||
print(message, file=sys.stderr)
|
||||
self._git_event_log.ErrorEvent(message, f'{message}')
|
||||
|
||||
def _LogMessagePrefix(self):
|
||||
"""Returns the prefix string to be logged in each log message"""
|
||||
return f'repo superproject branch: {self._branch} url: {self._remote_url}'
|
||||
|
||||
def _LogError(self, message):
|
||||
"""Logs error message to stderr and _git_event_log."""
|
||||
self._LogMessage(f'{self._LogMessagePrefix()} error: {message}')
|
||||
|
||||
def _LogWarning(self, message):
|
||||
"""Logs warning message to stderr and _git_event_log."""
|
||||
self._LogMessage(f'{self._LogMessagePrefix()} warning: {message}')
|
||||
|
||||
def _Init(self):
|
||||
"""Sets up a local Git repository to get a copy of a superproject.
|
||||
@ -146,27 +164,25 @@ class Superproject(object):
|
||||
capture_stderr=True)
|
||||
retval = p.Wait()
|
||||
if retval:
|
||||
self._LogError(f'repo: error: git init call failed, command: git {cmd}, '
|
||||
f'return code: {retval}, stderr: {p.stderr}')
|
||||
self._LogWarning(f'git init call failed, command: git {cmd}, '
|
||||
f'return code: {retval}, stderr: {p.stderr}')
|
||||
return False
|
||||
return True
|
||||
|
||||
def _Fetch(self, url):
|
||||
"""Fetches a local copy of a superproject for the manifest based on url.
|
||||
|
||||
Args:
|
||||
url: superproject's url.
|
||||
def _Fetch(self):
|
||||
"""Fetches a local copy of a superproject for the manifest based on |_remote_url|.
|
||||
|
||||
Returns:
|
||||
True if fetch is successful, or False.
|
||||
"""
|
||||
if not os.path.exists(self._work_git):
|
||||
self._LogError(f'git fetch missing directory: {self._work_git}')
|
||||
self._LogWarning(f'git fetch missing directory: {self._work_git}')
|
||||
return False
|
||||
if not git_require((2, 28, 0)):
|
||||
print('superproject requires a git version 2.28 or later', file=sys.stderr)
|
||||
self._LogWarning('superproject requires a git version 2.28 or later')
|
||||
return False
|
||||
cmd = ['fetch', url, '--depth', '1', '--force', '--no-tags', '--filter', 'blob:none']
|
||||
cmd = ['fetch', self._remote_url, '--depth', '1', '--force', '--no-tags',
|
||||
'--filter', 'blob:none']
|
||||
if self._branch:
|
||||
cmd += [self._branch + ':' + self._branch]
|
||||
p = GitCommand(None,
|
||||
@ -176,8 +192,8 @@ class Superproject(object):
|
||||
capture_stderr=True)
|
||||
retval = p.Wait()
|
||||
if retval:
|
||||
self._LogError(f'repo: error: git fetch call failed, command: git {cmd}, '
|
||||
f'return code: {retval}, stderr: {p.stderr}')
|
||||
self._LogWarning(f'git fetch call failed, command: git {cmd}, '
|
||||
f'return code: {retval}, stderr: {p.stderr}')
|
||||
return False
|
||||
return True
|
||||
|
||||
@ -190,7 +206,7 @@ class Superproject(object):
|
||||
data: data returned from 'git ls-tree ...' instead of None.
|
||||
"""
|
||||
if not os.path.exists(self._work_git):
|
||||
self._LogError(f'git ls-tree missing directory: {self._work_git}')
|
||||
self._LogWarning(f'git ls-tree missing directory: {self._work_git}')
|
||||
return None
|
||||
data = None
|
||||
branch = 'HEAD' if not self._branch else self._branch
|
||||
@ -205,8 +221,8 @@ class Superproject(object):
|
||||
if retval == 0:
|
||||
data = p.stdout
|
||||
else:
|
||||
self._LogError(f'repo: error: git ls-tree call failed, command: git {cmd}, '
|
||||
f'return code: {retval}, stderr: {p.stderr}')
|
||||
self._LogWarning(f'git ls-tree call failed, command: git {cmd}, '
|
||||
f'return code: {retval}, stderr: {p.stderr}')
|
||||
return data
|
||||
|
||||
def Sync(self):
|
||||
@ -215,24 +231,22 @@ class Superproject(object):
|
||||
Returns:
|
||||
SyncResult
|
||||
"""
|
||||
print('NOTICE: --use-superproject is in beta; report any issues to the '
|
||||
'address described in `repo version`', file=sys.stderr)
|
||||
|
||||
if not self._manifest.superproject:
|
||||
self._LogError(f'repo error: superproject tag is not defined in manifest: '
|
||||
f'{self._manifest.manifestFile}')
|
||||
self._LogWarning(f'superproject tag is not defined in manifest: '
|
||||
f'{self._manifest.manifestFile}')
|
||||
return SyncResult(False, False)
|
||||
|
||||
print('NOTICE: --use-superproject is in beta; report any issues to the '
|
||||
'address described in `repo version`', file=sys.stderr)
|
||||
should_exit = True
|
||||
url = self._manifest.superproject['remote'].url
|
||||
if not url:
|
||||
self._LogError(f'repo error: superproject URL is not defined in manifest: '
|
||||
f'{self._manifest.manifestFile}')
|
||||
if not self._remote_url:
|
||||
self._LogWarning(f'superproject URL is not defined in manifest: '
|
||||
f'{self._manifest.manifestFile}')
|
||||
return SyncResult(False, should_exit)
|
||||
|
||||
if not self._Init():
|
||||
return SyncResult(False, should_exit)
|
||||
if not self._Fetch(url):
|
||||
if not self._Fetch():
|
||||
return SyncResult(False, should_exit)
|
||||
if not self._quiet:
|
||||
print('%s: Initial setup for superproject completed.' % self._work_git)
|
||||
@ -250,8 +264,8 @@ class Superproject(object):
|
||||
|
||||
data = self._LsTree()
|
||||
if not data:
|
||||
print('warning: git ls-tree failed to return data for superproject',
|
||||
file=sys.stderr)
|
||||
self._LogWarning(f'git ls-tree failed to return data for manifest: '
|
||||
f'{self._manifest.manifestFile}')
|
||||
return CommitIdsResult(None, True)
|
||||
|
||||
# Parse lines like the following to select lines starting with '160000' and
|
||||
@ -270,14 +284,14 @@ class Superproject(object):
|
||||
self._project_commit_ids = commit_ids
|
||||
return CommitIdsResult(commit_ids, False)
|
||||
|
||||
def _WriteManfiestFile(self):
|
||||
def _WriteManifestFile(self):
|
||||
"""Writes manifest to a file.
|
||||
|
||||
Returns:
|
||||
manifest_path: Path name of the file into which manifest is written instead of None.
|
||||
"""
|
||||
if not os.path.exists(self._superproject_path):
|
||||
self._LogError(f'error: missing superproject directory: {self._superproject_path}')
|
||||
self._LogWarning(f'missing superproject directory: {self._superproject_path}')
|
||||
return None
|
||||
manifest_str = self._manifest.ToXml(groups=self._manifest.GetGroupsStr()).toxml()
|
||||
manifest_path = self._manifest_path
|
||||
@ -285,7 +299,7 @@ class Superproject(object):
|
||||
with open(manifest_path, 'w', encoding='utf-8') as fp:
|
||||
fp.write(manifest_str)
|
||||
except IOError as e:
|
||||
self._LogError(f'error: cannot write manifest to : {manifest_path} {e}')
|
||||
self._LogError(f'cannot write manifest to : {manifest_path} {e}')
|
||||
return None
|
||||
return manifest_path
|
||||
|
||||
@ -321,7 +335,6 @@ class Superproject(object):
|
||||
commit_ids_result = self._GetAllProjectsCommitIds()
|
||||
commit_ids = commit_ids_result.commit_ids
|
||||
if not commit_ids:
|
||||
print('warning: Cannot get project commit ids from manifest', file=sys.stderr)
|
||||
return UpdateProjectsResult(None, commit_ids_result.fatal)
|
||||
|
||||
projects_missing_commit_ids = []
|
||||
@ -336,15 +349,15 @@ class Superproject(object):
|
||||
# If superproject doesn't have a commit id for a project, then report an
|
||||
# error event and continue as if do not use superproject is specified.
|
||||
if projects_missing_commit_ids:
|
||||
self._LogError(f'error: please file a bug using {self._manifest.contactinfo.bugurl} '
|
||||
f'to report missing commit_ids for: {projects_missing_commit_ids}')
|
||||
self._LogWarning(f'please file a bug using {self._manifest.contactinfo.bugurl} '
|
||||
f'to report missing commit_ids for: {projects_missing_commit_ids}')
|
||||
return UpdateProjectsResult(None, False)
|
||||
|
||||
for project in projects:
|
||||
if not self._SkipUpdatingProjectRevisionId(project):
|
||||
project.SetRevisionId(commit_ids.get(project.relpath))
|
||||
|
||||
manifest_path = self._WriteManfiestFile()
|
||||
manifest_path = self._WriteManifestFile()
|
||||
return UpdateProjectsResult(manifest_path, False)
|
||||
|
||||
|
||||
@ -352,67 +365,51 @@ class Superproject(object):
|
||||
def _UseSuperprojectFromConfiguration():
|
||||
"""Returns the user choice of whether to use superproject."""
|
||||
user_cfg = RepoConfig.ForUser()
|
||||
system_cfg = RepoConfig.ForSystem()
|
||||
time_now = int(time.time())
|
||||
|
||||
user_value = user_cfg.GetBoolean('repo.superprojectChoice')
|
||||
if user_value is not None:
|
||||
user_expiration = user_cfg.GetInt('repo.superprojectChoiceExpire')
|
||||
if user_expiration is not None and (user_expiration <= 0 or user_expiration >= time_now):
|
||||
if user_expiration is None or user_expiration <= 0 or user_expiration >= time_now:
|
||||
# TODO(b/190688390) - Remove prompt when we are comfortable with the new
|
||||
# default value.
|
||||
print(('You are currently enrolled in Git submodules experiment '
|
||||
'(go/android-submodules-quickstart). Use --no-use-superproject '
|
||||
'to override.\n'), file=sys.stderr)
|
||||
if user_value:
|
||||
print(('You are currently enrolled in Git submodules experiment '
|
||||
'(go/android-submodules-quickstart). Use --no-use-superproject '
|
||||
'to override.\n'), file=sys.stderr)
|
||||
else:
|
||||
print(('You are not currently enrolled in Git submodules experiment '
|
||||
'(go/android-submodules-quickstart). Use --use-superproject '
|
||||
'to override.\n'), file=sys.stderr)
|
||||
return user_value
|
||||
|
||||
# We don't have an unexpired choice, ask for one.
|
||||
system_cfg = RepoConfig.ForSystem()
|
||||
system_value = system_cfg.GetBoolean('repo.superprojectChoice')
|
||||
if system_value:
|
||||
# The system configuration is proposing that we should enable the
|
||||
# use of superproject. Present this to user for confirmation if we
|
||||
# are on a TTY, or, when we are not on a TTY, accept the system
|
||||
# default for this time only.
|
||||
# use of superproject. Treat the user as enrolled for two weeks.
|
||||
#
|
||||
# TODO(b/190688390) - Remove prompt when we are comfortable with the new
|
||||
# default value.
|
||||
prompt = ('Repo can now use Git submodules (go/android-submodules-quickstart) '
|
||||
'instead of manifests to represent the state of the Android '
|
||||
'superproject, which results in faster syncs and better atomicity.\n\n')
|
||||
if sys.stdout.isatty():
|
||||
prompt += 'Would you like to opt in for two weeks (y/N)? '
|
||||
response = input(prompt).lower()
|
||||
time_choiceexpire = time_now + (86400 * 14)
|
||||
if response in ('y', 'yes'):
|
||||
userchoice = True
|
||||
elif response in ('a', 'always'):
|
||||
userchoice = True
|
||||
time_choiceexpire = 0
|
||||
elif response == 'never':
|
||||
userchoice = False
|
||||
time_choiceexpire = 0
|
||||
elif response in ('n', 'no'):
|
||||
userchoice = False
|
||||
else:
|
||||
# Unrecognized user response, assume the intention was no, but
|
||||
# only for 2 hours instead of 2 weeks to balance between not
|
||||
# being overly pushy while still retain the opportunity to
|
||||
# enroll.
|
||||
userchoice = False
|
||||
time_choiceexpire = time_now + 7200
|
||||
|
||||
user_cfg.SetString('repo.superprojectChoiceExpire', str(time_choiceexpire))
|
||||
user_cfg.SetBoolean('repo.superprojectChoice', userchoice)
|
||||
|
||||
return userchoice
|
||||
else:
|
||||
print('Accepting once since we are not on a TTY', file=sys.stderr)
|
||||
return True
|
||||
userchoice = True
|
||||
time_choiceexpire = time_now + (86400 * 14)
|
||||
user_cfg.SetString('repo.superprojectChoiceExpire', str(time_choiceexpire))
|
||||
user_cfg.SetBoolean('repo.superprojectChoice', userchoice)
|
||||
print('You are automatically enrolled in Git submodules experiment '
|
||||
'(go/android-submodules-quickstart) for another two weeks.\n',
|
||||
file=sys.stderr)
|
||||
return True
|
||||
|
||||
# For all other cases, we would not use superproject by default.
|
||||
return False
|
||||
|
||||
|
||||
def PrintMessages(opt, manifest):
|
||||
"""Returns a boolean if error/warning messages are to be printed."""
|
||||
return opt.use_superproject is not None or manifest.superproject
|
||||
|
||||
|
||||
def UseSuperproject(opt, manifest):
|
||||
"""Returns a boolean if use-superproject option is enabled."""
|
||||
|
||||
|
@ -167,6 +167,22 @@ class EventLog(object):
|
||||
repo_config = {k: v for k, v in config.items() if k.startswith('repo.')}
|
||||
self.LogConfigEvents(repo_config, 'def_param')
|
||||
|
||||
def LogDataConfigEvents(self, config, prefix):
|
||||
"""Append a 'data' event for each config key/value in |config| to the current log.
|
||||
|
||||
For each keyX and valueX of the config, "key" field of the event is '|prefix|/keyX'
|
||||
and the "value" of the "key" field is valueX.
|
||||
|
||||
Args:
|
||||
config: Configuration dictionary.
|
||||
prefix: Prefix for each key that is logged.
|
||||
"""
|
||||
for key, value in config.items():
|
||||
event = self._CreateEventDict('data')
|
||||
event['key'] = f'{prefix}/{key}'
|
||||
event['value'] = value
|
||||
self._log.append(event)
|
||||
|
||||
def ErrorEvent(self, msg, fmt):
|
||||
"""Append a 'error' event to the current log."""
|
||||
error_event = self._CreateEventDict('error')
|
||||
|
@ -20,7 +20,8 @@ It is equivalent to "git branch \fB\-D\fR <branchname>".
|
||||
show this help message and exit
|
||||
.TP
|
||||
\fB\-j\fR JOBS, \fB\-\-jobs\fR=\fI\,JOBS\/\fR
|
||||
number of jobs to run in parallel (default: 4)
|
||||
number of jobs to run in parallel (default: based on
|
||||
number of CPU cores)
|
||||
.TP
|
||||
\fB\-\-all\fR
|
||||
delete all branches in all projects
|
||||
|
@ -46,7 +46,8 @@ is shown, then the branch appears in all projects.
|
||||
show this help message and exit
|
||||
.TP
|
||||
\fB\-j\fR JOBS, \fB\-\-jobs\fR=\fI\,JOBS\/\fR
|
||||
number of jobs to run in parallel (default: 4)
|
||||
number of jobs to run in parallel (default: based on
|
||||
number of CPU cores)
|
||||
.SS Logging options:
|
||||
.TP
|
||||
\fB\-v\fR, \fB\-\-verbose\fR
|
||||
|
@ -15,7 +15,8 @@ Checkout a branch for development
|
||||
show this help message and exit
|
||||
.TP
|
||||
\fB\-j\fR JOBS, \fB\-\-jobs\fR=\fI\,JOBS\/\fR
|
||||
number of jobs to run in parallel (default: 4)
|
||||
number of jobs to run in parallel (default: based on
|
||||
number of CPU cores)
|
||||
.SS Logging options:
|
||||
.TP
|
||||
\fB\-v\fR, \fB\-\-verbose\fR
|
||||
|
@ -19,7 +19,8 @@ to the Unix 'patch' command.
|
||||
show this help message and exit
|
||||
.TP
|
||||
\fB\-j\fR JOBS, \fB\-\-jobs\fR=\fI\,JOBS\/\fR
|
||||
number of jobs to run in parallel (default: 4)
|
||||
number of jobs to run in parallel (default: based on
|
||||
number of CPU cores)
|
||||
.TP
|
||||
\fB\-u\fR, \fB\-\-absolute\fR
|
||||
paths are relative to the repository root
|
||||
|
@ -17,7 +17,8 @@ repo forall \fB\-r\fR str1 [str2] ... \fB\-c\fR <command> [<arg>...]
|
||||
show this help message and exit
|
||||
.TP
|
||||
\fB\-j\fR JOBS, \fB\-\-jobs\fR=\fI\,JOBS\/\fR
|
||||
number of jobs to run in parallel (default: 4)
|
||||
number of jobs to run in parallel (default: based on
|
||||
number of CPU cores)
|
||||
.TP
|
||||
\fB\-r\fR, \fB\-\-regex\fR
|
||||
execute the command only on projects matching regex or
|
||||
|
@ -15,7 +15,8 @@ Print lines matching a pattern
|
||||
show this help message and exit
|
||||
.TP
|
||||
\fB\-j\fR JOBS, \fB\-\-jobs\fR=\fI\,JOBS\/\fR
|
||||
number of jobs to run in parallel (default: 4)
|
||||
number of jobs to run in parallel (default: based on
|
||||
number of CPU cores)
|
||||
.SS Logging options:
|
||||
.TP
|
||||
\fB\-\-verbose\fR
|
||||
|
@ -15,7 +15,8 @@ Prune (delete) already merged topics
|
||||
show this help message and exit
|
||||
.TP
|
||||
\fB\-j\fR JOBS, \fB\-\-jobs\fR=\fI\,JOBS\/\fR
|
||||
number of jobs to run in parallel (default: 4)
|
||||
number of jobs to run in parallel (default: based on
|
||||
number of CPU cores)
|
||||
.SS Logging options:
|
||||
.TP
|
||||
\fB\-v\fR, \fB\-\-verbose\fR
|
||||
|
@ -15,7 +15,8 @@ Update working tree to the latest known good revision
|
||||
show this help message and exit
|
||||
.TP
|
||||
\fB\-j\fR JOBS, \fB\-\-jobs\fR=\fI\,JOBS\/\fR
|
||||
number of jobs to run in parallel (default: 1)
|
||||
number of jobs to run in parallel (default: based on
|
||||
number of CPU cores)
|
||||
.TP
|
||||
\fB\-\-jobs\-network\fR=\fI\,JOBS\/\fR
|
||||
number of network jobs to run in parallel (defaults to
|
||||
|
@ -15,7 +15,8 @@ Start a new branch for development
|
||||
show this help message and exit
|
||||
.TP
|
||||
\fB\-j\fR JOBS, \fB\-\-jobs\fR=\fI\,JOBS\/\fR
|
||||
number of jobs to run in parallel (default: 4)
|
||||
number of jobs to run in parallel (default: based on
|
||||
number of CPU cores)
|
||||
.TP
|
||||
\fB\-\-all\fR
|
||||
begin branch in all projects
|
||||
|
@ -15,7 +15,8 @@ Show the working tree status
|
||||
show this help message and exit
|
||||
.TP
|
||||
\fB\-j\fR JOBS, \fB\-\-jobs\fR=\fI\,JOBS\/\fR
|
||||
number of jobs to run in parallel (default: 4)
|
||||
number of jobs to run in parallel (default: based on
|
||||
number of CPU cores)
|
||||
.TP
|
||||
\fB\-o\fR, \fB\-\-orphans\fR
|
||||
include objects in working directory outside of repo
|
||||
|
@ -15,7 +15,8 @@ Update working tree to the latest revision
|
||||
show this help message and exit
|
||||
.TP
|
||||
\fB\-j\fR JOBS, \fB\-\-jobs\fR=\fI\,JOBS\/\fR
|
||||
number of jobs to run in parallel (default: 1)
|
||||
number of jobs to run in parallel (default: based on
|
||||
number of CPU cores)
|
||||
.TP
|
||||
\fB\-\-jobs\-network\fR=\fI\,JOBS\/\fR
|
||||
number of network jobs to run in parallel (defaults to
|
||||
|
@ -15,7 +15,8 @@ Upload changes for code review
|
||||
show this help message and exit
|
||||
.TP
|
||||
\fB\-j\fR JOBS, \fB\-\-jobs\fR=\fI\,JOBS\/\fR
|
||||
number of jobs to run in parallel (default: 4)
|
||||
number of jobs to run in parallel (default: based on
|
||||
number of CPU cores)
|
||||
.TP
|
||||
\fB\-t\fR
|
||||
send local branch name to Gerrit Code Review
|
||||
|
@ -47,6 +47,11 @@ def main(argv):
|
||||
if not shutil.which('help2man'):
|
||||
sys.exit('Please install help2man to continue.')
|
||||
|
||||
# Let repo know we're generating man pages so it can avoid some dynamic
|
||||
# behavior (like probing active number of CPUs). We use a weird name &
|
||||
# value to make it less likely for users to set this var themselves.
|
||||
os.environ['_REPO_GENERATE_MANPAGES_'] = ' indeed! '
|
||||
|
||||
# "repo branch" is an alias for "repo branches".
|
||||
del subcmds.all_commands['branch']
|
||||
(MANDIR / 'repo-branch.1').write_text('.so man1/repo-branches.1')
|
||||
|
@ -298,10 +298,12 @@ later is required to fix a server side protocol bug.
|
||||
Returns:
|
||||
Returns path to the overriding manifest file instead of None.
|
||||
"""
|
||||
print_messages = git_superproject.PrintMessages(opt, self.manifest)
|
||||
superproject = git_superproject.Superproject(self.manifest,
|
||||
self.repodir,
|
||||
self.git_event_log,
|
||||
quiet=opt.quiet)
|
||||
quiet=opt.quiet,
|
||||
print_messages=print_messages)
|
||||
if opt.local_only:
|
||||
manifest_path = superproject.manifest_path
|
||||
if manifest_path:
|
||||
@ -317,10 +319,11 @@ later is required to fix a server side protocol bug.
|
||||
if manifest_path:
|
||||
self._ReloadManifest(manifest_path, load_local_manifests)
|
||||
else:
|
||||
print('warning: Update of revisionId from superproject has failed, '
|
||||
'repo sync will not use superproject to fetch the source. ',
|
||||
'Please resync with the --no-use-superproject option to avoid this repo warning.',
|
||||
file=sys.stderr)
|
||||
if print_messages:
|
||||
print('warning: Update of revisionId from superproject has failed, '
|
||||
'repo sync will not use superproject to fetch the source. ',
|
||||
'Please resync with the --no-use-superproject option to avoid this repo warning.',
|
||||
file=sys.stderr)
|
||||
if update_result.fatal and opt.use_superproject is not None:
|
||||
sys.exit(1)
|
||||
return manifest_path
|
||||
@ -970,6 +973,7 @@ later is required to fix a server side protocol bug.
|
||||
superproject_logging_data = {
|
||||
'superproject': use_superproject,
|
||||
'haslocalmanifests': bool(self.manifest.HasLocalManifests),
|
||||
'hassuperprojecttag': bool(self.manifest.superproject),
|
||||
}
|
||||
if use_superproject:
|
||||
manifest_name = self._UpdateProjectsRevisionId(
|
||||
@ -1088,13 +1092,13 @@ later is required to fix a server side protocol bug.
|
||||
sys.exit(1)
|
||||
|
||||
# Log the previous sync analysis state from the config.
|
||||
self.git_event_log.LogConfigEvents(mp.config.GetSyncAnalysisStateData(),
|
||||
'previous_sync_state')
|
||||
self.git_event_log.LogDataConfigEvents(mp.config.GetSyncAnalysisStateData(),
|
||||
'previous_sync_state')
|
||||
|
||||
# Update and log with the new sync analysis state.
|
||||
mp.config.UpdateSyncAnalysisState(opt, superproject_logging_data)
|
||||
self.git_event_log.LogConfigEvents(mp.config.GetSyncAnalysisStateData(),
|
||||
'current_sync_state')
|
||||
self.git_event_log.LogDataConfigEvents(mp.config.GetSyncAnalysisStateData(),
|
||||
'current_sync_state')
|
||||
|
||||
if not opt.quiet:
|
||||
print('repo sync has finished successfully.')
|
||||
|
2
tests/fixtures/test.gitconfig
vendored
2
tests/fixtures/test.gitconfig
vendored
@ -12,7 +12,7 @@
|
||||
intm = 10m
|
||||
intg = 10g
|
||||
[repo "syncstate.main"]
|
||||
synctime = 2021-07-29T22:07:43.463365Z
|
||||
synctime = 2021-09-14T17:23:43.537338Z
|
||||
version = 1
|
||||
[repo "syncstate.sys"]
|
||||
argv = ['/usr/bin/pytest-3']
|
||||
|
@ -203,7 +203,7 @@ class SuperprojectTestCase(unittest.TestCase):
|
||||
project.SetRevisionId('ABCDEF')
|
||||
# Create temporary directory so that it can write the file.
|
||||
os.mkdir(self._superproject._superproject_path)
|
||||
manifest_path = self._superproject._WriteManfiestFile()
|
||||
manifest_path = self._superproject._WriteManifestFile()
|
||||
self.assertIsNotNone(manifest_path)
|
||||
with open(manifest_path, 'r') as fp:
|
||||
manifest_xml_data = fp.read()
|
||||
|
@ -234,6 +234,39 @@ class EventLogTestCase(unittest.TestCase):
|
||||
self.assertEqual(len(self._log_data), 1)
|
||||
self.verifyCommonKeys(self._log_data[0], expected_event_name='version')
|
||||
|
||||
def test_data_event_config(self):
|
||||
"""Test 'data' event data outputs all config keys.
|
||||
|
||||
Expected event log:
|
||||
<version event>
|
||||
<data event>
|
||||
<data event>
|
||||
"""
|
||||
config = {
|
||||
'git.foo': 'bar',
|
||||
'repo.partialclone': 'false',
|
||||
'repo.syncstate.superproject.hassuperprojecttag': 'true',
|
||||
}
|
||||
prefix_value = 'prefix'
|
||||
self._event_log_module.LogDataConfigEvents(config, prefix_value)
|
||||
|
||||
with tempfile.TemporaryDirectory(prefix='event_log_tests') as tempdir:
|
||||
log_path = self._event_log_module.Write(path=tempdir)
|
||||
self._log_data = self.readLog(log_path)
|
||||
|
||||
self.assertEqual(len(self._log_data), 4)
|
||||
data_events = self._log_data[1:]
|
||||
self.verifyCommonKeys(self._log_data[0], expected_event_name='version')
|
||||
|
||||
for event in data_events:
|
||||
self.verifyCommonKeys(event, expected_event_name='data')
|
||||
# Check for 'data' event specific fields.
|
||||
self.assertIn('key', event)
|
||||
self.assertIn('value', event)
|
||||
key = event['key'].removeprefix(f'{prefix_value}/')
|
||||
value = event['value']
|
||||
self.assertTrue(key in config and value == config[key])
|
||||
|
||||
def test_error_event(self):
|
||||
"""Test and validate 'error' event data is valid.
|
||||
|
||||
|
Reference in New Issue
Block a user