Compare commits

..

12 Commits

Author SHA1 Message Date
0ce6ca9c7b Fix mirror clients with no worktree
Commit "Make path references OS independent" (df14a70c45)
broke mirror clients by trying to invoke replace() on None
when there is no worktree.

Change-Id: Ie0a187058358f7dcdf83119e45cc65409c980f11
2011-01-10 13:26:34 -08:00
0fc3a39829 Bump repo version to 1,10
Change-Id: Ifdc041e7152af31de413b9269f20000acd945b3b
2011-01-10 09:01:24 -08:00
c7c57e34db help: Don't show empty Summary or Description sections
Signed-off-by: Shawn O. Pearce <sop@google.com>
(cherry picked from commit 60e679209a)
2011-01-09 17:39:22 -08:00
0d2b61f11d sync: Run git gc --auto after fetch
Users may wind up with a lot of loose object content in projects they
don't frequently make changes in, but that are modified by others.

Since we bypass many git code paths that would have otherwise called
out to `git gc --auto`, its possible for these projects to have
their loose object database grow out of control.  To help prevent
that, we now invoke it ourselves during the network half of sync.

Signed-off-by: Shawn O. Pearce <sop@google.com>
(cherry picked from commit 1875ddd47c)
2011-01-09 17:39:22 -08:00
2bf9db0d3b Add "repo branch" as an alias for "repo branches"
For those of us that are used to typing "git branch".

Signed-off-by: Mike Lockwood <lockwood@android.com>
(cherry picked from commit 33f0e786bb)
2011-01-09 17:39:22 -08:00
f00e0ce556 upload: Catch and cleanly report connectivity errors
Instead of giving a Python backtrace when there is a connectivity
problem during repo upload, report that we cannot access the host,
and why, with a halfway decent error message.

Bug: REPO-45
Change-Id: I9a45b387e86e48073a2d99bd6d594c1a7d6d99d4
Signed-off-by: Shawn O. Pearce <sop@google.com>
(cherry picked from commit d2dfac81ad)
2011-01-09 17:39:22 -08:00
1b5a4a0c5d forall: Silently skip missing projects
If a project is missing locally, it might be OK to skip over it
and continue running the same command in other projects.

Bug: REPO-43
Change-Id: I64f97eb315f379ab2c51fc53d24ed340b3d09250
Signed-off-by: Shawn O. Pearce <sop@google.com>
(cherry picked from commit d4cd69bdef)
2011-01-09 17:39:22 -08:00
de8b2c4276 Fix to display the usage message of the command download when the user
don't provide any arguments to 'repo download'.

Signed-off-by: Thiago Farina <thiago.farina@gmail.com>
(cherry picked from commit 840ed0fab7)
2011-01-09 17:39:22 -08:00
727ee98a40 Use os.environ.copy() instead of dict()
Signed-off-by: Shawn O. Pearce <sop@google.com>
(cherry picked from commit 3218c13205)
2011-01-09 17:39:22 -08:00
df14a70c45 Make path references OS independent
Change-Id: I5573995adfd52fd54bddc62d1d1ea78fb1328130
(cherry picked from commit b0f9a02394)

Conflicts:

	command.py
2011-01-09 17:39:19 -08:00
f18cb76173 Encode the environment variables passed to git
Windows allows the environment to have unicode values.
This will cause Python to fail to execute the command.

Change-Id: I37d922c3d7ced0d5b4883f0220346ac42defc5e9
Signed-off-by: Shawn O. Pearce <sop@google.com>
2011-01-09 16:13:56 -08:00
d3fd537ea5 Exit with statuscode 0 for repo help init
The complete help text is printed, so the program executed successfully.

Some tools (like OpenGrok) detects the availibility of a program by
running it with a known set of options and check the return code.
It is an easy and portable way of checking for the existence of a program
instead of searching the path (and handle extensions) ourselves.

Change-Id: Ic13428c77be4a36d599ccb8c86d893308818eae3
2011-01-09 16:10:04 -08:00
13 changed files with 65 additions and 28 deletions

View File

