[Python-modules-commits] [python-git] 03/08: Import python-git_2.0.5.orig.tar.gz
Barry Warsaw
barry at moszumanska.debian.org
Wed Jun 15 10:56:31 UTC 2016
This is an automated email from the git hooks/post-receive script.
barry pushed a commit to branch master
in repository python-git.
commit 673a76fe139b987b1c91ee01bf88a3ea956b5129
Author: Barry Warsaw <barry at python.org>
Date: Wed Jun 15 12:35:06 2016 +0300
Import python-git_2.0.5.orig.tar.gz
---
CHANGES | 2 +-
GitPython.egg-info/PKG-INFO | 2 +-
GitPython.egg-info/SOURCES.txt | 1 +
PKG-INFO | 2 +-
VERSION | 2 +-
doc/source/changes.rst | 28 ++++++++++
doc/source/intro.rst | 24 +++++----
git/__init__.py | 4 +-
git/cmd.py | 21 ++++----
git/compat.py | 2 +-
git/diff.py | 26 ++++++++-
git/index/fun.py | 2 +-
git/objects/commit.py | 6 +--
git/remote.py | 90 +++++++++++++++++++++++--------
git/repo/base.py | 17 ++++--
git/test/fixtures/blame_incremental | 2 +-
git/test/fixtures/commit_invalid_data | 6 +++
git/test/fixtures/diff_patch_unsafe_paths | 7 +++
git/test/test_base.py | 2 +-
git/test/test_commit.py | 7 +++
git/test/test_diff.py | 15 +++---
git/test/test_docs.py | 13 ++---
git/test/test_git.py | 2 +-
git/test/test_index.py | 2 +-
git/test/test_remote.py | 8 +++
git/test/test_repo.py | 2 +-
git/util.py | 30 ++++++++---
requirements.txt | 1 -
28 files changed, 240 insertions(+), 86 deletions(-)
diff --git a/CHANGES b/CHANGES
index 9242253..aa8116b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,2 +1,2 @@
Please see the online documentation for the latest changelog:
-https://github.com/gitpython-developers/GitPython/blob/0.3/doc/source/changes.rst
+https://github.com/gitpython-developers/GitPython/blob/master/doc/source/changes.rst
diff --git a/GitPython.egg-info/PKG-INFO b/GitPython.egg-info/PKG-INFO
index 0bafac6..b13be03 100644
--- a/GitPython.egg-info/PKG-INFO
+++ b/GitPython.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: GitPython
-Version: 2.0.2
+Version: 2.0.5
Summary: Python Git Library
Home-page: https://github.com/gitpython-developers/GitPython
Author: Sebastian Thiel, Michael Trier
diff --git a/GitPython.egg-info/SOURCES.txt b/GitPython.egg-info/SOURCES.txt
index c1db831..3c82ba0 100644
--- a/GitPython.egg-info/SOURCES.txt
+++ b/GitPython.egg-info/SOURCES.txt
@@ -88,6 +88,7 @@ git/test/fixtures/cat_file.py
git/test/fixtures/cat_file_blob
git/test/fixtures/cat_file_blob_nl
git/test/fixtures/cat_file_blob_size
+git/test/fixtures/commit_invalid_data
git/test/fixtures/commit_with_gpgsig
git/test/fixtures/diff_2
git/test/fixtures/diff_2f
diff --git a/PKG-INFO b/PKG-INFO
index 0bafac6..b13be03 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: GitPython
-Version: 2.0.2
+Version: 2.0.5
Summary: Python Git Library
Home-page: https://github.com/gitpython-developers/GitPython
Author: Sebastian Thiel, Michael Trier
diff --git a/VERSION b/VERSION
index e9307ca..e010258 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.0.2
+2.0.5
diff --git a/doc/source/changes.rst b/doc/source/changes.rst
index 51d3954..6a8e87d 100644
--- a/doc/source/changes.rst
+++ b/doc/source/changes.rst
@@ -2,6 +2,34 @@
Changelog
=========
+2.0.5 - Fixes
+=============
+
+* Fix: parser of fetch info lines choked on some legitimate lines
+
+2.0.4 - Fixes
+=============
+
+* Fix: parser of commit object data is now robust against cases where
+ commit object contains invalid bytes. The invalid characters are now
+ replaced rather than choked on.
+* Fix: non-ASCII paths are now properly decoded and returned in
+ ``.diff()`` output
+* Fix: `RemoteProgress` will now strip the ', ' prefix or suffix from messages.
+* API: Remote.[fetch|push|pull](...) methods now allow the ``progress`` argument to
+ be a callable. This saves you from creating a custom type with usually just one
+ implemented method.
+
+2.0.3 - Fixes
+=============
+
+* Fix: bug in ``git-blame --incremental`` output parser that broken when
+ commit messages contained ``\r`` characters
+* Fix: progress handler exceptions are not caught anymore, which would usually just hide bugs
+ previously.
+* Fix: The `Git.execute` method will now redirect `stdout` to `devnull` if `with_stdout` is false,
+ which is the intended behaviour based on the parameter's documentation.
+
2.0.2 - Fixes
=============
diff --git a/doc/source/intro.rst b/doc/source/intro.rst
index 78d4034..6c4e50f 100644
--- a/doc/source/intro.rst
+++ b/doc/source/intro.rst
@@ -13,6 +13,9 @@ The object database implementation is optimized for handling large quantities of
Requirements
============
+* `Python`_ 2.7 or newer
+ Since GitPython 2.0.0. Please note that python 2.6 is still reasonably well supported, but might
+ deteriorate over time.
* `Git`_ 1.7.0 or newer
It should also work with older versions, but it may be that some operations
involving remotes will not work as expected.
@@ -20,10 +23,11 @@ Requirements
* `Python Nose`_ - used for running the tests
* `Mock by Michael Foord`_ used for tests. Requires version 0.5
-.. _Git: http://git-scm.com/
-.. _Python Nose: http://code.google.com/p/python-nose/
+.. _Python: https://www.python.org
+.. _Git: https://git-scm.com/
+.. _Python Nose: https://nose.readthedocs.io/en/latest/
.. _Mock by Michael Foord: http://www.voidspace.org.uk/python/mock.html
-.. _GitDB: http://pypi.python.org/pypi/gitdb
+.. _GitDB: https://pypi.python.org/pypi/gitdb
Installing GitPython
====================
@@ -52,7 +56,7 @@ script:
.. sourcecode:: none
# python setup.py install
-
+
.. note:: In this case, you have to manually install `GitDB`_ as well. It would be recommended to use the :ref:`git source repository <source-code-label>` in that case.
Getting Started
@@ -80,16 +84,16 @@ GitPython's git repo is available on GitHub, which can be browsed at:
and cloned using::
$ git clone https://github.com/gitpython-developers/GitPython git-python
-
+
Initialize all submodules to obtain the required dependencies with::
-
+
$ cd git-python
$ git submodule update --init --recursive
-
+
Finally verify the installation by running the `nose powered <http://code.google.com/p/python-nose/>`_ unit tests::
-
+
$ nosetests
-
+
Questions and Answers
=====================
Please use stackoverflow for questions, and don't forget to tag it with `gitpython` to assure the right people see the question in a timely manner.
@@ -101,7 +105,7 @@ Issue Tracker
The issue tracker is hosted by github:
https://github.com/gitpython-developers/GitPython/issues
-
+
License Information
===================
GitPython is licensed under the New BSD License. See the LICENSE file for
diff --git a/git/__init__.py b/git/__init__.py
index 4ed60c4..81752b4 100644
--- a/git/__init__.py
+++ b/git/__init__.py
@@ -9,13 +9,13 @@ import os
import sys
import inspect
-__version__ = '2.0.2'
+__version__ = '2.0.5'
#{ Initialization
def _init_externals():
"""Initialize external projects by putting them into the path"""
- if __version__ == '2.0.2':
+ if __version__ == '2.0.5':
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'ext', 'gitdb'))
try:
diff --git a/git/cmd.py b/git/cmd.py
index e4e3d6d..c29e348 100644
--- a/git/cmd.py
+++ b/git/cmd.py
@@ -13,6 +13,8 @@ import threading
import errno
import mmap
+from git.odict import OrderedDict
+
from contextlib import contextmanager
import signal
from subprocess import (
@@ -42,7 +44,8 @@ from git.compat import (
execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output',
'with_exceptions', 'as_process', 'stdout_as_string',
- 'output_stream', 'with_stdout', 'kill_after_timeout')
+ 'output_stream', 'with_stdout', 'kill_after_timeout',
+ 'universal_newlines')
log = logging.getLogger('git.cmd')
log.addHandler(logging.NullHandler())
@@ -111,12 +114,7 @@ def handle_process_output(process, stdout_handler, stderr_handler, finalizer):
def _dispatch_single_line(line, handler):
line = line.decode(defenc)
if line and handler:
- try:
- handler(line)
- except Exception:
- # Keep reading, have to pump the lines empty nontheless
- log.error("Line handler exception on line: %s", line, exc_info=True)
- # end
+ handler(line)
# end dispatch helper
# end single line helper
@@ -490,6 +488,7 @@ class Git(LazyMixin):
stdout_as_string=True,
kill_after_timeout=None,
with_stdout=True,
+ universal_newlines=False,
**subprocess_kwargs
):
"""Handles executing the command on the shell and consumes and returns
@@ -544,7 +543,9 @@ class Git(LazyMixin):
specify may not be the same ones.
:param with_stdout: If True, default True, we open stdout on the created process
-
+ :param universal_newlines:
+ if True, pipes will be opened as text, and lines are split at
+ all known line endings.
:param kill_after_timeout:
To specify a timeout in seconds for the git command, after which the process
should be killed. This will have no effect if as_process is set to True. It is
@@ -608,9 +609,10 @@ class Git(LazyMixin):
bufsize=-1,
stdin=istream,
stderr=PIPE,
- stdout=with_stdout and PIPE or None,
+ stdout=PIPE if with_stdout else open(os.devnull, 'wb'),
shell=self.USE_SHELL,
close_fds=(os.name == 'posix'), # unsupported on windows
+ universal_newlines=universal_newlines,
**subprocess_kwargs
)
except cmd_not_found_exception as err:
@@ -783,6 +785,7 @@ class Git(LazyMixin):
def transform_kwargs(self, split_single_char_options=True, **kwargs):
"""Transforms Python style kwargs into git command line options."""
args = list()
+ kwargs = OrderedDict(sorted(kwargs.items(), key=lambda x: x[0]))
for k, v in kwargs.items():
if isinstance(v, (list, tuple)):
for value in v:
diff --git a/git/compat.py b/git/compat.py
index 7bd8e49..76509ba 100644
--- a/git/compat.py
+++ b/git/compat.py
@@ -1,4 +1,4 @@
-#-*-coding:utf-8-*-
+# -*- coding: utf-8 -*-
# config.py
# Copyright (C) 2008, 2009 Michael Trier (mtrier at gmail.com) and contributors
#
diff --git a/git/diff.py b/git/diff.py
index 7642694..9073767 100644
--- a/git/diff.py
+++ b/git/diff.py
@@ -15,12 +15,23 @@ from git.compat import (
PY3
)
-
__all__ = ('Diffable', 'DiffIndex', 'Diff', 'NULL_TREE')
# Special object to compare against the empty tree in diffs
NULL_TREE = object()
+_octal_byte_re = re.compile(b'\\\\([0-9]{3})')
+
+
+def _octal_repl(matchobj):
+ value = matchobj.group(1)
+ value = int(value, 8)
+ if PY3:
+ value = bytes(bytearray((value,)))
+ else:
+ value = chr(value)
+ return value
+
def decode_path(path, has_ab_prefix=True):
if path == b'/dev/null':
@@ -32,6 +43,8 @@ def decode_path(path, has_ab_prefix=True):
.replace(b'\\"', b'"')
.replace(b'\\\\', b'\\'))
+ path = _octal_byte_re.sub(_octal_repl, path)
+
if has_ab_prefix:
assert path.startswith(b'a/') or path.startswith(b'b/')
path = path[2:]
@@ -333,7 +346,16 @@ class Diff(object):
@property
def renamed(self):
- """:returns: True if the blob of our diff has been renamed"""
+ """:returns: True if the blob of our diff has been renamed
+ :note: This property is deprecated, please use ``renamed_file`` instead.
+ """
+ return self.renamed_file
+
+ @property
+ def renamed_file(self):
+ """:returns: True if the blob of our diff has been renamed
+ :note: This property is deprecated, please use ``renamed_file`` instead.
+ """
return self.rename_from != self.rename_to
@classmethod
diff --git a/git/index/fun.py b/git/index/fun.py
index c1026fd..4dd32b1 100644
--- a/git/index/fun.py
+++ b/git/index/fun.py
@@ -93,7 +93,7 @@ def stat_mode_to_index_mode(mode):
return S_IFLNK
if S_ISDIR(mode) or S_IFMT(mode) == S_IFGITLINK: # submodules
return S_IFGITLINK
- return S_IFREG | 0o644 | (mode & 0o100) # blobs with or without executable bit
+ return S_IFREG | 0o644 | (mode & 0o111) # blobs with or without executable bit
def write_cache(entries, stream, extension_data=None, ShaStreamCls=IndexFileSHA1Writer):
diff --git a/git/objects/commit.py b/git/objects/commit.py
index dc722f9..58a8912 100644
--- a/git/objects/commit.py
+++ b/git/objects/commit.py
@@ -501,14 +501,14 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable):
try:
self.author, self.authored_date, self.author_tz_offset = \
- parse_actor_and_date(author_line.decode(self.encoding))
+ parse_actor_and_date(author_line.decode(self.encoding, errors='replace'))
except UnicodeDecodeError:
log.error("Failed to decode author line '%s' using encoding %s", author_line, self.encoding,
exc_info=True)
try:
self.committer, self.committed_date, self.committer_tz_offset = \
- parse_actor_and_date(committer_line.decode(self.encoding))
+ parse_actor_and_date(committer_line.decode(self.encoding, errors='replace'))
except UnicodeDecodeError:
log.error("Failed to decode committer line '%s' using encoding %s", committer_line, self.encoding,
exc_info=True)
@@ -518,7 +518,7 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable):
# The end of our message stream is marked with a newline that we strip
self.message = stream.read()
try:
- self.message = self.message.decode(self.encoding)
+ self.message = self.message.decode(self.encoding, errors='replace')
except UnicodeDecodeError:
log.error("Failed to decode message '%s' using encoding %s", self.message, self.encoding, exc_info=True)
# END exception handling
diff --git a/git/remote.py b/git/remote.py
index e430abf..4275397 100644
--- a/git/remote.py
+++ b/git/remote.py
@@ -20,13 +20,12 @@ from .refs import (
SymbolicReference,
TagReference
)
-
-
from git.util import (
LazyMixin,
Iterable,
IterableList,
- RemoteProgress
+ RemoteProgress,
+ CallableRemoteProgress
)
from git.util import (
join_path,
@@ -34,7 +33,10 @@ from git.util import (
)
from git.cmd import handle_process_output
from gitdb.util import join
-from git.compat import defenc
+from git.compat import (defenc, force_text)
+import logging
+
+log = logging.getLogger('git.remote')
__all__ = ('RemoteProgress', 'PushInfo', 'FetchInfo', 'Remote')
@@ -48,8 +50,8 @@ def add_progress(kwargs, git, progress):
given, we do not request any progress
:return: possibly altered kwargs"""
if progress is not None:
- v = git.version_info
- if v[0] > 1 or v[1] > 7 or v[2] > 0 or v[3] > 3:
+ v = git.version_info[:2]
+ if v >= (1, 7):
kwargs['progress'] = True
# END handle --progress
# END handle progress
@@ -58,6 +60,23 @@ def add_progress(kwargs, git, progress):
#} END utilities
+def to_progress_instance(progress):
+ """Given the 'progress' return a suitable object derived from
+ RemoteProgress().
+ """
+ # new API only needs progress as a function
+ if callable(progress):
+ return CallableRemoteProgress(progress)
+
+ # where None is passed create a parser that eats the progress
+ elif progress is None:
+ return RemoteProgress()
+
+ # assume its the old API with an instance of RemoteProgress.
+ else:
+ return progress
+
+
class PushInfo(object):
"""
@@ -185,7 +204,7 @@ class FetchInfo(object):
NEW_TAG, NEW_HEAD, HEAD_UPTODATE, TAG_UPDATE, REJECTED, FORCED_UPDATE, \
FAST_FORWARD, ERROR = [1 << x for x in range(8)]
- re_fetch_result = re.compile("^\s*(.) (\[?[\w\s\.$@]+\]?)\s+(.+) -> ([/\w_\+\.\-$@#]+)( \(.*\)?$)?")
+ re_fetch_result = re.compile("^\s*(.) (\[?[\w\s\.$@]+\]?)\s+(.+) -> ([/\w_\+\.\-$@#()]+)( \(.*\)?$)?")
_flag_map = {'!': ERROR,
'+': FORCED_UPDATE,
@@ -536,6 +555,8 @@ class Remote(LazyMixin, Iterable):
return self
def _get_fetch_info_from_stderr(self, proc, progress):
+ progress = to_progress_instance(progress)
+
# skip first line as it is some remote info we are not interested in
output = IterableList('name')
@@ -549,8 +570,8 @@ class Remote(LazyMixin, Iterable):
progress_handler = progress.new_message_handler()
- for line in proc.stderr.readlines():
- line = line.decode(defenc)
+ for line in proc.stderr:
+ line = force_text(line)
for pline in progress_handler(line):
if line.startswith('fatal:') or line.startswith('error:'):
raise GitCommandError(("Error when fetching: %s" % line,), 2)
@@ -570,16 +591,28 @@ class Remote(LazyMixin, Iterable):
fetch_head_info = [l.decode(defenc) for l in fp.readlines()]
fp.close()
- # NOTE: We assume to fetch at least enough progress lines to allow matching each fetch head line with it.
l_fil = len(fetch_info_lines)
l_fhi = len(fetch_head_info)
- assert l_fil >= l_fhi, "len(%s) <= len(%s)" % (l_fil, l_fhi)
-
+ if l_fil != l_fhi:
+ msg = "Fetch head lines do not match lines provided via progress information\n"
+ msg += "length of progress lines %i should be equal to lines in FETCH_HEAD file %i\n"
+ msg += "Will ignore extra progress lines or fetch head lines."
+ msg %= (l_fil, l_fhi)
+ log.debug(msg)
+ if l_fil < l_fhi:
+ fetch_head_info = fetch_head_info[:l_fil]
+ else:
+ fetch_info_lines = fetch_info_lines[:l_fhi]
+ # end truncate correct list
+ # end sanity check + sanitization
+
output.extend(FetchInfo._from_line(self.repo, err_line, fetch_line)
for err_line, fetch_line in zip(fetch_info_lines, fetch_head_info))
return output
def _get_push_info(self, proc, progress):
+ progress = to_progress_instance(progress)
+
# read progress information from stderr
# we hope stdout can hold all the data, it should ...
# read the lines manually as it will use carriage returns between the messages
@@ -652,9 +685,9 @@ class Remote(LazyMixin, Iterable):
else:
args = [refspec]
- proc = self.repo.git.fetch(self, *args, as_process=True, with_stdout=False, v=True,
- **kwargs)
- res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress())
+ proc = self.repo.git.fetch(self, *args, as_process=True, with_stdout=False,
+ universal_newlines=True, v=True, **kwargs)
+ res = self._get_fetch_info_from_stderr(proc, progress)
if hasattr(self.repo.odb, 'update_cache'):
self.repo.odb.update_cache()
return res
@@ -671,8 +704,9 @@ class Remote(LazyMixin, Iterable):
# No argument refspec, then ensure the repo's config has a fetch refspec.
self._assert_refspec()
kwargs = add_progress(kwargs, self.repo.git, progress)
- proc = self.repo.git.pull(self, refspec, with_stdout=False, as_process=True, v=True, **kwargs)
- res = self._get_fetch_info_from_stderr(proc, progress or RemoteProgress())
+ proc = self.repo.git.pull(self, refspec, with_stdout=False, as_process=True,
+ universal_newlines=True, v=True, **kwargs)
+ res = self._get_fetch_info_from_stderr(proc, progress)
if hasattr(self.repo.odb, 'update_cache'):
self.repo.odb.update_cache()
return res
@@ -682,10 +716,19 @@ class Remote(LazyMixin, Iterable):
:param refspec: see 'fetch' method
:param progress:
- Instance of type RemoteProgress allowing the caller to receive
- progress information until the method returns.
- If None, progress information will be discarded
-
+ Can take one of many value types:
+
+ * None to discard progress information
+ * A function (callable) that is called with the progress infomation.
+
+ Signature: ``progress(op_code, cur_count, max_count=None, message='')``.
+
+ `Click here <http://goo.gl/NPa7st>`_ for a description of all arguments
+ given to the function.
+ * An instance of a class derived from ``git.RemoteProgress`` that
+ overrides the ``update()`` function.
+
+ :note: No further progress information is returned after push returns.
:param kwargs: Additional arguments to be passed to git-push
:return:
IterableList(PushInfo, ...) iterable list of PushInfo instances, each
@@ -696,8 +739,9 @@ class Remote(LazyMixin, Iterable):
If the operation fails completely, the length of the returned IterableList will
be null."""
kwargs = add_progress(kwargs, self.repo.git, progress)
- proc = self.repo.git.push(self, refspec, porcelain=True, as_process=True, **kwargs)
- return self._get_push_info(proc, progress or RemoteProgress())
+ proc = self.repo.git.push(self, refspec, porcelain=True, as_process=True,
+ universal_newlines=True, **kwargs)
+ return self._get_push_info(proc, progress)
@property
def config_reader(self):
diff --git a/git/repo/base.py b/git/repo/base.py
index 0274c0a..f43cc46 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -32,7 +32,8 @@ from git.index import IndexFile
from git.config import GitConfigParser
from git.remote import (
Remote,
- add_progress
+ add_progress,
+ to_progress_instance
)
from git.db import GitCmdObjectDB
@@ -254,7 +255,9 @@ class Repo(object):
@property
def index(self):
- """:return: IndexFile representing this repository's index."""
+ """:return: IndexFile representing this repository's index.
+ :note: This property can be expensive, as the returned ``IndexFile`` will be
+ reinitialized. It's recommended to re-use the object."""
return IndexFile(self)
@property
@@ -624,7 +627,10 @@ class Repo(object):
are relative to the current working directory of the git command.
:note:
- ignored files will not appear here, i.e. files mentioned in .gitignore"""
+ ignored files will not appear here, i.e. files mentioned in .gitignore
+ :note:
+ This property is expensive, as no cache is involved. To process the result, please
+ consider caching it yourself."""
return self._get_untracked_files()
def _get_untracked_files(self, **kwargs):
@@ -677,10 +683,9 @@ class Repo(object):
data = self.git.blame(rev, '--', file, p=True, incremental=True, stdout_as_string=False, **kwargs)
commits = dict()
- stream = iter(data.splitlines())
+ stream = (line for line in data.split(b'\n') if line)
while True:
line = next(stream) # when exhausted, casues a StopIteration, terminating this function
-
hexsha, orig_lineno, lineno, num_lines = line.split()
lineno = int(lineno)
num_lines = int(num_lines)
@@ -868,6 +873,8 @@ class Repo(object):
@classmethod
def _clone(cls, git, url, path, odb_default_type, progress, **kwargs):
+ progress = to_progress_instance(progress)
+
# special handling for windows for path at which the clone should be
# created.
# tilde '~' will be expanded to the HOME no matter where the ~ occours. Hence
diff --git a/git/test/fixtures/blame_incremental b/git/test/fixtures/blame_incremental
index 9a0d9e3..67310ae 100644
--- a/git/test/fixtures/blame_incremental
+++ b/git/test/fixtures/blame_incremental
@@ -7,7 +7,7 @@ committer Sebastian Thiel
committer-mail <byronimo at gmail.com>
committer-time 1270634931
committer-tz +0200
-summary Used this release for a first beta of the 0.2 branch of development
+summary Used this release
for a first beta of the 0.2 branch of development
previous 501bf602abea7d21c3dbb409b435976e92033145 AUTHORS
filename AUTHORS
82b8902e033430000481eb355733cd7065342037 14 14 1
diff --git a/git/test/fixtures/commit_invalid_data b/git/test/fixtures/commit_invalid_data
new file mode 100644
index 0000000..d112bf2
--- /dev/null
+++ b/git/test/fixtures/commit_invalid_data
@@ -0,0 +1,6 @@
+tree 9f1a495d7d9692d24f5caedaa89f5c2c32d59368
+parent 492ace2ffce0e426ebeb55e364e987bcf024dd3b
+author E.Azer Ko�o�o�oculu <azer at kodfabrik.com> 1306710073 +0300
+committer E.Azer Ko�o�o�oculu <azer at kodfabrik.com> 1306710073 +0300
+
+add environjs
diff --git a/git/test/fixtures/diff_patch_unsafe_paths b/git/test/fixtures/diff_patch_unsafe_paths
index 14375f7..9ee6b83 100644
--- a/git/test/fixtures/diff_patch_unsafe_paths
+++ b/git/test/fixtures/diff_patch_unsafe_paths
@@ -61,6 +61,13 @@ index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94
+++ "b/path/¯\\_(ツ)_|¯"
@@ -0,0 +1 @@
+dummy content
+diff --git "a/path/\360\237\222\251.txt" "b/path/\360\237\222\251.txt"
+new file mode 100644
+index 0000000000000000000000000000000000000000..eaf5f7510320b6a327fb308379de2f94d8859a54
+--- /dev/null
++++ "b/path/\360\237\222\251.txt"
+@@ -0,0 +1 @@
++dummy content
diff --git a/a/with spaces b/b/with some spaces
similarity index 100%
rename from a/with spaces
diff --git a/git/test/test_base.py b/git/test/test_base.py
index 94379ca..7b71a77 100644
--- a/git/test/test_base.py
+++ b/git/test/test_base.py
@@ -1,4 +1,4 @@
-#-*-coding:utf-8-*-
+# -*- coding: utf-8 -*-
# test_base.py
# Copyright (C) 2008, 2009 Michael Trier (mtrier at gmail.com) and contributors
#
diff --git a/git/test/test_commit.py b/git/test/test_commit.py
index 23b7154..ea8cd9a 100644
--- a/git/test/test_commit.py
+++ b/git/test/test_commit.py
@@ -306,6 +306,13 @@ class TestCommit(TestBase):
# it appears
cmt.author.__repr__()
+ def test_invalid_commit(self):
+ cmt = self.rorepo.commit()
+ cmt._deserialize(open(fixture_path('commit_invalid_data'), 'rb'))
+
+ assert cmt.author.name == u'E.Azer Ko�o�o�oculu', cmt.author.name
+ assert cmt.author.email == 'azer at kodfabrik.com', cmt.author.email
+
def test_gpgsig(self):
cmt = self.rorepo.commit()
cmt._deserialize(open(fixture_path('commit_with_gpgsig'), 'rb'))
diff --git a/git/test/test_diff.py b/git/test/test_diff.py
index 858b399..8966351 100644
--- a/git/test/test_diff.py
+++ b/git/test/test_diff.py
@@ -86,6 +86,7 @@ class TestDiff(TestBase):
assert_equal(1, len(diffs))
diff = diffs[0]
+ assert_true(diff.renamed_file)
assert_true(diff.renamed)
assert_equal(diff.rename_from, u'Jérôme')
assert_equal(diff.rename_to, u'müller')
@@ -95,6 +96,7 @@ class TestDiff(TestBase):
diffs = Diff._index_from_raw_format(self.rorepo, output.stdout)
assert len(diffs) == 1
diff = diffs[0]
+ assert diff.renamed_file
assert diff.renamed
assert diff.rename_from == 'this'
assert diff.rename_to == 'that'
@@ -159,16 +161,17 @@ class TestDiff(TestBase):
self.assertEqual(res[6].b_path, u'path/with spaces')
self.assertEqual(res[7].b_path, u'path/with-question-mark?')
self.assertEqual(res[8].b_path, u'path/¯\\_(ツ)_|¯')
+ self.assertEqual(res[9].b_path, u'path/💩.txt')
# The "Moves"
# NOTE: The path prefixes a/ and b/ here are legit! We're actually
# verifying that it's not "a/a/" that shows up, see the fixture data.
- self.assertEqual(res[9].a_path, u'a/with spaces') # NOTE: path a/ here legit!
- self.assertEqual(res[9].b_path, u'b/with some spaces') # NOTE: path b/ here legit!
- self.assertEqual(res[10].a_path, u'a/ending in a space ')
- self.assertEqual(res[10].b_path, u'b/ending with space ')
- self.assertEqual(res[11].a_path, u'a/"with-quotes"')
- self.assertEqual(res[11].b_path, u'b/"with even more quotes"')
+ self.assertEqual(res[10].a_path, u'a/with spaces') # NOTE: path a/ here legit!
+ self.assertEqual(res[10].b_path, u'b/with some spaces') # NOTE: path b/ here legit!
+ self.assertEqual(res[11].a_path, u'a/ending in a space ')
+ self.assertEqual(res[11].b_path, u'b/ending with space ')
+ self.assertEqual(res[12].a_path, u'a/"with-quotes"')
+ self.assertEqual(res[12].b_path, u'b/"with even more quotes"')
def test_diff_patch_format(self):
# test all of the 'old' format diffs for completness - it should at least
diff --git a/git/test/test_docs.py b/git/test/test_docs.py
index 189cdc4..2747074 100644
--- a/git/test/test_docs.py
+++ b/git/test/test_docs.py
@@ -1,4 +1,4 @@
-#-*-coding:utf-8-*-
+# -*- coding: utf-8 -*-
# test_git.py
# Copyright (C) 2008, 2009 Michael Trier (mtrier at gmail.com) and contributors
#
@@ -7,11 +7,12 @@
import os
from git.test.lib import TestBase
-from gitdb.test.lib import with_rw_directory
+from gitdb.test.lib import skip_on_travis_ci, with_rw_directory
class Tutorials(TestBase):
+ @skip_on_travis_ci
@with_rw_directory
def test_init_repo_object(self, rw_dir):
# [1-test_init_repo_object]
@@ -165,7 +166,7 @@ class Tutorials(TestBase):
for sm in cloned_repo.submodules:
assert not sm.remove().exists() # after removal, the sm doesn't exist anymore
sm = cloned_repo.create_submodule('mysubrepo', 'path/to/subrepo', url=bare_repo.git_dir, branch='master')
-
+
# .gitmodules was written and added to the index, which is now being committed
cloned_repo.index.commit("Added submodule")
assert sm.exists() and sm.module_exists() # this submodule is defintely available
@@ -395,7 +396,7 @@ class Tutorials(TestBase):
hcommit.diff() # diff tree against index
hcommit.diff('HEAD~1') # diff tree against previous tree
hcommit.diff(None) # diff tree against working tree
-
+
index = repo.index
index.diff() # diff index against itself yielding empty diff
index.diff(None) # diff index against working copy
@@ -446,7 +447,7 @@ class Tutorials(TestBase):
sm = sms[0]
assert sm.name == 'gitdb' # git-python has gitdb as single submodule ...
assert sm.children()[0].name == 'smmap' # ... which has smmap as single submodule
-
+
# The module is the repository referenced by the submodule
assert sm.module_exists() # the module is available, which doesn't have to be the case.
assert sm.module().working_tree_dir.endswith('gitdb')
@@ -458,7 +459,7 @@ class Tutorials(TestBase):
assert sm.config_reader().get_value('path') == sm.path
assert len(sm.children()) == 1 # query the submodule hierarchy
# ![1-test_submodules]
-
+
@with_rw_directory
def test_add_file_and_commit(self, rw_dir):
import git
diff --git a/git/test/test_git.py b/git/test/test_git.py
index 00592b8..2d6ca8b 100644
--- a/git/test/test_git.py
+++ b/git/test/test_git.py
@@ -1,4 +1,4 @@
-#-*-coding:utf-8-*-
+# -*- coding: utf-8 -*-
# test_git.py
# Copyright (C) 2008, 2009 Michael Trier (mtrier at gmail.com) and contributors
#
diff --git a/git/test/test_index.py b/git/test/test_index.py
index f5f9d70..ca87783 100644
--- a/git/test/test_index.py
+++ b/git/test/test_index.py
@@ -1,4 +1,4 @@
-#-*-coding:utf-8-*-
+# -*- coding: utf-8 -*-
# test_index.py
# Copyright (C) 2008, 2009 Michael Trier (mtrier at gmail.com) and contributors
#
diff --git a/git/test/test_remote.py b/git/test/test_remote.py
index 6c37614..9ca2f20 100644
--- a/git/test/test_remote.py
+++ b/git/test/test_remote.py
@@ -62,6 +62,14 @@ class TestRemoteProgress(RemoteProgress):
# check each stage only comes once
op_id = op_code & self.OP_MASK
assert op_id in (self.COUNTING, self.COMPRESSING, self.WRITING)
+
+ if op_code & self.WRITING > 0:
+ if op_code & self.BEGIN > 0:
+ assert not message, 'should not have message when remote begins writing'
+ elif op_code & self.END > 0:
+ assert message
+ assert not message.startswith(', '), "Sanitize progress messages: '%s'" % message
+ assert not message.endswith(', '), "Sanitize progress messages: '%s'" % message
self._stages_per_op.setdefault(op_id, 0)
self._stages_per_op[op_id] = self._stages_per_op[op_id] | (op_code & self.STAGE_MASK)
diff --git a/git/test/test_repo.py b/git/test/test_repo.py
index d7437d3..fc8125f 100644
--- a/git/test/test_repo.py
+++ b/git/test/test_repo.py
@@ -1,4 +1,4 @@
-#-*-coding:utf-8-*-
+# -*- coding: utf-8 -*-
# test_repo.py
# Copyright (C) 2008, 2009 Michael Trier (mtrier at gmail.com) and contributors
#
diff --git a/git/util.py b/git/util.py
index bfcb894..5ed014f 100644
--- a/git/util.py
+++ b/git/util.py
@@ -39,7 +39,7 @@ from gitdb.util import ( # NOQA
__all__ = ("stream_copy", "join_path", "to_native_path_windows", "to_native_path_linux",
"join_path_native", "Stats", "IndexFileSHA1Writer", "Iterable", "IterableList",
"BlockingLockFile", "LockFile", 'Actor', 'get_user_id', 'assure_directory_exists',
- 'RemoteProgress', 'rmtree', 'WaitGroup', 'unbare_repo')
+ 'RemoteProgress', 'CallableRemoteProgress', 'rmtree', 'WaitGroup', 'unbare_repo')
#{ Utility Methods
@@ -160,7 +160,6 @@ def finalize_process(proc, **kwargs):
class RemoteProgress(object):
-
"""
Handler providing an interface to parse progress information emitted by git-push
and git-fetch and to dispatch callbacks allowing subclasses to react to the progress.
@@ -171,12 +170,16 @@ class RemoteProgress(object):
STAGE_MASK = BEGIN | END
OP_MASK = ~STAGE_MASK
+ DONE_TOKEN = 'done.'
+ TOKEN_SEPARATOR = ', '
+
__slots__ = ("_cur_line", "_seen_ops")
- re_op_absolute = re.compile("(remote: )?([\w\s]+):\s+()(\d+)()(.*)")
- re_op_relative = re.compile("(remote: )?([\w\s]+):\s+(\d+)% \((\d+)/(\d+)\)(.*)")
+ re_op_absolute = re.compile(r"(remote: )?([\w\s]+):\s+()(\d+)()(.*)")
+ re_op_relative = re.compile(r"(remote: )?([\w\s]+):\s+(\d+)% \((\d+)/(\d+)\)(.*)")
def __init__(self):
self._seen_ops = list()
+ self._cur_line = None
def _parse_progress_line(self, line):
"""Parse progress information from the given line as retrieved by git-push
@@ -257,11 +260,11 @@ class RemoteProgress(object):
# END message handling
message = message.strip()
- done_token = ', done.'
- if message.endswith(done_token):
+ if message.endswith(self.DONE_TOKEN):
op_code |= self.END
- message = message[:-len(done_token)]
+ message = message[:-len(self.DONE_TOKEN)]
# END end message handling
+ message = message.strip(self.TOKEN_SEPARATOR)
self.update(op_code,
cur_count and float(cur_count),
@@ -309,10 +312,21 @@ class RemoteProgress(object):
You may read the contents of the current line in self._cur_line"""
pass
+
+class CallableRemoteProgress(RemoteProgress):
+ """An implementation forwarding updates to any callable"""
+ __slots__ = ('_callable')
+
+ def __init__(self, fn):
+ self._callable = fn
+ super(CallableRemoteProgress, self).__init__()
-class Actor(object):
+ def update(self, *args, **kwargs):
+ self._callable(*args, **kwargs)
+
+class Actor(object):
"""Actors hold information about a person acting on the repository. They
can be committers and authors or anything with a name and an email as
mentioned in the git log entries."""
diff --git a/requirements.txt b/requirements.txt
index d2d0da9..2316b96 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1 @@
-GitPython
gitdb>=0.6.4
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-git.git
More information about the Python-modules-commits
mailing list