Compare commits

...

13 Commits
v2.7 ... v2.9

Author SHA1 Message Date
Mike Frysinger
4b325813fc stop testing Python 2.7
A recent change broke `repo version` on Python 2.7.  Rather than
fix it, lets drop Python 2.7 support so it can slowly rot.

Bug: https://crbug.com/gerrit/10418
Change-Id: I5c6e3d18e4a193b0a978062c23f7cea392e95d0f
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/259155
Reviewed-by: David Pursehouse <david.pursehouse@gmail.com>
Tested-by: Mike Frysinger <vapier@google.com>
2020-09-06 17:53:47 +00:00
Mike Frysinger
0578ebf61a init: reject unknown args
If you pass args to `repo init` when first creating a checkout, the
repo launcher throws an error.  But the init subcommand that runs in
an existing checkout silently ignores them.  Throw a proper error.

Change-Id: I433bfcc73902d25f6b6a2974e77f6a977a75ed16
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/279696
Reviewed-by: Jonathan Nieder <jrn@google.com>
Tested-by: Mike Frysinger <vapier@google.com>
2020-09-02 07:53:16 +00:00
Adrien Bioteau
65f51ad29b Fix Git base version for worktreeconfig extension
worktreeconfig extension only appears with version Git 2.20.0

Change-Id: I3ea8b7d9f8a1f7953e536edd77b09cbc4f8f3158
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/276700
Reviewed-by: Mike Frysinger <vapier@google.com>
Tested-by: Adrien Bioteau <adrien.bioteau@gmail.com>
2020-07-30 20:46:11 +00:00
Mike Frysinger
80944b538d upload: exit non-zero when preupload hooks fail
Bug: https://crbug.com/gerrit/13159
Change-Id: Id140b619242c841223c6bc5d4aa0c37a7ce0219d
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/276294
Reviewed-by: Jonathan Nieder <jrn@google.com>
Tested-by: Mike Frysinger <vapier@google.com>
2020-07-25 08:31:52 +00:00
Mike Frysinger
89f3ae5ae6 release-process: document schedule (including freezes) publicly
Change-Id: Ic037b54630017740d7859292b32b8c57f4af7854
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/274772
Tested-by: Mike Frysinger <vapier@google.com>
Reviewed-by: Jonathan Nieder <jrn@google.com>
2020-07-23 08:07:38 +00:00
Roger Shimizu
ac29ac397f subcmds/sync.py: Fix typo in help
Change-Id: I70b63477241284249e395b8b0a220cb6f44f836b
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/270183
Reviewed-by: Mike Frysinger <vapier@google.com>
Reviewed-by: David Pursehouse <dpursehouse@digital.ai>
Tested-by: David Pursehouse <dpursehouse@digital.ai>
2020-06-06 23:46:00 +00:00
Mike Frysinger
cebf227026 manifest: normalize name & path when constructing fs paths
If the manifest uses a trailing slash on the name attribute, repo
will construct bad internal filesystem paths which confuses tools
later on.

For example, this manifest entry:
  <project name="aosp/platform/system/libhidl/" ...
will cause repo to use paths like:
  .repo/project-objects/aosp/platform/system/libhidl/.git/
when it really should be using:
  .repo/project-objects/aosp/platform/system/libhidl.git

Apply the normalization when we construct the local filesystem paths
as we cannot guarantee that the remote URL constructed from these
will behave the same.  A server might really want:
  https://example.com/aosp/platform/system/libhidl/
and would throw an error if we instead tried to fetch:
  https://example.com/aosp/platform/system/libhidl

Unfortunately, any existing repo client checkouts that use such a
manifest will hit a one-time sync error as the internal git location
has changed.  I'm not sure there's a way to cleanly migrate that.

Bug: https://crbug.com/1086043
Change-Id: I30bea0ffd23e478de89a035f408055e48a102658
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/268742
Tested-by: Mike Frysinger <vapier@google.com>
Reviewed-by: David Pursehouse <dpursehouse@digital.ai>
2020-05-26 05:15:58 +00:00
Mike Frysinger
7ae210a15b sync: fix duplicate word in description
Bug: https://crbug.com/gerrit/12814
Change-Id: Id722eec9a59dded588f13bc605ce2c94b4047265
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/268739
Tested-by: Mike Frysinger <vapier@google.com>
Reviewed-by: David Pursehouse <dpursehouse@digital.ai>
2020-05-24 23:51:28 +00:00
Mike Frysinger
60fc51bb1d launcher: fix version to latest
We've already released 2.7, and the next tag is 2.8, so this should
be pulled up to 2.8 so it'll stay in sync.

Change-Id: Id47bdbdb8050b29ea36442ac2149dd948648237f
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/268572
Tested-by: Mike Frysinger <vapier@google.com>
Reviewed-by: David Pursehouse <dpursehouse@digital.ai>
2020-05-21 22:46:11 +00:00
Mike Frysinger
72325c5f3e launcher: bump version for cli changes
Change-Id: I9b2194df0c1af3bc5b42115a25992747368a7383
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/268532
Reviewed-by: Xin Li <delphij@google.com>
Tested-by: Xin Li <delphij@google.com>
Tested-by: Mike Frysinger <vapier@google.com>
2020-05-21 21:04:42 +00:00
Xin Li
d79a4bc51b Make partial clone imply no-clone-bundle by default.
For large projects, clone bundle is useful because it provided a way to
efficiently transfer a large portion of git objects through CDN, without
needing to interact with git server. However, with partial clones, the
intention is to not download most of the objects, so the use of clone
bundles would defeat the space savings normally seen with partial
clones, as they are downloaded before the first fetch.

A new option, --clone-bundle is added to override this behavior.
Add a new repo.clonebundle variable which remembers the choice if
explicitly given from command line at repo init.

Change-Id: I03638474af303a82af34579e16cd4700690b5f43
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/268452
Tested-by: Xin Li <delphij@google.com>
Reviewed-by: Jonathan Nieder <jrn@google.com>
2020-05-21 19:47:36 +00:00
Sean McAllister
682f0b6426 Fix how we format the full destination branch when uploading.
If the dest-branch attribute is set in the project manifest, then
we need to push to that branch.  Previously, we would unconditionally
pre-pend the refs/heads prefix to it.  The dest-branch attribute is
allowed to be a ref expression though, so it may already have it.

Simple fix is to check if it already has the prefix before adding it.

Bug: crbug.com/gerrit/12770

Change-Id: I45d6107ed6cf305cf223023b0ddad4278f7f4146
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/268152
Reviewed-by: Mike Frysinger <vapier@google.com>
Tested-by: Sean McAllister <smcallis@google.com>
2020-05-19 15:25:42 +00:00
Daniel Kutik
e7082ccb54 repo info findRemoteLocalDiff use short branch
When running repo info -d an error would be thrown saying:
  fatal: bad revision 'refs/remotes/m/refs/heads/master..'

Using the short branch name here instead, like 'refs/remotes/m/master..'
resolves this issue.

Signed-off-by: Daniel Kutik <daniel.kutik@lavawerk.com>
Change-Id: I50ea92c45c011b2c3e3a63803decb88e7837a380
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/266578
Reviewed-by: Mike Frysinger <vapier@google.com>
2020-05-12 16:15:01 +00:00
14 changed files with 184 additions and 30 deletions

View File

@@ -14,10 +14,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [2.7, 3.6, 3.7, 3.8]
exclude:
- os: windows-latest
python-version: 2.7
python-version: [3.6, 3.7, 3.8]
runs-on: ${{ matrix.os }}
steps:

View File

@@ -134,6 +134,7 @@ User controlled settings are initialized when running `repo init`.
|-------------------|---------------------------|-------------|
| manifest.groups | `--groups` & `--platform` | The manifest groups to sync |
| repo.archive | `--archive` | Use `git archive` for checkouts |
| repo.clonebundle | `--clone-bundle` | Whether the initial sync used clone.bundle explicitly |
| repo.clonefilter | `--clone-filter` | Filter setting when using [partial git clones] |
| repo.depth | `--depth` | Create shallow checkouts when cloning |
| repo.dissociate | `--dissociate` | Dissociate from any reference/mirrors after initial clone |

View File