@ -74,7 +74,7 @@ class Command(object):
project = all.get(arg) project = all.get(arg)
if not project: if not project:
path = os.path.abspath(arg) path = os.path.abspath(arg).replace('\\', '/')
if not by_path: if not by_path:
by_path = dict() by_path = dict()
@ -82,13 +82,15 @@ class Command(object):
by_path[p.worktree] = p by_path[p.worktree] = p
if os.path.exists(path): if os.path.exists(path):
oldpath = None
while path \ while path \
and path != '/' \ and path != oldpath \
and path != self.manifest.topdir: and path != self.manifest.topdir:
try: try:
project = by_path[path] project = by_path[path]
break break
except KeyError: except KeyError:
oldpath = path
path = os.path.dirname(path) path = os.path.dirname(path)
else: else:
try: try:

View File

@ -112,6 +112,9 @@ def git_require(min_version, fail=False):
sys.exit(1) sys.exit(1)
return False return False
def _setenv(env, name, value):
env[name] = value.encode()
class GitCommand(object): class GitCommand(object):
def __init__(self, def __init__(self,
project, project,
@ -124,7 +127,7 @@ class GitCommand(object):
ssh_proxy = False, ssh_proxy = False,
cwd = None, cwd = None,
gitdir = None): gitdir = None):
env = dict(os.environ) env = os.environ.copy()
for e in [REPO_TRACE, for e in [REPO_TRACE,
GIT_DIR, GIT_DIR,
@ -137,10 +140,10 @@ class GitCommand(object):
del env[e] del env[e]
if disable_editor: if disable_editor:
env['GIT_EDITOR'] = ':' _setenv(env, 'GIT_EDITOR', ':')
if ssh_proxy: if ssh_proxy:
env['REPO_SSH_SOCK'] = ssh_sock() _setenv(env, 'REPO_SSH_SOCK', ssh_sock())
env['GIT_SSH'] = _ssh_proxy() _setenv(env, 'GIT_SSH', _ssh_proxy())
if project: if project:
if not cwd: if not cwd:
@ -151,7 +154,7 @@ class GitCommand(object):
command = [GIT] command = [GIT]
if bare: if bare:
if gitdir: if gitdir:
env[GIT_DIR] = gitdir _setenv(env, GIT_DIR, gitdir)
cwd = None cwd = None
command.extend(cmdv) command.extend(cmdv)

View File

@ -23,6 +23,8 @@ try:
except ImportError: except ImportError:
import dummy_threading as _threading import dummy_threading as _threading
import time import time
import urllib2
from signal import SIGTERM from signal import SIGTERM
from urllib2 import urlopen, HTTPError from urllib2 import urlopen, HTTPError
from error import GitError, UploadError from error import GitError, UploadError
@ -563,23 +565,25 @@ class Remote(object):
try: try:
info = urlopen(u).read() info = urlopen(u).read()
if info == 'NOT_AVAILABLE': if info == 'NOT_AVAILABLE':
raise UploadError('Upload over ssh unavailable') raise UploadError('%s: SSH disabled' % self.review)
if '<' in info: if '<' in info:
# Assume the server gave us some sort of HTML # Assume the server gave us some sort of HTML
# response back, like maybe a login page. # response back, like maybe a login page.
# #
raise UploadError('Cannot read %s:\n%s' % (u, info)) raise UploadError('%s: Cannot parse response' % u)
self._review_protocol = 'ssh' self._review_protocol = 'ssh'
self._review_host = info.split(" ")[0] self._review_host = info.split(" ")[0]
self._review_port = info.split(" ")[1] self._review_port = info.split(" ")[1]
except urllib2.URLError, e:
raise UploadError('%s: %s' % (self.review, e.reason[1]))
except HTTPError, e: except HTTPError, e:
if e.code == 404: if e.code == 404:
self._review_protocol = 'http-post' self._review_protocol = 'http-post'
self._review_host = None self._review_host = None
self._review_port = None self._review_port = None
else: else:
raise UploadError('Cannot guess Gerrit version') raise UploadError('Upload over ssh unavailable')
REVIEW_CACHE[u] = ( REVIEW_CACHE[u] = (
self._review_protocol, self._review_protocol,

View File

@ -61,6 +61,8 @@ class _Repo(object):
def __init__(self, repodir): def __init__(self, repodir):
self.repodir = repodir self.repodir = repodir
self.commands = all_commands self.commands = all_commands
# add 'branch' as an alias for 'branches'
all_commands['branch'] = all_commands['branches']
def _Run(self, argv): def _Run(self, argv):
name = None name = None

View File

@ -435,7 +435,7 @@ class XmlManifest(object):
worktree = None worktree = None
gitdir = os.path.join(self.topdir, '%s.git' % name) gitdir = os.path.join(self.topdir, '%s.git' % name)
else: else:
worktree = os.path.join(self.topdir, path) worktree = os.path.join(self.topdir, path).replace('\\', '/')
gitdir = os.path.join(self.repodir, 'projects/%s.git' % path) gitdir = os.path.join(self.repodir, 'projects/%s.git' % path)
project = Project(manifest = self, project = Project(manifest = self,

View File

@ -236,8 +236,11 @@ class Project(object):
self.manifest = manifest self.manifest = manifest
self.name = name self.name = name
self.remote = remote self.remote = remote
self.gitdir = gitdir self.gitdir = gitdir.replace('\\', '/')
self.worktree = worktree if worktree:
self.worktree = worktree.replace('\\', '/')
else:
self.worktree = None
self.relpath = relpath self.relpath = relpath
self.revisionExpr = revisionExpr self.revisionExpr = revisionExpr

17
repo
View File

@ -28,7 +28,7 @@ if __name__ == '__main__':
del magic del magic
# increment this whenever we make important changes to this script # increment this whenever we make important changes to this script
VERSION = (1, 9) VERSION = (1, 10)
# increment this if the MAINTAINER_KEYS block is modified # increment this if the MAINTAINER_KEYS block is modified
KEYRING_VERSION = (1,0) KEYRING_VERSION = (1,0)
@ -259,8 +259,8 @@ def _SetupGnuPG(quiet):
gpg_dir, e.strerror) gpg_dir, e.strerror)
sys.exit(1) sys.exit(1)
env = dict(os.environ) env = os.environ.copy()
env['GNUPGHOME'] = gpg_dir env['GNUPGHOME'] = gpg_dir.encode()
cmd = ['gpg', '--import'] cmd = ['gpg', '--import']
try: try:
@ -378,8 +378,8 @@ def _Verify(cwd, branch, quiet):
% (branch, cur) % (branch, cur)
print >>sys.stderr print >>sys.stderr
env = dict(os.environ) env = os.environ.copy()
env['GNUPGHOME'] = gpg_dir env['GNUPGHOME'] = gpg_dir.encode()
cmd = [GIT, 'tag', '-v', cur] cmd = [GIT, 'tag', '-v', cur]
proc = subprocess.Popen(cmd, proc = subprocess.Popen(cmd,
@ -430,10 +430,14 @@ def _FindRepo():
dir = os.getcwd() dir = os.getcwd()
repo = None repo = None
while dir != '/' and not repo: olddir = None
while dir != '/' \
and dir != olddir \
and not repo:
repo = os.path.join(dir, repodir, REPO_MAIN) repo = os.path.join(dir, repodir, REPO_MAIN)
if not os.path.isfile(repo): if not os.path.isfile(repo):
repo = None repo = None
olddir = dir
dir = os.path.dirname(dir) dir = os.path.dirname(dir)
return (repo, os.path.join(dir, repodir)) return (repo, os.path.join(dir, repodir))
@ -479,6 +483,7 @@ def _Help(args):
if args: if args:
if args[0] == 'init': if args[0] == 'init':
init_optparse.print_help() init_optparse.print_help()
sys.exit(0)
else: else:
print >>sys.stderr,\ print >>sys.stderr,\
"error: '%s' is not a bootstrap command.\n"\ "error: '%s' is not a bootstrap command.\n"\

View File

@ -36,6 +36,9 @@ makes it available in your project's local working directory.
pass pass
def _ParseChangeIds(self, args): def _ParseChangeIds(self, args):
if not args:
self.Usage()
to_get = [] to_get = []
project = None project = None

View File

@ -151,11 +151,11 @@ terminal and are not redirected.
first = True first = True
for project in self.GetProjects(args): for project in self.GetProjects(args):
env = dict(os.environ.iteritems()) env = os.environ.copy()
def setenv(name, val): def setenv(name, val):
if val is None: if val is None:
val = '' val = ''
env[name] = val env[name] = val.encode()
setenv('REPO_PROJECT', project.name) setenv('REPO_PROJECT', project.name)
setenv('REPO_PATH', project.relpath) setenv('REPO_PATH', project.relpath)
@ -169,6 +169,12 @@ terminal and are not redirected.
else: else:
cwd = project.worktree cwd = project.worktree
if not os.path.exists(cwd):
if (opt.project_header and opt.verbose) \
or not opt.project_header:
print >>sys.stderr, 'skipping %s/' % project.relpath
continue
if opt.project_header: if opt.project_header:
stdin = subprocess.PIPE stdin = subprocess.PIPE
stdout = subprocess.PIPE stdout = subprocess.PIPE

View File

@ -94,6 +94,8 @@ See 'repo help --all' for a complete list of recognized commands.
body = getattr(cmd, bodyAttr) body = getattr(cmd, bodyAttr)
except AttributeError: except AttributeError:
return return
if body == '' or body is None:
return
self.nl() self.nl()

View File

@ -55,6 +55,7 @@ need to be performed by an end-user.
print >>sys.stderr, "error: can't update repo" print >>sys.stderr, "error: can't update repo"
sys.exit(1) sys.exit(1)
rp.bare_git.gc('--auto')
_PostRepoFetch(rp, _PostRepoFetch(rp,
no_repo_verify = opt.no_repo_verify, no_repo_verify = opt.no_repo_verify,
verbose = True) verbose = True)

View File

@ -185,6 +185,8 @@ later is required to fix a server side protocol bug.
t.join() t.join()
pm.end() pm.end()
for project in projects:
project.bare_git.gc('--auto')
return fetched return fetched
def UpdateProjectList(self): def UpdateProjectList(self):
@ -269,7 +271,7 @@ uncommitted changes are present' % project.relpath
if branch.startswith(R_HEADS): if branch.startswith(R_HEADS):
branch = branch[len(R_HEADS):] branch = branch[len(R_HEADS):]
env = dict(os.environ) env = os.environ.copy()
if (env.has_key('TARGET_PRODUCT') and if (env.has_key('TARGET_PRODUCT') and
env.has_key('TARGET_BUILD_VARIANT')): env.has_key('TARGET_BUILD_VARIANT')):
target = '%s-%s' % (env['TARGET_PRODUCT'], target = '%s-%s' % (env['TARGET_PRODUCT'],
@ -413,9 +415,9 @@ warning: Cannot automatically authenticate repo."""
% (project.name, rev) % (project.name, rev)
return False return False
env = dict(os.environ) env = os.environ.copy()
env['GIT_DIR'] = project.gitdir env['GIT_DIR'] = project.gitdir.encode()
env['GNUPGHOME'] = gpg_dir env['GNUPGHOME'] = gpg_dir.encode()
cmd = [GIT, 'tag', '-v', cur] cmd = [GIT, 'tag', '-v', cur]
proc = subprocess.Popen(cmd, proc = subprocess.Popen(cmd,

View File

@ -283,15 +283,19 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
have_errors = True have_errors = True
print >>sys.stderr, '' print >>sys.stderr, ''
print >>sys.stderr, '--------------------------------------------' print >>sys.stderr, '----------------------------------------------------------------------'
if have_errors: if have_errors:
for branch in todo: for branch in todo:
if not branch.uploaded: if not branch.uploaded:
print >>sys.stderr, '[FAILED] %-15s %-15s (%s)' % ( if len(str(branch.error)) <= 30:
fmt = ' (%s)'
else:
fmt = '\n (%s)'
print >>sys.stderr, ('[FAILED] %-15s %-15s' + fmt) % (
branch.project.relpath + '/', \ branch.project.relpath + '/', \
branch.name, \ branch.name, \
branch.error) str(branch.error))
print >>sys.stderr, '' print >>sys.stderr, ''
for branch in todo: for branch in todo: