Compare commits

...

13 Commits

Author SHA1 Message Date
21c5c34ee2 Support detached HEAD in manifest repository
If the manifest repository is on a detached HEAD and we are parsing
an XML formatted manifest we should simply set the branch property
to None, rather than crash with an AttributeError.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-25 16:47:30 -07:00
54fccd71fb Document any crashes from the user's text editor
Rather than failing with no information, display the child exit
status and the command line we tried to use to edit a text file.
There may be some useful information to help understand the crash.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-24 07:15:21 -07:00
fb5c8fd948 Fix invalid use of try-catch
Its try-except in Python.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-16 14:59:19 -07:00
26120ca18d Don't crash if the ssh client is already dead
If the SSH client terminated abnormally in the background (e.g. the
server shutdown while we were doing a sync) then the pid won't exist.
Instead of crashing, ignore it, the result we wanted (a non-orphaned
ssh process) is already acheived.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-16 11:49:10 -07:00
7da73d6f3b branches: Describe output format in repo help branches
Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-12 17:35:43 -07:00
f0d4c36701 grep: Only use --color on git 1.6.3 and later
The --color flag wasn't introduced until git 1.6.3.  Prior to that
version, `git grep --color` just produces a fatal error, as it is
an unsupported option.  Since this is just pretty output and is not
critical to execution, we can simply omit the option if the version
of git we are running on doesn't support it.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-12 09:33:48 -07:00
2ec00b9272 Refactor git version detection for reuse
This way we can use it to detect feature support in the underlying
git, such as new options or commands that have been added in more
recent versions.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-12 09:32:50 -07:00
2a3a81b51f Ignore EOFError when reading a truncated pickle file
If the pickle config file is 0 bytes in length,  we may have
crashed (or been aborted) while writing the file out to disk.
Instead of crashing with a backtrace, just treat the file as
though it wasn't present and load off a `git config` fork.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-12 09:10:07 -07:00
7b4f43542a Add missing return False to preconnect
Noticed by users on repo-discuss, we were missing a return False
here to signal that SSH control master was not used to setup the
network connection.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-12 09:08:34 -07:00
9fb29ce123 sync: Keep the project.list file sorted
Its easier to locate an entry visually if the file is sorted.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-04 20:41:26 -07:00
3a68bb4c7f sync: Tolerate blank lines in project.list
If a line is blank in project.list, its not a relevant project path,
so skip over it.  Existing project.list files may have blank lines if
sync was run with no projects at all, and the file was created empty.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-04 16:21:01 -07:00
cd1d7ff81e sync: Don't process project.list in a mirror
We have no working tree, so we cannot update the project.list
state file, nor should we try to delete a directory if a project is
removed from the manifest.  Clients would still need the repository
for historical records.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-04 16:20:02 -07:00
da88ff4411 Silence 'Current branch %s is up to date' during sync
We accidentally introduced this message during 1.6.8 by always
invoking `git rebase` when there were no new commits from the
upstream, but the user had local commits.

Signed-off-by: Shawn O. Pearce <sop@google.com>
2009-06-03 11:09:31 -07:00
10 changed files with 90 additions and 26 deletions

View File

@ -76,8 +76,15 @@ least one of these before using this command."""
os.close(fd)
fd = None
if subprocess.Popen(editor + [path]).wait() != 0:
raise EditorError()
try:
rc = subprocess.Popen(editor + [path]).wait()
except OSError, e:
raise EditorError('editor failed, %s: %s %s'
% (str(e), cls._GetEditor(), path))
if rc != 0:
raise EditorError('editor failed with exit status %d: %s %s'
% (rc, cls._GetEditor(), path))
fd2 = open(path)
try:
return fd2.read()

View File

@ -24,6 +24,11 @@ class ManifestInvalidRevisionError(Exception):
class EditorError(Exception):
"""Unspecified error from the user's text editor.
"""
def __init__(self, reason):
self.reason = reason
def __str__(self):
return self.reason
class GitError(Exception):
"""Unspecified internal error from git.

View File