@@ -5,6 +5,37 @@ related topics and flows.
[TOC]
## Schedule
There is no specific schedule for when releases are made.
Usually it's more along the lines of "enough minor changes have been merged",
or "there's a known issue the maintainers know should get fixed".
If you find a fix has been merged for an issue important to you, but hasn't been
released after a week or so, feel free to [contact] us to request a new release.
### Release Freezes {#freeze}
We try to observe a regular schedule for when **not** to release.
If something goes wrong, staff need to be active in order to respond quickly &
effectively.
We also don't want to disrupt non-Google organizations if possible.
We generally follow the rules:
* Release during Mon - Thu, 9:00 - 14:00 [US PT]
* Avoid holidays
* All regular [US holidays]
* Large international ones if possible
* All the various [New Years]
* Jan 1 in Gregorian calendar is the most obvious
* Check for large Lunar New Years too
* Follow the normal [Google production freeze schedule]
[US holidays]: https://en.wikipedia.org/wiki/Federal_holidays_in_the_United_States
[US PT]: https://en.wikipedia.org/wiki/Pacific_Time_Zone
[New Years]: https://en.wikipedia.org/wiki/New_Year
[Google production freeze schedule]: http://goto.google.com/prod-freeze
## Launcher script
The main repo script serves as a standalone program and is often referred to as
@@ -242,6 +273,7 @@ Things in italics are things we used to care about but probably don't anymore.
| Apr 2020 | **Apr 2030** | | | **20.04 Focal** | 2.25.0 | 2.7.17 3.7.5 |
[contact]: ../README.md#contact
[rel-d]: https://en.wikipedia.org/wiki/Debian_version_history
[rel-g]: https://en.wikipedia.org/wiki/Git#Releases
[rel-p]: https://en.wikipedia.org/wiki/History_of_Python#Table_of_versions

View File

@@ -501,6 +501,14 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
self._Load()
return self._manifest_server
@property
def CloneBundle(self):
clone_bundle = self.manifestProject.config.GetBoolean('repo.clonebundle')
if clone_bundle is None:
return False if self.manifestProject.config.GetBoolean('repo.partialclone') else True
else:
return clone_bundle
@property
def CloneFilter(self):
if self.manifestProject.config.GetBoolean('repo.partialclone'):
@@ -970,6 +978,10 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
return project
def GetProjectPaths(self, name, path):
# The manifest entries might have trailing slashes. Normalize them to avoid
# unexpected filesystem behavior since we do string concatenation below.
path = path.rstrip('/')
name = name.rstrip('/')
use_git_worktrees = False
relpath = path
if self.IsMirror:
@@ -1002,6 +1014,10 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
return os.path.relpath(relpath, parent_relpath)
def GetSubprojectPaths(self, parent, name, path):
# The manifest entries might have trailing slashes. Normalize them to avoid
# unexpected filesystem behavior since we do string concatenation below.
path = path.rstrip('/')
name = name.rstrip('/')
relpath = self._JoinRelpath(parent.relpath, path)
gitdir = os.path.join(parent.gitdir, 'subprojects', '%s.git' % path)
objdir = os.path.join(parent.gitdir, 'subproject-objects', '%s.git' % name)

View File

@@ -2793,7 +2793,7 @@ class Project(object):
# Enable per-worktree config file support if possible. This is more a
# nice-to-have feature for users rather than a hard requirement.
if git_require((2, 19, 0)):
if git_require((2, 20, 0)):
self.EnableRepositoryExtension('worktreeConfig')
# If we have a separate directory to hold refs, initialize it as well.

View File

@@ -18,11 +18,7 @@
This is intended to be run only by the official Repo release managers, but it
could be run by people maintaining their own fork of the project.
NB: Avoid new releases on off-hours. If something goes wrong, staff/oncall need
to be active in order to respond quickly & effectively. Recommend sticking to:
* Mon - Thu, 9:00 - 14:00 PT (i.e. MTV time)
* Avoid US holidays (and large international ones if possible)
* Follow the normal Google production freeze schedule
NB: Check docs/release-process.md for production freeze information.
"""
import argparse

11
repo
View File

@@ -133,7 +133,7 @@ if not REPO_REV:
REPO_REV = 'stable'
# increment this whenever we make important changes to this script
VERSION = (2, 5)
VERSION = (2, 8)
# increment this if the MAINTAINER_KEYS block is modified
KEYRING_VERSION = (2, 3)
@@ -317,9 +317,11 @@ def GetParser(gitc_init=False):
help='restrict manifest projects to ones with a specified '
'platform group [auto|all|none|linux|darwin|...]',
metavar='PLATFORM')
group.add_option('--clone-bundle', action='store_true',
help='enable use of /clone.bundle on HTTP/HTTPS (default if not --partial-clone)')
group.add_option('--no-clone-bundle',
dest='clone_bundle', default=True, action='store_false',
help='disable use of /clone.bundle on HTTP/HTTPS')
dest='clone_bundle', action='store_false',
help='disable use of /clone.bundle on HTTP/HTTPS (default if --partial-clone)')
group.add_option('--no-tags',
dest='tags', default=True, action='store_false',
help="don't fetch tags in the manifest")
@@ -502,6 +504,9 @@ def _Init(args, gitc_init=False):
opt.quiet = opt.output_mode is False
opt.verbose = opt.output_mode is True
if opt.clone_bundle is None:
opt.clone_bundle = False if opt.partial_clone else True
url = opt.repo_url or REPO_URL
rev = opt.repo_rev or REPO_REV

View File

@@ -16,7 +16,7 @@
from command import PagedCommand
from color import Coloring
from git_refs import R_M
from git_refs import R_M, R_HEADS
class _Coloring(Coloring):
@@ -127,7 +127,10 @@ class Info(PagedCommand):
if not self.opt.local:
project.Sync_NetworkHalf(quiet=True, current_branch_only=True)
logTarget = R_M + self.manifest.manifestProject.config.GetBranch("default").merge
branch = self.manifest.manifestProject.config.GetBranch('default').merge
if branch.startswith(R_HEADS):
branch = branch[len(R_HEADS):]
logTarget = R_M + branch
bareTmp = project.bare_git._bare
project.bare_git._bare = False

View File

@@ -155,9 +155,11 @@ to update the working directory files.
help='restrict manifest projects to ones with a specified '
'platform group [auto|all|none|linux|darwin|...]',
metavar='PLATFORM')
g.add_option('--clone-bundle', action='store_true',
help='force use of /clone.bundle on HTTP/HTTPS (default if not --partial-clone)')
g.add_option('--no-clone-bundle',
dest='clone_bundle', default=True, action='store_false',
help='disable use of /clone.bundle on HTTP/HTTPS')
dest='clone_bundle', action='store_false',
help='disable use of /clone.bundle on HTTP/HTTPS (default if --partial-clone)')
g.add_option('--no-tags',
dest='tags', default=True, action='store_false',
help="don't fetch tags in the manifest")
@@ -303,6 +305,11 @@ to update the working directory files.
else:
opt.clone_filter = None
if opt.clone_bundle is None:
opt.clone_bundle = False if opt.partial_clone else True
else:
m.config.SetString('repo.clonebundle', 'true' if opt.clone_bundle else 'false')
if opt.submodules:
m.config.SetString('repo.submodules', 'true')
@@ -481,6 +488,9 @@ to update the working directory files.
if opt.archive and opt.mirror:
self.OptionParser.error('--mirror and --archive cannot be used together.')
if args:
self.OptionParser.error('init takes no arguments')
def Execute(self, opt, args):
git_require(MIN_GIT_VERSION_HARD, fail=True)
if not git_require(MIN_GIT_VERSION_SOFT):

View File

@@ -138,11 +138,11 @@ if the manifest server specified in the manifest file already includes
credentials.
By default, all projects will be synced. The --fail-fast option can be used
to halt syncing as soon as possible when the the first project fails to sync.
to halt syncing as soon as possible when the first project fails to sync.
The --force-sync option can be used to overwrite existing git
directories if they have previously been linked to a different
object direcotry. WARNING: This may cause data to be lost since
object directory. WARNING: This may cause data to be lost since
refs may be removed when overwriting.
The --force-remove-dirty option can be used to remove previously used
@@ -247,8 +247,9 @@ later is required to fix a server side protocol bug.
p.add_option('-m', '--manifest-name',
dest='manifest_name',
help='temporary manifest to use for this sync', metavar='NAME.xml')
p.add_option('--no-clone-bundle',
dest='clone_bundle', default=True, action='store_false',
p.add_option('--clone-bundle', action='store_true',
help='enable use of /clone.bundle on HTTP/HTTPS')
p.add_option('--no-clone-bundle', dest='clone_bundle', action='store_false',
help='disable use of /clone.bundle on HTTP/HTTPS')
p.add_option('-u', '--manifest-server-username', action='store',
dest='manifest_server_username',
@@ -836,6 +837,9 @@ later is required to fix a server side protocol bug.
smart_sync_manifest_path = os.path.join(
self.manifest.manifestProject.worktree, 'smart_sync_override.xml')
if opt.clone_bundle is None:
opt.clone_bundle = self.manifest.CloneBundle
if opt.smart_sync or opt.smart_tag:
manifest_name = self._SmartSyncSetup(opt, smart_sync_manifest_path)
else:

View File

@@ -23,6 +23,7 @@ from command import InteractiveCommand
from editor import Editor
from error import HookError, UploadError
from git_command import GitCommand
from git_refs import R_HEADS
from project import RepoHook
from pyversion import is_python3
@@ -462,7 +463,10 @@ Gerrit Code Review: https://www.gerritcodereview.com/
# Make sure our local branch is not setup to track a different remote branch
merge_branch = self._GetMergeBranch(branch.project)
if destination:
full_dest = 'refs/heads/%s' % destination
full_dest = destination
if not full_dest.startswith(R_HEADS):
full_dest = R_HEADS + full_dest
if not opt.dest_branch and merge_branch and merge_branch != full_dest:
print('merge branch %s does not match destination branch %s'
% (merge_branch, full_dest))
@@ -592,7 +596,7 @@ Gerrit Code Review: https://www.gerritcodereview.com/
print('\nWARNING: pre-upload hooks failed, but uploading anyways.',
file=sys.stderr)
else:
return
return 1
if opt.reviewers:
reviewers = _SplitEmails(opt.reviewers)

43
tests/test_subcmds.py Normal file
View File

@@ -0,0 +1,43 @@
# Copyright (C) 2020 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.
"""Unittests for the subcmds module (mostly __init__.py than subcommands)."""
import unittest
import subcmds
class AllCommands(unittest.TestCase):
"""Check registered all_commands."""
def test_required_basic(self):
"""Basic checking of registered commands."""
# NB: We don't test all subcommands as we want to avoid "change detection"
# tests, so we just look for the most common/important ones here that are
# unlikely to ever change.
for cmd in {'cherry-pick', 'help', 'init', 'start', 'sync', 'upload'}:
self.assertIn(cmd, subcmds.all_commands)
def test_naming(self):
"""Verify we don't add things that we shouldn't."""
for cmd in subcmds.all_commands:
# Reject filename suffixes like "help.py".
self.assertNotIn('.', cmd)
# Make sure all '_' were converted to '-'.
self.assertNotIn('_', cmd)
# Reject internal python paths like "__init__".
self.assertFalse(cmd.startswith('__'))

View File

@@ -0,0 +1,49 @@
# Copyright (C) 2020 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.
"""Unittests for the subcmds/init.py module."""
import unittest
from subcmds import init
class InitCommand(unittest.TestCase):
"""Check registered all_commands."""
def setUp(self):
self.cmd = init.Init()
def test_cli_parser_good(self):
"""Check valid command line options."""
ARGV = (
[],
)
for argv in ARGV:
opts, args = self.cmd.OptionParser.parse_args(argv)
self.cmd.ValidateOptions(opts, args)
def test_cli_parser_bad(self):
"""Check invalid command line options."""
ARGV = (
# Too many arguments.
['asdf'],
# Conflicting options.
['--mirror', '--archive'],
)
for argv in ARGV:
opts, args = self.cmd.OptionParser.parse_args(argv)
with self.assertRaises(SystemExit):
self.cmd.ValidateOptions(opts, args)

View File

@@ -15,11 +15,10 @@
# https://tox.readthedocs.io/
[tox]
envlist = py27, py36, py37, py38
envlist = py36, py37, py38
[gh-actions]
python =
2.7: py27
3.6: py36
3.7: py37
3.8: py38
@@ -31,8 +30,3 @@ setenv =
GIT_AUTHOR_NAME = Repo test author
GIT_COMMITTER_NAME = Repo test committer
EMAIL = repo@gerrit.nodomain
[testenv:py27]
deps =
mock
pytest