diff --git a/.mailmap b/.mailmap index 6c74bd4..0f38635 100644 --- a/.mailmap +++ b/.mailmap @@ -18,3 +18,7 @@ Vlad Temian <vladtemian@gmail.com> Matthew Gamble <git@matthewgamble.net> Kaarel Kitsemets <kitsemets@gmail.com> + +Matthias Bartelmeß <mba@fourplusone.de> +Robert Hölzl <robert.hoelzl@posteo.de> +Anatoly Techtonik <techtonik@gmail.com> diff --git a/README.rst b/README.rst index 893b0f4..4fdb512 100644 --- a/README.rst +++ b/README.rst @@ -5,6 +5,9 @@ pygit2 - libgit2 bindings in Python .. image:: https://travis-ci.org/libgit2/pygit2.svg?branch=master :target: http://travis-ci.org/libgit2/pygit2 +.. image:: https://ci.appveyor.com/api/projects/status/edmwc0dctk5nacx0/branch/master?svg=true + :target: https://ci.appveyor.com/project/jdavid/pygit2/branch/master + Pygit2 is a set of Python bindings to the libgit2 shared library, libgit2 implements Git plumbing. Pygit2 works with Python 2.7, 3.2, 3.3, 3.4, 3.5 and PyPy 2.6 @@ -25,6 +28,27 @@ How to install Changelog ============== +0.24.2 (2016-11-01) +------------------------- + +- Unit tests pass on Windows, integration with AppVeyor + `#641 <https://github.com/libgit2/pygit2/pull/641>`_ + `#655 <https://github.com/libgit2/pygit2/issues/655>`_ + `#657 <https://github.com/libgit2/pygit2/pull/657>`_ + `#659 <https://github.com/libgit2/pygit2/pull/659>`_ + `#660 <https://github.com/libgit2/pygit2/pull/660>`_ + `#661 <https://github.com/libgit2/pygit2/pull/661>`_ + `#667 <https://github.com/libgit2/pygit2/pull/667>`_ + +- Fix when libgit2 error messages have non-ascii chars + `#651 <https://github.com/libgit2/pygit2/pull/651>`_ + +- Documentation improvements + `#643 <https://github.com/libgit2/pygit2/pull/643>`_ + `#653 <https://github.com/libgit2/pygit2/pull/653>`_ + `#663 <https://github.com/libgit2/pygit2/pull/663>`_ + + 0.24.1 (2016-06-21) ------------------------- @@ -797,30 +821,31 @@ Other: `#331 <https://github.com/libgit2/pygit2/pull/331>`_ Authors ============== -108 developers have contributed at least 1 commit to pygit2:: +112 developers have contributed at least 1 commit to pygit2:: J. David Ibáñez Carlos Martín Nieto Nico von Geyso - W. Trevor King Dave Borowitz Daniel Rodríguez Troitiño - Richo Healey Christian Boos Julien Miotte - Richard Möhn Xu Tao Jose Plana - Matthew Duggan Matthew Gamble Martin Lenders - Petr Hosek Victor Garcia Xavier Delannoy - Yonggang Luo Patrick Steinhardt Valentin Haenel - Michael Jones Bernardo Heynemann Brodie Rao - John Szakmeister Vlad Temian Nicolas Dandrimont - David Versmisse Rémi Duraffort Santiago Perez De Rosso - Sebastian Thiel Thom Wiggers Alok Singhal - Fraser Tweedale Han-Wen Nienhuys Leonardo Rhodes - Petr Viktorin Ron Cohen Thomas Kluyver - Alex Chamberlain Alexander Bayandin Amit Bakshi - Andrey Devyatkin Arno van Lumig Ben Davis - Dustin Raimondi Eric Schrijver Greg Fitzgerald - Hervé Cauwelier Huang Huang Ian P. McCullough - Igor Gnatenko Jack O'Connor Jared Flatow - Jiunn Haur Lim Jun Omae Kaarel Kitsemets - Kevin KIN-FOO Masud Rahman Michael Sondergaard - Ondřej Nový Sarath Lakshman Vicent Marti - Zoran Zaric Adam Spiers Andrew Chin + W. Trevor King Dave Borowitz Matthias Bartelmeß + Daniel Rodríguez Troitiño Richo Healey Christian Boos + Julien Miotte Richard Möhn Xu Tao + Jose Plana Matthew Duggan Matthew Gamble + Martin Lenders Petr Hosek Victor Garcia + Xavier Delannoy Yonggang Luo Patrick Steinhardt + Valentin Haenel Michael Jones Bernardo Heynemann + Brodie Rao John Szakmeister Vlad Temian + Nicolas Dandrimont David Versmisse Rémi Duraffort + Santiago Perez De Rosso Sebastian Thiel Thom Wiggers + Alok Singhal Fraser Tweedale Han-Wen Nienhuys + Leonardo Rhodes Petr Viktorin Ron Cohen + Thomas Kluyver anatoly techtonik Alex Chamberlain + Alexander Bayandin Amit Bakshi Andrey Devyatkin + Arno van Lumig Ben Davis Dustin Raimondi + Eric Schrijver Greg Fitzgerald Hervé Cauwelier + Huang Huang Ian P. McCullough Igor Gnatenko + Jack O'Connor Jared Flatow Jiunn Haur Lim + Jun Omae Kaarel Kitsemets Kevin KIN-FOO + Masud Rahman Michael Sondergaard Ondřej Nový + Sarath Lakshman Vicent Marti Zoran Zaric + mrh1997 Adam Spiers Andrew Chin András Veres-Szentkirályi Ash Berlin Benjamin Kircher Benjamin Pollack Bryan O'Sullivan Cam Cope Chason Chaffin Chris Rebert Colin Watson @@ -832,9 +857,10 @@ Authors Justin Clift Kyriakos Oikonomakos Lukas Fleischer Mathieu Bridon Nicolás Sanguinetti Noah Fontes Óscar San José Peter Dave Hello Philippe Ombredanne - Ridge Kennedy Ross Nicoll Rui Abreu Ferreira - Sheeo Soasme Vladimir Rutsky - Yu Jianjian chengyuhang earl + Ridge Kennedy Robert Hölzl Ross Nicoll + Rui Abreu Ferreira Sheeo Soasme + Vladimir Rutsky Yu Jianjian chengyuhang + earl License diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..228279f --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,49 @@ +version: 1.0.{build} +image: Visual Studio 2015 +configuration: Release +environment: + matrix: + - GENERATOR: 'Visual Studio 10' + PYTHON: 'C:\Python27\python.exe' + - GENERATOR: 'Visual Studio 10 Win64' + PYTHON: 'C:\Python27-x64\python.exe' + - GENERATOR: 'Visual Studio 10' + PYTHON: 'C:\Python33\python.exe' + - GENERATOR: 'Visual Studio 10 Win64' + PYTHON: 'C:\Python33-x64\python.exe' + - GENERATOR: 'Visual Studio 10' + PYTHON: 'C:\Python34\python.exe' + - GENERATOR: 'Visual Studio 10 Win64' + PYTHON: 'C:\Python34-x64\python.exe' + - GENERATOR: 'Visual Studio 14' + PYTHON: 'C:\Python35\python.exe' + - GENERATOR: 'Visual Studio 14 Win64' + PYTHON: 'C:\Python35-x64\python.exe' + +init: +- cmd: '%PYTHON% -m pip install -U nose wheel' +build_script: +- cmd: | + set LIBGIT2=%APPVEYOR_BUILD_FOLDER%\build\libgit2 + git clone --depth=1 -b maint/v0.24 https://github.com/libgit2/libgit2.git libgit2 + mkdir build + + cd build + cmake -DSTDCALL=OFF -DBUILD_CLAR=OFF -DCMAKE_INSTALL_PREFIX="%LIBGIT2%" ../libgit2 -G "%GENERATOR%" + cmake --build . --config Release --target install + cd .. + + IF "%GENERATOR%"=="Visual Studio 10 Win64" ( call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" ) + + "%PYTHON%" setup.py bdist_wheel +test_script: +- ps: | + cp build\Release\git2.dll . + &$env:PYTHON setup.py nosetests --with-xunit + if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) } + # upload results to AppVeyor + $wc = New-Object 'System.Net.WebClient' + $wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\nosetests.xml)) + +artifacts: +- path: dist\*.whl diff --git a/debian/changelog b/debian/changelog index 45ac85b..1395a88 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,10 +1,12 @@ -python-pygit2 (0.24.1-2) UNRELEASED; urgency=medium +python-pygit2 (0.24.2-1) unstable; urgency=medium + * New upstream release * d/s/options: extend-diff-ignore of .gitreview * d/control: Using OpenStack's Gerrit as VCS URLs. * Bumped debhelper version to 10 + * d/patches: Rebased for new release - -- Ondřej Nový <onovy@debian.org> Thu, 17 Nov 2016 16:41:17 +0100 + -- Ondřej Nový <onovy@debian.org> Thu, 17 Nov 2016 20:31:10 +0100 python-pygit2 (0.24.1-1) unstable; urgency=medium diff --git a/debian/patches/remove-broken-tests.patch b/debian/patches/remove-broken-tests.patch index 972faa9..f1f0e66 100644 --- a/debian/patches/remove-broken-tests.patch +++ b/debian/patches/remove-broken-tests.patch @@ -64,7 +64,7 @@ Last-Update: 2016-02-06 unittest.main() --- a/test/test_remote.py +++ b/test/test_remote.py -@@ -49,44 +49,6 @@ +@@ -50,44 +50,6 @@ ORIGIN_REFSPEC = '+refs/heads/*:refs/remotes/origin/*' class RepositoryTest(utils.RepoTestCase): @@ -109,7 +109,7 @@ Last-Update: 2016-02-06 def test_remote_rename(self): remote = self.repo.remotes[0] -@@ -99,22 +61,6 @@ +@@ -100,22 +62,6 @@ self.assertRaises(ValueError, self.repo.remotes.rename, None, None) @@ -132,7 +132,7 @@ Last-Update: 2016-02-06 def test_refspec(self): remote = self.repo.remotes["origin"] -@@ -156,30 +102,6 @@ +@@ -157,30 +103,6 @@ remote = self.repo.remotes["origin"] self.assertEqual(['+refs/test/*:refs/test/remotes/*'], remote.push_refspecs) @@ -165,7 +165,7 @@ Last-Update: 2016-02-06 start = sys.getrefcount(self.repo) --- a/test/test_repository.py +++ b/test/test_repository.py -@@ -527,13 +527,6 @@ +@@ -538,13 +538,6 @@ self.assertTrue('refs/remotes/custom_remote/master' in repo.listall_references()) self.assertIsNotNone(repo.remotes["custom_remote"]) diff --git a/debian/patches/removed-privacy-breach2.patch b/debian/patches/removed-privacy-breach2.patch index 592d0e0..4c99e9f 100644 --- a/debian/patches/removed-privacy-breach2.patch +++ b/debian/patches/removed-privacy-breach2.patch @@ -3,14 +3,17 @@ Author: Thomas Goirand <zigo@debian.org> Forwarded: no Last-Update: 2015-09-08 ---- python-pygit2-0.23.0.orig/docs/development.rst -+++ python-pygit2-0.23.0/docs/development.rst -@@ -2,9 +2,6 @@ +--- a/docs/development.rst ++++ b/docs/development.rst +@@ -2,12 +2,6 @@ The development version ********************************************************************** -.. image:: https://travis-ci.org/libgit2/pygit2.svg?branch=master - :target: http://travis-ci.org/libgit2/pygit2 +- +-.. image:: https://ci.appveyor.com/api/projects/status/edmwc0dctk5nacx0/branch/master?svg=true +- :target: https://ci.appveyor.com/project/jdavid/pygit2/branch/master - .. code-block:: sh diff --git a/docs/conf.py b/docs/conf.py index e98c238..9cff9b1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -52,7 +52,7 @@ copyright = u'2010-2015 The pygit2 contributors' # The short X.Y version. version = '0.24' # The full version, including alpha/beta/rc tags. -release = '0.24.0' +release = '0.24.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/development.rst b/docs/development.rst index d9ecf83..fc9b1c2 100644 --- a/docs/development.rst +++ b/docs/development.rst @@ -5,6 +5,9 @@ The development version .. image:: https://travis-ci.org/libgit2/pygit2.svg?branch=master :target: http://travis-ci.org/libgit2/pygit2 +.. image:: https://ci.appveyor.com/api/projects/status/edmwc0dctk5nacx0/branch/master?svg=true + :target: https://ci.appveyor.com/project/jdavid/pygit2/branch/master + .. code-block:: sh $ git clone git://github.com/libgit2/pygit2.git diff --git a/docs/general.rst b/docs/general.rst index 4afdcaa..d17490f 100644 --- a/docs/general.rst +++ b/docs/general.rst @@ -18,7 +18,7 @@ library that has been built against. The version number has a .. py:data:: LIBGIT2_VER_MAJOR Integer value of the major version number. For example, for the version - ``0.24.1``:: + ``0.24.2``:: >>> print LIBGIT2_VER_MAJOR 0 @@ -26,7 +26,7 @@ library that has been built against. The version number has a .. py:data:: LIBGIT2_VER_MINOR Integer value of the minor version number. For example, for the version - ``0.24.1``:: + ``0.24.2``:: >>> print LIBGIT2_VER_MINOR 24 @@ -34,17 +34,17 @@ library that has been built against. The version number has a .. py:data:: LIBGIT2_VER_REVISION Integer value of the revision version number. For example, for the version - ``0.24.1``:: + ``0.24.2``:: >>> print LIBGIT2_VER_REVISION - 1 + 2 .. py:data:: LIBGIT2_VERSION The libgit2 version number as a string:: >>> print LIBGIT2_VERSION - '0.24.1' + '0.24.2' Errors ====== diff --git a/docs/install.rst b/docs/install.rst index e89e841..094333e 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -43,11 +43,11 @@ while the last number |lq| *.micro* |rq| auto-increments independently. As illustration see this table of compatible releases: -+-----------+----------------+----------------------------------------+ -|**libgit2**| 0.24.0, 0.24.1 | 0.23.0, 0.23.1, 0.23.2, 0.23.3, 0.23.4 | -+-----------+----------------+----------------------------------------+ -|**pygit2** | 0.24.0, 0.24.1 | 0.23.0, 0.23.1, 0.23.2, 0.23.3 | -+-----------+----------------+----------------------------------------+ ++-----------+-----------------------+----------------------------------------+ +|**libgit2**| 0.24.0, 0.24.1 0.24.2 | 0.23.0, 0.23.1, 0.23.2, 0.23.3, 0.23.4 | ++-----------+-----------------------+----------------------------------------+ +|**pygit2** | 0.24.0, 0.24.1 0.24.2 | 0.23.0, 0.23.1, 0.23.2, 0.23.3 | ++-----------+-----------------------+----------------------------------------+ .. warning:: @@ -64,9 +64,9 @@ directory, do: .. code-block:: sh - $ wget https://github.com/libgit2/libgit2/archive/v0.24.1.tar.gz - $ tar xzf v0.24.1.tar.gz - $ cd libgit2-0.24.1/ + $ wget https://github.com/libgit2/libgit2/archive/v0.24.2.tar.gz + $ tar xzf v0.24.2.tar.gz + $ cd libgit2-0.24.2/ $ cmake . $ make $ sudo make install diff --git a/docs/repository.rst b/docs/repository.rst index ff88007..ca85788 100644 --- a/docs/repository.rst +++ b/docs/repository.rst @@ -73,3 +73,4 @@ Below there are some general attributes and methods: .. automethod:: pygit2.Repository.ahead_behind .. automethod:: pygit2.Repository.describe .. automethod:: pygit2.Repository.path_is_ignored +.. automethod:: pygit2.Repository.create_reference diff --git a/pygit2/_build.py b/pygit2/_build.py index c9a0b9c..2ef2b4c 100644 --- a/pygit2/_build.py +++ b/pygit2/_build.py @@ -37,7 +37,7 @@ from os import getenv # # The version number of pygit2 # -__version__ = '0.24.1' +__version__ = '0.24.2' # diff --git a/pygit2/errors.py b/pygit2/errors.py index e814440..57c155c 100644 --- a/pygit2/errors.py +++ b/pygit2/errors.py @@ -40,7 +40,7 @@ def check_error(err, io=False): # Error message giterr = C.giterr_last() if giterr != ffi.NULL: - message = ffi.string(giterr.message).decode() + message = ffi.string(giterr.message).decode('utf8') else: message = "err %d (no message provided)" % err @@ -64,4 +64,6 @@ def check_error(err, io=False): raise GitError(message) # Indicate that we want libgit2 to pretend a function was not set -Passthrough = Exception("The function asked for pass-through") +class Passthrough(Exception): + def __init__(self): + super(Passthrough, self).__init__( "The function asked for pass-through") diff --git a/pygit2/index.py b/pygit2/index.py index d312bb6..f36a0d1 100644 --- a/pygit2/index.py +++ b/pygit2/index.py @@ -28,6 +28,8 @@ # Import from the future from __future__ import absolute_import, unicode_literals +import weakref + # Import from pygit2 from _pygit2 import Oid, Tree, Diff from .errors import check_error @@ -305,10 +307,12 @@ class Index(object): self._conflicts = None return None - if self._conflicts is None: - self._conflicts = ConflictCollection(self) + if self._conflicts is None or self._conflicts() is None: + conflicts = ConflictCollection(self) + self._conflicts = weakref.ref(conflicts) + return conflicts - return self._conflicts + return self._conflicts() class IndexEntry(object): diff --git a/pygit2/remote.py b/pygit2/remote.py index 431b356..4ccf6ff 100644 --- a/pygit2/remote.py +++ b/pygit2/remote.py @@ -278,11 +278,9 @@ class RemoteCallbacks(object): try: ccred = get_credentials(credentials, url, username, allowed) cred_out[0] = ccred[0] - + except Passthrough as e: + return C.GIT_PASSTHROUGH except Exception as e: - if e is Passthrough: - return C.GIT_PASSTHROUGH - self._stored_exception = e return C.GIT_EUSER @@ -308,15 +306,14 @@ class RemoteCallbacks(object): val = certificate_check(None, bool(valid), ffi.string(host)) if not val: return C.GIT_ECERTIFICATE + except Passthrough as e: + if is_ssh: + return 0 + elif valid: + return 0 + else: + return C.GIT_ECERTIFICATE except Exception as e: - if e is Passthrough: - if is_ssh: - return 0 - elif valid: - return 0 - else: - return C.GIT_ECERTIFICATE - self._stored_exception = e return C.GIT_EUSER @@ -416,6 +413,12 @@ class Remote(object): """Push the given refspec to the remote. Raises ``GitError`` on protocol error or unpack failure. + When the remote has a githook installed, that denies the reference + this function will return successfully. Thus it is stronly recommended + to install a callback, that implements + :py:meth:`RemoteCallbacks.push_update_reference` and check the passed + parameters for successfull operations. + :param [str] specs: push refspecs to use """ push_opts = ffi.new('git_push_options *') diff --git a/pygit2/repository.py b/pygit2/repository.py index 693d7a4..aeeb981 100644 --- a/pygit2/repository.py +++ b/pygit2/repository.py @@ -322,8 +322,23 @@ class Repository(_Repository): Keyword arguments: + a + None, a str (that refers to an Object, see revparse_single()) or a + Reference object. + If None, b must be None, too. In this case the working directory is + compared with the index. Otherwise the referred object is compared to + 'b'. + + b + None, a str (that refers to an Object, see revparse_single()) or a + Reference object. + If None, the working directory is compared to 'a'. (except + 'cached' is True, in which case the index is compared to 'a'). + Otherwise the referred object is compared to 'a' + cached - use staged changes instead of workdir + if 'b' is None, by default the working directory is compared to 'a'. + If 'cached' is set to True, the index/staging area is used for comparing. flag a GIT_DIFF_* constant diff --git a/test/test_remote.py b/test/test_remote.py index 489a6ae..5d76f06 100644 --- a/test/test_remote.py +++ b/test/test_remote.py @@ -33,6 +33,7 @@ import pygit2 import sys from pygit2 import Oid from . import utils +import gc try: import __pypy__ @@ -238,6 +239,11 @@ class PushTestCase(unittest.TestCase): self.remote = self.clone.create_remote('origin', self.origin.path) def tearDown(self): + self.origin = None + self.clone = None + self.remote = None + gc.collect() + self.origin_ctxtmgr.__exit__(None, None, None) self.clone_ctxtmgr.__exit__(None, None, None) diff --git a/test/test_repository.py b/test/test_repository.py index 5590ea2..cfdf01e 100644 --- a/test/test_repository.py +++ b/test/test_repository.py @@ -41,6 +41,12 @@ import sys import six +if six.PY2: + from urllib import pathname2url + +if six.PY3: + from urllib.request import pathname2url + # Import from pygit2 from pygit2 import GIT_OBJ_ANY, GIT_OBJ_BLOB, GIT_OBJ_COMMIT from pygit2 import init_repository, clone_repository, discover_repository @@ -192,8 +198,8 @@ class RepositoryTest(utils.BareRepoTestCase): def test_hashfile(self): data = "bazbarfoo" - tempfile_path = tempfile.mkstemp()[1] - with open(tempfile_path, 'w') as fh: + handle, tempfile_path = tempfile.mkstemp() + with os.fdopen(handle, 'w') as fh: fh.write(data) hashed_sha1 = hashfile(tempfile_path) os.unlink(tempfile_path) @@ -513,7 +519,12 @@ class CloneRepositoryTest(utils.NoRepoTestCase): def test_clone_repository_and_remote_callbacks(self): src_repo_relpath = "./test/data/testrepo.git/" repo_path = os.path.join(self._temp_dir, "clone-into") - url = 'file://' + os.path.realpath(src_repo_relpath) + url = pathname2url(os.path.realpath(src_repo_relpath)) + + if url.startswith('///'): + url = 'file:' + url + else: + url = 'file://' + url def create_repository(path, bare): return init_repository(path, bare) diff --git a/test/utils.py b/test/utils.py index a751e91..01c07b5 100644 --- a/test/utils.py +++ b/test/utils.py @@ -35,6 +35,7 @@ import tarfile import tempfile import unittest import hashlib +import gc import pygit2 @@ -94,6 +95,7 @@ class NoRepoTestCase(unittest.TestCase): def tearDown(self): del self.repo + gc.collect() rmtree(self._temp_dir) def assertRaisesAssign(self, exc_class, instance, name, value): @@ -132,8 +134,8 @@ class AutoRepoTestCase(NoRepoTestCase): self.repo = pygit2.Repository(self.repo_path) def tearDown(self): - self.repo_ctxtmgr.__exit__(None, None, None) super(AutoRepoTestCase, self).tearDown() + self.repo_ctxtmgr.__exit__(None, None, None) class BareRepoTestCase(AutoRepoTestCase):