mirror of
https://gerrit.googlesource.com/git-repo
synced 2025-06-26 20:17:52 +00:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
37dbf2bf0f | |||
438c54713a | |||
e020ebee4e | |||
21c5c34ee2 | |||
54fccd71fb | |||
fb5c8fd948 | |||
26120ca18d | |||
7da73d6f3b | |||
f0d4c36701 | |||
2ec00b9272 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
*.pyc
|
||||
.repopickle_*
|
||||
|
11
editor.py
11
editor.py
@ -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()
|
||||
|
5
error.py
5
error.py
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -259,21 +259,26 @@ class GitConfig(object):
|
||||
os.remove(self._pickle)
|
||||
|
||||
def _ReadGit(self):
|
||||
d = self._do('--null', '--list')
|
||||
c = {}
|
||||
while d:
|
||||
lf = d.index('\n')
|
||||
nul = d.index('\0', lf + 1)
|
||||
"""
|
||||
Read configuration data from git.
|
||||
|
||||
key = _key(d[0:lf])
|
||||
val = d[lf + 1:nul]
|
||||
This internal method populates the GitConfig cache.
|
||||
|
||||
"""
|
||||
d = self._do('--null', '--list').rstrip('\0')
|
||||
c = {}
|
||||
for line in d.split('\0'):
|
||||
if '\n' in line:
|
||||
key, val = line.split('\n', 1)
|
||||
else:
|
||||
key = line
|
||||
val = None
|
||||
|
||||
if key in c:
|
||||
c[key].append(val)
|
||||
else:
|
||||
c[key] = [val]
|
||||
|
||||
d = d[nul + 1:]
|
||||
return c
|
||||
|
||||
def _do(self, *args):
|
||||
@ -385,8 +390,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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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',[]))
|
||||
|
||||
|
@ -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
|
||||
@ -161,20 +148,33 @@ to update the working directory files.
|
||||
print >>sys.stderr, 'fatal: %s' % str(e)
|
||||
sys.exit(1)
|
||||
|
||||
def _PromptKey(self, prompt, key, value):
|
||||
def _Prompt(self, prompt, value):
|
||||
mp = self.manifest.manifestProject
|
||||
|
||||
sys.stdout.write('%-10s [%s]: ' % (prompt, value))
|
||||
a = sys.stdin.readline().strip()
|
||||
if a != '' and a != value:
|
||||
mp.config.SetString(key, a)
|
||||
if a == '':
|
||||
return value
|
||||
return a
|
||||
|
||||
def _ConfigureUser(self):
|
||||
mp = self.manifest.manifestProject
|
||||
|
||||
print ''
|
||||
self._PromptKey('Your Name', 'user.name', mp.UserName)
|
||||
self._PromptKey('Your Email', 'user.email', mp.UserEmail)
|
||||
while True:
|
||||
print ''
|
||||
name = self._Prompt('Your Name', mp.UserName)
|
||||
email = self._Prompt('Your Email', mp.UserEmail)
|
||||
|
||||
print ''
|
||||
print 'Your identity is: %s <%s>' % (name, email)
|
||||
sys.stdout.write('is this correct [yes/no]? ')
|
||||
if 'yes' == sys.stdin.readline().strip():
|
||||
break
|
||||
|
||||
if name != mp.UserName:
|
||||
mp.config.SetString('user.name', name)
|
||||
if email != mp.UserEmail:
|
||||
mp.config.SetString('user.email', email)
|
||||
|
||||
def _HasColorSet(self, gc):
|
||||
for n in ['ui', 'diff', 'status']:
|
||||
@ -214,7 +214,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)
|
||||
|
||||
|
3
tests/fixtures/test.gitconfig
vendored
Normal file
3
tests/fixtures/test.gitconfig
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[section]
|
||||
empty
|
||||
nonempty = true
|
43
tests/test_git_config.py
Normal file
43
tests/test_git_config.py
Normal file
@ -0,0 +1,43 @@
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import git_config
|
||||
|
||||
def fixture(*paths):
|
||||
"""Return a path relative to test/fixtures.
|
||||
"""
|
||||
return os.path.join(os.path.dirname(__file__), 'fixtures', *paths)
|
||||
|
||||
class GitConfigUnitTest(unittest.TestCase):
|
||||
"""Tests the GitConfig class.
|
||||
"""
|
||||
def setUp(self):
|
||||
"""Create a GitConfig object using the test.gitconfig fixture.
|
||||
"""
|
||||
config_fixture = fixture('test.gitconfig')
|
||||
self.config = git_config.GitConfig(config_fixture)
|
||||
|
||||
def test_GetString_with_empty_config_values(self):
|
||||
"""
|
||||
Test config entries with no value.
|
||||
|
||||
[section]
|
||||
empty
|
||||
|
||||
"""
|
||||
val = self.config.GetString('section.empty')
|
||||
self.assertEqual(val, None)
|
||||
|
||||
def test_GetString_with_true_value(self):
|
||||
"""
|
||||
Test config entries with a string value.
|
||||
|
||||
[section]
|
||||
nonempty = true
|
||||
|
||||
"""
|
||||
val = self.config.GetString('section.nonempty')
|
||||
self.assertEqual(val, 'true')
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Reference in New Issue
Block a user