mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
sync: pass --bare option when doing git clone of superproject.
Changed "git pull" to "git fetch" as we are using --bare option. Used the following command to fetch: git fetch origin +refs/heads/*:refs/heads/* --prune Pass --branch argument to Superproject's UpdateProjectsRevisionId function. Returned False/None when directories don't exist instead of raise GitError exception from _Fetch and _LsTree functions. The caller of Fetch does Clone if Fetch fails. Tested the code with the following commands. $ ./run_tests -v Tested the init and sync code by copying all the repo changes into my Android AOSP checkout and running repo sync with --use-superproject option. Bug: https://crbug.com/gerrit/13709 Bug: https://crbug.com/gerrit/13707 Tested-by: Raman Tenneti <rtenneti@google.com> Change-Id: I3e441ecdfc87c735f46eff0eb98efa63cc2eb22a Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/296222 Reviewed-by: Mike Frysinger <vapier@google.com>
This commit is contained in:
parent
1fd7bc2438
commit
8d43dea6ea
@ -29,6 +29,9 @@ from error import BUG_REPORT_URL, GitError
|
|||||||
from git_command import GitCommand
|
from git_command import GitCommand
|
||||||
import platform_utils
|
import platform_utils
|
||||||
|
|
||||||
|
_SUPERPROJECT_GIT_NAME = 'superproject.git'
|
||||||
|
_SUPERPROJECT_MANIFEST_NAME = 'superproject_override.xml'
|
||||||
|
|
||||||
|
|
||||||
class Superproject(object):
|
class Superproject(object):
|
||||||
"""Get SHAs from superproject.
|
"""Get SHAs from superproject.
|
||||||
@ -48,8 +51,9 @@ class Superproject(object):
|
|||||||
self._superproject_dir = superproject_dir
|
self._superproject_dir = superproject_dir
|
||||||
self._superproject_path = os.path.join(self._repodir, superproject_dir)
|
self._superproject_path = os.path.join(self._repodir, superproject_dir)
|
||||||
self._manifest_path = os.path.join(self._superproject_path,
|
self._manifest_path = os.path.join(self._superproject_path,
|
||||||
'superproject_override.xml')
|
_SUPERPROJECT_MANIFEST_NAME)
|
||||||
self._work_git = os.path.join(self._superproject_path, 'superproject')
|
self._work_git = os.path.join(self._superproject_path,
|
||||||
|
_SUPERPROJECT_GIT_NAME)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def project_shas(self):
|
def project_shas(self):
|
||||||
@ -66,8 +70,9 @@ class Superproject(object):
|
|||||||
Returns:
|
Returns:
|
||||||
True if 'git clone <url> <branch>' is successful, or False.
|
True if 'git clone <url> <branch>' is successful, or False.
|
||||||
"""
|
"""
|
||||||
|
if not os.path.exists(self._superproject_path):
|
||||||
os.mkdir(self._superproject_path)
|
os.mkdir(self._superproject_path)
|
||||||
cmd = ['clone', url, '--filter', 'blob:none']
|
cmd = ['clone', url, '--filter', 'blob:none', '--bare']
|
||||||
if branch:
|
if branch:
|
||||||
cmd += ['--branch', branch]
|
cmd += ['--branch', branch]
|
||||||
p = GitCommand(None,
|
p = GitCommand(None,
|
||||||
@ -84,15 +89,17 @@ class Superproject(object):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _Pull(self):
|
def _Fetch(self):
|
||||||
"""Do a 'git pull' to to fetch the latest content.
|
"""Do a 'git fetch' to to fetch the latest content.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if 'git pull <branch>' is successful, or False.
|
True if 'git fetch' is successful, or False.
|
||||||
"""
|
"""
|
||||||
if not os.path.exists(self._work_git):
|
if not os.path.exists(self._work_git):
|
||||||
raise GitError('git pull missing drectory: %s' % self._work_git)
|
print('git fetch missing drectory: %s' % self._work_git,
|
||||||
cmd = ['pull']
|
file=sys.stderr)
|
||||||
|
return False
|
||||||
|
cmd = ['fetch', 'origin', '+refs/heads/*:refs/heads/*', '--prune']
|
||||||
p = GitCommand(None,
|
p = GitCommand(None,
|
||||||
cmd,
|
cmd,
|
||||||
cwd=self._work_git,
|
cwd=self._work_git,
|
||||||
@ -100,7 +107,7 @@ class Superproject(object):
|
|||||||
capture_stderr=True)
|
capture_stderr=True)
|
||||||
retval = p.Wait()
|
retval = p.Wait()
|
||||||
if retval:
|
if retval:
|
||||||
print('repo: error: git pull call failed with return code: %r, stderr: %r' %
|
print('repo: error: git fetch call failed with return code: %r, stderr: %r' %
|
||||||
(retval, p.stderr), file=sys.stderr)
|
(retval, p.stderr), file=sys.stderr)
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
@ -114,7 +121,9 @@ class Superproject(object):
|
|||||||
data: data returned from 'git ls-tree -r HEAD' instead of None.
|
data: data returned from 'git ls-tree -r HEAD' instead of None.
|
||||||
"""
|
"""
|
||||||
if not os.path.exists(self._work_git):
|
if not os.path.exists(self._work_git):
|
||||||
raise GitError('git ls-tree. Missing drectory: %s' % self._work_git)
|
print('git ls-tree missing drectory: %s' % self._work_git,
|
||||||
|
file=sys.stderr)
|
||||||
|
return None
|
||||||
data = None
|
data = None
|
||||||
cmd = ['ls-tree', '-z', '-r', 'HEAD']
|
cmd = ['ls-tree', '-z', '-r', 'HEAD']
|
||||||
p = GitCommand(None,
|
p = GitCommand(None,
|
||||||
@ -136,18 +145,19 @@ class Superproject(object):
|
|||||||
"""Get SHAs for all projects from superproject and save them in _project_shas.
|
"""Get SHAs for all projects from superproject and save them in _project_shas.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
url: superproject's url to be passed to git clone or pull.
|
url: superproject's url to be passed to git clone or fetch.
|
||||||
branch: The branchname to be passed as argument to git clone or pull.
|
branch: The branchname to be passed as argument to git clone or fetch.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A dictionary with the projects/SHAs instead of None.
|
A dictionary with the projects/SHAs instead of None.
|
||||||
"""
|
"""
|
||||||
if not url:
|
if not url:
|
||||||
raise ValueError('url argument is not supplied.')
|
raise ValueError('url argument is not supplied.')
|
||||||
|
|
||||||
do_clone = True
|
do_clone = True
|
||||||
if os.path.exists(self._superproject_path):
|
if os.path.exists(self._superproject_path):
|
||||||
if not self._Pull():
|
if not self._Fetch():
|
||||||
# If pull fails due to a corrupted git directory, then do a git clone.
|
# If fetch fails due to a corrupted git directory, then do a git clone.
|
||||||
platform_utils.rmtree(self._superproject_path)
|
platform_utils.rmtree(self._superproject_path)
|
||||||
else:
|
else:
|
||||||
do_clone = False
|
do_clone = False
|
||||||
@ -208,7 +218,7 @@ class Superproject(object):
|
|||||||
manifest: A Manifest object that is to be written to a file.
|
manifest: A Manifest object that is to be written to a file.
|
||||||
projects: List of projects whose revisionId needs to be updated.
|
projects: List of projects whose revisionId needs to be updated.
|
||||||
url: superproject's url to be passed to git clone or fetch.
|
url: superproject's url to be passed to git clone or fetch.
|
||||||
branch: The branchname to be passed as argument to git clone or pull.
|
branch: The branchname to be passed as argument to git clone or fetch.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
manifest_path: Path name of the overriding manfiest file instead of None.
|
manifest_path: Path name of the overriding manfiest file instead of None.
|
||||||
|
@ -271,6 +271,15 @@ later is required to fix a server side protocol bug.
|
|||||||
dest='repo_upgraded', action='store_true',
|
dest='repo_upgraded', action='store_true',
|
||||||
help=SUPPRESS_HELP)
|
help=SUPPRESS_HELP)
|
||||||
|
|
||||||
|
def _GetBranch(self):
|
||||||
|
"""Returns the branch name for getting the approved manifest."""
|
||||||
|
p = self.manifest.manifestProject
|
||||||
|
b = p.GetBranch(p.CurrentBranch)
|
||||||
|
branch = b.merge
|
||||||
|
if branch.startswith(R_HEADS):
|
||||||
|
branch = branch[len(R_HEADS):]
|
||||||
|
return branch
|
||||||
|
|
||||||
def _UpdateProjectsRevisionId(self, opt, args):
|
def _UpdateProjectsRevisionId(self, opt, args):
|
||||||
"""Update revisionId of every project with the SHA from superproject.
|
"""Update revisionId of every project with the SHA from superproject.
|
||||||
|
|
||||||
@ -302,9 +311,11 @@ later is required to fix a server side protocol bug.
|
|||||||
all_projects = self.GetProjects(args,
|
all_projects = self.GetProjects(args,
|
||||||
missing_ok=True,
|
missing_ok=True,
|
||||||
submodules_ok=opt.fetch_submodules)
|
submodules_ok=opt.fetch_submodules)
|
||||||
|
branch = self._GetBranch()
|
||||||
manifest_path = superproject.UpdateProjectsRevisionId(self.manifest,
|
manifest_path = superproject.UpdateProjectsRevisionId(self.manifest,
|
||||||
all_projects,
|
all_projects,
|
||||||
url=superproject_url)
|
url=superproject_url,
|
||||||
|
branch=branch)
|
||||||
if not manifest_path:
|
if not manifest_path:
|
||||||
print('error: Update of revsionId from superproject has failed',
|
print('error: Update of revsionId from superproject has failed',
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
@ -753,11 +764,7 @@ later is required to fix a server side protocol bug.
|
|||||||
try:
|
try:
|
||||||
server = xmlrpc.client.Server(manifest_server, transport=transport)
|
server = xmlrpc.client.Server(manifest_server, transport=transport)
|
||||||
if opt.smart_sync:
|
if opt.smart_sync:
|
||||||
p = self.manifest.manifestProject
|
branch = self._GetBranch()
|
||||||
b = p.GetBranch(p.CurrentBranch)
|
|
||||||
branch = b.merge
|
|
||||||
if branch.startswith(R_HEADS):
|
|
||||||
branch = branch[len(R_HEADS):]
|
|
||||||
|
|
||||||
if 'SYNC_TARGET' in os.environ:
|
if 'SYNC_TARGET' in os.environ:
|
||||||
target = os.environ['SYNC_TARGET']
|
target = os.environ['SYNC_TARGET']
|
||||||
|
@ -78,11 +78,11 @@ class SuperprojectTestCase(unittest.TestCase):
|
|||||||
with mock.patch.object(self._superproject, '_Clone', return_value=False):
|
with mock.patch.object(self._superproject, '_Clone', return_value=False):
|
||||||
self._superproject._GetAllProjectsSHAs(url='localhost')
|
self._superproject._GetAllProjectsSHAs(url='localhost')
|
||||||
|
|
||||||
def test_superproject_get_project_shas_mock_pull(self):
|
def test_superproject_get_project_shas_mock_fetch(self):
|
||||||
"""Test with _Pull failing."""
|
"""Test with _Fetch failing."""
|
||||||
with self.assertRaises(GitError):
|
with self.assertRaises(GitError):
|
||||||
with mock.patch.object(self._superproject, '_Clone', return_value=True):
|
with mock.patch.object(self._superproject, '_Clone', return_value=True):
|
||||||
with mock.patch.object(self._superproject, '_Pull', return_value=False):
|
with mock.patch.object(self._superproject, '_Fetch', return_value=False):
|
||||||
self._superproject._GetAllProjectsSHAs(url='localhost')
|
self._superproject._GetAllProjectsSHAs(url='localhost')
|
||||||
|
|
||||||
def test_superproject_get_project_shas_mock_ls_tree(self):
|
def test_superproject_get_project_shas_mock_ls_tree(self):
|
||||||
@ -141,7 +141,7 @@ class SuperprojectTestCase(unittest.TestCase):
|
|||||||
data = ('160000 commit 2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea\tart\x00'
|
data = ('160000 commit 2c2724cb36cd5a9cec6c852c681efc3b7c6b86ea\tart\x00'
|
||||||
'160000 commit e9d25da64d8d365dbba7c8ee00fe8c4473fe9a06\tbootable/recovery\x00')
|
'160000 commit e9d25da64d8d365dbba7c8ee00fe8c4473fe9a06\tbootable/recovery\x00')
|
||||||
with mock.patch.object(self._superproject, '_Clone', return_value=True):
|
with mock.patch.object(self._superproject, '_Clone', return_value=True):
|
||||||
with mock.patch.object(self._superproject, '_Pull', return_value=True):
|
with mock.patch.object(self._superproject, '_Fetch', return_value=True):
|
||||||
with mock.patch.object(self._superproject, '_LsTree', return_value=data):
|
with mock.patch.object(self._superproject, '_LsTree', return_value=data):
|
||||||
# Create temporary directory so that it can write the file.
|
# Create temporary directory so that it can write the file.
|
||||||
os.mkdir(self._superproject._superproject_path)
|
os.mkdir(self._superproject._superproject_path)
|
||||||
|
Loading…
Reference in New Issue
Block a user