@ -68,6 +68,30 @@ class _GitCall(object):
return fun
git = _GitCall()
_git_version = None
def git_require(min_version, fail=False):
global _git_version
if _git_version is None:
ver_str = git.version()
if ver_str.startswith('git version '):
_git_version = tuple(
map(lambda x: int(x),
ver_str[len('git version '):].strip().split('.')[0:3]
))
else:
print >>sys.stderr, 'fatal: "%s" unsupported' % ver_str
sys.exit(1)
if min_version <= _git_version:
return True
if fail:
need = '.'.join(map(lambda x: str(x), min_version))
print >>sys.stderr, 'fatal: git %s or later required' % need
sys.exit(1)
return False
class GitCommand(object):
def __init__(self,
project,

View File

@ -236,6 +236,9 @@ class GitConfig(object):
return cPickle.load(fd)
finally:
fd.close()
except EOFError:
os.remove(self._pickle)
return None
except IOError:
os.remove(self._pickle)
return None
@ -382,8 +385,11 @@ def _open_ssh(host, port):
def close_ssh():
for key,p in _ssh_cache.iteritems():
os.kill(p.pid, SIGTERM)
p.wait()
try:
os.kill(p.pid, SIGTERM)
p.wait()
except OSError:
pass
_ssh_cache.clear()
d = _ssh_sock(create=False)
@ -414,6 +420,7 @@ def _preconnect(url):
host = m.group(1)
return _open_ssh(host, 22)
return False
class Remote(object):
"""Configuration options related to a remote.

View File

@ -183,7 +183,7 @@ class XmlManifest(object):
if not self._loaded:
m = self.manifestProject
b = m.GetBranch(m.CurrentBranch).merge
if b.startswith(R_HEADS):
if b is not None and b.startswith(R_HEADS):
b = b[len(R_HEADS):]
self.branch = b

View File

@ -733,9 +733,7 @@ class Project(object):
last_mine = commit_id
cnt_mine += 1
if not local_changes and not upstream_gain:
# Trivially no changes caused by the upstream.
#
if not upstream_gain and cnt_mine == len(local_changes):
return
if self.IsDirty(consider_untracked=False):

View File

@ -61,6 +61,33 @@ class Branches(Command):
%prog [<project>...]
Summarizes the currently available topic branches.
Branch Display
--------------
The branch display output by this command is organized into four
columns of information; for example:
*P nocolor | in repo
repo2 |
The first column contains a * if the branch is the currently
checked out branch in any of the specified projects, or a blank
if no project has the branch checked out.
The second column contains either blank, p or P, depending upon
the upload status of the branch.
(blank): branch not yet published by repo upload
P: all commits were published by repo upload
p: only some commits were published by repo upload
The third column contains the branch name.
The fourth column (after the | separator) lists the projects that
the branch appears in, or does not appear in. If no project list
is shown, then the branch appears in all projects.
"""
def Execute(self, opt, args):

View File

@ -17,7 +17,7 @@ import sys
from optparse import SUPPRESS_HELP
from color import Coloring
from command import PagedCommand
from git_command import GitCommand
from git_command import git_require, GitCommand
class GrepColoring(Coloring):
def __init__(self, config):
@ -158,7 +158,7 @@ contain a line that matches both expressions:
out = GrepColoring(self.manifest.manifestProject.config)
cmd_argv = ['grep']
if out.is_on:
if out.is_on and git_require((1,6,3)):
cmd_argv.append('--color')
cmd_argv.extend(getattr(opt,'cmd_argv',[]))

View File

@ -20,7 +20,7 @@ from color import Coloring
from command import InteractiveCommand, MirrorSafeCommand
from error import ManifestParseError
from project import SyncBuffer
from git_command import git, MIN_GIT_VERSION
from git_command import git_require, MIN_GIT_VERSION
class Init(InteractiveCommand, MirrorSafeCommand):
common = True
@ -85,19 +85,6 @@ to update the working directory files.
dest='no_repo_verify', action='store_true',
help='do not verify repo source code')
def _CheckGitVersion(self):
ver_str = git.version()
if not ver_str.startswith('git version '):
print >>sys.stderr, 'error: "%s" unsupported' % ver_str
sys.exit(1)
ver_str = ver_str[len('git version '):].strip()
ver_act = tuple(map(lambda x: int(x), ver_str.split('.')[0:3]))
if ver_act < MIN_GIT_VERSION:
need = '.'.join(map(lambda x: str(x), MIN_GIT_VERSION))
print >>sys.stderr, 'fatal: git %s or later required' % need
sys.exit(1)
def _SyncManifest(self, opt):
m = self.manifest.manifestProject
is_new = not m.Exists
@ -214,7 +201,7 @@ to update the working directory files.
gc.SetString('color.ui', 'auto')
def Execute(self, opt, args):
self._CheckGitVersion()
git_require(MIN_GIT_VERSION, fail=True)
self._SyncManifest(opt)
self._LinkManifest(opt.manifest_name)

View File

@ -123,7 +123,8 @@ later is required to fix a server side protocol bug.
def UpdateProjectList(self):
new_project_paths = []
for project in self.manifest.projects.values():
new_project_paths.append(project.relpath)
if project.relpath:
new_project_paths.append(project.relpath)
file_name = 'project.list'
file_path = os.path.join(self.manifest.repodir, file_name)
old_project_paths = []
@ -135,6 +136,8 @@ later is required to fix a server side protocol bug.
finally:
fd.close()
for path in old_project_paths:
if not path:
continue
if path not in new_project_paths:
project = Project(
manifest = self.manifest,
@ -163,9 +166,11 @@ uncommitted changes are present' % project.relpath
break
dir = os.path.dirname(dir)
new_project_paths.sort()
fd = open(file_path, 'w')
try:
fd.write('\n'.join(new_project_paths))
fd.write('\n')
finally:
fd.close()
return 0
@ -217,6 +222,10 @@ uncommitted changes are present' % project.relpath
missing.append(project)
self._Fetch(missing)
if self.manifest.IsMirror:
# bail out now, we have no working tree
return
if self.UpdateProjectList():
sys.exit(1)