mirror of
https://gerrit.googlesource.com/git-repo
synced 2025-06-28 20:17:26 +00:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
5554572f02 | |||
97ca50f5f9 | |||
8896b68926 | |||
fec8cd6704 | |||
b8139bdcf8 | |||
26fa3180fb | |||
d379e77f44 |
@ -135,6 +135,8 @@ def GetEventTargetPath():
|
|||||||
if retval == 0:
|
if retval == 0:
|
||||||
# Strip trailing carriage-return in path.
|
# Strip trailing carriage-return in path.
|
||||||
path = p.stdout.rstrip("\n")
|
path = p.stdout.rstrip("\n")
|
||||||
|
if path == "":
|
||||||
|
return None
|
||||||
elif retval != 1:
|
elif retval != 1:
|
||||||
# `git config --get` is documented to produce an exit status of `1`
|
# `git config --get` is documented to produce an exit status of `1`
|
||||||
# if the requested variable is not present in the configuration.
|
# if the requested variable is not present in the configuration.
|
||||||
|
11
main.py
11
main.py
@ -270,10 +270,14 @@ class _Repo:
|
|||||||
self._PrintHelp(short=True)
|
self._PrintHelp(short=True)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
run = lambda: self._RunLong(name, gopts, argv) or 0
|
git_trace2_event_log = EventLog()
|
||||||
|
run = (
|
||||||
|
lambda: self._RunLong(name, gopts, argv, git_trace2_event_log) or 0
|
||||||
|
)
|
||||||
with Trace(
|
with Trace(
|
||||||
"starting new command: %s",
|
"starting new command: %s [sid=%s]",
|
||||||
", ".join([name] + argv),
|
", ".join([name] + argv),
|
||||||
|
git_trace2_event_log.full_sid,
|
||||||
first_trace=True,
|
first_trace=True,
|
||||||
):
|
):
|
||||||
if gopts.trace_python:
|
if gopts.trace_python:
|
||||||
@ -290,12 +294,11 @@ class _Repo:
|
|||||||
result = run()
|
result = run()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _RunLong(self, name, gopts, argv):
|
def _RunLong(self, name, gopts, argv, git_trace2_event_log):
|
||||||
"""Execute the (longer running) requested subcommand."""
|
"""Execute the (longer running) requested subcommand."""
|
||||||
result = 0
|
result = 0
|
||||||
SetDefaultColoring(gopts.color)
|
SetDefaultColoring(gopts.color)
|
||||||
|
|
||||||
git_trace2_event_log = EventLog()
|
|
||||||
outer_client = RepoClient(self.repodir)
|
outer_client = RepoClient(self.repodir)
|
||||||
repo_client = outer_client
|
repo_client = outer_client
|
||||||
if gopts.submanifest_path:
|
if gopts.submanifest_path:
|
||||||
|
4
repo
4
repo
@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
#
|
#
|
||||||
# Copyright (C) 2008 The Android Open Source Project
|
# Copyright (C) 2008 The Android Open Source Project
|
||||||
#
|
#
|
||||||
@ -124,7 +124,7 @@ if not REPO_REV:
|
|||||||
BUG_URL = "https://issues.gerritcodereview.com/issues/new?component=1370071"
|
BUG_URL = "https://issues.gerritcodereview.com/issues/new?component=1370071"
|
||||||
|
|
||||||
# increment this whenever we make important changes to this script
|
# increment this whenever we make important changes to this script
|
||||||
VERSION = (2, 40)
|
VERSION = (2, 42)
|
||||||
|
|
||||||
# increment this if the MAINTAINER_KEYS block is modified
|
# increment this if the MAINTAINER_KEYS block is modified
|
||||||
KEYRING_VERSION = (2, 3)
|
KEYRING_VERSION = (2, 3)
|
||||||
|
@ -21,6 +21,7 @@ import multiprocessing
|
|||||||
import netrc
|
import netrc
|
||||||
import optparse
|
import optparse
|
||||||
import os
|
import os
|
||||||
|
from pathlib import Path
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
@ -82,16 +83,50 @@ from wrapper import Wrapper
|
|||||||
|
|
||||||
_ONE_DAY_S = 24 * 60 * 60
|
_ONE_DAY_S = 24 * 60 * 60
|
||||||
|
|
||||||
# Env var to implicitly turn auto-gc back on. This was added to allow a user to
|
|
||||||
# revert a change in default behavior in v2.29.9. Remove after 2023-04-01.
|
|
||||||
_REPO_AUTO_GC = "REPO_AUTO_GC"
|
|
||||||
_AUTO_GC = os.environ.get(_REPO_AUTO_GC) == "1"
|
|
||||||
|
|
||||||
_REPO_ALLOW_SHALLOW = os.environ.get("REPO_ALLOW_SHALLOW")
|
_REPO_ALLOW_SHALLOW = os.environ.get("REPO_ALLOW_SHALLOW")
|
||||||
|
|
||||||
logger = RepoLogger(__file__)
|
logger = RepoLogger(__file__)
|
||||||
|
|
||||||
|
|
||||||
|
def _SafeCheckoutOrder(checkouts: List[Project]) -> List[List[Project]]:
|
||||||
|
"""Generate a sequence of checkouts that is safe to perform. The client
|
||||||
|
should checkout everything from n-th index before moving to n+1.
|
||||||
|
|
||||||
|
This is only useful if manifest contains nested projects.
|
||||||
|
|
||||||
|
E.g. if foo, foo/bar and foo/bar/baz are project paths, then foo needs to
|
||||||
|
finish before foo/bar can proceed, and foo/bar needs to finish before
|
||||||
|
foo/bar/baz."""
|
||||||
|
res = [[]]
|
||||||
|
current = res[0]
|
||||||
|
|
||||||
|
# depth_stack contains a current stack of parent paths.
|
||||||
|
depth_stack = []
|
||||||
|
# checkouts are iterated in asc order by relpath. That way, it can easily be
|
||||||
|
# determined if the previous checkout is parent of the current checkout.
|
||||||
|
for checkout in sorted(checkouts, key=lambda x: x.relpath):
|
||||||
|
checkout_path = Path(checkout.relpath)
|
||||||
|
while depth_stack:
|
||||||
|
try:
|
||||||
|
checkout_path.relative_to(depth_stack[-1])
|
||||||
|
except ValueError:
|
||||||
|
# Path.relative_to returns ValueError if paths are not relative.
|
||||||
|
# TODO(sokcevic): Switch to is_relative_to once min supported
|
||||||
|
# version is py3.9.
|
||||||
|
depth_stack.pop()
|
||||||
|
else:
|
||||||
|
if len(depth_stack) >= len(res):
|
||||||
|
# Another depth created.
|
||||||
|
res.append([])
|
||||||
|
break
|
||||||
|
|
||||||
|
current = res[len(depth_stack)]
|
||||||
|
current.append(checkout)
|
||||||
|
depth_stack.append(checkout_path)
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
class _FetchOneResult(NamedTuple):
|
class _FetchOneResult(NamedTuple):
|
||||||
"""_FetchOne return value.
|
"""_FetchOne return value.
|
||||||
|
|
||||||
@ -1040,15 +1075,21 @@ later is required to fix a server side protocol bug.
|
|||||||
pm.update(msg=project.name)
|
pm.update(msg=project.name)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
proc_res = self.ExecuteInParallel(
|
for projects in _SafeCheckoutOrder(all_projects):
|
||||||
opt.jobs_checkout,
|
proc_res = self.ExecuteInParallel(
|
||||||
functools.partial(
|
opt.jobs_checkout,
|
||||||
self._CheckoutOne, opt.detach_head, opt.force_sync, opt.verbose
|
functools.partial(
|
||||||
),
|
self._CheckoutOne,
|
||||||
all_projects,
|
opt.detach_head,
|
||||||
callback=_ProcessResults,
|
opt.force_sync,
|
||||||
output=Progress("Checking out", len(all_projects), quiet=opt.quiet),
|
opt.verbose,
|
||||||
)
|
),
|
||||||
|
projects,
|
||||||
|
callback=_ProcessResults,
|
||||||
|
output=Progress(
|
||||||
|
"Checking out", len(all_projects), quiet=opt.quiet
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
self._local_sync_state.Save()
|
self._local_sync_state.Save()
|
||||||
return proc_res and not err_results
|
return proc_res and not err_results
|
||||||
@ -1544,9 +1585,7 @@ later is required to fix a server side protocol bug.
|
|||||||
mp, event_log.TASK_SYNC_LOCAL, start, time.time(), clean
|
mp, event_log.TASK_SYNC_LOCAL, start, time.time(), clean
|
||||||
)
|
)
|
||||||
if not clean:
|
if not clean:
|
||||||
raise UpdateManifestError(
|
raise UpdateManifestError(aggregate_errors=errors)
|
||||||
aggregate_errors=errors, project=mp.name
|
|
||||||
)
|
|
||||||
self._ReloadManifest(manifest_name, mp.manifest)
|
self._ReloadManifest(manifest_name, mp.manifest)
|
||||||
|
|
||||||
def ValidateOptions(self, opt, args):
|
def ValidateOptions(self, opt, args):
|
||||||
@ -1577,16 +1616,6 @@ later is required to fix a server side protocol bug.
|
|||||||
if opt.prune is None:
|
if opt.prune is None:
|
||||||
opt.prune = True
|
opt.prune = True
|
||||||
|
|
||||||
if opt.auto_gc is None and _AUTO_GC:
|
|
||||||
logger.error(
|
|
||||||
"Will run `git gc --auto` because %s is set. %s is deprecated "
|
|
||||||
"and will be removed in a future release. Use `--auto-gc` "
|
|
||||||
"instead.",
|
|
||||||
_REPO_AUTO_GC,
|
|
||||||
_REPO_AUTO_GC,
|
|
||||||
)
|
|
||||||
opt.auto_gc = True
|
|
||||||
|
|
||||||
def _ValidateOptionsWithManifest(self, opt, mp):
|
def _ValidateOptionsWithManifest(self, opt, mp):
|
||||||
"""Like ValidateOptions, but after we've updated the manifest.
|
"""Like ValidateOptions, but after we've updated the manifest.
|
||||||
|
|
||||||
@ -1630,7 +1659,7 @@ later is required to fix a server side protocol bug.
|
|||||||
errors = []
|
errors = []
|
||||||
try:
|
try:
|
||||||
self._ExecuteHelper(opt, args, errors)
|
self._ExecuteHelper(opt, args, errors)
|
||||||
except RepoExitError:
|
except (RepoExitError, RepoChangedException):
|
||||||
raise
|
raise
|
||||||
except (KeyboardInterrupt, Exception) as e:
|
except (KeyboardInterrupt, Exception) as e:
|
||||||
raise RepoUnhandledExceptionError(e, aggregate_errors=errors)
|
raise RepoUnhandledExceptionError(e, aggregate_errors=errors)
|
||||||
|
@ -304,6 +304,32 @@ class LocalSyncState(unittest.TestCase):
|
|||||||
self.assertEqual(self.state.GetFetchTime(projA), 5)
|
self.assertEqual(self.state.GetFetchTime(projA), 5)
|
||||||
|
|
||||||
|
|
||||||
|
class SafeCheckoutOrder(unittest.TestCase):
|
||||||
|
def test_no_nested(self):
|
||||||
|
p_f = mock.MagicMock(relpath="f")
|
||||||
|
p_foo = mock.MagicMock(relpath="foo")
|
||||||
|
out = sync._SafeCheckoutOrder([p_f, p_foo])
|
||||||
|
self.assertEqual(out, [[p_f, p_foo]])
|
||||||
|
|
||||||
|
def test_basic_nested(self):
|
||||||
|
p_foo = p_foo = mock.MagicMock(relpath="foo")
|
||||||
|
p_foo_bar = mock.MagicMock(relpath="foo/bar")
|
||||||
|
out = sync._SafeCheckoutOrder([p_foo, p_foo_bar])
|
||||||
|
self.assertEqual(out, [[p_foo], [p_foo_bar]])
|
||||||
|
|
||||||
|
def test_complex_nested(self):
|
||||||
|
p_foo = mock.MagicMock(relpath="foo")
|
||||||
|
p_foo_bar = mock.MagicMock(relpath="foo/bar")
|
||||||
|
p_foo_bar_baz_baq = mock.MagicMock(relpath="foo/bar/baz/baq")
|
||||||
|
p_bar = mock.MagicMock(relpath="bar")
|
||||||
|
out = sync._SafeCheckoutOrder(
|
||||||
|
[p_foo_bar_baz_baq, p_foo, p_foo_bar, p_bar]
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
out, [[p_bar, p_foo], [p_foo_bar], [p_foo_bar_baz_baq]]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class GetPreciousObjectsState(unittest.TestCase):
|
class GetPreciousObjectsState(unittest.TestCase):
|
||||||
"""Tests for _GetPreciousObjectsState."""
|
"""Tests for _GetPreciousObjectsState."""
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user