Compare commits
156 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
371c97cadb | ||
![]() |
ab3bb01249 | ||
![]() |
62c70e852d | ||
![]() |
e81f45c4c6 | ||
![]() |
295166bb64 | ||
![]() |
96d37e16a9 | ||
![]() |
2ce8b952c4 | ||
![]() |
e41f71f458 | ||
![]() |
c6305a062b | ||
![]() |
87beb76dcc | ||
![]() |
f18de427bf | ||
![]() |
f841c62fa6 | ||
![]() |
035d4a9396 | ||
![]() |
21d668421f | ||
![]() |
b88dc86842 | ||
![]() |
8559b2da20 | ||
![]() |
9325494d6f | ||
![]() |
74717bed55 | ||
![]() |
3818555e14 | ||
![]() |
706c60c4ab | ||
![]() |
0733ba4da3 | ||
![]() |
320ee5e733 | ||
![]() |
d6716e035a | ||
![]() |
d14438725e | ||
![]() |
dd57c9b366 | ||
![]() |
f2c89a760a | ||
![]() |
f37cf25b8e | ||
![]() |
11ff7a99eb | ||
![]() |
9335819795 | ||
![]() |
784583d21e | ||
![]() |
b81810e9cb | ||
![]() |
7ee851273a | ||
![]() |
1fadc2eae0 | ||
![]() |
453fd8a9a3 | ||
![]() |
630d905e73 | ||
![]() |
9be907983f | ||
![]() |
b31ac50210 | ||
![]() |
da233b16c5 | ||
![]() |
1a842ff8bd | ||
![]() |
cbbf9f1f87 | ||
![]() |
a294655aa5 | ||
![]() |
5a940987cd | ||
![]() |
354d56a95c | ||
![]() |
8327e1bee3 | ||
![]() |
15326b731f | ||
![]() |
f5cd6da307 | ||
![]() |
803b1cb154 | ||
![]() |
d622e87654 | ||
![]() |
819cbff552 | ||
![]() |
4fbc1f1c05 | ||
![]() |
5c061cbb0a | ||
![]() |
68817aad4f | ||
![]() |
0b513d57fa | ||
![]() |
074a726d7f | ||
![]() |
950249442e | ||
![]() |
809fe33b8a | ||
![]() |
6402302002 | ||
![]() |
77f0585645 | ||
![]() |
acdec78617 | ||
![]() |
66280af83a | ||
![]() |
b2a34bd901 | ||
![]() |
44ef9ad2e9 | ||
![]() |
db213113f4 | ||
![]() |
ee28de65a0 | ||
![]() |
825f3e45bd | ||
![]() |
00dd78bf1b | ||
![]() |
e2393a5e24 | ||
![]() |
da59cb1c92 | ||
![]() |
e873c6a363 | ||
![]() |
865c2f0e82 | ||
![]() |
6d6931cd26 | ||
![]() |
9b364dc7f3 | ||
![]() |
578cf58cd7 | ||
![]() |
554f167353 | ||
![]() |
54e4da837b | ||
![]() |
faf6a63d25 | ||
![]() |
30980751cf | ||
![]() |
dae61ded38 | ||
![]() |
0e270c72bd | ||
![]() |
1afbde0d7f | ||
![]() |
7fe7a4da8d | ||
![]() |
fd1e9e3d35 | ||
![]() |
cdd57b2c0f | ||
![]() |
ffc514fa24 | ||
![]() |
c57a3aeb22 | ||
![]() |
ca444f3c7d | ||
![]() |
96beae5c82 | ||
![]() |
68de0f8bb6 | ||
![]() |
df53551cb2 | ||
![]() |
5864b17b57 | ||
![]() |
6c4fa88d07 | ||
![]() |
e96d0286b8 | ||
![]() |
4fa43e234e | ||
![]() |
4416f65fe1 | ||
![]() |
5dcc793aff | ||
![]() |
30f539ff35 | ||
![]() |
df30f9213f | ||
![]() |
50c0569cf0 | ||
![]() |
d8fd2e78d8 | ||
![]() |
fd9a39a91b | ||
![]() |
270dad8cd3 | ||
![]() |
51915ddf0e | ||
![]() |
f2864c0511 | ||
![]() |
456bf59a88 | ||
![]() |
22021c67fc | ||
![]() |
c1d831c98a | ||
![]() |
391a3a74e9 | ||
![]() |
141f0abe62 | ||
![]() |
6b926494db | ||
![]() |
cde5b5170b | ||
![]() |
735510f14d | ||
![]() |
bc424e342f | ||
![]() |
3470fbc1c6 | ||
![]() |
487fb5913e | ||
![]() |
33cf1a1ca2 | ||
![]() |
95ad6b1b0a | ||
![]() |
fa60e2233d | ||
![]() |
daff45f2d4 | ||
![]() |
a5cfea21a7 | ||
![]() |
99dfce9ab8 | ||
![]() |
7a8474cd44 | ||
![]() |
91bb93d266 | ||
![]() |
13f4ddec1d | ||
![]() |
f92d38e25f | ||
![]() |
70edbf256a | ||
![]() |
203335bd63 | ||
![]() |
64150d3535 | ||
![]() |
d25a0d61de | ||
![]() |
f5aa1829ac | ||
![]() |
9db8737364 | ||
![]() |
cf439e4286 | ||
![]() |
eadc2a320f | ||
![]() |
2b083a1509 | ||
![]() |
681c7d4341 | ||
![]() |
8a66da1278 | ||
![]() |
0d2bc05708 | ||
![]() |
b8e6852d26 | ||
![]() |
563cb9018e | ||
![]() |
ac2e363d04 | ||
![]() |
ab97c08f72 | ||
![]() |
7b97ade6ce | ||
![]() |
e4ef8ea5c2 | ||
![]() |
50f4b20e7d | ||
![]() |
802976535a | ||
![]() |
ade211de60 | ||
![]() |
8911416d4f | ||
![]() |
4b607b8256 | ||
![]() |
ec23762c09 | ||
![]() |
ac7738bbb3 | ||
![]() |
29a8dbc6b2 | ||
![]() |
f28a199351 | ||
![]() |
becc265c78 | ||
![]() |
25d02259df | ||
![]() |
38b1975991 | ||
![]() |
9cce003efe | ||
![]() |
78d134c016 |
.gitignore.mailmap.travis.sh.travis.ymlCHANGELOG.rstREADME.rstappveyor.yml
docs
backends.rstconf.pydevelopment.rstdiff.rstgeneral.rstindex.rstinstall.rstobjects.rst
recipes
references.rstremotes.rstrepository.rstsubmodule.rstworking-copy.rstpygit2
__init__.py_build.py_run.pyblame.pyconfig.pycredentials.pydecl.herrors.pyffi.pyindex.pypy2.pypy3.pyrefspec.pyremote.pyrepository.pysettings.pysubmodule.pyutils.py
setup.pysrc
blob.cblob.hbranch.cbranch.hcommit.ccommit.hdiff.cdiff.herror.cerror.hnote.cnote.hobject.cobject.hoid.coid.hoptions.coptions.hpatch.cpatch.hpygit2.creference.creference.hrepository.crepository.hsignature.csignature.htag.ctag.htree.ctree.htreebuilder.ctreebuilder.htypes.hutils.cutils.hwalker.cwalker.h
test
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,6 +3,7 @@ build
|
|||||||
dist
|
dist
|
||||||
pygit2.so
|
pygit2.so
|
||||||
_pygit2.so
|
_pygit2.so
|
||||||
|
.tox/
|
||||||
test/*.pyc
|
test/*.pyc
|
||||||
test/__pycache__
|
test/__pycache__
|
||||||
pygit2/*.pyc
|
pygit2/*.pyc
|
||||||
|
8
.mailmap
8
.mailmap
@ -18,3 +18,11 @@ Vlad Temian <vladtemian@gmail.com>
|
|||||||
Matthew Gamble <git@matthewgamble.net>
|
Matthew Gamble <git@matthewgamble.net>
|
||||||
|
|
||||||
Kaarel Kitsemets <kitsemets@gmail.com>
|
Kaarel Kitsemets <kitsemets@gmail.com>
|
||||||
|
|
||||||
|
Matthias Bartelmeß <mba@fourplusone.de>
|
||||||
|
Robert Hölzl <robert.hoelzl@posteo.de>
|
||||||
|
Anatoly Techtonik <techtonik@gmail.com>
|
||||||
|
|
||||||
|
Guillermo Pérez <bisho@fb.com> <bisho@freedreams.org>
|
||||||
|
Matthew Duggan <mduggan@qti.qualcomm.com> <mgithub@guarana.org>
|
||||||
|
Alexander Bayandin <a.bayandin@gmail.com> <bayandin@users.noreply.github.com>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
cd ~
|
cd ~
|
||||||
|
|
||||||
git clone --depth=1 -b maint/v0.23 https://github.com/libgit2/libgit2.git
|
git clone --depth=1 -b maint/v0.26 https://github.com/libgit2/libgit2.git
|
||||||
cd libgit2/
|
cd libgit2/
|
||||||
|
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
|
@ -2,11 +2,12 @@ language: python
|
|||||||
|
|
||||||
python:
|
python:
|
||||||
- "2.7"
|
- "2.7"
|
||||||
- "3.2"
|
|
||||||
- "3.3"
|
- "3.3"
|
||||||
- "3.4"
|
- "3.4"
|
||||||
|
- "3.5"
|
||||||
|
- "3.6"
|
||||||
- "pypy"
|
- "pypy"
|
||||||
- "pypy3"
|
# - "pypy3"
|
||||||
|
|
||||||
env: LIBGIT2=~/libgit2/_install/ LD_LIBRARY_PATH=~/libgit2/_install/lib
|
env: LIBGIT2=~/libgit2/_install/ LD_LIBRARY_PATH=~/libgit2/_install/lib
|
||||||
|
|
||||||
|
859
CHANGELOG.rst
Normal file
859
CHANGELOG.rst
Normal file
@ -0,0 +1,859 @@
|
|||||||
|
0.26.0 (2017-07-06)
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
- Update to libgit2 v0.26
|
||||||
|
`#713 <https://github.com/libgit2/pygit2/pull/713>`_
|
||||||
|
|
||||||
|
- Drop support for Python 3.2, add support for cffi 1.10
|
||||||
|
`#706 <https://github.com/libgit2/pygit2/pull/706>`_
|
||||||
|
`#694 <https://github.com/libgit2/pygit2/issues/694>`_
|
||||||
|
|
||||||
|
- New ``Repository.revert_commit(...)``
|
||||||
|
`#711 <https://github.com/libgit2/pygit2/pull/711>`_
|
||||||
|
`#710 <https://github.com/libgit2/pygit2/issues/710>`_
|
||||||
|
|
||||||
|
- New ``Branch.is_checked_out()``
|
||||||
|
`#696 <https://github.com/libgit2/pygit2/pull/696>`_
|
||||||
|
|
||||||
|
- Various fixes
|
||||||
|
`#706 <https://github.com/libgit2/pygit2/pull/706>`_
|
||||||
|
`#707 <https://github.com/libgit2/pygit2/pull/707>`_
|
||||||
|
`#708 <https://github.com/libgit2/pygit2/pull/708>`_
|
||||||
|
|
||||||
|
|
||||||
|
0.25.1 (2017-04-25)
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
- Add suport for Python 3.6
|
||||||
|
|
||||||
|
- New support for stash: repository methods ``stash``, ``stash_apply``,
|
||||||
|
``stash_drop`` and ``stash_pop``
|
||||||
|
`#695 <https://github.com/libgit2/pygit2/pull/695>`_
|
||||||
|
|
||||||
|
- Improved support for submodules: new repository methods ``init_submodules``
|
||||||
|
and ``update_submodules``
|
||||||
|
`#692 <https://github.com/libgit2/pygit2/pull/692>`_
|
||||||
|
|
||||||
|
- New friendlier API for branches & references: ``Repository.branches`` and
|
||||||
|
``Repository.references``
|
||||||
|
`#700 <https://github.com/libgit2/pygit2/pull/700>`_
|
||||||
|
`#701 <https://github.com/libgit2/pygit2/pull/701>`_
|
||||||
|
|
||||||
|
- New support for custom backends
|
||||||
|
`#690 <https://github.com/libgit2/pygit2/pull/690>`_
|
||||||
|
|
||||||
|
- Fix ``init_repository`` crash on None input
|
||||||
|
`#688 <https://github.com/libgit2/pygit2/issues/688>`_
|
||||||
|
`#697 <https://github.com/libgit2/pygit2/pull/697>`_
|
||||||
|
|
||||||
|
- Fix checkout with an orphan master branch
|
||||||
|
`#669 <https://github.com/libgit2/pygit2/issues/669>`_
|
||||||
|
`#685 <https://github.com/libgit2/pygit2/pull/685>`_
|
||||||
|
|
||||||
|
- Better error messages for opening repositories
|
||||||
|
`#645 <https://github.com/libgit2/pygit2/issues/645>`_
|
||||||
|
`#698 <https://github.com/libgit2/pygit2/pull/698>`_
|
||||||
|
|
||||||
|
|
||||||
|
0.25.0 (2016-12-26)
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
- Upgrade to libgit2 0.25
|
||||||
|
`#670 <https://github.com/libgit2/pygit2/pull/670>`_
|
||||||
|
|
||||||
|
- Now Commit.tree raises an error if tree is not found
|
||||||
|
`#682 <https://github.com/libgit2/pygit2/pull/682>`_
|
||||||
|
|
||||||
|
- New settings.mwindow_mapped_limit, cached_memory, enable_caching,
|
||||||
|
cache_max_size and cache_object_limit
|
||||||
|
`#677 <https://github.com/libgit2/pygit2/pull/677>`_
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
- New ``Repository.listall_reference_objects()``
|
||||||
|
`#634 <https://github.com/libgit2/pygit2/pull/634>`_
|
||||||
|
|
||||||
|
- Fix ``Repository.write_archive(...)``
|
||||||
|
`#619 <https://github.com/libgit2/pygit2/pull/619>`_
|
||||||
|
`#621 <https://github.com/libgit2/pygit2/pull/621>`_
|
||||||
|
|
||||||
|
- Reproducible builds
|
||||||
|
`#636 <https://github.com/libgit2/pygit2/pull/636>`_
|
||||||
|
|
||||||
|
- Documentation fixes
|
||||||
|
`#606 <https://github.com/libgit2/pygit2/pull/606>`_
|
||||||
|
`#607 <https://github.com/libgit2/pygit2/pull/607>`_
|
||||||
|
`#609 <https://github.com/libgit2/pygit2/pull/609>`_
|
||||||
|
`#623 <https://github.com/libgit2/pygit2/pull/623>`_
|
||||||
|
|
||||||
|
- Test updates
|
||||||
|
`#629 <https://github.com/libgit2/pygit2/pull/629>`_
|
||||||
|
|
||||||
|
|
||||||
|
0.24.0 (2016-03-05)
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
- Update to libgit2 v0.24
|
||||||
|
`#594 <https://github.com/libgit2/pygit2/pull/594>`_
|
||||||
|
|
||||||
|
- Support Python 3.5
|
||||||
|
|
||||||
|
- New dependency, `six <https://pypi.python.org/pypi/six/>`_
|
||||||
|
|
||||||
|
- New ``Repository.path_is_ignored(path)``
|
||||||
|
`#589 <https://github.com/libgit2/pygit2/pull/589>`_
|
||||||
|
|
||||||
|
- Fix error in ``Repository(path)`` when path is a bytes string
|
||||||
|
`#588 <https://github.com/libgit2/pygit2/issues/588>`_
|
||||||
|
`#593 <https://github.com/libgit2/pygit2/pull/593>`_
|
||||||
|
|
||||||
|
- Fix memory issue in ``Repository.describe(...)``
|
||||||
|
`#592 <https://github.com/libgit2/pygit2/issues/592>`_
|
||||||
|
`#597 <https://github.com/libgit2/pygit2/issues/597>`_
|
||||||
|
`#599 <https://github.com/libgit2/pygit2/pull/599>`_
|
||||||
|
|
||||||
|
- Allow testing with `tox <https://pypi.python.org/pypi/tox/>`_
|
||||||
|
`#600 <https://github.com/libgit2/pygit2/pull/600>`_
|
||||||
|
|
||||||
|
|
||||||
|
0.23.3 (2016-01-01)
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
- New ``Repository.create_blob_fromiobase(...)``
|
||||||
|
`#490 <https://github.com/libgit2/pygit2/pull/490>`_
|
||||||
|
`#577 <https://github.com/libgit2/pygit2/pull/577>`_
|
||||||
|
|
||||||
|
- New ``Repository.describe(...)``
|
||||||
|
`#585 <https://github.com/libgit2/pygit2/pull/585>`_
|
||||||
|
|
||||||
|
- Fix ``Signature`` default encoding, UTF-8 now
|
||||||
|
`#581 <https://github.com/libgit2/pygit2/issues/581>`_
|
||||||
|
|
||||||
|
- Fixing ``pip install pygit2``, should install cffi first
|
||||||
|
|
||||||
|
- Unit tests, fix binary diff test
|
||||||
|
`#586 <https://github.com/libgit2/pygit2/pull/586>`_
|
||||||
|
|
||||||
|
- Document that ``Diff.patch`` can be ``None``
|
||||||
|
`#587 <https://github.com/libgit2/pygit2/pull/587>`_
|
||||||
|
|
||||||
|
|
||||||
|
0.23.2 (2015-10-11)
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
- Unify callbacks system for remotes and clone
|
||||||
|
`#568 <https://github.com/libgit2/pygit2/pull/568>`_
|
||||||
|
|
||||||
|
- New ``TreeEntry._name``
|
||||||
|
`#570 <https://github.com/libgit2/pygit2/pull/570>`_
|
||||||
|
|
||||||
|
- Fix segfault in ``Tag._message``
|
||||||
|
`#572 <https://github.com/libgit2/pygit2/pull/572>`_
|
||||||
|
|
||||||
|
- Documentation improvements
|
||||||
|
`#569 <https://github.com/libgit2/pygit2/pull/569>`_
|
||||||
|
`#574 <https://github.com/libgit2/pygit2/pull/574>`_
|
||||||
|
|
||||||
|
API changes to clone::
|
||||||
|
|
||||||
|
# Before
|
||||||
|
clone_repository(..., credentials, certificate)
|
||||||
|
|
||||||
|
# Now
|
||||||
|
callbacks = RemoteCallbacks(credentials, certificate)
|
||||||
|
clone_repository(..., callbacks)
|
||||||
|
|
||||||
|
API changes to remote::
|
||||||
|
|
||||||
|
# Before
|
||||||
|
def transfer_progress(stats):
|
||||||
|
...
|
||||||
|
|
||||||
|
remote.credentials = credentials
|
||||||
|
remote.transfer_progress = transfer_progress
|
||||||
|
remote.fetch()
|
||||||
|
remote.push(specs)
|
||||||
|
|
||||||
|
# Now
|
||||||
|
class MyCallbacks(RemoteCallbacks):
|
||||||
|
def transfer_progress(self, stats):
|
||||||
|
...
|
||||||
|
|
||||||
|
callbacks = MyCallbacks(credentials)
|
||||||
|
remote.fetch(callbacks=callbacks)
|
||||||
|
remote.push(specs, callbacks=callbacks)
|
||||||
|
|
||||||
|
|
||||||
|
0.23.1 (2015-09-26)
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
- Improve support for cffi 1.0+
|
||||||
|
`#529 <https://github.com/libgit2/pygit2/pull/529>`_
|
||||||
|
`#561 <https://github.com/libgit2/pygit2/pull/561>`_
|
||||||
|
|
||||||
|
- Fix ``Remote.push``
|
||||||
|
`#557 <https://github.com/libgit2/pygit2/pull/557>`_
|
||||||
|
|
||||||
|
- New ``TreeEntry.type``
|
||||||
|
`#560 <https://github.com/libgit2/pygit2/pull/560>`_
|
||||||
|
|
||||||
|
- New ``pygit2.GIT_DIFF_SHOW_BINARY``
|
||||||
|
`#566 <https://github.com/libgit2/pygit2/pull/566>`_
|
||||||
|
|
||||||
|
|
||||||
|
0.23.0 (2015-08-14)
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
- Update to libgit2 v0.23
|
||||||
|
`#540 <https://github.com/libgit2/pygit2/pull/540>`_
|
||||||
|
|
||||||
|
- Now ``Repository.merge_base(...)`` returns ``None`` if no merge base is found
|
||||||
|
`#550 <https://github.com/libgit2/pygit2/pull/550>`_
|
||||||
|
|
||||||
|
- Documentation updates
|
||||||
|
`#547 <https://github.com/libgit2/pygit2/pull/547>`_
|
||||||
|
|
||||||
|
API changes:
|
||||||
|
|
||||||
|
- How to set identity (aka signature) in a reflog has changed::
|
||||||
|
|
||||||
|
# Before
|
||||||
|
signature = Signature('foo', 'bar')
|
||||||
|
...
|
||||||
|
reference.set_target(target, signature=signature, message=message)
|
||||||
|
repo.set_head(target, signature=signature)
|
||||||
|
remote.fetch(signature=signature)
|
||||||
|
remote.push(signature=signature)
|
||||||
|
|
||||||
|
# Now
|
||||||
|
repo.set_ident('foo', 'bar')
|
||||||
|
...
|
||||||
|
reference.set_target(target, message=message)
|
||||||
|
repo.set_head(target)
|
||||||
|
remote.push()
|
||||||
|
|
||||||
|
# The current identity can be get with
|
||||||
|
repo.ident
|
||||||
|
|
||||||
|
- Some remote setters have been replaced by methods::
|
||||||
|
|
||||||
|
# Before # Now
|
||||||
|
Remote.url = url Repository.remotes.set_url(name, url)
|
||||||
|
Remote.push_url = url Repository.remotes.set_push_url(name, url)
|
||||||
|
|
||||||
|
Remote.add_fetch(refspec) Repository.remotes.add_fetch(name, refspec)
|
||||||
|
Remote.add_push(refspec) Repository.remotes.add_push(name, refspec)
|
||||||
|
|
||||||
|
Remote.fetch_refspecs = [...] removed, use the config API instead
|
||||||
|
Remote.push_refspecs = [...] removed, use the config API instead
|
||||||
|
|
||||||
|
|
||||||
|
0.22.1 (2015-07-12)
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Diff interface refactoring
|
||||||
|
`#346 <https://github.com/libgit2/pygit2/pull/346>`_
|
||||||
|
(in progress):
|
||||||
|
|
||||||
|
- New ``iter(pygit2.Blame)``
|
||||||
|
|
||||||
|
- New ``pygit2.DiffDelta``, ``pygit2.DiffFile`` and ``pygit.DiffLine``
|
||||||
|
|
||||||
|
- API changes, translation table::
|
||||||
|
|
||||||
|
Hunk => DiffHunk
|
||||||
|
Patch.old_file_path => Patch.delta.old_file.path
|
||||||
|
Patch.new_file_path => Patch.delta.new_file.path
|
||||||
|
Patch.old_id => Patch.delta.old_file.id
|
||||||
|
Patch.new_id => Patch.delta.new_file.id
|
||||||
|
Patch.status => Patch.delta.status
|
||||||
|
Patch.similarity => Patch.delta.similarity
|
||||||
|
Patch.is_binary => Patch.delta.is_binary
|
||||||
|
Patch.additions => Patch.line_stats[1]
|
||||||
|
Patch.deletions => Patch.line_stats[2]
|
||||||
|
|
||||||
|
- ``DiffHunk.lines`` is now a list of ``DiffLine`` objects, not tuples
|
||||||
|
|
||||||
|
New features:
|
||||||
|
|
||||||
|
- New ``Repository.expand_id(...)`` and ``Repository.ahead_behind(...)``
|
||||||
|
`#448 <https://github.com/libgit2/pygit2/pull/448>`_
|
||||||
|
|
||||||
|
- New ``prefix`` parameter in ``Repository.write_archive``
|
||||||
|
`#481 <https://github.com/libgit2/pygit2/pull/481>`_
|
||||||
|
|
||||||
|
- New ``Repository.merge_trees(...)``
|
||||||
|
`#489 <https://github.com/libgit2/pygit2/pull/489>`_
|
||||||
|
|
||||||
|
- New ``Repository.cherrypick(...)``
|
||||||
|
`#436 <https://github.com/libgit2/pygit2/issues/436>`_
|
||||||
|
`#492 <https://github.com/libgit2/pygit2/pull/492>`_
|
||||||
|
|
||||||
|
- New support for submodules
|
||||||
|
`#499 <https://github.com/libgit2/pygit2/pull/499>`_
|
||||||
|
`#514 <https://github.com/libgit2/pygit2/pull/514>`_
|
||||||
|
|
||||||
|
- New ``Repository.merge_file_from_index(...)``
|
||||||
|
`#503 <https://github.com/libgit2/pygit2/pull/503>`_
|
||||||
|
|
||||||
|
- Now ``Repository.diff`` supports diffing two blobs
|
||||||
|
`#508 <https://github.com/libgit2/pygit2/pull/508>`_
|
||||||
|
|
||||||
|
- New optional ``fetch`` parameter in ``Remote.create``
|
||||||
|
`#526 <https://github.com/libgit2/pygit2/pull/526>`_
|
||||||
|
|
||||||
|
- New ``pygit2.DiffStats``
|
||||||
|
`#406 <https://github.com/libgit2/pygit2/issues/406>`_
|
||||||
|
`#525 <https://github.com/libgit2/pygit2/pull/525>`_
|
||||||
|
|
||||||
|
- New ``Repository.get_attr(...)``
|
||||||
|
`#528 <https://github.com/libgit2/pygit2/pull/528>`_
|
||||||
|
|
||||||
|
- New ``level`` optional parameter in ``Index.remove``
|
||||||
|
`#533 <https://github.com/libgit2/pygit2/pull/533>`_
|
||||||
|
|
||||||
|
- New ``repr(TreeEntry)``
|
||||||
|
`#543 <https://github.com/libgit2/pygit2/pull/543>`_
|
||||||
|
|
||||||
|
Build and install improvements:
|
||||||
|
|
||||||
|
- Make pygit work in a frozen environment
|
||||||
|
`#453 <https://github.com/libgit2/pygit2/pull/453>`_
|
||||||
|
|
||||||
|
- Make pygit2 work with pyinstaller
|
||||||
|
`#510 <https://github.com/libgit2/pygit2/pull/510>`_
|
||||||
|
|
||||||
|
Bugs fixed:
|
||||||
|
|
||||||
|
- Fix memory issues
|
||||||
|
`#477 <https://github.com/libgit2/pygit2/issues/477>`_
|
||||||
|
`#487 <https://github.com/libgit2/pygit2/pull/487>`_
|
||||||
|
`#520 <https://github.com/libgit2/pygit2/pull/520>`_
|
||||||
|
|
||||||
|
- Fix TreeEntry equality testing
|
||||||
|
`#458 <https://github.com/libgit2/pygit2/issues/458>`_
|
||||||
|
`#488 <https://github.com/libgit2/pygit2/pull/488>`_
|
||||||
|
|
||||||
|
- ``Repository.write_archive`` fix handling of symlinks
|
||||||
|
`#480 <https://github.com/libgit2/pygit2/pull/480>`_
|
||||||
|
|
||||||
|
- Fix type check in ``Diff[...]``
|
||||||
|
`#495 <https://github.com/libgit2/pygit2/issues/495>`_
|
||||||
|
|
||||||
|
- Fix error when merging files with unicode content
|
||||||
|
`#505 <https://github.com/libgit2/pygit2/pull/505>`_
|
||||||
|
|
||||||
|
Other:
|
||||||
|
|
||||||
|
- Documentation improvements and fixes
|
||||||
|
`#448 <https://github.com/libgit2/pygit2/pull/448>`_
|
||||||
|
`#491 <https://github.com/libgit2/pygit2/pull/491>`_
|
||||||
|
`#497 <https://github.com/libgit2/pygit2/pull/497>`_
|
||||||
|
`#507 <https://github.com/libgit2/pygit2/pull/507>`_
|
||||||
|
`#517 <https://github.com/libgit2/pygit2/pull/517>`_
|
||||||
|
`#518 <https://github.com/libgit2/pygit2/pull/518>`_
|
||||||
|
`#519 <https://github.com/libgit2/pygit2/pull/519>`_
|
||||||
|
`#521 <https://github.com/libgit2/pygit2/pull/521>`_
|
||||||
|
`#523 <https://github.com/libgit2/pygit2/pull/523>`_
|
||||||
|
`#527 <https://github.com/libgit2/pygit2/pull/527>`_
|
||||||
|
`#536 <https://github.com/libgit2/pygit2/pull/536>`_
|
||||||
|
|
||||||
|
- Expose the ``pygit2.GIT_REPOSITORY_INIT_*`` constants
|
||||||
|
`#483 <https://github.com/libgit2/pygit2/issues/483>`_
|
||||||
|
|
||||||
|
|
||||||
|
0.22.0 (2015-01-16)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
New:
|
||||||
|
|
||||||
|
- Update to libgit2 v0.22
|
||||||
|
`#459 <https://github.com/libgit2/pygit2/pull/459>`_
|
||||||
|
|
||||||
|
- Add support for libgit2 feature detection
|
||||||
|
(new ``pygit2.features`` and ``pygit2.GIT_FEATURE_*``)
|
||||||
|
`#475 <https://github.com/libgit2/pygit2/pull/475>`_
|
||||||
|
|
||||||
|
- New ``Repository.remotes`` (``RemoteCollection``)
|
||||||
|
`#447 <https://github.com/libgit2/pygit2/pull/447>`_
|
||||||
|
|
||||||
|
API Changes:
|
||||||
|
|
||||||
|
- Prototype of ``clone_repository`` changed, check documentation
|
||||||
|
|
||||||
|
- Removed ``clone_into``, use ``clone_repository`` with callbacks instead
|
||||||
|
|
||||||
|
- Use ``Repository.remotes.rename(name, new_name)`` instead of
|
||||||
|
``Remote.rename(new_name)``
|
||||||
|
|
||||||
|
- Use ``Repository.remotes.delete(name)`` instead of ``Remote.delete()``
|
||||||
|
|
||||||
|
- Now ``Remote.push(...)`` takes a list of refspecs instead of just one
|
||||||
|
|
||||||
|
- Change ``Patch.old_id``, ``Patch.new_id``, ``Note.annotated_id``,
|
||||||
|
``RefLogEntry.oid_old`` and ``RefLogEntry.oid_new`` to be ``Oid`` objects
|
||||||
|
instead of strings
|
||||||
|
`#449 <https://github.com/libgit2/pygit2/pull/449>`_
|
||||||
|
|
||||||
|
Other:
|
||||||
|
|
||||||
|
- Fix ``init_repository`` when passing optional parameters ``workdir_path``,
|
||||||
|
``description``, ``template_path``, ``initial_head`` or ``origin_url``
|
||||||
|
`#466 <https://github.com/libgit2/pygit2/issues/466>`_
|
||||||
|
`#471 <https://github.com/libgit2/pygit2/pull/471>`_
|
||||||
|
|
||||||
|
- Fix use-after-free when patch outlives diff
|
||||||
|
`#457 <https://github.com/libgit2/pygit2/issues/457>`_
|
||||||
|
`#461 <https://github.com/libgit2/pygit2/pull/461>`_
|
||||||
|
`#474 <https://github.com/libgit2/pygit2/pull/474>`_
|
||||||
|
|
||||||
|
- Documentation improvements
|
||||||
|
`#456 <https://github.com/libgit2/pygit2/issues/456>`_
|
||||||
|
`#462 <https://github.com/libgit2/pygit2/pull/462>`_
|
||||||
|
`#465 <https://github.com/libgit2/pygit2/pull/465>`_
|
||||||
|
`#472 <https://github.com/libgit2/pygit2/pull/472>`_
|
||||||
|
`#473 <https://github.com/libgit2/pygit2/pull/473>`_
|
||||||
|
|
||||||
|
- Make the GPL exception explicit in setup.py
|
||||||
|
`#450 <https://github.com/libgit2/pygit2/pull/450>`_
|
||||||
|
|
||||||
|
|
||||||
|
0.21.4 (2014-11-04)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- Fix credentials callback not set when pushing
|
||||||
|
`#431 <https://github.com/libgit2/pygit2/pull/431>`_
|
||||||
|
`#435 <https://github.com/libgit2/pygit2/issues/435>`_
|
||||||
|
`#437 <https://github.com/libgit2/pygit2/issues/437>`_
|
||||||
|
`#438 <https://github.com/libgit2/pygit2/pull/438>`_
|
||||||
|
|
||||||
|
- Fix ``Repository.diff(...)`` when treeish is "empty"
|
||||||
|
`#432 <https://github.com/libgit2/pygit2/issues/432>`_
|
||||||
|
|
||||||
|
- New ``Reference.peel(...)`` renders ``Reference.get_object()`` obsolete
|
||||||
|
`#434 <https://github.com/libgit2/pygit2/pull/434>`_
|
||||||
|
|
||||||
|
- New, authenticate using ssh agent
|
||||||
|
`#424 <https://github.com/libgit2/pygit2/pull/424>`_
|
||||||
|
|
||||||
|
- New ``Repository.merge_commits(...)``
|
||||||
|
`#445 <https://github.com/libgit2/pygit2/pull/445>`_
|
||||||
|
|
||||||
|
- Make it easier to run when libgit2 not in a standard location
|
||||||
|
`#441 <https://github.com/libgit2/pygit2/issues/441>`_
|
||||||
|
|
||||||
|
- Documentation: review install chapter
|
||||||
|
|
||||||
|
- Documentation: many corrections
|
||||||
|
`#427 <https://github.com/libgit2/pygit2/pull/427>`_
|
||||||
|
`#429 <https://github.com/libgit2/pygit2/pull/429>`_
|
||||||
|
`#439 <https://github.com/libgit2/pygit2/pull/439>`_
|
||||||
|
`#440 <https://github.com/libgit2/pygit2/pull/440>`_
|
||||||
|
`#442 <https://github.com/libgit2/pygit2/pull/442>`_
|
||||||
|
`#443 <https://github.com/libgit2/pygit2/pull/443>`_
|
||||||
|
`#444 <https://github.com/libgit2/pygit2/pull/444>`_
|
||||||
|
|
||||||
|
|
||||||
|
0.21.3 (2014-09-15)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Breaking changes:
|
||||||
|
|
||||||
|
- Now ``Repository.blame(...)`` returns ``Oid`` instead of string
|
||||||
|
`#413 <https://github.com/libgit2/pygit2/pull/413>`_
|
||||||
|
|
||||||
|
- New ``Reference.set_target(...)`` replaces the ``Reference.target`` setter
|
||||||
|
and ``Reference.log_append(...)``
|
||||||
|
`#414 <https://github.com/libgit2/pygit2/pull/414>`_
|
||||||
|
|
||||||
|
- New ``Repository.set_head(...)`` replaces the ``Repository.head`` setter
|
||||||
|
`#414 <https://github.com/libgit2/pygit2/pull/414>`_
|
||||||
|
|
||||||
|
- ``Repository.merge(...)`` now uses the ``SAFE_CREATE`` strategy by default
|
||||||
|
`#417 <https://github.com/libgit2/pygit2/pull/417>`_
|
||||||
|
|
||||||
|
Other changes:
|
||||||
|
|
||||||
|
- New ``Remote.delete()``
|
||||||
|
`#418 <https://github.com/libgit2/pygit2/issues/418>`_
|
||||||
|
`#420 <https://github.com/libgit2/pygit2/pull/420>`_
|
||||||
|
|
||||||
|
- New ``Repository.write_archive(...)``
|
||||||
|
`#421 <https://github.com/libgit2/pygit2/pull/421>`_
|
||||||
|
|
||||||
|
- Now ``Repository.checkout(...)`` accepts branch objects
|
||||||
|
`#408 <https://github.com/libgit2/pygit2/pull/408>`_
|
||||||
|
|
||||||
|
- Fix refcount leak in remotes
|
||||||
|
`#403 <https://github.com/libgit2/pygit2/issues/403>`_
|
||||||
|
`#404 <https://github.com/libgit2/pygit2/pull/404>`_
|
||||||
|
`#419 <https://github.com/libgit2/pygit2/pull/419>`_
|
||||||
|
|
||||||
|
- Various fixes to ``clone_repository(...)``
|
||||||
|
`#399 <https://github.com/libgit2/pygit2/issues/399>`_
|
||||||
|
`#411 <https://github.com/libgit2/pygit2/pull/411>`_
|
||||||
|
`#425 <https://github.com/libgit2/pygit2/issues/425>`_
|
||||||
|
`#426 <https://github.com/libgit2/pygit2/pull/426>`_
|
||||||
|
|
||||||
|
- Fix build error in Python 3
|
||||||
|
`#401 <https://github.com/libgit2/pygit2/pull/401>`_
|
||||||
|
|
||||||
|
- Now ``pip install pygit2`` installs cffi first
|
||||||
|
`#380 <https://github.com/libgit2/pygit2/issues/380>`_
|
||||||
|
`#407 <https://github.com/libgit2/pygit2/pull/407>`_
|
||||||
|
|
||||||
|
- Add support for PyPy3
|
||||||
|
`#422 <https://github.com/libgit2/pygit2/pull/422>`_
|
||||||
|
|
||||||
|
- Documentation improvements
|
||||||
|
`#398 <https://github.com/libgit2/pygit2/pull/398>`_
|
||||||
|
`#409 <https://github.com/libgit2/pygit2/pull/409>`_
|
||||||
|
|
||||||
|
|
||||||
|
0.21.2 (2014-08-09)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- Fix regression with Python 2, ``IndexEntry.path`` returns str
|
||||||
|
(bytes in Python 2 and unicode in Python 3)
|
||||||
|
|
||||||
|
- Get back ``IndexEntry.oid`` for backwards compatibility
|
||||||
|
|
||||||
|
- Config, iterate over the keys (instead of the key/value pairs)
|
||||||
|
`#395 <https://github.com/libgit2/pygit2/pull/395>`_
|
||||||
|
|
||||||
|
- ``Diff.find_similar`` supports new threshold arguments
|
||||||
|
`#396 <https://github.com/libgit2/pygit2/pull/396>`_
|
||||||
|
|
||||||
|
- Optimization, do not load the object when expanding an oid prefix
|
||||||
|
`#397 <https://github.com/libgit2/pygit2/pull/397>`_
|
||||||
|
|
||||||
|
|
||||||
|
0.21.1 (2014-07-22)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- Install fix
|
||||||
|
`#382 <https://github.com/libgit2/pygit2/pull/382>`_
|
||||||
|
|
||||||
|
- Documentation improved, including
|
||||||
|
`#383 <https://github.com/libgit2/pygit2/pull/383>`_
|
||||||
|
`#385 <https://github.com/libgit2/pygit2/pull/385>`_
|
||||||
|
`#388 <https://github.com/libgit2/pygit2/pull/388>`_
|
||||||
|
|
||||||
|
- Documentation, use the read-the-docs theme
|
||||||
|
`#387 <https://github.com/libgit2/pygit2/pull/387>`_
|
||||||
|
|
||||||
|
- Coding style improvements
|
||||||
|
`#392 <https://github.com/libgit2/pygit2/pull/392>`_
|
||||||
|
|
||||||
|
- New ``Repository.state_cleanup()``
|
||||||
|
`#386 <https://github.com/libgit2/pygit2/pull/386>`_
|
||||||
|
|
||||||
|
- New ``Index.conflicts``
|
||||||
|
`#345 <https://github.com/libgit2/pygit2/issues/345>`_
|
||||||
|
`#389 <https://github.com/libgit2/pygit2/pull/389>`_
|
||||||
|
|
||||||
|
- New checkout option to define the target directory
|
||||||
|
`#390 <https://github.com/libgit2/pygit2/pull/390>`_
|
||||||
|
|
||||||
|
|
||||||
|
Backward incompatible changes:
|
||||||
|
|
||||||
|
- Now the checkout strategy must be a keyword argument.
|
||||||
|
|
||||||
|
Change ``Repository.checkout(refname, strategy)`` to
|
||||||
|
``Repository.checkout(refname, strategy=strategy)``
|
||||||
|
|
||||||
|
Idem for ``checkout_head``, ``checkout_index`` and ``checkout_tree``
|
||||||
|
|
||||||
|
|
||||||
|
0.21.0 (2014-06-27)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Highlights:
|
||||||
|
|
||||||
|
- Drop official support for Python 2.6, and add support for Python 3.4
|
||||||
|
`#376 <https://github.com/libgit2/pygit2/pull/376>`_
|
||||||
|
|
||||||
|
- Upgrade to libgit2 v0.21.0
|
||||||
|
`#374 <https://github.com/libgit2/pygit2/pull/374>`_
|
||||||
|
|
||||||
|
- Start using cffi
|
||||||
|
`#360 <https://github.com/libgit2/pygit2/pull/360>`_
|
||||||
|
`#361 <https://github.com/libgit2/pygit2/pull/361>`_
|
||||||
|
|
||||||
|
Backward incompatible changes:
|
||||||
|
|
||||||
|
- Replace ``oid`` by ``id`` through the API to follow libgit2 conventions.
|
||||||
|
- Merge API overhaul following changes in libgit2.
|
||||||
|
- New ``Remote.rename(...)`` replaces ``Remote.name = ...``
|
||||||
|
- Now ``Remote.fetch()`` returns a ``TransferProgress`` object.
|
||||||
|
- Now ``Config.get_multivar(...)`` returns an iterator instead of a list.
|
||||||
|
|
||||||
|
New features:
|
||||||
|
|
||||||
|
- New ``Config.snapshot()`` and ``Repository.config_snapshot()``
|
||||||
|
|
||||||
|
- New ``Config`` methods: ``get_bool(...)``, ``get_int(...)``,
|
||||||
|
``parse_bool(...)`` and ``parse_int(...)``
|
||||||
|
`#357 <https://github.com/libgit2/pygit2/pull/357>`_
|
||||||
|
|
||||||
|
- Blob: implement the memory buffer interface
|
||||||
|
`#362 <https://github.com/libgit2/pygit2/pull/362>`_
|
||||||
|
|
||||||
|
- New ``clone_into(...)`` function
|
||||||
|
`#368 <https://github.com/libgit2/pygit2/pull/368>`_
|
||||||
|
|
||||||
|
- Now ``Index`` can be used alone, without a repository
|
||||||
|
`#372 <https://github.com/libgit2/pygit2/pull/372>`_
|
||||||
|
|
||||||
|
- Add more options to ``init_repository``
|
||||||
|
`#347 <https://github.com/libgit2/pygit2/pull/347>`_
|
||||||
|
|
||||||
|
- Support ``Repository.workdir = ...`` and
|
||||||
|
support setting detached heads ``Repository.head = <Oid>``
|
||||||
|
`#377 <https://github.com/libgit2/pygit2/pull/377>`_
|
||||||
|
|
||||||
|
Other:
|
||||||
|
|
||||||
|
- Fix again build with VS2008
|
||||||
|
`#364 <https://github.com/libgit2/pygit2/pull/364>`_
|
||||||
|
|
||||||
|
- Fix ``Blob.diff(...)`` and ``Blob.diff_to_buffer(...)`` arguments passing
|
||||||
|
`#366 <https://github.com/libgit2/pygit2/pull/366>`_
|
||||||
|
|
||||||
|
- Fail gracefully when compiling against the wrong version of libgit2
|
||||||
|
`#365 <https://github.com/libgit2/pygit2/pull/365>`_
|
||||||
|
|
||||||
|
- Several documentation improvements and updates
|
||||||
|
`#359 <https://github.com/libgit2/pygit2/pull/359>`_
|
||||||
|
`#375 <https://github.com/libgit2/pygit2/pull/375>`_
|
||||||
|
`#378 <https://github.com/libgit2/pygit2/pull/378>`_
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
0.20.3 (2014-04-02)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- A number of memory issues fixed
|
||||||
|
`#328 <https://github.com/libgit2/pygit2/pull/328>`_
|
||||||
|
`#348 <https://github.com/libgit2/pygit2/pull/348>`_
|
||||||
|
`#353 <https://github.com/libgit2/pygit2/pull/353>`_
|
||||||
|
`#355 <https://github.com/libgit2/pygit2/pull/355>`_
|
||||||
|
`#356 <https://github.com/libgit2/pygit2/pull/356>`_
|
||||||
|
- Compatibility fixes for
|
||||||
|
PyPy (`#338 <https://github.com/libgit2/pygit2/pull/338>`_),
|
||||||
|
Visual Studio 2008 (`#343 <https://github.com/libgit2/pygit2/pull/343>`_)
|
||||||
|
and Python 3.3 (`#351 <https://github.com/libgit2/pygit2/pull/351>`_)
|
||||||
|
- Make the sort mode parameter in ``Repository.walk(...)`` optional
|
||||||
|
`#337 <https://github.com/libgit2/pygit2/pull/337>`_
|
||||||
|
- New ``Object.peel(...)``
|
||||||
|
`#342 <https://github.com/libgit2/pygit2/pull/342>`_
|
||||||
|
- New ``Index.add_all(...)``
|
||||||
|
`#344 <https://github.com/libgit2/pygit2/pull/344>`_
|
||||||
|
- Introduce support for libgit2 options
|
||||||
|
`#350 <https://github.com/libgit2/pygit2/pull/350>`_
|
||||||
|
- More informative repr for ``Repository`` objects
|
||||||
|
`#352 <https://github.com/libgit2/pygit2/pull/352>`_
|
||||||
|
- Introduce support for credentials
|
||||||
|
`#354 <https://github.com/libgit2/pygit2/pull/354>`_
|
||||||
|
- Several documentation fixes
|
||||||
|
`#302 <https://github.com/libgit2/pygit2/issues/302>`_
|
||||||
|
`#336 <https://github.com/libgit2/pygit2/issues/336>`_
|
||||||
|
- Tests, remove temporary files
|
||||||
|
`#341 <https://github.com/libgit2/pygit2/pull/341>`_
|
||||||
|
|
||||||
|
|
||||||
|
0.20.2 (2014-02-04)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- Support PyPy
|
||||||
|
`#209 <https://github.com/libgit2/pygit2/issues/209>`_
|
||||||
|
`#327 <https://github.com/libgit2/pygit2/pull/327>`_
|
||||||
|
`#333 <https://github.com/libgit2/pygit2/pull/333>`_
|
||||||
|
|
||||||
|
Repository:
|
||||||
|
|
||||||
|
- New ``Repository.default_signature``
|
||||||
|
`#310 <https://github.com/libgit2/pygit2/pull/310>`_
|
||||||
|
|
||||||
|
Oid:
|
||||||
|
|
||||||
|
- New ``str(Oid)`` deprecates ``Oid.hex``
|
||||||
|
`#322 <https://github.com/libgit2/pygit2/pull/322>`_
|
||||||
|
|
||||||
|
Object:
|
||||||
|
|
||||||
|
- New ``Object.id`` deprecates ``Object.oid``
|
||||||
|
`#322 <https://github.com/libgit2/pygit2/pull/322>`_
|
||||||
|
|
||||||
|
- New ``TreeEntry.id`` deprecates ``TreeEntry.oid``
|
||||||
|
`#322 <https://github.com/libgit2/pygit2/pull/322>`_
|
||||||
|
|
||||||
|
- New ``Blob.diff(...)`` and ``Blob.diff_to_buffer(...)``
|
||||||
|
`#307 <https://github.com/libgit2/pygit2/pull/307>`_
|
||||||
|
|
||||||
|
- New ``Commit.tree_id`` and ``Commit.parent_ids``
|
||||||
|
`#73 <https://github.com/libgit2/pygit2/issues/73>`_
|
||||||
|
`#311 <https://github.com/libgit2/pygit2/pull/311>`_
|
||||||
|
|
||||||
|
- New rich comparison between tree entries
|
||||||
|
`#305 <https://github.com/libgit2/pygit2/issues/305>`_
|
||||||
|
`#313 <https://github.com/libgit2/pygit2/pull/313>`_
|
||||||
|
|
||||||
|
- Now ``Tree.__contains__(key)`` supports paths
|
||||||
|
`#306 <https://github.com/libgit2/pygit2/issues/306>`_
|
||||||
|
`#316 <https://github.com/libgit2/pygit2/pull/316>`_
|
||||||
|
|
||||||
|
Index:
|
||||||
|
|
||||||
|
- Now possible to create ``IndexEntry(...)``
|
||||||
|
`#325 <https://github.com/libgit2/pygit2/pull/325>`_
|
||||||
|
|
||||||
|
- Now ``IndexEntry.path``, ``IndexEntry.oid`` and ``IndexEntry.mode`` are
|
||||||
|
writable
|
||||||
|
`#325 <https://github.com/libgit2/pygit2/pull/325>`_
|
||||||
|
|
||||||
|
- Now ``Index.add(...)`` accepts an ``IndexEntry`` too
|
||||||
|
`#325 <https://github.com/libgit2/pygit2/pull/325>`_
|
||||||
|
|
||||||
|
- Now ``Index.write_tree(...)`` is able to write to a different repository
|
||||||
|
`#325 <https://github.com/libgit2/pygit2/pull/325>`_
|
||||||
|
|
||||||
|
- Fix memory leak in ``IndexEntry.path`` setter
|
||||||
|
`#335 <https://github.com/libgit2/pygit2/pull/335>`_
|
||||||
|
|
||||||
|
Config:
|
||||||
|
|
||||||
|
- New ``Config`` iterator replaces ``Config.foreach``
|
||||||
|
`#183 <https://github.com/libgit2/pygit2/issues/183>`_
|
||||||
|
`#312 <https://github.com/libgit2/pygit2/pull/312>`_
|
||||||
|
|
||||||
|
Remote:
|
||||||
|
|
||||||
|
- New type ``Refspec``
|
||||||
|
`#314 <https://github.com/libgit2/pygit2/pull/314>`_
|
||||||
|
|
||||||
|
- New ``Remote.push_url``
|
||||||
|
`#315 <https://github.com/libgit2/pygit2/pull/314>`_
|
||||||
|
|
||||||
|
- New ``Remote.add_push`` and ``Remote.add_fetch``
|
||||||
|
`#255 <https://github.com/libgit2/pygit2/issues/255>`_
|
||||||
|
`#318 <https://github.com/libgit2/pygit2/pull/318>`_
|
||||||
|
|
||||||
|
- New ``Remote.fetch_refspecs`` replaces ``Remote.get_fetch_refspecs()`` and
|
||||||
|
``Remote.set_fetch_refspecs(...)``
|
||||||
|
`#319 <https://github.com/libgit2/pygit2/pull/319>`_
|
||||||
|
|
||||||
|
- New ``Remote.push_refspecs`` replaces ``Remote.get_push_refspecs()`` and
|
||||||
|
``Remote.set_push_refspecs(...)``
|
||||||
|
`#319 <https://github.com/libgit2/pygit2/pull/319>`_
|
||||||
|
|
||||||
|
- New ``Remote.progress``, ``Remote.transfer_progress`` and
|
||||||
|
``Remote.update_tips``
|
||||||
|
`#274 <https://github.com/libgit2/pygit2/issues/274>`_
|
||||||
|
`#324 <https://github.com/libgit2/pygit2/pull/324>`_
|
||||||
|
|
||||||
|
- New type ``TransferProgress``
|
||||||
|
`#274 <https://github.com/libgit2/pygit2/issues/274>`_
|
||||||
|
`#324 <https://github.com/libgit2/pygit2/pull/324>`_
|
||||||
|
|
||||||
|
- Fix refcount leak in ``Repository.remotes``
|
||||||
|
`#321 <https://github.com/libgit2/pygit2/issues/321>`_
|
||||||
|
`#332 <https://github.com/libgit2/pygit2/pull/332>`_
|
||||||
|
|
||||||
|
Other: `#331 <https://github.com/libgit2/pygit2/pull/331>`_
|
||||||
|
|
||||||
|
|
||||||
|
0.20.1 (2013-12-24)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- New remote ref-specs API:
|
||||||
|
`#290 <https://github.com/libgit2/pygit2/pull/290>`_
|
||||||
|
|
||||||
|
- New ``Repository.reset(...)``:
|
||||||
|
`#292 <https://github.com/libgit2/pygit2/pull/292>`_,
|
||||||
|
`#294 <https://github.com/libgit2/pygit2/pull/294>`_
|
||||||
|
|
||||||
|
- Export ``GIT_DIFF_MINIMAL``:
|
||||||
|
`#293 <https://github.com/libgit2/pygit2/pull/293>`_
|
||||||
|
|
||||||
|
- New ``Repository.merge(...)``:
|
||||||
|
`#295 <https://github.com/libgit2/pygit2/pull/295>`_
|
||||||
|
|
||||||
|
- Fix ``Repository.blame`` argument handling:
|
||||||
|
`#297 <https://github.com/libgit2/pygit2/pull/297>`_
|
||||||
|
|
||||||
|
- Fix build error on Windows:
|
||||||
|
`#298 <https://github.com/libgit2/pygit2/pull/298>`_
|
||||||
|
|
||||||
|
- Fix typo in the README file, Blog → Blob:
|
||||||
|
`#301 <https://github.com/libgit2/pygit2/pull/301>`_
|
||||||
|
|
||||||
|
- Now ``Diff.patch`` returns ``None`` if no patch:
|
||||||
|
`#232 <https://github.com/libgit2/pygit2/pull/232>`_,
|
||||||
|
`#303 <https://github.com/libgit2/pygit2/pull/303>`_
|
||||||
|
|
||||||
|
- New ``Walker.simplify_first_parent()``:
|
||||||
|
`#304 <https://github.com/libgit2/pygit2/pull/304>`_
|
||||||
|
|
||||||
|
0.20.0 (2013-11-24)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
- Upgrade to libgit2 v0.20.0:
|
||||||
|
`#288 <https://github.com/libgit2/pygit2/pull/288>`_
|
||||||
|
|
||||||
|
- New ``Repository.head_is_unborn`` replaces ``Repository.head_is_orphaned``
|
||||||
|
|
||||||
|
- Changed ``pygit2.clone_repository(...)``. Drop ``push_url``, ``fetch_spec``
|
||||||
|
and ``push_spec`` parameters. Add ``ignore_cert_errors``.
|
||||||
|
|
||||||
|
- New ``Patch.additions`` and ``Patch.deletions``:
|
||||||
|
`#275 <https://github.com/libgit2/pygit2/pull/275>`_
|
||||||
|
|
||||||
|
- New ``Patch.is_binary``:
|
||||||
|
`#276 <https://github.com/libgit2/pygit2/pull/276>`_
|
||||||
|
|
||||||
|
- New ``Reference.log_append(...)``:
|
||||||
|
`#277 <https://github.com/libgit2/pygit2/pull/277>`_
|
||||||
|
|
||||||
|
- New ``Blob.is_binary``:
|
||||||
|
`#278 <https://github.com/libgit2/pygit2/pull/278>`_
|
||||||
|
|
||||||
|
- New ``len(Diff)`` shows the number of patches:
|
||||||
|
`#281 <https://github.com/libgit2/pygit2/pull/281>`_
|
||||||
|
|
||||||
|
- Rewrite ``Repository.status()``:
|
||||||
|
`#283 <https://github.com/libgit2/pygit2/pull/283>`_
|
||||||
|
|
||||||
|
- New ``Reference.shorthand``:
|
||||||
|
`#284 <https://github.com/libgit2/pygit2/pull/284>`_
|
||||||
|
|
||||||
|
- New ``Repository.blame(...)``:
|
||||||
|
`#285 <https://github.com/libgit2/pygit2/pull/285>`_
|
||||||
|
|
||||||
|
- Now ``Repository.listall_references()`` and
|
||||||
|
``Repository.listall_branches()`` return a list, not a tuple:
|
||||||
|
`#289 <https://github.com/libgit2/pygit2/pull/289>`_
|
711
README.rst
711
README.rst
@ -5,16 +5,19 @@ pygit2 - libgit2 bindings in Python
|
|||||||
.. image:: https://travis-ci.org/libgit2/pygit2.svg?branch=master
|
.. image:: https://travis-ci.org/libgit2/pygit2.svg?branch=master
|
||||||
:target: http://travis-ci.org/libgit2/pygit2
|
: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
|
Pygit2 is a set of Python bindings to the libgit2 shared library, libgit2
|
||||||
implements the core of Git. Pygit2 works with Python 2.7, 3.2, 3.3, 3.4 and
|
implements Git plumbing. Pygit2 works with Python 2.7, 3.3, 3.4, 3.5, 3.6
|
||||||
pypy.
|
and PyPy 2.6
|
||||||
|
|
||||||
Links:
|
Links:
|
||||||
|
|
||||||
- http://github.com/libgit2/pygit2 -- Source code and issue tracker
|
- https://github.com/libgit2/pygit2 -- Source code and issue tracker
|
||||||
- http://www.pygit2.org/ -- Documentation
|
- http://www.pygit2.org/ -- Documentation
|
||||||
- http://pypi.python.org/pypi/pygit2 -- Download
|
- https://pypi.python.org/pypi/pygit2 -- Download
|
||||||
|
- https://github.com/libgit2/pygit2/blob/master/CHANGELOG.rst -- Changelog
|
||||||
|
|
||||||
How to install
|
How to install
|
||||||
==============
|
==============
|
||||||
@ -22,680 +25,50 @@ How to install
|
|||||||
- Check http://www.pygit2.org/install.html
|
- Check http://www.pygit2.org/install.html
|
||||||
|
|
||||||
|
|
||||||
Changelog
|
|
||||||
==============
|
|
||||||
|
|
||||||
0.23.0 (2015-08-14)
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
- Update to libgit2 v0.23
|
|
||||||
`#540 <https://github.com/libgit2/pygit2/pull/540>`_
|
|
||||||
|
|
||||||
- Now ``Repository.merge_base(...)`` returns ``None`` if no merge base is found
|
|
||||||
`#550 <https://github.com/libgit2/pygit2/pull/550>`_
|
|
||||||
|
|
||||||
- Documentation updates
|
|
||||||
`#547 <https://github.com/libgit2/pygit2/pull/547>`_
|
|
||||||
|
|
||||||
API changes:
|
|
||||||
|
|
||||||
- How to set identity (aka signature) in a reflog has changed::
|
|
||||||
|
|
||||||
# Before
|
|
||||||
signature = Signature('foo', 'bar')
|
|
||||||
...
|
|
||||||
reference.set_target(target, signature=signature, message=message)
|
|
||||||
repo.set_head(target, signature=signature)
|
|
||||||
remote.fetch(signature=signature)
|
|
||||||
remote.push(signature=signature)
|
|
||||||
|
|
||||||
# Now
|
|
||||||
repo.set_ident('foo', 'bar')
|
|
||||||
...
|
|
||||||
reference.set_target(target, message=message)
|
|
||||||
repo.set_head(target)
|
|
||||||
remote.push()
|
|
||||||
|
|
||||||
# The current identity can be get with
|
|
||||||
repo.ident
|
|
||||||
|
|
||||||
- Some remote setters have been replaced by methods::
|
|
||||||
|
|
||||||
# Before # Now
|
|
||||||
Remote.url = url Repository.remotes.set_url(name, url)
|
|
||||||
Remote.push_url = url Repository.remotes.set_push_url(name, url)
|
|
||||||
|
|
||||||
Remote.add_fetch(refspec) Repository.remotes.add_fetch(name, refspec)
|
|
||||||
Remote.add_push(refspec) Repository.remotes.add_push(name, refspec)
|
|
||||||
|
|
||||||
Remote.fetch_refspecs = [...] removed, use the config API instead
|
|
||||||
Remote.push_refspecs = [...] removed, use the config API instead
|
|
||||||
|
|
||||||
|
|
||||||
0.22.1 (2015-07-12)
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
Diff interface refactoring
|
|
||||||
`#346 <https://github.com/libgit2/pygit2/pull/346>`_
|
|
||||||
(in progress):
|
|
||||||
|
|
||||||
- New ``iter(pygit2.Blame)``
|
|
||||||
|
|
||||||
- New ``pygit2.DiffDelta``, ``pygit2.DiffFile`` and ``pygit.DiffLine``
|
|
||||||
|
|
||||||
- API changes, translation table::
|
|
||||||
|
|
||||||
Hunk => DiffHunk
|
|
||||||
Patch.old_file_path => Patch.delta.old_file.path
|
|
||||||
Patch.new_file_path => Patch.delta.new_file.path
|
|
||||||
Patch.old_id => Patch.delta.old_file.id
|
|
||||||
Patch.new_id => Patch.delta.new_file.id
|
|
||||||
Patch.status => Patch.delta.status
|
|
||||||
Patch.similarity => Patch.delta.similarity
|
|
||||||
Patch.is_binary => Patch.delta.is_binary
|
|
||||||
Patch.additions => Patch.line_stats[1]
|
|
||||||
Patch.deletions => Patch.line_stats[2]
|
|
||||||
|
|
||||||
- ``DiffHunk.lines`` is now a list of ``DiffLine`` objects, not tuples
|
|
||||||
|
|
||||||
New features:
|
|
||||||
|
|
||||||
- New ``Repository.expand_id(...)`` and ``Repository.ahead_behind(...)``
|
|
||||||
`#448 <https://github.com/libgit2/pygit2/pull/448>`_
|
|
||||||
|
|
||||||
- New ``prefix`` parameter in ``Repository.write_archive``
|
|
||||||
`#481 <https://github.com/libgit2/pygit2/pull/481>`_
|
|
||||||
|
|
||||||
- New ``Repository.merge_trees(...)``
|
|
||||||
`#489 <https://github.com/libgit2/pygit2/pull/489>`_
|
|
||||||
|
|
||||||
- New ``Repository.cherrypick(...)``
|
|
||||||
`#436 <https://github.com/libgit2/pygit2/issues/436>`_
|
|
||||||
`#492 <https://github.com/libgit2/pygit2/pull/492>`_
|
|
||||||
|
|
||||||
- New support for submodules
|
|
||||||
`#499 <https://github.com/libgit2/pygit2/pull/499>`_
|
|
||||||
`#514 <https://github.com/libgit2/pygit2/pull/514>`_
|
|
||||||
|
|
||||||
- New ``Repository.merge_file_from_index(...)``
|
|
||||||
`#503 <https://github.com/libgit2/pygit2/pull/503>`_
|
|
||||||
|
|
||||||
- Now ``Repository.diff`` supports diffing two blobs
|
|
||||||
`#508 <https://github.com/libgit2/pygit2/pull/508>`_
|
|
||||||
|
|
||||||
- New optional ``fetch`` parameter in ``Remote.create``
|
|
||||||
`#526 <https://github.com/libgit2/pygit2/pull/526>`_
|
|
||||||
|
|
||||||
- New ``pygit2.DiffStats``
|
|
||||||
`#406 <https://github.com/libgit2/pygit2/issues/406>`_
|
|
||||||
`#525 <https://github.com/libgit2/pygit2/pull/525>`_
|
|
||||||
|
|
||||||
- New ``Repository.get_attr(...)``
|
|
||||||
`#528 <https://github.com/libgit2/pygit2/pull/528>`_
|
|
||||||
|
|
||||||
- New ``level`` optional parameter in ``Index.remove``
|
|
||||||
`#533 <https://github.com/libgit2/pygit2/pull/533>`_
|
|
||||||
|
|
||||||
- New ``repr(TreeEntry)``
|
|
||||||
`#543 <https://github.com/libgit2/pygit2/pull/543>`_
|
|
||||||
|
|
||||||
Build and install improvements:
|
|
||||||
|
|
||||||
- Make pygit work in a frozen environment
|
|
||||||
`#453 <https://github.com/libgit2/pygit2/pull/453>`_
|
|
||||||
|
|
||||||
- Make pygit2 work with pyinstaller
|
|
||||||
`#510 <https://github.com/libgit2/pygit2/pull/510>`_
|
|
||||||
|
|
||||||
Bugs fixed:
|
|
||||||
|
|
||||||
- Fix memory issues
|
|
||||||
`#477 <https://github.com/libgit2/pygit2/issues/477>`_
|
|
||||||
`#487 <https://github.com/libgit2/pygit2/pull/487>`_
|
|
||||||
`#520 <https://github.com/libgit2/pygit2/pull/520>`_
|
|
||||||
|
|
||||||
- Fix TreeEntry equality testing
|
|
||||||
`#458 <https://github.com/libgit2/pygit2/issues/458>`_
|
|
||||||
`#488 <https://github.com/libgit2/pygit2/pull/488>`_
|
|
||||||
|
|
||||||
- ``Repository.write_archive`` fix handling of symlinks
|
|
||||||
`#480 <https://github.com/libgit2/pygit2/pull/480>`_
|
|
||||||
|
|
||||||
- Fix type check in ``Diff[...]``
|
|
||||||
`#495 <https://github.com/libgit2/pygit2/issues/495>`_
|
|
||||||
|
|
||||||
- Fix error when merging files with unicode content
|
|
||||||
`#505 <https://github.com/libgit2/pygit2/pull/505>`_
|
|
||||||
|
|
||||||
Other:
|
|
||||||
|
|
||||||
- Documentation improvements and fixes
|
|
||||||
`#448 <https://github.com/libgit2/pygit2/pull/448>`_
|
|
||||||
`#491 <https://github.com/libgit2/pygit2/pull/491>`_
|
|
||||||
`#497 <https://github.com/libgit2/pygit2/pull/497>`_
|
|
||||||
`#507 <https://github.com/libgit2/pygit2/pull/507>`_
|
|
||||||
`#517 <https://github.com/libgit2/pygit2/pull/517>`_
|
|
||||||
`#518 <https://github.com/libgit2/pygit2/pull/518>`_
|
|
||||||
`#519 <https://github.com/libgit2/pygit2/pull/519>`_
|
|
||||||
`#521 <https://github.com/libgit2/pygit2/pull/521>`_
|
|
||||||
`#523 <https://github.com/libgit2/pygit2/pull/523>`_
|
|
||||||
`#527 <https://github.com/libgit2/pygit2/pull/527>`_
|
|
||||||
`#536 <https://github.com/libgit2/pygit2/pull/536>`_
|
|
||||||
|
|
||||||
- Expose the ``pygit2.GIT_REPOSITORY_INIT_*`` constants
|
|
||||||
`#483 <https://github.com/libgit2/pygit2/issues/483>`_
|
|
||||||
|
|
||||||
|
|
||||||
0.22.0 (2015-01-16)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
New:
|
|
||||||
|
|
||||||
- Update to libgit2 v0.22
|
|
||||||
`#459 <https://github.com/libgit2/pygit2/pull/459>`_
|
|
||||||
|
|
||||||
- Add support for libgit2 feature detection
|
|
||||||
(new ``pygit2.features`` and ``pygit2.GIT_FEATURE_*``)
|
|
||||||
`#475 <https://github.com/libgit2/pygit2/pull/475>`_
|
|
||||||
|
|
||||||
- New ``Repository.remotes`` (``RemoteCollection``)
|
|
||||||
`#447 <https://github.com/libgit2/pygit2/pull/447>`_
|
|
||||||
|
|
||||||
API Changes:
|
|
||||||
|
|
||||||
- Prototype of ``clone_repository`` changed, check documentation
|
|
||||||
|
|
||||||
- Removed ``clone_into``, use ``clone_repository`` with callbacks instead
|
|
||||||
|
|
||||||
- Use ``Repository.remotes.rename(name, new_name)`` instead of
|
|
||||||
``Remote.rename(new_name)``
|
|
||||||
|
|
||||||
- Use ``Repository.remotes.delete(name)`` instead of ``Remote.delete()``
|
|
||||||
|
|
||||||
- Now ``Remote.push(...)`` takes a list of refspecs instead of just one
|
|
||||||
|
|
||||||
- Change ``Patch.old_id``, ``Patch.new_id``, ``Note.annotated_id``,
|
|
||||||
``RefLogEntry.oid_old`` and ``RefLogEntry.oid_new`` to be ``Oid`` objects
|
|
||||||
instead of strings
|
|
||||||
`#449 <https://github.com/libgit2/pygit2/pull/449>`_
|
|
||||||
|
|
||||||
Other:
|
|
||||||
|
|
||||||
- Fix ``init_repository`` when passing optional parameters ``workdir_path``,
|
|
||||||
``description``, ``template_path``, ``initial_head`` or ``origin_url``
|
|
||||||
`#466 <https://github.com/libgit2/pygit2/issues/466>`_
|
|
||||||
`#471 <https://github.com/libgit2/pygit2/pull/471>`_
|
|
||||||
|
|
||||||
- Fix use-after-free when patch outlives diff
|
|
||||||
`#457 <https://github.com/libgit2/pygit2/issues/457>`_
|
|
||||||
`#461 <https://github.com/libgit2/pygit2/pull/461>`_
|
|
||||||
`#474 <https://github.com/libgit2/pygit2/pull/474>`_
|
|
||||||
|
|
||||||
- Documentation improvements
|
|
||||||
`#456 <https://github.com/libgit2/pygit2/issues/456>`_
|
|
||||||
`#462 <https://github.com/libgit2/pygit2/pull/462>`_
|
|
||||||
`#465 <https://github.com/libgit2/pygit2/pull/465>`_
|
|
||||||
`#472 <https://github.com/libgit2/pygit2/pull/472>`_
|
|
||||||
`#473 <https://github.com/libgit2/pygit2/pull/473>`_
|
|
||||||
|
|
||||||
- Make the GPL exception explicit in setup.py
|
|
||||||
`#450 <https://github.com/libgit2/pygit2/pull/450>`_
|
|
||||||
|
|
||||||
|
|
||||||
0.21.4 (2014-11-04)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- Fix credentials callback not set when pushing
|
|
||||||
`#431 <https://github.com/libgit2/pygit2/pull/431>`_
|
|
||||||
`#435 <https://github.com/libgit2/pygit2/issues/435>`_
|
|
||||||
`#437 <https://github.com/libgit2/pygit2/issues/437>`_
|
|
||||||
`#438 <https://github.com/libgit2/pygit2/pull/438>`_
|
|
||||||
|
|
||||||
- Fix ``Repository.diff(...)`` when treeish is "empty"
|
|
||||||
`#432 <https://github.com/libgit2/pygit2/issues/432>`_
|
|
||||||
|
|
||||||
- New ``Reference.peel(...)`` renders ``Reference.get_object()`` obsolete
|
|
||||||
`#434 <https://github.com/libgit2/pygit2/pull/434>`_
|
|
||||||
|
|
||||||
- New, authenticate using ssh agent
|
|
||||||
`#424 <https://github.com/libgit2/pygit2/pull/424>`_
|
|
||||||
|
|
||||||
- New ``Repository.merge_commits(...)``
|
|
||||||
`#445 <https://github.com/libgit2/pygit2/pull/445>`_
|
|
||||||
|
|
||||||
- Make it easier to run when libgit2 not in a standard location
|
|
||||||
`#441 <https://github.com/libgit2/pygit2/issues/441>`_
|
|
||||||
|
|
||||||
- Documentation: review install chapter
|
|
||||||
|
|
||||||
- Documentation: many corrections
|
|
||||||
`#427 <https://github.com/libgit2/pygit2/pull/427>`_
|
|
||||||
`#429 <https://github.com/libgit2/pygit2/pull/429>`_
|
|
||||||
`#439 <https://github.com/libgit2/pygit2/pull/439>`_
|
|
||||||
`#440 <https://github.com/libgit2/pygit2/pull/440>`_
|
|
||||||
`#442 <https://github.com/libgit2/pygit2/pull/442>`_
|
|
||||||
`#443 <https://github.com/libgit2/pygit2/pull/443>`_
|
|
||||||
`#444 <https://github.com/libgit2/pygit2/pull/444>`_
|
|
||||||
|
|
||||||
|
|
||||||
0.21.3 (2014-09-15)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Breaking changes:
|
|
||||||
|
|
||||||
- Now ``Repository.blame(...)`` returns ``Oid`` instead of string
|
|
||||||
`#413 <https://github.com/libgit2/pygit2/pull/413>`_
|
|
||||||
|
|
||||||
- New ``Reference.set_target(...)`` replaces the ``Reference.target`` setter
|
|
||||||
and ``Reference.log_append(...)``
|
|
||||||
`#414 <https://github.com/libgit2/pygit2/pull/414>`_
|
|
||||||
|
|
||||||
- New ``Repository.set_head(...)`` replaces the ``Repository.head`` setter
|
|
||||||
`#414 <https://github.com/libgit2/pygit2/pull/414>`_
|
|
||||||
|
|
||||||
- ``Repository.merge(...)`` now uses the ``SAFE_CREATE`` strategy by default
|
|
||||||
`#417 <https://github.com/libgit2/pygit2/pull/417>`_
|
|
||||||
|
|
||||||
Other changes:
|
|
||||||
|
|
||||||
- New ``Remote.delete()``
|
|
||||||
`#418 <https://github.com/libgit2/pygit2/issues/418>`_
|
|
||||||
`#420 <https://github.com/libgit2/pygit2/pull/420>`_
|
|
||||||
|
|
||||||
- New ``Repository.write_archive(...)``
|
|
||||||
`#421 <https://github.com/libgit2/pygit2/pull/421>`_
|
|
||||||
|
|
||||||
- Now ``Repository.checkout(...)`` accepts branch objects
|
|
||||||
`#408 <https://github.com/libgit2/pygit2/pull/408>`_
|
|
||||||
|
|
||||||
- Fix refcount leak in remotes
|
|
||||||
`#403 <https://github.com/libgit2/pygit2/issues/403>`_
|
|
||||||
`#404 <https://github.com/libgit2/pygit2/pull/404>`_
|
|
||||||
`#419 <https://github.com/libgit2/pygit2/pull/419>`_
|
|
||||||
|
|
||||||
- Various fixes to ``clone_repository(...)``
|
|
||||||
`#399 <https://github.com/libgit2/pygit2/issues/399>`_
|
|
||||||
`#411 <https://github.com/libgit2/pygit2/pull/411>`_
|
|
||||||
`#425 <https://github.com/libgit2/pygit2/issues/425>`_
|
|
||||||
`#426 <https://github.com/libgit2/pygit2/pull/426>`_
|
|
||||||
|
|
||||||
- Fix build error in Python 3
|
|
||||||
`#401 <https://github.com/libgit2/pygit2/pull/401>`_
|
|
||||||
|
|
||||||
- Now ``pip install pygit2`` installs cffi first
|
|
||||||
`#380 <https://github.com/libgit2/pygit2/issues/380>`_
|
|
||||||
`#407 <https://github.com/libgit2/pygit2/pull/407>`_
|
|
||||||
|
|
||||||
- Add support for pypy3
|
|
||||||
`#422 <https://github.com/libgit2/pygit2/pull/422>`_
|
|
||||||
|
|
||||||
- Documentation improvements
|
|
||||||
`#398 <https://github.com/libgit2/pygit2/pull/398>`_
|
|
||||||
`#409 <https://github.com/libgit2/pygit2/pull/409>`_
|
|
||||||
|
|
||||||
|
|
||||||
0.21.2 (2014-08-09)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- Fix regression with Python 2, ``IndexEntry.path`` returns str
|
|
||||||
(bytes in Python 2 and unicode in Python 3)
|
|
||||||
|
|
||||||
- Get back ``IndexEntry.oid`` for backwards compatibility
|
|
||||||
|
|
||||||
- Config, iterate over the keys (instead of the key/value pairs)
|
|
||||||
`#395 <https://github.com/libgit2/pygit2/pull/395>`_
|
|
||||||
|
|
||||||
- ``Diff.find_similar`` supports new threshold arguments
|
|
||||||
`#396 <https://github.com/libgit2/pygit2/pull/396>`_
|
|
||||||
|
|
||||||
- Optimization, do not load the object when expanding an oid prefix
|
|
||||||
`#397 <https://github.com/libgit2/pygit2/pull/397>`_
|
|
||||||
|
|
||||||
|
|
||||||
0.21.1 (2014-07-22)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- Install fix
|
|
||||||
`#382 <https://github.com/libgit2/pygit2/pull/382>`_
|
|
||||||
|
|
||||||
- Documentation improved, including
|
|
||||||
`#383 <https://github.com/libgit2/pygit2/pull/383>`_
|
|
||||||
`#385 <https://github.com/libgit2/pygit2/pull/385>`_
|
|
||||||
`#388 <https://github.com/libgit2/pygit2/pull/388>`_
|
|
||||||
|
|
||||||
- Documentation, use the read-the-docs theme
|
|
||||||
`#387 <https://github.com/libgit2/pygit2/pull/387>`_
|
|
||||||
|
|
||||||
- Coding style improvements
|
|
||||||
`#392 <https://github.com/libgit2/pygit2/pull/392>`_
|
|
||||||
|
|
||||||
- New ``Repository.state_cleanup()``
|
|
||||||
`#386 <https://github.com/libgit2/pygit2/pull/386>`_
|
|
||||||
|
|
||||||
- New ``Index.conflicts``
|
|
||||||
`#345 <https://github.com/libgit2/pygit2/issues/345>`_
|
|
||||||
`#389 <https://github.com/libgit2/pygit2/pull/389>`_
|
|
||||||
|
|
||||||
- New checkout option to define the target directory
|
|
||||||
`#390 <https://github.com/libgit2/pygit2/pull/390>`_
|
|
||||||
|
|
||||||
|
|
||||||
Backward incompatible changes:
|
|
||||||
|
|
||||||
- Now the checkout strategy must be a keyword argument.
|
|
||||||
|
|
||||||
Change ``Repository.checkout(refname, strategy)`` to
|
|
||||||
``Repository.checkout(refname, strategy=strategy)``
|
|
||||||
|
|
||||||
Idem for ``checkout_head``, ``checkout_index`` and ``checkout_tree``
|
|
||||||
|
|
||||||
|
|
||||||
0.21.0 (2014-06-27)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Highlights:
|
|
||||||
|
|
||||||
- Drop official support for Python 2.6, and add support for Python 3.4
|
|
||||||
`#376 <https://github.com/libgit2/pygit2/pull/376>`_
|
|
||||||
|
|
||||||
- Upgrade to libgit2 v0.21.0
|
|
||||||
`#374 <https://github.com/libgit2/pygit2/pull/374>`_
|
|
||||||
|
|
||||||
- Start using cffi
|
|
||||||
`#360 <https://github.com/libgit2/pygit2/pull/360>`_
|
|
||||||
`#361 <https://github.com/libgit2/pygit2/pull/361>`_
|
|
||||||
|
|
||||||
Backward incompatible changes:
|
|
||||||
|
|
||||||
- Replace ``oid`` by ``id`` through the API to follow libgit2 conventions.
|
|
||||||
- Merge API overhaul following changes in libgit2.
|
|
||||||
- New ``Remote.rename(...)`` replaces ``Remote.name = ...``
|
|
||||||
- Now ``Remote.fetch()`` returns a ``TransferProgress`` object.
|
|
||||||
- Now ``Config.get_multivar(...)`` returns an iterator instead of a list.
|
|
||||||
|
|
||||||
New features:
|
|
||||||
|
|
||||||
- New ``Config.snapshot()`` and ``Repository.config_snapshot()``
|
|
||||||
|
|
||||||
- New ``Config`` methods: ``get_bool(...)``, ``get_int(...)``,
|
|
||||||
``parse_bool(...)`` and ``parse_int(...)``
|
|
||||||
`#357 <https://github.com/libgit2/pygit2/pull/357>`_
|
|
||||||
|
|
||||||
- Blob: implement the memory buffer interface
|
|
||||||
`#362 <https://github.com/libgit2/pygit2/pull/362>`_
|
|
||||||
|
|
||||||
- New ``clone_into(...)`` function
|
|
||||||
`#368 <https://github.com/libgit2/pygit2/pull/368>`_
|
|
||||||
|
|
||||||
- Now ``Index`` can be used alone, without a repository
|
|
||||||
`#372 <https://github.com/libgit2/pygit2/pull/372>`_
|
|
||||||
|
|
||||||
- Add more options to ``init_repository``
|
|
||||||
`#347 <https://github.com/libgit2/pygit2/pull/347>`_
|
|
||||||
|
|
||||||
- Support ``Repository.workdir = ...`` and
|
|
||||||
support setting detached heads ``Repository.head = <Oid>``
|
|
||||||
`#377 <https://github.com/libgit2/pygit2/pull/377>`_
|
|
||||||
|
|
||||||
Other:
|
|
||||||
|
|
||||||
- Fix again build with VS2008
|
|
||||||
`#364 <https://github.com/libgit2/pygit2/pull/364>`_
|
|
||||||
|
|
||||||
- Fix ``Blob.diff(...)`` and ``Blob.diff_to_buffer(...)`` arguments passing
|
|
||||||
`#366 <https://github.com/libgit2/pygit2/pull/366>`_
|
|
||||||
|
|
||||||
- Fail gracefully when compiling against the wrong version of libgit2
|
|
||||||
`#365 <https://github.com/libgit2/pygit2/pull/365>`_
|
|
||||||
|
|
||||||
- Several documentation improvements and updates
|
|
||||||
`#359 <https://github.com/libgit2/pygit2/pull/359>`_
|
|
||||||
`#375 <https://github.com/libgit2/pygit2/pull/375>`_
|
|
||||||
`#378 <https://github.com/libgit2/pygit2/pull/378>`_
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
0.20.3 (2014-04-02)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- A number of memory issues fixed
|
|
||||||
`#328 <https://github.com/libgit2/pygit2/pull/328>`_
|
|
||||||
`#348 <https://github.com/libgit2/pygit2/pull/348>`_
|
|
||||||
`#353 <https://github.com/libgit2/pygit2/pull/353>`_
|
|
||||||
`#355 <https://github.com/libgit2/pygit2/pull/355>`_
|
|
||||||
`#356 <https://github.com/libgit2/pygit2/pull/356>`_
|
|
||||||
- Compatibility fixes for
|
|
||||||
PyPy (`#338 <https://github.com/libgit2/pygit2/pull/338>`_),
|
|
||||||
Visual Studio 2008 (`#343 <https://github.com/libgit2/pygit2/pull/343>`_)
|
|
||||||
and Python 3.3 (`#351 <https://github.com/libgit2/pygit2/pull/351>`_)
|
|
||||||
- Make the sort mode parameter in ``Repository.walk(...)`` optional
|
|
||||||
`#337 <https://github.com/libgit2/pygit2/pull/337>`_
|
|
||||||
- New ``Object.peel(...)``
|
|
||||||
`#342 <https://github.com/libgit2/pygit2/pull/342>`_
|
|
||||||
- New ``Index.add_all(...)``
|
|
||||||
`#344 <https://github.com/libgit2/pygit2/pull/344>`_
|
|
||||||
- Introduce support for libgit2 options
|
|
||||||
`#350 <https://github.com/libgit2/pygit2/pull/350>`_
|
|
||||||
- More informative repr for ``Repository`` objects
|
|
||||||
`#352 <https://github.com/libgit2/pygit2/pull/352>`_
|
|
||||||
- Introduce support for credentials
|
|
||||||
`#354 <https://github.com/libgit2/pygit2/pull/354>`_
|
|
||||||
- Several documentation fixes
|
|
||||||
`#302 <https://github.com/libgit2/pygit2/issues/302>`_
|
|
||||||
`#336 <https://github.com/libgit2/pygit2/issues/336>`_
|
|
||||||
- Tests, remove temporary files
|
|
||||||
`#341 <https://github.com/libgit2/pygit2/pull/341>`_
|
|
||||||
|
|
||||||
|
|
||||||
0.20.2 (2014-02-04)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- Support pypy
|
|
||||||
`#209 <https://github.com/libgit2/pygit2/issues/209>`_
|
|
||||||
`#327 <https://github.com/libgit2/pygit2/pull/327>`_
|
|
||||||
`#333 <https://github.com/libgit2/pygit2/pull/333>`_
|
|
||||||
|
|
||||||
Repository:
|
|
||||||
|
|
||||||
- New ``Repository.default_signature``
|
|
||||||
`#310 <https://github.com/libgit2/pygit2/pull/310>`_
|
|
||||||
|
|
||||||
Oid:
|
|
||||||
|
|
||||||
- New ``str(Oid)`` deprecates ``Oid.hex``
|
|
||||||
`#322 <https://github.com/libgit2/pygit2/pull/322>`_
|
|
||||||
|
|
||||||
Object:
|
|
||||||
|
|
||||||
- New ``Object.id`` deprecates ``Object.oid``
|
|
||||||
`#322 <https://github.com/libgit2/pygit2/pull/322>`_
|
|
||||||
|
|
||||||
- New ``TreeEntry.id`` deprecates ``TreeEntry.oid``
|
|
||||||
`#322 <https://github.com/libgit2/pygit2/pull/322>`_
|
|
||||||
|
|
||||||
- New ``Blob.diff(...)`` and ``Blob.diff_to_buffer(...)``
|
|
||||||
`#307 <https://github.com/libgit2/pygit2/pull/307>`_
|
|
||||||
|
|
||||||
- New ``Commit.tree_id`` and ``Commit.parent_ids``
|
|
||||||
`#73 <https://github.com/libgit2/pygit2/issues/73>`_
|
|
||||||
`#311 <https://github.com/libgit2/pygit2/pull/311>`_
|
|
||||||
|
|
||||||
- New rich comparison between tree entries
|
|
||||||
`#305 <https://github.com/libgit2/pygit2/issues/305>`_
|
|
||||||
`#313 <https://github.com/libgit2/pygit2/pull/313>`_
|
|
||||||
|
|
||||||
- Now ``Tree.__contains__(key)`` supports paths
|
|
||||||
`#306 <https://github.com/libgit2/pygit2/issues/306>`_
|
|
||||||
`#316 <https://github.com/libgit2/pygit2/pull/316>`_
|
|
||||||
|
|
||||||
Index:
|
|
||||||
|
|
||||||
- Now possible to create ``IndexEntry(...)``
|
|
||||||
`#325 <https://github.com/libgit2/pygit2/pull/325>`_
|
|
||||||
|
|
||||||
- Now ``IndexEntry.path``, ``IndexEntry.oid`` and ``IndexEntry.mode`` are
|
|
||||||
writable
|
|
||||||
`#325 <https://github.com/libgit2/pygit2/pull/325>`_
|
|
||||||
|
|
||||||
- Now ``Index.add(...)`` accepts an ``IndexEntry`` too
|
|
||||||
`#325 <https://github.com/libgit2/pygit2/pull/325>`_
|
|
||||||
|
|
||||||
- Now ``Index.write_tree(...)`` is able to write to a different repository
|
|
||||||
`#325 <https://github.com/libgit2/pygit2/pull/325>`_
|
|
||||||
|
|
||||||
- Fix memory leak in ``IndexEntry.path`` setter
|
|
||||||
`#335 <https://github.com/libgit2/pygit2/pull/335>`_
|
|
||||||
|
|
||||||
Config:
|
|
||||||
|
|
||||||
- New ``Config`` iterator replaces ``Config.foreach``
|
|
||||||
`#183 <https://github.com/libgit2/pygit2/issues/183>`_
|
|
||||||
`#312 <https://github.com/libgit2/pygit2/pull/312>`_
|
|
||||||
|
|
||||||
Remote:
|
|
||||||
|
|
||||||
- New type ``Refspec``
|
|
||||||
`#314 <https://github.com/libgit2/pygit2/pull/314>`_
|
|
||||||
|
|
||||||
- New ``Remote.push_url``
|
|
||||||
`#315 <https://github.com/libgit2/pygit2/pull/314>`_
|
|
||||||
|
|
||||||
- New ``Remote.add_push`` and ``Remote.add_fetch``
|
|
||||||
`#255 <https://github.com/libgit2/pygit2/issues/255>`_
|
|
||||||
`#318 <https://github.com/libgit2/pygit2/pull/318>`_
|
|
||||||
|
|
||||||
- New ``Remote.fetch_refspecs`` replaces ``Remote.get_fetch_refspecs()`` and
|
|
||||||
``Remote.set_fetch_refspecs(...)``
|
|
||||||
`#319 <https://github.com/libgit2/pygit2/pull/319>`_
|
|
||||||
|
|
||||||
- New ``Remote.push_refspecs`` replaces ``Remote.get_push_refspecs()`` and
|
|
||||||
``Remote.set_push_refspecs(...)``
|
|
||||||
`#319 <https://github.com/libgit2/pygit2/pull/319>`_
|
|
||||||
|
|
||||||
- New ``Remote.progress``, ``Remote.transfer_progress`` and
|
|
||||||
``Remote.update_tips``
|
|
||||||
`#274 <https://github.com/libgit2/pygit2/issues/274>`_
|
|
||||||
`#324 <https://github.com/libgit2/pygit2/pull/324>`_
|
|
||||||
|
|
||||||
- New type ``TransferProgress``
|
|
||||||
`#274 <https://github.com/libgit2/pygit2/issues/274>`_
|
|
||||||
`#324 <https://github.com/libgit2/pygit2/pull/324>`_
|
|
||||||
|
|
||||||
- Fix refcount leak in ``Repository.remotes``
|
|
||||||
`#321 <https://github.com/libgit2/pygit2/issues/321>`_
|
|
||||||
`#332 <https://github.com/libgit2/pygit2/pull/332>`_
|
|
||||||
|
|
||||||
Other: `#331 <https://github.com/libgit2/pygit2/pull/331>`_
|
|
||||||
|
|
||||||
|
|
||||||
0.20.1 (2013-12-24)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- New remote ref-specs API:
|
|
||||||
`#290 <https://github.com/libgit2/pygit2/pull/290>`_
|
|
||||||
|
|
||||||
- New ``Repository.reset(...)``:
|
|
||||||
`#292 <https://github.com/libgit2/pygit2/pull/292>`_,
|
|
||||||
`#294 <https://github.com/libgit2/pygit2/pull/294>`_
|
|
||||||
|
|
||||||
- Export ``GIT_DIFF_MINIMAL``:
|
|
||||||
`#293 <https://github.com/libgit2/pygit2/pull/293>`_
|
|
||||||
|
|
||||||
- New ``Repository.merge(...)``:
|
|
||||||
`#295 <https://github.com/libgit2/pygit2/pull/295>`_
|
|
||||||
|
|
||||||
- Fix ``Repository.blame`` argument handling:
|
|
||||||
`#297 <https://github.com/libgit2/pygit2/pull/297>`_
|
|
||||||
|
|
||||||
- Fix build error on Windows:
|
|
||||||
`#298 <https://github.com/libgit2/pygit2/pull/298>`_
|
|
||||||
|
|
||||||
- Fix typo in the README file, Blog → Blob:
|
|
||||||
`#301 <https://github.com/libgit2/pygit2/pull/301>`_
|
|
||||||
|
|
||||||
- Now ``Diff.patch`` returns ``None`` if no patch:
|
|
||||||
`#232 <https://github.com/libgit2/pygit2/pull/232>`_,
|
|
||||||
`#303 <https://github.com/libgit2/pygit2/pull/303>`_
|
|
||||||
|
|
||||||
- New ``Walker.simplify_first_parent()``:
|
|
||||||
`#304 <https://github.com/libgit2/pygit2/pull/304>`_
|
|
||||||
|
|
||||||
0.20.0 (2013-11-24)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
- Upgrade to libgit2 v0.20.0:
|
|
||||||
`#288 <https://github.com/libgit2/pygit2/pull/288>`_
|
|
||||||
|
|
||||||
- New ``Repository.head_is_unborn`` replaces ``Repository.head_is_orphaned``
|
|
||||||
|
|
||||||
- Changed ``pygit2.clone_repository(...)``. Drop ``push_url``, ``fetch_spec``
|
|
||||||
and ``push_spec`` parameters. Add ``ignore_cert_errors``.
|
|
||||||
|
|
||||||
- New ``Patch.additions`` and ``Patch.deletions``:
|
|
||||||
`#275 <https://github.com/libgit2/pygit2/pull/275>`_
|
|
||||||
|
|
||||||
- New ``Patch.is_binary``:
|
|
||||||
`#276 <https://github.com/libgit2/pygit2/pull/276>`_
|
|
||||||
|
|
||||||
- New ``Reference.log_append(...)``:
|
|
||||||
`#277 <https://github.com/libgit2/pygit2/pull/277>`_
|
|
||||||
|
|
||||||
- New ``Blob.is_binary``:
|
|
||||||
`#278 <https://github.com/libgit2/pygit2/pull/278>`_
|
|
||||||
|
|
||||||
- New ``len(Diff)`` shows the number of patches:
|
|
||||||
`#281 <https://github.com/libgit2/pygit2/pull/281>`_
|
|
||||||
|
|
||||||
- Rewrite ``Repository.status()``:
|
|
||||||
`#283 <https://github.com/libgit2/pygit2/pull/283>`_
|
|
||||||
|
|
||||||
- New ``Reference.shorthand``:
|
|
||||||
`#284 <https://github.com/libgit2/pygit2/pull/284>`_
|
|
||||||
|
|
||||||
- New ``Repository.blame(...)``:
|
|
||||||
`#285 <https://github.com/libgit2/pygit2/pull/285>`_
|
|
||||||
|
|
||||||
- Now ``Repository.listall_references()`` and
|
|
||||||
``Repository.listall_branches()`` return a list, not a tuple:
|
|
||||||
`#289 <https://github.com/libgit2/pygit2/pull/289>`_
|
|
||||||
|
|
||||||
|
|
||||||
Authors
|
Authors
|
||||||
==============
|
==============
|
||||||
|
|
||||||
93 developers have contributed at least 1 commit to pygit2::
|
117 developers have contributed at least 1 commit to pygit2::
|
||||||
|
|
||||||
J. David Ibáñez Carlos Martín Nieto Nico von Geyso
|
J. David Ibáñez Carlos Martín Nieto Nico von Geyso
|
||||||
W. Trevor King Dave Borowitz Daniel Rodríguez Troitiño
|
W. Trevor King Dave Borowitz Matthias Bartelmeß
|
||||||
Richo Healey Christian Boos Julien Miotte
|
Daniel Rodríguez Troitiño Richo Healey Christian Boos
|
||||||
Richard Möhn Xu Tao Jose Plana
|
Julien Miotte Richard Möhn Xu Tao
|
||||||
Matthew Duggan Matthew Gamble Martin Lenders
|
Jose Plana Matthew Duggan Matthew Gamble
|
||||||
Petr Hosek Victor Garcia Xavier Delannoy
|
Martin Lenders Nick Hynes Petr Hosek
|
||||||
Yonggang Luo Patrick Steinhardt Valentin Haenel
|
Victor Garcia Xavier Delannoy Yonggang Luo
|
||||||
Michael Jones Bernardo Heynemann John Szakmeister
|
Patrick Steinhardt Tamir Bahar Valentin Haenel
|
||||||
Vlad Temian Brodie Rao David Versmisse
|
Michael Jones Bernardo Heynemann Brodie Rao
|
||||||
Rémi Duraffort Sebastian Thiel Alok Singhal
|
John Szakmeister Vlad Temian Lukas Fleischer
|
||||||
Fraser Tweedale Han-Wen Nienhuys Leonardo Rhodes
|
Nicolas Dandrimont David Versmisse Rémi Duraffort
|
||||||
Petr Viktorin Ron Cohen Santiago Perez De Rosso
|
Santiago Perez De Rosso Sebastian Thiel Thom Wiggers
|
||||||
|
Alok Singhal Anatoly Techtonik Fraser Tweedale
|
||||||
|
Han-Wen Nienhuys Jason Ziglar Leonardo Rhodes
|
||||||
|
Petr Viktorin Robert Hölzl Ron Cohen
|
||||||
Thomas Kluyver Alex Chamberlain Alexander Bayandin
|
Thomas Kluyver Alex Chamberlain Alexander Bayandin
|
||||||
Amit Bakshi Andrey Devyatkin Arno van Lumig
|
Amit Bakshi Andrey Devyatkin Arno van Lumig
|
||||||
Ben Davis Eric Schrijver Greg Fitzgerald
|
Ben Davis Dustin Raimondi Eric Schrijver
|
||||||
Hervé Cauwelier Huang Huang Ian P. McCullough
|
Greg Fitzgerald Guillermo Pérez Hervé Cauwelier
|
||||||
|
Huang Huang Ian P. McCullough Igor Gnatenko
|
||||||
Jack O'Connor Jared Flatow Jiunn Haur Lim
|
Jack O'Connor Jared Flatow Jiunn Haur Lim
|
||||||
Jun Omae Kaarel Kitsemets Kevin KIN-FOO
|
Jun Omae Kaarel Kitsemets Kevin KIN-FOO
|
||||||
Sarath Lakshman Vicent Marti Zoran Zaric
|
Mark Adams Masud Rahman Michael Sondergaard
|
||||||
Adam Spiers Andrew Chin András Veres-Szentkirályi
|
Ondřej Nový Sarath Lakshman Szucs Krisztian
|
||||||
Ash Berlin Benjamin Kircher Benjamin Pollack
|
Vicent Marti Zoran Zaric Adam Spiers
|
||||||
Bryan O'Sullivan Colin Watson Daniel Bruce
|
Andrew Chin András Veres-Szentkirályi Ash Berlin
|
||||||
David Fischer David Sanders Devaev Maxim
|
Benjamin Kircher Benjamin Pollack Bryan O'Sullivan
|
||||||
|
Cam Cope Chason Chaffin Chris Rebert
|
||||||
|
Colin Watson Daniel Bruce David Fischer
|
||||||
|
David Sanders David Six Devaev Maxim
|
||||||
Eric Davis Erik Meusel Erik van Zijst
|
Eric Davis Erik Meusel Erik van Zijst
|
||||||
Ferengee Gustavo Di Pietro Holger Frey
|
Ferengee Gustavo Di Pietrou Holger Frey
|
||||||
Hugh Cole-Baker Jasper Lievisse Josh Bleecher Snyder
|
Hugh Cole-Baker Jasper Lievisse Adriaanse Josh Bleecher Snyder
|
||||||
Justin Clift Kyriakos Oikonomakos Lukas Fleischer
|
Justin Clift Kyriakos Oikonomakos Mathieu Bridon
|
||||||
Mathieu Bridon Michael Sondergaard Óscar San José
|
Matthaus Woolard Nicolás Sanguinetti Noah Fontes
|
||||||
Peter Dave Hello Philippe Ombredanne Ridge Kennedy
|
Óscar San José Peter Dave Hello Philippe Ombredanne
|
||||||
Ross Nicoll Rui Abreu Ferreira Soasme
|
Ridge Kennedy Ross Nicoll Rui Abreu Ferreira
|
||||||
Vladimir Rutsky chengyuhang earl
|
Sheeo Soasme Vladimir Rutsky
|
||||||
|
Yu Jianjian chengyuhang earl
|
||||||
|
|
||||||
|
|
||||||
License
|
License
|
||||||
|
53
appveyor.yml
Normal file
53
appveyor.yml
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
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'
|
||||||
|
- GENERATOR: 'Visual Studio 14'
|
||||||
|
PYTHON: 'C:\Python36\python.exe'
|
||||||
|
- GENERATOR: 'Visual Studio 14 Win64'
|
||||||
|
PYTHON: 'C:\Python36-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.26 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
|
8
docs/backends.rst
Normal file
8
docs/backends.rst
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
**********************************************************************
|
||||||
|
Custom backends
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
There is some support for custom backends, but undocumented. See
|
||||||
|
`<https://github.com/libgit2/pygit2/pull/690/commits>`_
|
||||||
|
|
||||||
|
Documentation contributions are very welcome.
|
@ -43,16 +43,16 @@ master_doc = 'index'
|
|||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = u'pygit2'
|
project = u'pygit2'
|
||||||
copyright = u'2010-2014 The pygit2 contributors'
|
copyright = u'2010-2015 The pygit2 contributors'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
# |version| and |release|, also used in various other places throughout the
|
# |version| and |release|, also used in various other places throughout the
|
||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '0.23'
|
version = '0.26'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '0.23.0'
|
release = '0.26.0'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
@ -5,6 +5,9 @@ The development version
|
|||||||
.. image:: https://travis-ci.org/libgit2/pygit2.svg?branch=master
|
.. image:: https://travis-ci.org/libgit2/pygit2.svg?branch=master
|
||||||
:target: http://travis-ci.org/libgit2/pygit2
|
: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
|
.. code-block:: sh
|
||||||
|
|
||||||
$ git clone git://github.com/libgit2/pygit2.git
|
$ git clone git://github.com/libgit2/pygit2.git
|
||||||
|
@ -83,6 +83,9 @@ Attributes:
|
|||||||
|
|
||||||
.. autoattribute:: pygit2.DiffFile.path
|
.. autoattribute:: pygit2.DiffFile.path
|
||||||
.. autoattribute:: pygit2.DiffFile.id
|
.. autoattribute:: pygit2.DiffFile.id
|
||||||
|
.. autoattribute:: pygit2.DiffFile.size
|
||||||
|
.. autoattribute:: pygit2.DiffFile.flags
|
||||||
|
.. autoattribute:: pygit2.DiffFile.mode
|
||||||
|
|
||||||
|
|
||||||
The DiffHunk type
|
The DiffHunk type
|
||||||
@ -108,5 +111,5 @@ The DiffLine type
|
|||||||
.. autoattribute :: pygit2.DiffLine.origin
|
.. autoattribute :: pygit2.DiffLine.origin
|
||||||
.. autoattribute :: pygit2.DiffLine.content
|
.. autoattribute :: pygit2.DiffLine.content
|
||||||
.. autoattribute :: pygit2.DiffLine.old_lineno
|
.. autoattribute :: pygit2.DiffLine.old_lineno
|
||||||
.. autoattribute :: pygit2.DiffLine.old_lineno
|
.. autoattribute :: pygit2.DiffLine.new_lineno
|
||||||
.. autoattribute :: pygit2.DiffLine.num_lines
|
.. autoattribute :: pygit2.DiffLine.num_lines
|
||||||
|
@ -18,7 +18,7 @@ library that has been built against. The version number has a
|
|||||||
.. py:data:: LIBGIT2_VER_MAJOR
|
.. py:data:: LIBGIT2_VER_MAJOR
|
||||||
|
|
||||||
Integer value of the major version number. For example, for the version
|
Integer value of the major version number. For example, for the version
|
||||||
``0.23.0``::
|
``0.26.0``::
|
||||||
|
|
||||||
>>> print LIBGIT2_VER_MAJOR
|
>>> print LIBGIT2_VER_MAJOR
|
||||||
0
|
0
|
||||||
@ -26,15 +26,15 @@ library that has been built against. The version number has a
|
|||||||
.. py:data:: LIBGIT2_VER_MINOR
|
.. py:data:: LIBGIT2_VER_MINOR
|
||||||
|
|
||||||
Integer value of the minor version number. For example, for the version
|
Integer value of the minor version number. For example, for the version
|
||||||
``0.23.0``::
|
``0.26.0``::
|
||||||
|
|
||||||
>>> print LIBGIT2_VER_MINOR
|
>>> print LIBGIT2_VER_MINOR
|
||||||
22
|
26
|
||||||
|
|
||||||
.. py:data:: LIBGIT2_VER_REVISION
|
.. py:data:: LIBGIT2_VER_REVISION
|
||||||
|
|
||||||
Integer value of the revision version number. For example, for the version
|
Integer value of the revision version number. For example, for the version
|
||||||
``0.23.0``::
|
``0.26.0``::
|
||||||
|
|
||||||
>>> print LIBGIT2_VER_REVISION
|
>>> print LIBGIT2_VER_REVISION
|
||||||
0
|
0
|
||||||
@ -44,7 +44,7 @@ library that has been built against. The version number has a
|
|||||||
The libgit2 version number as a string::
|
The libgit2 version number as a string::
|
||||||
|
|
||||||
>>> print LIBGIT2_VERSION
|
>>> print LIBGIT2_VERSION
|
||||||
'0.23.0'
|
'0.26.0'
|
||||||
|
|
||||||
Errors
|
Errors
|
||||||
======
|
======
|
||||||
|
@ -7,17 +7,18 @@ Welcome to pygit2's documentation!
|
|||||||
==================================
|
==================================
|
||||||
|
|
||||||
Pygit2 is a set of Python bindings to the libgit2 shared library, libgit2
|
Pygit2 is a set of Python bindings to the libgit2 shared library, libgit2
|
||||||
implements the core of Git. Pygit2 works with Python 2.7, 3.2, 3.3, 3.4 and
|
implements the core of Git. Pygit2 works with Python 2.7, 3.3, 3.4, 3.5,
|
||||||
pypy.
|
3.6 and pypy.
|
||||||
|
|
||||||
It is likely to work with Python 2.6 and 3.1, but these versions are not
|
It is likely to work with Python 2.6 and 3.1, but these versions are not
|
||||||
officially supported.
|
officially supported.
|
||||||
|
|
||||||
Pygit2 links:
|
Links:
|
||||||
|
|
||||||
- http://github.com/libgit2/pygit2 -- Source code and issue tracker
|
- https://github.com/libgit2/pygit2 -- Source code and issue tracker
|
||||||
- http://www.pygit2.org/ -- Documentation
|
- http://www.pygit2.org/ -- Documentation
|
||||||
- http://pypi.python.org/pypi/pygit2 -- Download
|
- https://pypi.python.org/pypi/pygit2 -- Download
|
||||||
|
- https://github.com/libgit2/pygit2/blob/master/CHANGELOG.rst -- Changelog
|
||||||
|
|
||||||
Start:
|
Start:
|
||||||
|
|
||||||
@ -49,6 +50,7 @@ Usage guide:
|
|||||||
blame
|
blame
|
||||||
settings
|
settings
|
||||||
features
|
features
|
||||||
|
backends
|
||||||
|
|
||||||
|
|
||||||
Indices and tables
|
Indices and tables
|
||||||
|
@ -13,11 +13,19 @@ Installation
|
|||||||
Requirements
|
Requirements
|
||||||
============
|
============
|
||||||
|
|
||||||
- Python 2.7, 3.2+ or pypy (including the development headers)
|
- Python 2.7, 3.3+ or PyPy 2.6+ (including the development headers)
|
||||||
- Libgit2 v0.23.x
|
- Libgit2 v0.26.x
|
||||||
- cffi 0.8.1+
|
- cffi 1.0+
|
||||||
- Libssh2, optional, used for SSH network operations.
|
- six
|
||||||
- pkg-config, optional, used for SSH network operations.
|
- tox (optional)
|
||||||
|
|
||||||
|
Optional libgit2 dependecies to support ssh and https:
|
||||||
|
|
||||||
|
- https: WinHTTP (Windows), SecureTransport (OS X) or OpenSSL.
|
||||||
|
- ssh: libssh2, pkg-config
|
||||||
|
|
||||||
|
It should work with older versions of cffi and PyPy, but using cffi 1.0+
|
||||||
|
(and PyPy 2.6+) is strongly encouraged.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
@ -35,11 +43,11 @@ while the last number |lq| *.micro* |rq| auto-increments independently.
|
|||||||
|
|
||||||
As illustration see this table of compatible releases:
|
As illustration see this table of compatible releases:
|
||||||
|
|
||||||
+-----------+--------+----------------+----------------------------------------+
|
+-----------+--------+----------------+------------------------+
|
||||||
|**libgit2**| 0.23.0 | 0.22.0, 0.22.1 | 0.21.1, 0.21.2 |
|
|**libgit2**| 0.26.0 | 0.25.0, 0.25.1 | 0.24.0, 0.24.1, 0.24.2 |
|
||||||
+-----------+--------+----------------+----------------------------------------+
|
+-----------+--------+----------------+------------------------+
|
||||||
|**pygit2** | 0.23.0 | 0.22.0 | 0.21.0, 0.21.1, 0.21.2, 0.21.3, 0.21.4 |
|
|**pygit2** | 0.26.0 | 0.25.0, 0.25.1 | 0.24.0, 0.24.1, 0.24.2 |
|
||||||
+-----------+--------+----------------+----------------------------------------+
|
+-----------+--------+----------------+------------------------+
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
|
|
||||||
@ -56,9 +64,9 @@ directory, do:
|
|||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
$ wget https://github.com/libgit2/libgit2/archive/v0.23.0.tar.gz
|
$ wget https://github.com/libgit2/libgit2/archive/v0.26.0.tar.gz
|
||||||
$ tar xzf v0.23.0.tar.gz
|
$ tar xzf v0.26.0.tar.gz
|
||||||
$ cd libgit2-0.23.0/
|
$ cd libgit2-0.26.0/
|
||||||
$ cmake .
|
$ cmake .
|
||||||
$ make
|
$ make
|
||||||
$ sudo make install
|
$ sudo make install
|
||||||
@ -140,9 +148,9 @@ Install libgit2 (see we define the installation prefix):
|
|||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
$ wget https://github.com/libgit2/libgit2/archive/v0.23.0.tar.gz
|
$ wget https://github.com/libgit2/libgit2/archive/v0.26.0.tar.gz
|
||||||
$ tar xzf v0.23.0.tar.gz
|
$ tar xzf v0.26.0.tar.gz
|
||||||
$ cd libgit2-0.23.0/
|
$ cd libgit2-0.26.0/
|
||||||
$ cmake . -DCMAKE_INSTALL_PREFIX=$LIBGIT2
|
$ cmake . -DCMAKE_INSTALL_PREFIX=$LIBGIT2
|
||||||
$ make
|
$ make
|
||||||
$ make install
|
$ make install
|
||||||
@ -178,32 +186,34 @@ everytime. Verify yourself if curious:
|
|||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
$ readelf --dynamic lib/python2.7/site-packages/pygit2-0.23.0-py2.7-linux-x86_64.egg/_pygit2.so | grep PATH
|
$ readelf --dynamic lib/python2.7/site-packages/pygit2-0.26.0-py2.7-linux-x86_64.egg/_pygit2.so | grep PATH
|
||||||
0x000000000000001d (RUNPATH) Library runpath: [/tmp/venv/lib]
|
0x000000000000001d (RUNPATH) Library runpath: [/tmp/venv/lib]
|
||||||
|
|
||||||
|
|
||||||
Installing on Windows
|
Installing on Windows
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
pygit2 expects to find the libgit2 installed files in the directory specified
|
`pygit2` for Windows is packaged into wheels and can be easily
|
||||||
in the ``LIBGIT2`` environment variable.
|
installed with `pip`:
|
||||||
|
|
||||||
In addition, make sure that libgit2 is build in "__cdecl" mode.
|
pip install pygit2
|
||||||
The following recipe shows you how to do it, assuming you're working
|
|
||||||
from a bash shell:
|
For development it is also possible to build `pygit2` with `libgit2`
|
||||||
|
from sources. `libgit2` location is specified by the ``LIBGIT2``
|
||||||
|
environment variable. `libgit2` should be built in "__cdecl" mode.
|
||||||
|
The following recipe shows you how to do it from a bash shell:
|
||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
$ export LIBGIT2=C:/Dev/libgit2
|
$ export LIBGIT2=C:/Dev/libgit2
|
||||||
$ wget https://github.com/libgit2/libgit2/archive/v0.23.0.tar.gz
|
$ git clone --depth=1 -b maint/v0.26 https://github.com/libgit2/libgit2.git
|
||||||
$ tar xzf v0.23.0.tar.gz
|
$ cd libgit2
|
||||||
$ cd libgit2-0.23.0/
|
|
||||||
$ cmake . -DSTDCALL=OFF -DCMAKE_INSTALL_PREFIX=$LIBGIT2 -G "Visual Studio 9 2008"
|
$ cmake . -DSTDCALL=OFF -DCMAKE_INSTALL_PREFIX=$LIBGIT2 -G "Visual Studio 9 2008"
|
||||||
$ cmake --build . --config release --target install
|
$ cmake --build . --config release --target install
|
||||||
$ ctest -v
|
$ ctest -v
|
||||||
|
|
||||||
At this point, you're ready to execute the generic pygit2 installation
|
At this point, you're ready to execute the generic `pygit2`
|
||||||
steps described above.
|
installation steps described at the start of this page.
|
||||||
|
|
||||||
|
|
||||||
Installing on OS X
|
Installing on OS X
|
||||||
|
@ -132,6 +132,7 @@ them to the Git object database:
|
|||||||
|
|
||||||
.. automethod:: pygit2.Repository.create_blob_fromworkdir
|
.. automethod:: pygit2.Repository.create_blob_fromworkdir
|
||||||
.. automethod:: pygit2.Repository.create_blob_fromdisk
|
.. automethod:: pygit2.Repository.create_blob_fromdisk
|
||||||
|
.. automethod:: pygit2.Repository.create_blob_fromiobase
|
||||||
|
|
||||||
There are also some functions to calculate the id for a byte string without
|
There are also some functions to calculate the id for a byte string without
|
||||||
creating the blob object:
|
creating the blob object:
|
||||||
@ -176,6 +177,7 @@ Tree entries
|
|||||||
.. autoattribute:: pygit2.TreeEntry.id
|
.. autoattribute:: pygit2.TreeEntry.id
|
||||||
.. autoattribute:: pygit2.TreeEntry.hex
|
.. autoattribute:: pygit2.TreeEntry.hex
|
||||||
.. autoattribute:: pygit2.TreeEntry.filemode
|
.. autoattribute:: pygit2.TreeEntry.filemode
|
||||||
|
.. autoattribute:: pygit2.TreeEntry.type
|
||||||
|
|
||||||
.. method:: TreeEntry.__cmp__(TreeEntry)
|
.. method:: TreeEntry.__cmp__(TreeEntry)
|
||||||
|
|
||||||
@ -188,14 +190,14 @@ Example::
|
|||||||
6
|
6
|
||||||
|
|
||||||
>>> for entry in tree: # Iteration
|
>>> for entry in tree: # Iteration
|
||||||
... print(entry.id, entry.name)
|
... print(entry.id, entry.type, entry.name)
|
||||||
...
|
...
|
||||||
7151ca7cd3e59f3eab19c485cfbf3cb30928d7fa .gitignore
|
7151ca7cd3e59f3eab19c485cfbf3cb30928d7fa blob .gitignore
|
||||||
c36f4cf1e38ec1bb9d9ad146ed572b89ecfc9f18 COPYING
|
c36f4cf1e38ec1bb9d9ad146ed572b89ecfc9f18 blob COPYING
|
||||||
32b30b90b062f66957d6790c3c155c289c34424e README.md
|
32b30b90b062f66957d6790c3c155c289c34424e blob README.md
|
||||||
c87dae4094b3a6d10e08bc6c5ef1f55a7e448659 pygit2.c
|
c87dae4094b3a6d10e08bc6c5ef1f55a7e448659 blob pygit2.c
|
||||||
85a67270a49ef16cdd3d328f06a3e4b459f09b27 setup.py
|
85a67270a49ef16cdd3d328f06a3e4b459f09b27 blob setup.py
|
||||||
3d8985bbec338eb4d47c5b01b863ee89d044bd53 test
|
3d8985bbec338eb4d47c5b01b863ee89d044bd53 tree test
|
||||||
|
|
||||||
>>> entry = tree['pygit2.c'] # Get an entry by name
|
>>> entry = tree['pygit2.c'] # Get an entry by name
|
||||||
>>> entry
|
>>> entry
|
||||||
|
@ -49,7 +49,7 @@ example `three-argument rebases`_.
|
|||||||
repo = pygit2.Repository('/path/to/repo')
|
repo = pygit2.Repository('/path/to/repo')
|
||||||
|
|
||||||
cherry = repo.revparse_single('9e044d03c')
|
cherry = repo.revparse_single('9e044d03c')
|
||||||
basket = repo.lookup_branch('basket')
|
basket = repo.branches.get('basket')
|
||||||
|
|
||||||
base = repo.merge_base(cherry.oid, basket.target)
|
base = repo.merge_base(cherry.oid, basket.target)
|
||||||
base_tree = cherry.parents[0].tree
|
base_tree = cherry.parents[0].tree
|
||||||
|
@ -4,15 +4,25 @@ References
|
|||||||
|
|
||||||
.. contents::
|
.. contents::
|
||||||
|
|
||||||
.. automethod:: pygit2.Repository.listall_references
|
.. autoclass:: pygit2.repository.References
|
||||||
.. automethod:: pygit2.Repository.lookup_reference
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:special-members: __getitem__, __iter__, __contains__
|
||||||
|
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
>>> all_refs = repo.listall_references()
|
>>> all_refs = list(repo.references)
|
||||||
|
|
||||||
>>> master_ref = repo.lookup_reference("refs/heads/master")
|
>>> master_ref = repo.lookup_reference("refs/heads/master")
|
||||||
>>> commit = master_ref.get_object() # or repo[master_ref.target]
|
>>> commit = master_ref.get_object() # or repo[master_ref.target]
|
||||||
|
|
||||||
|
# Create a reference
|
||||||
|
>>> ref = repo.references.create('refs/tags/version1', LAST_COMMIT)
|
||||||
|
|
||||||
|
# Delete a reference
|
||||||
|
>>> repo.references.delete('refs/tags/version1')
|
||||||
|
|
||||||
|
|
||||||
The Reference type
|
The Reference type
|
||||||
====================
|
====================
|
||||||
@ -68,28 +78,33 @@ Branches
|
|||||||
Branches inherit from References, and additionally provide specialized
|
Branches inherit from References, and additionally provide specialized
|
||||||
accessors for some unique features.
|
accessors for some unique features.
|
||||||
|
|
||||||
.. automethod:: pygit2.Repository.listall_branches
|
.. autoclass:: pygit2.repository.Branches
|
||||||
.. automethod:: pygit2.Repository.lookup_branch
|
:members:
|
||||||
.. automethod:: pygit2.Repository.create_branch
|
:undoc-members:
|
||||||
|
:special-members: __getitem__, __iter__, __contains__
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
>>> local_branches = repo.listall_branches()
|
>>> # Listing all branches
|
||||||
>>> # equivalent to
|
>>> branches_list = list(repo.branches)
|
||||||
>>> local_branches = repo.listall_branches(pygit2.GIT_BRANCH_LOCAL)
|
>>> # Local only
|
||||||
|
>>> local_branches = list(repo.branches.local)
|
||||||
|
>>> # Remote only
|
||||||
|
>>> remote_branches = list(repo.branches.remote)
|
||||||
|
|
||||||
>>> remote_branches = repo.listall_branches(pygit2.GIT_BRANCH_REMOTE)
|
>>> # Get a branch
|
||||||
|
>>> branch = repo.branches['master']
|
||||||
|
>>> other_branch = repo.branches['does-not-exist'] # Will raise a KeyError
|
||||||
|
>>> other_branch = repo.branches.get('does-not-exist') # Returns None
|
||||||
|
|
||||||
>>> all_branches = repo.listall_branches(pygit2.GIT_BRANCH_REMOTE |
|
>>> remote_branch = repo.branches.remote['upstream/feature']
|
||||||
pygit2.GIT_BRANCH_LOCAL)
|
|
||||||
|
|
||||||
>>> master_branch = repo.lookup_branch('master')
|
>>> # Create a local branch
|
||||||
>>> # equivalent to
|
>>> new_branch = repo.branches.local.create('new-branch')
|
||||||
>>> master_branch = repo.lookup_branch('master',
|
|
||||||
pygit2.GIT_BRANCH_LOCAL)
|
>>> And delete it
|
||||||
|
>>> repo.branches.delete('new-branch')
|
||||||
|
|
||||||
>>> remote_branch = repo.lookup_branch('upstream/feature',
|
|
||||||
pygit2.GIT_BRANCH_REMOTE)
|
|
||||||
|
|
||||||
The Branch type
|
The Branch type
|
||||||
====================
|
====================
|
||||||
@ -98,17 +113,19 @@ The Branch type
|
|||||||
.. autoattribute:: pygit2.Branch.remote_name
|
.. autoattribute:: pygit2.Branch.remote_name
|
||||||
.. autoattribute:: pygit2.Branch.upstream
|
.. autoattribute:: pygit2.Branch.upstream
|
||||||
.. autoattribute:: pygit2.Branch.upstream_name
|
.. autoattribute:: pygit2.Branch.upstream_name
|
||||||
|
|
||||||
.. automethod:: pygit2.Branch.rename
|
.. automethod:: pygit2.Branch.rename
|
||||||
.. automethod:: pygit2.Branch.delete
|
.. automethod:: pygit2.Branch.delete
|
||||||
.. automethod:: pygit2.Branch.is_head
|
.. automethod:: pygit2.Branch.is_head
|
||||||
|
.. automethod:: pygit2.Branch.is_checked_out
|
||||||
|
|
||||||
The reference log
|
The reference log
|
||||||
====================
|
====================
|
||||||
|
|
||||||
Example::
|
Example::
|
||||||
|
|
||||||
>>> head = repo.lookup_reference('refs/heads/master')
|
>>> head = repo.references.get('refs/heads/master') # Returns None if not found
|
||||||
|
>>> # Almost equivalent to
|
||||||
|
>>> head = repo.references['refs/heads/master'] # Raises KeyError if not found
|
||||||
>>> for entry in head.log():
|
>>> for entry in head.log():
|
||||||
... print(entry.message)
|
... print(entry.message)
|
||||||
|
|
||||||
|
@ -21,6 +21,12 @@ The Remote type
|
|||||||
.. autoclass:: pygit2.Remote
|
.. autoclass:: pygit2.Remote
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
The RemoteCallbacks type
|
||||||
|
========================
|
||||||
|
|
||||||
|
.. autoclass:: pygit2.RemoteCallbacks
|
||||||
|
:members:
|
||||||
|
|
||||||
The TransferProgress type
|
The TransferProgress type
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
@ -42,8 +48,6 @@ Refspecs objects are not constructed directly, but returned by
|
|||||||
Credentials
|
Credentials
|
||||||
================
|
================
|
||||||
|
|
||||||
.. automethod:: pygit2.Remote.credentials
|
|
||||||
|
|
||||||
There are two types of credentials: username/password and SSH key
|
There are two types of credentials: username/password and SSH key
|
||||||
pairs. Both :py:class:`pygit2.UserPass` and :py:class:`pygit2.Keypair`
|
pairs. Both :py:class:`pygit2.UserPass` and :py:class:`pygit2.Keypair`
|
||||||
are callable objects, with the appropriate signature for the
|
are callable objects, with the appropriate signature for the
|
||||||
|
@ -67,7 +67,11 @@ Below there are some general attributes and methods:
|
|||||||
.. autoattribute:: pygit2.Repository.default_signature
|
.. autoattribute:: pygit2.Repository.default_signature
|
||||||
.. automethod:: pygit2.Repository.read
|
.. automethod:: pygit2.Repository.read
|
||||||
.. automethod:: pygit2.Repository.write
|
.. automethod:: pygit2.Repository.write
|
||||||
|
.. automethod:: pygit2.Repository.ahead_behind
|
||||||
|
.. automethod:: pygit2.Repository.create_reference
|
||||||
|
.. automethod:: pygit2.Repository.describe
|
||||||
|
.. automethod:: pygit2.Repository.path_is_ignored
|
||||||
.. automethod:: pygit2.Repository.reset
|
.. automethod:: pygit2.Repository.reset
|
||||||
|
.. automethod:: pygit2.Repository.revert_commit
|
||||||
.. automethod:: pygit2.Repository.state_cleanup
|
.. automethod:: pygit2.Repository.state_cleanup
|
||||||
.. automethod:: pygit2.Repository.write_archive
|
.. automethod:: pygit2.Repository.write_archive
|
||||||
.. automethod:: pygit2.Repository.ahead_behind
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
**********************************************************************
|
**********************************************************************
|
||||||
The submodule
|
Submodules
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
A submodule is a foreign repository that is embedded within a
|
A submodule is a foreign repository that is embedded within a
|
||||||
dedicated subdirectory of the repositories tree.
|
dedicated subdirectory of the repositories tree.
|
||||||
|
|
||||||
|
.. automethod:: pygit2.Repository.init_submodules
|
||||||
|
.. automethod:: pygit2.Repository.update_submodules
|
||||||
.. automethod:: pygit2.Repository.lookup_submodule
|
.. automethod:: pygit2.Repository.lookup_submodule
|
||||||
.. automethod:: pygit2.Repository.listall_submodules
|
.. automethod:: pygit2.Repository.listall_submodules
|
||||||
|
|
||||||
|
@ -71,3 +71,11 @@ Lower level API:
|
|||||||
.. automethod:: pygit2.Repository.checkout_head
|
.. automethod:: pygit2.Repository.checkout_head
|
||||||
.. automethod:: pygit2.Repository.checkout_tree
|
.. automethod:: pygit2.Repository.checkout_tree
|
||||||
.. automethod:: pygit2.Repository.checkout_index
|
.. automethod:: pygit2.Repository.checkout_index
|
||||||
|
|
||||||
|
Stash
|
||||||
|
====================
|
||||||
|
|
||||||
|
.. automethod:: pygit2.Repository.stash
|
||||||
|
.. automethod:: pygit2.Repository.stash_apply
|
||||||
|
.. automethod:: pygit2.Repository.stash_drop
|
||||||
|
.. automethod:: pygit2.Repository.stash_pop
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -35,15 +35,15 @@ from _pygit2 import *
|
|||||||
from .blame import Blame, BlameHunk
|
from .blame import Blame, BlameHunk
|
||||||
from .config import Config
|
from .config import Config
|
||||||
from .credentials import *
|
from .credentials import *
|
||||||
from .errors import check_error
|
from .errors import check_error, Passthrough
|
||||||
from .ffi import ffi, C
|
from .ffi import ffi, C
|
||||||
from .index import Index, IndexEntry
|
from .index import Index, IndexEntry
|
||||||
from .remote import Remote, get_credentials
|
from .remote import Remote, RemoteCallbacks, get_credentials
|
||||||
from .repository import Repository
|
from .repository import Repository
|
||||||
from .settings import Settings
|
from .settings import Settings
|
||||||
from .submodule import Submodule
|
from .submodule import Submodule
|
||||||
from .utils import to_bytes, to_str
|
from .utils import to_bytes, to_str
|
||||||
from ._utils import __version__
|
from ._build import __version__
|
||||||
|
|
||||||
|
|
||||||
# Features
|
# Features
|
||||||
@ -105,6 +105,9 @@ def init_repository(path, bare=False,
|
|||||||
See libgit2's documentation on git_repository_init_ext for further details.
|
See libgit2's documentation on git_repository_init_ext for further details.
|
||||||
"""
|
"""
|
||||||
# Pre-process input parameters
|
# Pre-process input parameters
|
||||||
|
if path is None:
|
||||||
|
raise TypeError('Expected string type for path, found None.')
|
||||||
|
|
||||||
if bare:
|
if bare:
|
||||||
flags |= GIT_REPOSITORY_INIT_BARE
|
flags |= GIT_REPOSITORY_INIT_BARE
|
||||||
|
|
||||||
@ -143,22 +146,6 @@ def init_repository(path, bare=False,
|
|||||||
# Ok
|
# Ok
|
||||||
return Repository(to_str(path))
|
return Repository(to_str(path))
|
||||||
|
|
||||||
|
|
||||||
@ffi.callback('int (*credentials)(git_cred **cred, const char *url,'
|
|
||||||
'const char *username_from_url, unsigned int allowed_types,'
|
|
||||||
'void *data)')
|
|
||||||
def _credentials_cb(cred_out, url, username_from_url, allowed, data):
|
|
||||||
d = ffi.from_handle(data)
|
|
||||||
|
|
||||||
try:
|
|
||||||
ccred = get_credentials(d['credentials_cb'], url, username_from_url, allowed)
|
|
||||||
cred_out[0] = ccred[0]
|
|
||||||
except Exception as e:
|
|
||||||
d['exception'] = e
|
|
||||||
return C.GIT_EUSER
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
@ffi.callback('int (*git_repository_create_cb)(git_repository **out,'
|
@ffi.callback('int (*git_repository_create_cb)(git_repository **out,'
|
||||||
'const char *path, int bare, void *payload)')
|
'const char *path, int bare, void *payload)')
|
||||||
def _repository_create_cb(repo_out, path, bare, data):
|
def _repository_create_cb(repo_out, path, bare, data):
|
||||||
@ -189,24 +176,9 @@ def _remote_create_cb(remote_out, repo, name, url, data):
|
|||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@ffi.callback('int (*git_transport_certificate_check_cb)'
|
|
||||||
'(git_cert *cert, int valid, const char *host, void *payload)')
|
|
||||||
def _certificate_cb(cert_i, valid, host, data):
|
|
||||||
d = ffi.from_handle(data)
|
|
||||||
try:
|
|
||||||
# python's parting is deep in the libraries and assumes an OpenSSL-owned cert
|
|
||||||
val = d['certificate_cb'](None, bool(valid), ffi.string(host))
|
|
||||||
if not val:
|
|
||||||
return C.GIT_ECERTIFICATE
|
|
||||||
except Exception as e:
|
|
||||||
d['exception'] = e
|
|
||||||
return C.GIT_EUSER
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def clone_repository(
|
def clone_repository(
|
||||||
url, path, bare=False, repository=None, remote=None,
|
url, path, bare=False, repository=None, remote=None,
|
||||||
checkout_branch=None, credentials=None, certificate=None):
|
checkout_branch=None, callbacks=None):
|
||||||
"""Clones a new Git repository from *url* in the given *path*.
|
"""Clones a new Git repository from *url* in the given *path*.
|
||||||
|
|
||||||
Returns a Repository class pointing to the newly cloned repository.
|
Returns a Repository class pointing to the newly cloned repository.
|
||||||
@ -224,11 +196,8 @@ def clone_repository(
|
|||||||
:param str checkout_branch: Branch to checkout after the
|
:param str checkout_branch: Branch to checkout after the
|
||||||
clone. The default is to use the remote's default branch.
|
clone. The default is to use the remote's default branch.
|
||||||
|
|
||||||
:param callable credentials: authentication to use if the remote
|
:param RemoteCallbacks callbacks: object which implements the
|
||||||
requires it
|
callbacks as methods.
|
||||||
|
|
||||||
:param callable certificate: callback to verify the host's
|
|
||||||
certificate or fingerprint.
|
|
||||||
|
|
||||||
:rtype: Repository
|
:rtype: Repository
|
||||||
|
|
||||||
@ -240,8 +209,8 @@ def clone_repository(
|
|||||||
signature. The Remote it returns will be used instead of the default
|
signature. The Remote it returns will be used instead of the default
|
||||||
one.
|
one.
|
||||||
|
|
||||||
The certificate callback has `(cert, valid, hostname) -> bool` as
|
The callbacks should be an object which inherits from
|
||||||
a signature. Return True to accept the connection, False to abort.
|
`pyclass:RemoteCallbacks`.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -252,10 +221,8 @@ def clone_repository(
|
|||||||
|
|
||||||
# Data, let's use a dict as we don't really want much more
|
# Data, let's use a dict as we don't really want much more
|
||||||
d = {}
|
d = {}
|
||||||
d['credentials_cb'] = credentials
|
|
||||||
d['repository_cb'] = repository
|
d['repository_cb'] = repository
|
||||||
d['remote_cb'] = remote
|
d['remote_cb'] = remote
|
||||||
d['certificate_cb'] = certificate
|
|
||||||
d_handle = ffi.new_handle(d)
|
d_handle = ffi.new_handle(d)
|
||||||
|
|
||||||
# Perform the initialization with the version we compiled
|
# Perform the initialization with the version we compiled
|
||||||
@ -277,13 +244,11 @@ def clone_repository(
|
|||||||
|
|
||||||
|
|
||||||
opts.bare = bare
|
opts.bare = bare
|
||||||
if credentials:
|
|
||||||
opts.fetch_opts.callbacks.credentials = _credentials_cb
|
|
||||||
opts.fetch_opts.callbacks.payload = d_handle
|
|
||||||
|
|
||||||
if certificate:
|
if callbacks is None:
|
||||||
opts.fetch_opts.callbacks.certificate_check = _certificate_cb
|
callbacks = RemoteCallbacks()
|
||||||
opts.fetch_opts.callbacks.payload = d_handle
|
|
||||||
|
callbacks._fill_fetch_options(opts.fetch_opts)
|
||||||
|
|
||||||
err = C.git_clone(crepo, to_bytes(url), to_bytes(path), opts)
|
err = C.git_clone(crepo, to_bytes(url), to_bytes(path), opts)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -26,23 +26,18 @@
|
|||||||
# Boston, MA 02110-1301, USA.
|
# Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This is an special module, it provides stuff used by setup.py and by
|
This is an special module, it provides stuff used by setup.py at build time.
|
||||||
pygit2 at run-time.
|
But also used by pygit2 at run time.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Import from the Standard Library
|
# Import from the Standard Library
|
||||||
from binascii import crc32
|
|
||||||
import codecs
|
|
||||||
import os
|
import os
|
||||||
from os import getenv
|
from os import getenv
|
||||||
from os.path import abspath, dirname
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# The version number of pygit2
|
# The version number of pygit2
|
||||||
#
|
#
|
||||||
__version__ = '0.23.0'
|
__version__ = '0.26.0'
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -67,44 +62,3 @@ def get_libgit2_paths():
|
|||||||
os.path.join(libgit2_path, 'include'),
|
os.path.join(libgit2_path, 'include'),
|
||||||
getenv('LIBGIT2_LIB', os.path.join(libgit2_path, 'lib')),
|
getenv('LIBGIT2_LIB', os.path.join(libgit2_path, 'lib')),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Loads the cffi extension
|
|
||||||
#
|
|
||||||
def get_ffi():
|
|
||||||
import cffi
|
|
||||||
|
|
||||||
ffi = cffi.FFI()
|
|
||||||
|
|
||||||
# Load C definitions
|
|
||||||
if getattr(sys, 'frozen', False):
|
|
||||||
if hasattr(sys, '_MEIPASS'):
|
|
||||||
dir_path = sys._MEIPASS
|
|
||||||
else:
|
|
||||||
dir_path = dirname(abspath(sys.executable))
|
|
||||||
else:
|
|
||||||
dir_path = dirname(abspath(__file__))
|
|
||||||
|
|
||||||
decl_path = os.path.join(dir_path, 'decl.h')
|
|
||||||
with codecs.open(decl_path, 'r', 'utf-8') as header:
|
|
||||||
ffi.cdef(header.read())
|
|
||||||
|
|
||||||
# The modulename
|
|
||||||
# Simplified version of what cffi does: remove kwargs and vengine
|
|
||||||
preamble = "#include <git2.h>"
|
|
||||||
key = [sys.version[:3], cffi.__version__, preamble] + ffi._cdefsources
|
|
||||||
key = '\x00'.join(key)
|
|
||||||
if sys.version_info >= (3,):
|
|
||||||
key = key.encode('utf-8')
|
|
||||||
k1 = hex(crc32(key[0::2]) & 0xffffffff).lstrip('0x').rstrip('L')
|
|
||||||
k2 = hex(crc32(key[1::2]) & 0xffffffff).lstrip('0').rstrip('L')
|
|
||||||
modulename = 'pygit2_cffi_%s%s' % (k1, k2)
|
|
||||||
|
|
||||||
# Load extension module
|
|
||||||
libgit2_bin, libgit2_include, libgit2_lib = get_libgit2_paths()
|
|
||||||
C = ffi.verify(preamble, modulename=modulename, libraries=["git2"],
|
|
||||||
include_dirs=[libgit2_include], library_dirs=[libgit2_lib])
|
|
||||||
|
|
||||||
# Ok
|
|
||||||
return ffi, C
|
|
76
pygit2/_run.py
Normal file
76
pygit2/_run.py
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
|
#
|
||||||
|
# This file is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
# as published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# In addition to the permissions in the GNU General Public License,
|
||||||
|
# the authors give you unlimited permission to link the compiled
|
||||||
|
# version of this file into combinations with other programs,
|
||||||
|
# and to distribute those combinations without any restriction
|
||||||
|
# coming from the use of this file. (The General Public License
|
||||||
|
# restrictions do apply in other respects; for example, they cover
|
||||||
|
# modification of the file, and distribution when not linked into
|
||||||
|
# a combined executable.)
|
||||||
|
#
|
||||||
|
# This file is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
"""
|
||||||
|
This is an special module, it provides stuff used by by pygit2 at run-time.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Import from the Standard Library
|
||||||
|
import codecs
|
||||||
|
import os
|
||||||
|
from os.path import abspath, dirname
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Import from cffi
|
||||||
|
from cffi import FFI
|
||||||
|
|
||||||
|
# Import from pygit2
|
||||||
|
from _build import get_libgit2_paths
|
||||||
|
|
||||||
|
|
||||||
|
# C_HEADER_SRC
|
||||||
|
if getattr(sys, 'frozen', False):
|
||||||
|
dir_path = getattr(sys, '_MEIPASS', None)
|
||||||
|
if dir_path is None:
|
||||||
|
dir_path = dirname(abspath(sys.executable))
|
||||||
|
else:
|
||||||
|
dir_path = dirname(abspath(__file__))
|
||||||
|
|
||||||
|
decl_path = os.path.join(dir_path, 'decl.h')
|
||||||
|
with codecs.open(decl_path, 'r', 'utf-8') as header:
|
||||||
|
C_HEADER_SRC = header.read()
|
||||||
|
|
||||||
|
# C_KEYWORDS
|
||||||
|
libgit2_bin, libgit2_include, libgit2_lib = get_libgit2_paths()
|
||||||
|
C_KEYWORDS = dict(libraries=['git2'],
|
||||||
|
library_dirs=[libgit2_lib],
|
||||||
|
include_dirs=[libgit2_include])
|
||||||
|
|
||||||
|
# preamble
|
||||||
|
preamble = "#include <git2.h>"
|
||||||
|
|
||||||
|
# ffi
|
||||||
|
ffi = FFI()
|
||||||
|
set_source = getattr(ffi, 'set_source', None)
|
||||||
|
if set_source is not None:
|
||||||
|
set_source("pygit2._libgit2", preamble, **C_KEYWORDS)
|
||||||
|
|
||||||
|
ffi.cdef(C_HEADER_SRC)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
ffi.compile()
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
198
pygit2/decl.h
198
pygit2/decl.h
@ -54,6 +54,16 @@ typedef enum {
|
|||||||
GIT_EINVALIDSPEC = -12,
|
GIT_EINVALIDSPEC = -12,
|
||||||
GIT_ECONFLICT = -13,
|
GIT_ECONFLICT = -13,
|
||||||
GIT_ELOCKED = -14,
|
GIT_ELOCKED = -14,
|
||||||
|
GIT_EMODIFIED = -15,
|
||||||
|
GIT_EAUTH = -16,
|
||||||
|
GIT_ECERTIFICATE = -17,
|
||||||
|
GIT_EAPPLIED = -18,
|
||||||
|
GIT_EPEEL = -19,
|
||||||
|
GIT_EEOF = -20,
|
||||||
|
GIT_EINVALID = -21,
|
||||||
|
GIT_EUNCOMMITTED = -22,
|
||||||
|
GIT_EDIRECTORY = -23,
|
||||||
|
GIT_EMERGECONFLICT = -24,
|
||||||
|
|
||||||
GIT_PASSTHROUGH = -30,
|
GIT_PASSTHROUGH = -30,
|
||||||
GIT_ITEROVER = -31,
|
GIT_ITEROVER = -31,
|
||||||
@ -131,21 +141,21 @@ typedef enum {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
git_cert_t cert_type;
|
git_cert_t cert_type;
|
||||||
|
} git_cert;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
git_cert parent;
|
||||||
git_cert_ssh_t type;
|
git_cert_ssh_t type;
|
||||||
unsigned char hash_md5[16];
|
unsigned char hash_md5[16];
|
||||||
unsigned char hash_sha1[20];
|
unsigned char hash_sha1[20];
|
||||||
} git_cert_hostkey;
|
} git_cert_hostkey;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
git_cert_t cert_type;
|
git_cert parent;
|
||||||
void *data;
|
void *data;
|
||||||
size_t len;
|
size_t len;
|
||||||
} git_cert_x509;
|
} git_cert_x509;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
git_cert_t cert_type;
|
|
||||||
} git_cert;
|
|
||||||
|
|
||||||
typedef int (*git_transport_message_cb)(const char *str, int len, void *data);
|
typedef int (*git_transport_message_cb)(const char *str, int len, void *data);
|
||||||
typedef int (*git_cred_acquire_cb)(
|
typedef int (*git_cred_acquire_cb)(
|
||||||
git_cred **cred,
|
git_cred **cred,
|
||||||
@ -197,10 +207,30 @@ struct git_remote_callbacks {
|
|||||||
|
|
||||||
typedef struct git_remote_callbacks git_remote_callbacks;
|
typedef struct git_remote_callbacks git_remote_callbacks;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GIT_PROXY_NONE,
|
||||||
|
GIT_PROXY_AUTO,
|
||||||
|
GIT_PROXY_SPECIFIED,
|
||||||
|
} git_proxy_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int version;
|
||||||
|
git_proxy_t type;
|
||||||
|
const char *url;
|
||||||
|
git_cred_acquire_cb credentials;
|
||||||
|
git_transport_certificate_check_cb certificate_check;
|
||||||
|
void *payload;
|
||||||
|
} git_proxy_options;
|
||||||
|
|
||||||
|
#define GIT_PROXY_OPTIONS_VERSION ...
|
||||||
|
int git_proxy_init_options(git_proxy_options *opts, unsigned int version);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
unsigned int pb_parallelism;
|
unsigned int pb_parallelism;
|
||||||
git_remote_callbacks callbacks;
|
git_remote_callbacks callbacks;
|
||||||
|
git_proxy_options proxy_opts;
|
||||||
|
git_strarray custom_headers;
|
||||||
} git_push_options;
|
} git_push_options;
|
||||||
|
|
||||||
#define GIT_PUSH_OPTIONS_VERSION ...
|
#define GIT_PUSH_OPTIONS_VERSION ...
|
||||||
@ -225,6 +255,8 @@ typedef struct {
|
|||||||
git_fetch_prune_t prune;
|
git_fetch_prune_t prune;
|
||||||
int update_fetchhead;
|
int update_fetchhead;
|
||||||
git_remote_autotag_option_t download_tags;
|
git_remote_autotag_option_t download_tags;
|
||||||
|
git_proxy_options proxy_opts;
|
||||||
|
git_strarray custom_headers;
|
||||||
} git_fetch_options;
|
} git_fetch_options;
|
||||||
|
|
||||||
#define GIT_FETCH_OPTIONS_VERSION ...
|
#define GIT_FETCH_OPTIONS_VERSION ...
|
||||||
@ -336,13 +368,20 @@ typedef int (*git_diff_notify_cb)(
|
|||||||
const char *matched_pathspec,
|
const char *matched_pathspec,
|
||||||
void *payload);
|
void *payload);
|
||||||
|
|
||||||
|
typedef int (*git_diff_progress_cb)(
|
||||||
|
const git_diff *diff_so_far,
|
||||||
|
const char *old_path,
|
||||||
|
const char *new_path,
|
||||||
|
void *payload);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
git_submodule_ignore_t ignore_submodules;
|
git_submodule_ignore_t ignore_submodules;
|
||||||
git_strarray pathspec;
|
git_strarray pathspec;
|
||||||
git_diff_notify_cb notify_cb;
|
git_diff_notify_cb notify_cb;
|
||||||
void *notify_payload;
|
git_diff_progress_cb progress_cb;
|
||||||
|
void *payload;
|
||||||
uint32_t context_lines;
|
uint32_t context_lines;
|
||||||
uint32_t interhunk_lines;
|
uint32_t interhunk_lines;
|
||||||
uint16_t id_abbrev;
|
uint16_t id_abbrev;
|
||||||
@ -371,7 +410,16 @@ int git_diff_tree_to_index(git_diff **diff, git_repository *repo, git_tree *old_
|
|||||||
* git_checkout
|
* git_checkout
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum { ... } git_checkout_notify_t;
|
typedef enum {
|
||||||
|
GIT_CHECKOUT_NOTIFY_NONE = 0,
|
||||||
|
GIT_CHECKOUT_NOTIFY_CONFLICT = 1,
|
||||||
|
GIT_CHECKOUT_NOTIFY_DIRTY = 2,
|
||||||
|
GIT_CHECKOUT_NOTIFY_UPDATED = 4,
|
||||||
|
GIT_CHECKOUT_NOTIFY_UNTRACKED = 8,
|
||||||
|
GIT_CHECKOUT_NOTIFY_IGNORED = 16,
|
||||||
|
|
||||||
|
GIT_CHECKOUT_NOTIFY_ALL = 0x0FFFF
|
||||||
|
} git_checkout_notify_t;
|
||||||
|
|
||||||
typedef int (*git_checkout_notify_cb)(
|
typedef int (*git_checkout_notify_cb)(
|
||||||
git_checkout_notify_t why,
|
git_checkout_notify_t why,
|
||||||
@ -478,11 +526,12 @@ typedef ... git_config;
|
|||||||
typedef ... git_config_iterator;
|
typedef ... git_config_iterator;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GIT_CONFIG_LEVEL_SYSTEM = 1,
|
GIT_CONFIG_LEVEL_PROGRAMDATA = 1,
|
||||||
GIT_CONFIG_LEVEL_XDG = 2,
|
GIT_CONFIG_LEVEL_SYSTEM = 2,
|
||||||
GIT_CONFIG_LEVEL_GLOBAL = 3,
|
GIT_CONFIG_LEVEL_XDG = 3,
|
||||||
GIT_CONFIG_LEVEL_LOCAL = 4,
|
GIT_CONFIG_LEVEL_GLOBAL = 4,
|
||||||
GIT_CONFIG_LEVEL_APP = 5,
|
GIT_CONFIG_LEVEL_LOCAL = 5,
|
||||||
|
GIT_CONFIG_LEVEL_APP = 6,
|
||||||
GIT_CONFIG_HIGHEST_LEVEL = -1,
|
GIT_CONFIG_HIGHEST_LEVEL = -1,
|
||||||
} git_config_level_t;
|
} git_config_level_t;
|
||||||
|
|
||||||
@ -671,22 +720,22 @@ typedef struct git_blame_options {
|
|||||||
uint16_t min_match_characters;
|
uint16_t min_match_characters;
|
||||||
git_oid newest_commit;
|
git_oid newest_commit;
|
||||||
git_oid oldest_commit;
|
git_oid oldest_commit;
|
||||||
uint32_t min_line;
|
size_t min_line;
|
||||||
uint32_t max_line;
|
size_t max_line;
|
||||||
} git_blame_options;
|
} git_blame_options;
|
||||||
|
|
||||||
#define GIT_BLAME_OPTIONS_VERSION ...
|
#define GIT_BLAME_OPTIONS_VERSION ...
|
||||||
|
|
||||||
typedef struct git_blame_hunk {
|
typedef struct git_blame_hunk {
|
||||||
uint16_t lines_in_hunk;
|
size_t lines_in_hunk;
|
||||||
|
|
||||||
git_oid final_commit_id;
|
git_oid final_commit_id;
|
||||||
uint16_t final_start_line_number;
|
size_t final_start_line_number;
|
||||||
git_signature *final_signature;
|
git_signature *final_signature;
|
||||||
|
|
||||||
git_oid orig_commit_id;
|
git_oid orig_commit_id;
|
||||||
const char *orig_path;
|
const char *orig_path;
|
||||||
uint16_t orig_start_line_number;
|
size_t orig_start_line_number;
|
||||||
git_signature *orig_signature;
|
git_signature *orig_signature;
|
||||||
|
|
||||||
char boundary;
|
char boundary;
|
||||||
@ -695,7 +744,7 @@ typedef struct git_blame_hunk {
|
|||||||
int git_blame_init_options(git_blame_options *opts, unsigned int version);
|
int git_blame_init_options(git_blame_options *opts, unsigned int version);
|
||||||
uint32_t git_blame_get_hunk_count(git_blame *blame);
|
uint32_t git_blame_get_hunk_count(git_blame *blame);
|
||||||
const git_blame_hunk *git_blame_get_hunk_byindex(git_blame *blame, uint32_t index);
|
const git_blame_hunk *git_blame_get_hunk_byindex(git_blame *blame, uint32_t index);
|
||||||
const git_blame_hunk *git_blame_get_hunk_byline(git_blame *blame, uint32_t lineno);
|
const git_blame_hunk *git_blame_get_hunk_byline(git_blame *blame, size_t lineno);
|
||||||
int git_blame_file(git_blame **out, git_repository *repo, const char *path, git_blame_options *options);
|
int git_blame_file(git_blame **out, git_repository *repo, const char *path, git_blame_options *options);
|
||||||
void git_blame_free(git_blame *blame);
|
void git_blame_free(git_blame *blame);
|
||||||
|
|
||||||
@ -703,7 +752,12 @@ void git_blame_free(git_blame *blame);
|
|||||||
* Merging
|
* Merging
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum { ... } git_merge_tree_flag_t;
|
typedef enum {
|
||||||
|
GIT_MERGE_FIND_RENAMES = 1,
|
||||||
|
GIT_MERGE_FAIL_ON_CONFLICT = 2,
|
||||||
|
GIT_MERGE_SKIP_REUC = 4,
|
||||||
|
GIT_MERGE_NO_RECURSIVE = 8,
|
||||||
|
} git_merge_flag_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
GIT_MERGE_FILE_FAVOR_NORMAL = 0,
|
GIT_MERGE_FILE_FAVOR_NORMAL = 0,
|
||||||
@ -714,10 +768,12 @@ typedef enum {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
git_merge_tree_flag_t tree_flags;
|
git_merge_flag_t flags;
|
||||||
unsigned int rename_threshold;
|
unsigned int rename_threshold;
|
||||||
unsigned int target_limit;
|
unsigned int target_limit;
|
||||||
git_diff_similarity_metric *metric;
|
git_diff_similarity_metric *metric;
|
||||||
|
unsigned int recursion_limit;
|
||||||
|
const char *default_driver;
|
||||||
git_merge_file_favor_t file_favor;
|
git_merge_file_favor_t file_favor;
|
||||||
unsigned int file_flags;
|
unsigned int file_flags;
|
||||||
} git_merge_options;
|
} git_merge_options;
|
||||||
@ -737,7 +793,12 @@ typedef enum {
|
|||||||
GIT_MERGE_FILE_STYLE_MERGE = 1,
|
GIT_MERGE_FILE_STYLE_MERGE = 1,
|
||||||
GIT_MERGE_FILE_STYLE_DIFF3 = 2,
|
GIT_MERGE_FILE_STYLE_DIFF3 = 2,
|
||||||
GIT_MERGE_FILE_SIMPLIFY_ALNUM = 4,
|
GIT_MERGE_FILE_SIMPLIFY_ALNUM = 4,
|
||||||
} git_merge_file_flags_t;
|
GIT_MERGE_FILE_IGNORE_WHITESPACE = 8,
|
||||||
|
GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE = 16,
|
||||||
|
GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL = 32,
|
||||||
|
GIT_MERGE_FILE_DIFF_PATIENCE = 64,
|
||||||
|
GIT_MERGE_FILE_DIFF_MINIMAL = 128,
|
||||||
|
} git_merge_file_flag_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
@ -745,7 +806,7 @@ typedef struct {
|
|||||||
const char *our_label;
|
const char *our_label;
|
||||||
const char *their_label;
|
const char *their_label;
|
||||||
git_merge_file_favor_t favor;
|
git_merge_file_favor_t favor;
|
||||||
git_merge_file_flags_t flags;
|
git_merge_file_flag_t flags;
|
||||||
} git_merge_file_options;
|
} git_merge_file_options;
|
||||||
|
|
||||||
#define GIT_MERGE_OPTIONS_VERSION ...
|
#define GIT_MERGE_OPTIONS_VERSION ...
|
||||||
@ -756,6 +817,97 @@ int git_merge_trees(git_index **out, git_repository *repo, const git_tree *ances
|
|||||||
int git_merge_file_from_index(git_merge_file_result *out, git_repository *repo, const git_index_entry *ancestor, const git_index_entry *ours, const git_index_entry *theirs, const git_merge_file_options *opts);
|
int git_merge_file_from_index(git_merge_file_result *out, git_repository *repo, const git_index_entry *ancestor, const git_index_entry *ours, const git_index_entry *theirs, const git_merge_file_options *opts);
|
||||||
void git_merge_file_result_free(git_merge_file_result *result);
|
void git_merge_file_result_free(git_merge_file_result *result);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* git_stash
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef int (*git_stash_cb)(
|
||||||
|
size_t index, const char* message, const git_oid *stash_id, void *payload);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GIT_STASH_APPLY_PROGRESS_NONE = 0,
|
||||||
|
GIT_STASH_APPLY_PROGRESS_LOADING_STASH = 1,
|
||||||
|
GIT_STASH_APPLY_PROGRESS_ANALYZE_INDEX = 2,
|
||||||
|
GIT_STASH_APPLY_PROGRESS_ANALYZE_MODIFIED = 3,
|
||||||
|
GIT_STASH_APPLY_PROGRESS_ANALYZE_UNTRACKED = 4,
|
||||||
|
GIT_STASH_APPLY_PROGRESS_CHECKOUT_UNTRACKED = 5,
|
||||||
|
GIT_STASH_APPLY_PROGRESS_CHECKOUT_MODIFIED = 6,
|
||||||
|
GIT_STASH_APPLY_PROGRESS_DONE = 7,
|
||||||
|
} git_stash_apply_progress_t;
|
||||||
|
|
||||||
|
typedef int (*git_stash_apply_progress_cb)(
|
||||||
|
git_stash_apply_progress_t progress, void *payload);
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GIT_STASH_DEFAULT = 0,
|
||||||
|
GIT_STASH_KEEP_INDEX = 1,
|
||||||
|
GIT_STASH_INCLUDE_UNTRACKED = 2,
|
||||||
|
GIT_STASH_INCLUDE_IGNORED = 4,
|
||||||
|
} git_stash_flags;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GIT_STASH_APPLY_DEFAULT = 0,
|
||||||
|
GIT_STASH_APPLY_REINSTATE_INDEX = 1,
|
||||||
|
} git_stash_apply_flags;
|
||||||
|
|
||||||
|
typedef struct git_stash_apply_options {
|
||||||
|
unsigned int version;
|
||||||
|
git_stash_apply_flags flags;
|
||||||
|
git_checkout_options checkout_options;
|
||||||
|
git_stash_apply_progress_cb progress_cb;
|
||||||
|
void *progress_payload;
|
||||||
|
} git_stash_apply_options;
|
||||||
|
|
||||||
|
#define GIT_STASH_APPLY_OPTIONS_VERSION ...
|
||||||
|
|
||||||
|
int git_stash_save(git_oid *out, git_repository *repo, const git_signature *stasher, const char *message, uint32_t flags);
|
||||||
|
int git_stash_apply_init_options(git_stash_apply_options *opts, unsigned int version);
|
||||||
|
int git_stash_apply(git_repository *repo, size_t index, const git_stash_apply_options *options);
|
||||||
|
int git_stash_foreach(git_repository *repo, git_stash_cb callback, void *payload);
|
||||||
|
int git_stash_drop(git_repository *repo, size_t index);
|
||||||
|
int git_stash_pop(git_repository *repo, size_t index, const git_stash_apply_options *options);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Describe
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
GIT_DESCRIBE_DEFAULT,
|
||||||
|
GIT_DESCRIBE_TAGS,
|
||||||
|
GIT_DESCRIBE_ALL,
|
||||||
|
} git_describe_strategy_t;
|
||||||
|
|
||||||
|
typedef struct git_describe_options {
|
||||||
|
unsigned int version;
|
||||||
|
unsigned int max_candidates_tags;
|
||||||
|
unsigned int describe_strategy;
|
||||||
|
const char *pattern;
|
||||||
|
int only_follow_first_parent;
|
||||||
|
int show_commit_oid_as_fallback;
|
||||||
|
} git_describe_options;
|
||||||
|
|
||||||
|
#define GIT_DESCRIBE_OPTIONS_VERSION ...
|
||||||
|
|
||||||
|
int git_describe_init_options(git_describe_options *opts, unsigned int version);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int version;
|
||||||
|
unsigned int abbreviated_size;
|
||||||
|
int always_use_long_format;
|
||||||
|
const char *dirty_suffix;
|
||||||
|
} git_describe_format_options;
|
||||||
|
|
||||||
|
#define GIT_DESCRIBE_FORMAT_OPTIONS_VERSION ...
|
||||||
|
|
||||||
|
int git_describe_init_format_options(git_describe_format_options *opts, unsigned int version);
|
||||||
|
|
||||||
|
typedef ... git_describe_result;
|
||||||
|
|
||||||
|
int git_describe_commit(git_describe_result **result, git_object *committish, git_describe_options *opts);
|
||||||
|
int git_describe_workdir(git_describe_result **out, git_repository *repo, git_describe_options *opts);
|
||||||
|
int git_describe_format(git_buf *out, const git_describe_result *result, const git_describe_format_options *opts);
|
||||||
|
void git_describe_result_free(git_describe_result *result);
|
||||||
|
|
||||||
#define GIT_ATTR_CHECK_FILE_THEN_INDEX ...
|
#define GIT_ATTR_CHECK_FILE_THEN_INDEX ...
|
||||||
#define GIT_ATTR_CHECK_INDEX_THEN_FILE ...
|
#define GIT_ATTR_CHECK_INDEX_THEN_FILE ...
|
||||||
#define GIT_ATTR_CHECK_INDEX_ONLY ...
|
#define GIT_ATTR_CHECK_INDEX_ONLY ...
|
||||||
@ -770,3 +922,5 @@ typedef enum {
|
|||||||
|
|
||||||
int git_attr_get(const char **value_out, git_repository *repo, uint32_t flags, const char *path, const char *name);
|
int git_attr_get(const char **value_out, git_repository *repo, uint32_t flags, const char *path, const char *name);
|
||||||
git_attr_t git_attr_value(const char *attr);
|
git_attr_t git_attr_value(const char *attr);
|
||||||
|
|
||||||
|
int git_revert_commit(git_index **out, git_repository *repo, git_commit *revert_commit, git_commit *our_commit, unsigned int mainline, const git_merge_options *merge_options);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -40,7 +40,7 @@ def check_error(err, io=False):
|
|||||||
# Error message
|
# Error message
|
||||||
giterr = C.giterr_last()
|
giterr = C.giterr_last()
|
||||||
if giterr != ffi.NULL:
|
if giterr != ffi.NULL:
|
||||||
message = ffi.string(giterr.message).decode()
|
message = ffi.string(giterr.message).decode('utf8')
|
||||||
else:
|
else:
|
||||||
message = "err %d (no message provided)" % err
|
message = "err %d (no message provided)" % err
|
||||||
|
|
||||||
@ -62,3 +62,8 @@ def check_error(err, io=False):
|
|||||||
|
|
||||||
# Generic Git error
|
# Generic Git error
|
||||||
raise GitError(message)
|
raise GitError(message)
|
||||||
|
|
||||||
|
# Indicate that we want libgit2 to pretend a function was not set
|
||||||
|
class Passthrough(Exception):
|
||||||
|
def __init__(self):
|
||||||
|
super(Passthrough, self).__init__( "The function asked for pass-through")
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -29,7 +29,8 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
# Import from pygit2
|
# Import from pygit2
|
||||||
from ._utils import get_ffi
|
try:
|
||||||
|
from ._libgit2 import ffi, lib as C
|
||||||
|
except ImportError:
|
||||||
ffi, C = get_ffi()
|
from ._run import ffi, preamble, C_KEYWORDS
|
||||||
|
C = ffi.verify(preamble, **C_KEYWORDS)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -28,6 +28,8 @@
|
|||||||
# Import from the future
|
# Import from the future
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
import weakref
|
||||||
|
|
||||||
# Import from pygit2
|
# Import from pygit2
|
||||||
from _pygit2 import Oid, Tree, Diff
|
from _pygit2 import Oid, Tree, Diff
|
||||||
from .errors import check_error
|
from .errors import check_error
|
||||||
@ -48,6 +50,7 @@ class Index(object):
|
|||||||
err = C.git_index_open(cindex, to_bytes(path))
|
err = C.git_index_open(cindex, to_bytes(path))
|
||||||
check_error(err)
|
check_error(err)
|
||||||
|
|
||||||
|
self._repo = None
|
||||||
self._index = cindex[0]
|
self._index = cindex[0]
|
||||||
self._cindex = cindex
|
self._cindex = cindex
|
||||||
|
|
||||||
@ -125,14 +128,15 @@ class Index(object):
|
|||||||
The tree will be read recursively and all its children will also be
|
The tree will be read recursively and all its children will also be
|
||||||
inserted into the Index.
|
inserted into the Index.
|
||||||
"""
|
"""
|
||||||
|
repo = self._repo
|
||||||
if is_string(tree):
|
if is_string(tree):
|
||||||
tree = self._repo[tree]
|
tree = repo[tree]
|
||||||
|
|
||||||
if isinstance(tree, Oid):
|
if isinstance(tree, Oid):
|
||||||
if not hasattr(self, '_repo'):
|
if repo is None:
|
||||||
raise TypeError("id given but no associated repository")
|
raise TypeError("id given but no associated repository")
|
||||||
|
|
||||||
tree = self._repo[tree]
|
tree = repo[tree]
|
||||||
elif not isinstance(tree, Tree):
|
elif not isinstance(tree, Tree):
|
||||||
raise TypeError("argument must be Oid or Tree")
|
raise TypeError("argument must be Oid or Tree")
|
||||||
|
|
||||||
@ -153,6 +157,9 @@ class Index(object):
|
|||||||
It returns the id of the resulting tree.
|
It returns the id of the resulting tree.
|
||||||
"""
|
"""
|
||||||
coid = ffi.new('git_oid *')
|
coid = ffi.new('git_oid *')
|
||||||
|
|
||||||
|
repo = repo or self._repo
|
||||||
|
|
||||||
if repo:
|
if repo:
|
||||||
err = C.git_index_write_tree_to(coid, self._index, repo._repo)
|
err = C.git_index_write_tree_to(coid, self._index, repo._repo)
|
||||||
else:
|
else:
|
||||||
@ -214,7 +221,8 @@ class Index(object):
|
|||||||
interhunk_lines: the maximum number of unchanged lines between hunk
|
interhunk_lines: the maximum number of unchanged lines between hunk
|
||||||
boundaries before the hunks will be merged into a one
|
boundaries before the hunks will be merged into a one
|
||||||
"""
|
"""
|
||||||
if not hasattr(self, '_repo'):
|
repo = self._repo
|
||||||
|
if repo is None:
|
||||||
raise ValueError('diff needs an associated repository')
|
raise ValueError('diff needs an associated repository')
|
||||||
|
|
||||||
copts = ffi.new('git_diff_options *')
|
copts = ffi.new('git_diff_options *')
|
||||||
@ -226,11 +234,11 @@ class Index(object):
|
|||||||
copts.interhunk_lines = interhunk_lines
|
copts.interhunk_lines = interhunk_lines
|
||||||
|
|
||||||
cdiff = ffi.new('git_diff **')
|
cdiff = ffi.new('git_diff **')
|
||||||
err = C.git_diff_index_to_workdir(cdiff, self._repo._repo,
|
err = C.git_diff_index_to_workdir(cdiff, repo._repo, self._index,
|
||||||
self._index, copts)
|
copts)
|
||||||
check_error(err)
|
check_error(err)
|
||||||
|
|
||||||
return Diff.from_c(bytes(ffi.buffer(cdiff)[:]), self._repo)
|
return Diff.from_c(bytes(ffi.buffer(cdiff)[:]), repo)
|
||||||
|
|
||||||
def diff_to_tree(self, tree, flags=0, context_lines=3, interhunk_lines=0):
|
def diff_to_tree(self, tree, flags=0, context_lines=3, interhunk_lines=0):
|
||||||
"""Diff the index against a tree. Return a <Diff> object with the
|
"""Diff the index against a tree. Return a <Diff> object with the
|
||||||
@ -248,8 +256,8 @@ class Index(object):
|
|||||||
interhunk_lines: the maximum number of unchanged lines between hunk
|
interhunk_lines: the maximum number of unchanged lines between hunk
|
||||||
boundaries before the hunks will be merged into a one.
|
boundaries before the hunks will be merged into a one.
|
||||||
"""
|
"""
|
||||||
|
repo = self._repo
|
||||||
if not hasattr(self, '_repo'):
|
if repo is None:
|
||||||
raise ValueError('diff needs an associated repository')
|
raise ValueError('diff needs an associated repository')
|
||||||
|
|
||||||
if not isinstance(tree, Tree):
|
if not isinstance(tree, Tree):
|
||||||
@ -267,11 +275,11 @@ class Index(object):
|
|||||||
ffi.buffer(ctree)[:] = tree._pointer[:]
|
ffi.buffer(ctree)[:] = tree._pointer[:]
|
||||||
|
|
||||||
cdiff = ffi.new('git_diff **')
|
cdiff = ffi.new('git_diff **')
|
||||||
err = C.git_diff_tree_to_index(cdiff, self._repo._repo, ctree[0],
|
err = C.git_diff_tree_to_index(cdiff, repo._repo, ctree[0],
|
||||||
self._index, copts)
|
self._index, copts)
|
||||||
check_error(err)
|
check_error(err)
|
||||||
|
|
||||||
return Diff.from_c(bytes(ffi.buffer(cdiff)[:]), self._repo)
|
return Diff.from_c(bytes(ffi.buffer(cdiff)[:]), repo)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -302,10 +310,12 @@ class Index(object):
|
|||||||
self._conflicts = None
|
self._conflicts = None
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if self._conflicts is None:
|
if self._conflicts is None or self._conflicts() is None:
|
||||||
self._conflicts = ConflictCollection(self)
|
conflicts = ConflictCollection(self)
|
||||||
|
self._conflicts = weakref.ref(conflicts)
|
||||||
|
return conflicts
|
||||||
|
|
||||||
return self._conflicts
|
return self._conflicts()
|
||||||
|
|
||||||
|
|
||||||
class IndexEntry(object):
|
class IndexEntry(object):
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
349
pygit2/remote.py
349
pygit2/remote.py
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -30,9 +30,8 @@ from __future__ import absolute_import
|
|||||||
|
|
||||||
# Import from pygit2
|
# Import from pygit2
|
||||||
from _pygit2 import Oid
|
from _pygit2 import Oid
|
||||||
from .errors import check_error, GitError
|
from .errors import check_error, Passthrough
|
||||||
from .ffi import ffi, C
|
from .ffi import ffi, C
|
||||||
from .credentials import KeypairFromAgent
|
|
||||||
from .refspec import Refspec
|
from .refspec import Refspec
|
||||||
from .utils import to_bytes, strarray_to_strings, StrArray
|
from .utils import to_bytes, strarray_to_strings, StrArray
|
||||||
|
|
||||||
@ -71,7 +70,27 @@ class TransferProgress(object):
|
|||||||
""""Number of bytes received up to now"""
|
""""Number of bytes received up to now"""
|
||||||
|
|
||||||
|
|
||||||
class Remote(object):
|
class RemoteCallbacks(object):
|
||||||
|
"""Base class for pygit2 remote callbacks.
|
||||||
|
|
||||||
|
Inherit from this class and override the callbacks which you want to use
|
||||||
|
in your class, which you can then pass to the network operations.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, credentials=None, certificate=None):
|
||||||
|
"""Initialize some callbacks in-line
|
||||||
|
|
||||||
|
Use this constructor to provide credentials and certificate
|
||||||
|
callbacks in-line, instead of defining your own class for these ones.
|
||||||
|
|
||||||
|
You can e.g. also pass in one of the credential objects as 'credentials'
|
||||||
|
instead of creating a function which returns a hard-coded object.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if credentials is not None:
|
||||||
|
self.credentials = credentials
|
||||||
|
if certificate is not None:
|
||||||
|
self.certificate = certificate
|
||||||
|
|
||||||
def sideband_progress(self, string):
|
def sideband_progress(self, string):
|
||||||
"""Progress output callback
|
"""Progress output callback
|
||||||
@ -80,7 +99,6 @@ class Remote(object):
|
|||||||
|
|
||||||
:param str string: Progress output from the remote
|
:param str string: Progress output from the remote
|
||||||
"""
|
"""
|
||||||
pass
|
|
||||||
|
|
||||||
def credentials(self, url, username_from_url, allowed_types):
|
def credentials(self, url, username_from_url, allowed_types):
|
||||||
"""Credentials callback
|
"""Credentials callback
|
||||||
@ -100,7 +118,26 @@ class Remote(object):
|
|||||||
|
|
||||||
Return value: credential
|
Return value: credential
|
||||||
"""
|
"""
|
||||||
pass
|
raise Passthrough
|
||||||
|
|
||||||
|
def certificate_check(self, certificate, valid, host):
|
||||||
|
"""Certificate callback
|
||||||
|
|
||||||
|
Override with your own function to determine whether the accept
|
||||||
|
the server's certificate.
|
||||||
|
|
||||||
|
:param None certificate: The certificate. It is currently always None
|
||||||
|
while we figure out how to represent it cross-platform
|
||||||
|
|
||||||
|
:param bool valid: Whether the TLS/SSH library thinks the certificate
|
||||||
|
is valid
|
||||||
|
|
||||||
|
:param str host: The hostname we want to connect to
|
||||||
|
|
||||||
|
Return value: True to connect, False to abort
|
||||||
|
"""
|
||||||
|
|
||||||
|
raise Passthrough
|
||||||
|
|
||||||
def transfer_progress(self, stats):
|
def transfer_progress(self, stats):
|
||||||
"""Transfer progress callback
|
"""Transfer progress callback
|
||||||
@ -109,7 +146,6 @@ class Remote(object):
|
|||||||
|
|
||||||
:param TransferProgress stats: The progress up to now
|
:param TransferProgress stats: The progress up to now
|
||||||
"""
|
"""
|
||||||
pass
|
|
||||||
|
|
||||||
def update_tips(self, refname, old, new):
|
def update_tips(self, refname, old, new):
|
||||||
"""Update tips callabck
|
"""Update tips callabck
|
||||||
@ -131,6 +167,159 @@ class Remote(object):
|
|||||||
:param str messsage: rejection message from the remote. If None, the update was accepted.
|
:param str messsage: rejection message from the remote. If None, the update was accepted.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def _fill_fetch_options(self, fetch_opts):
|
||||||
|
fetch_opts.callbacks.sideband_progress = self._sideband_progress_cb
|
||||||
|
fetch_opts.callbacks.transfer_progress = self._transfer_progress_cb
|
||||||
|
fetch_opts.callbacks.update_tips = self._update_tips_cb
|
||||||
|
fetch_opts.callbacks.credentials = self._credentials_cb
|
||||||
|
fetch_opts.callbacks.certificate_check = self._certificate_cb
|
||||||
|
# We need to make sure that this handle stays alive
|
||||||
|
self._self_handle = ffi.new_handle(self)
|
||||||
|
fetch_opts.callbacks.payload = self._self_handle
|
||||||
|
|
||||||
|
self._stored_exception = None
|
||||||
|
|
||||||
|
def _fill_push_options(self, push_opts):
|
||||||
|
push_opts.callbacks.sideband_progress = self._sideband_progress_cb
|
||||||
|
push_opts.callbacks.transfer_progress = self._transfer_progress_cb
|
||||||
|
push_opts.callbacks.update_tips = self._update_tips_cb
|
||||||
|
push_opts.callbacks.credentials = self._credentials_cb
|
||||||
|
push_opts.callbacks.certificate_check = self._certificate_cb
|
||||||
|
push_opts.callbacks.push_update_reference = self._push_update_reference_cb
|
||||||
|
# We need to make sure that this handle stays alive
|
||||||
|
self._self_handle = ffi.new_handle(self)
|
||||||
|
push_opts.callbacks.payload = self._self_handle
|
||||||
|
|
||||||
|
# These functions exist to be called by the git_remote as
|
||||||
|
# callbacks. They proxy the call to whatever the user set
|
||||||
|
|
||||||
|
@ffi.callback('git_transfer_progress_cb')
|
||||||
|
def _transfer_progress_cb(stats_ptr, data):
|
||||||
|
self = ffi.from_handle(data)
|
||||||
|
|
||||||
|
transfer_progress = getattr(self, 'transfer_progress', None)
|
||||||
|
if not transfer_progress:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
transfer_progress(TransferProgress(stats_ptr))
|
||||||
|
except Exception as e:
|
||||||
|
self._stored_exception = e
|
||||||
|
return C.GIT_EUSER
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
@ffi.callback('git_transport_message_cb')
|
||||||
|
def _sideband_progress_cb(string, length, data):
|
||||||
|
self = ffi.from_handle(data)
|
||||||
|
|
||||||
|
progress = getattr(self, 'progress', None)
|
||||||
|
if not progress:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
s = ffi.string(string, length).decode()
|
||||||
|
progress(s)
|
||||||
|
except Exception as e:
|
||||||
|
self._stored_exception = e
|
||||||
|
return C.GIT_EUSER
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
@ffi.callback('int (*update_tips)(const char *refname, const git_oid *a,'
|
||||||
|
'const git_oid *b, void *data)')
|
||||||
|
def _update_tips_cb(refname, a, b, data):
|
||||||
|
self = ffi.from_handle(data)
|
||||||
|
|
||||||
|
update_tips = getattr(self, 'update_tips', None)
|
||||||
|
if not update_tips:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
s = maybe_string(refname)
|
||||||
|
a = Oid(raw=bytes(ffi.buffer(a)[:]))
|
||||||
|
b = Oid(raw=bytes(ffi.buffer(b)[:]))
|
||||||
|
|
||||||
|
update_tips(s, a, b)
|
||||||
|
except Exception as e:
|
||||||
|
self._stored_exception = e
|
||||||
|
return C.GIT_EUSER
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
@ffi.callback("int (*push_update_reference)(const char *ref, const char *msg, void *data)")
|
||||||
|
def _push_update_reference_cb(ref, msg, data):
|
||||||
|
self = ffi.from_handle(data)
|
||||||
|
|
||||||
|
push_update_reference = getattr(self, 'push_update_reference', None)
|
||||||
|
if not push_update_reference:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
try:
|
||||||
|
refname = ffi.string(ref)
|
||||||
|
message = maybe_string(msg)
|
||||||
|
push_update_reference(refname, message)
|
||||||
|
except Exception as e:
|
||||||
|
self._stored_exception = e
|
||||||
|
return C.GIT_EUSER
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
@ffi.callback('int (*credentials)(git_cred **cred, const char *url,'
|
||||||
|
'const char *username_from_url, unsigned int allowed_types,'
|
||||||
|
'void *data)')
|
||||||
|
def _credentials_cb(cred_out, url, username, allowed, data):
|
||||||
|
self = ffi.from_handle(data)
|
||||||
|
|
||||||
|
credentials = getattr(self, 'credentials', None)
|
||||||
|
if not credentials:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
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:
|
||||||
|
self._stored_exception = e
|
||||||
|
return C.GIT_EUSER
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
@ffi.callback('int (*git_transport_certificate_check_cb)'
|
||||||
|
'(git_cert *cert, int valid, const char *host, void *payload)')
|
||||||
|
def _certificate_cb(cert_i, valid, host, data):
|
||||||
|
self = ffi.from_handle(data)
|
||||||
|
|
||||||
|
# We want to simulate what should happen if libgit2 supported pass-through for
|
||||||
|
# this callback. For SSH, 'valid' is always False, because it doesn't look
|
||||||
|
# at known_hosts, but we do want to let it through in order to do what libgit2 would
|
||||||
|
# if the callback were not set.
|
||||||
|
try:
|
||||||
|
is_ssh = cert_i.cert_type == C.GIT_CERT_HOSTKEY_LIBSSH2
|
||||||
|
|
||||||
|
certificate_check = getattr(self, 'certificate_check', None)
|
||||||
|
if not certificate_check:
|
||||||
|
raise Passthrough
|
||||||
|
|
||||||
|
# python's parsing is deep in the libraries and assumes an OpenSSL-owned cert
|
||||||
|
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:
|
||||||
|
self._stored_exception = e
|
||||||
|
return C.GIT_EUSER
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
class Remote(object):
|
||||||
def __init__(self, repo, ptr):
|
def __init__(self, repo, ptr):
|
||||||
"""The constructor is for internal use only"""
|
"""The constructor is for internal use only"""
|
||||||
|
|
||||||
@ -165,7 +354,7 @@ class Remote(object):
|
|||||||
err = C.git_remote_save(self._remote)
|
err = C.git_remote_save(self._remote)
|
||||||
check_error(err)
|
check_error(err)
|
||||||
|
|
||||||
def fetch(self, refspecs=None, message=None):
|
def fetch(self, refspecs=None, message=None, callbacks=None):
|
||||||
"""Perform a fetch against this remote. Returns a <TransferProgress>
|
"""Perform a fetch against this remote. Returns a <TransferProgress>
|
||||||
object.
|
object.
|
||||||
"""
|
"""
|
||||||
@ -173,24 +362,19 @@ class Remote(object):
|
|||||||
fetch_opts = ffi.new('git_fetch_options *')
|
fetch_opts = ffi.new('git_fetch_options *')
|
||||||
err = C.git_fetch_init_options(fetch_opts, C.GIT_FETCH_OPTIONS_VERSION)
|
err = C.git_fetch_init_options(fetch_opts, C.GIT_FETCH_OPTIONS_VERSION)
|
||||||
|
|
||||||
fetch_opts.callbacks.sideband_progress = self._sideband_progress_cb
|
if callbacks is None:
|
||||||
fetch_opts.callbacks.transfer_progress = self._transfer_progress_cb
|
callbacks = RemoteCallbacks()
|
||||||
fetch_opts.callbacks.update_tips = self._update_tips_cb
|
|
||||||
fetch_opts.callbacks.credentials = self._credentials_cb
|
|
||||||
# We need to make sure that this handle stays alive
|
|
||||||
self._self_handle = ffi.new_handle(self)
|
|
||||||
fetch_opts.callbacks.payload = self._self_handle
|
|
||||||
|
|
||||||
self._stored_exception = None
|
callbacks._fill_fetch_options(fetch_opts)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with StrArray(refspecs) as arr:
|
with StrArray(refspecs) as arr:
|
||||||
err = C.git_remote_fetch(self._remote, arr, fetch_opts, to_bytes(message))
|
err = C.git_remote_fetch(self._remote, arr, fetch_opts, to_bytes(message))
|
||||||
if self._stored_exception:
|
if callbacks._stored_exception:
|
||||||
raise self._stored_exception
|
raise callbacks._stored_exception
|
||||||
check_error(err)
|
check_error(err)
|
||||||
finally:
|
finally:
|
||||||
self._self_handle = None
|
callbacks._self_handle = None
|
||||||
|
|
||||||
return TransferProgress(C.git_remote_stats(self._remote))
|
return TransferProgress(C.git_remote_stats(self._remote))
|
||||||
|
|
||||||
@ -225,123 +409,33 @@ class Remote(object):
|
|||||||
|
|
||||||
return strarray_to_strings(specs)
|
return strarray_to_strings(specs)
|
||||||
|
|
||||||
def push(self, specs):
|
def push(self, specs, callbacks=None):
|
||||||
"""Push the given refspec to the remote. Raises ``GitError`` on
|
"""Push the given refspec to the remote. Raises ``GitError`` on
|
||||||
protocol error or unpack failure.
|
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
|
:param [str] specs: push refspecs to use
|
||||||
"""
|
"""
|
||||||
push_opts = ffi.new('git_push_options *')
|
push_opts = ffi.new('git_push_options *')
|
||||||
err = C.git_push_init_options(push_opts, C.GIT_PUSH_OPTIONS_VERSION)
|
err = C.git_push_init_options(push_opts, C.GIT_PUSH_OPTIONS_VERSION)
|
||||||
|
|
||||||
|
if callbacks is None:
|
||||||
|
callbacks = RemoteCallbacks()
|
||||||
|
|
||||||
|
callbacks._fill_push_options(push_opts)
|
||||||
# Build custom callback structure
|
# Build custom callback structure
|
||||||
push_opts.callbacks.sideband_progress = self._sideband_progress_cb
|
|
||||||
push_opts.callbacks.transfer_progress = self._transfer_progress_cb
|
|
||||||
push_opts.callbacks.update_tips = self._update_tips_cb
|
|
||||||
push_opts.callbacks.credentials = self._credentials_cb
|
|
||||||
push_opts.callbacks.push_update_reference = self._push_update_reference_cb
|
|
||||||
# We need to make sure that this handle stays alive
|
|
||||||
self._self_handle = ffi.new_handle(self)
|
|
||||||
push_opts.callbacks.payload = self._self_handle
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with StrArray(specs) as refspecs:
|
with StrArray(specs) as refspecs:
|
||||||
err = C.git_remote_push(self._remote, refspecs, ffi.NULL)
|
err = C.git_remote_push(self._remote, refspecs, push_opts)
|
||||||
check_error(err)
|
check_error(err)
|
||||||
finally:
|
finally:
|
||||||
self._self_handle = None
|
callbacks._self_handle = None
|
||||||
|
|
||||||
# These functions exist to be called by the git_remote as
|
|
||||||
# callbacks. They proxy the call to whatever the user set
|
|
||||||
|
|
||||||
@ffi.callback('git_transfer_progress_cb')
|
|
||||||
def _transfer_progress_cb(stats_ptr, data):
|
|
||||||
self = ffi.from_handle(data)
|
|
||||||
|
|
||||||
if not hasattr(self, 'transfer_progress') \
|
|
||||||
or not self.transfer_progress:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.transfer_progress(TransferProgress(stats_ptr))
|
|
||||||
except Exception as e:
|
|
||||||
self._stored_exception = e
|
|
||||||
return C.GIT_EUSER
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
@ffi.callback('git_transport_message_cb')
|
|
||||||
def _sideband_progress_cb(string, length, data):
|
|
||||||
self = ffi.from_handle(data)
|
|
||||||
|
|
||||||
if not hasattr(self, 'progress') or not self.progress:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
try:
|
|
||||||
s = ffi.string(string, length).decode()
|
|
||||||
self.progress(s)
|
|
||||||
except Exception as e:
|
|
||||||
self._stored_exception = e
|
|
||||||
return C.GIT_EUSER
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
@ffi.callback('int (*update_tips)(const char *refname, const git_oid *a,'
|
|
||||||
'const git_oid *b, void *data)')
|
|
||||||
def _update_tips_cb(refname, a, b, data):
|
|
||||||
self = ffi.from_handle(data)
|
|
||||||
|
|
||||||
if not hasattr(self, 'update_tips') or not self.update_tips:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
try:
|
|
||||||
s = maybe_string(refname)
|
|
||||||
a = Oid(raw=bytes(ffi.buffer(a)[:]))
|
|
||||||
b = Oid(raw=bytes(ffi.buffer(b)[:]))
|
|
||||||
|
|
||||||
self.update_tips(s, a, b)
|
|
||||||
except Exception as e:
|
|
||||||
self._stored_exception = e
|
|
||||||
return C.GIT_EUSER
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
@ffi.callback("int (*push_update_reference)(const char *ref, const char *msg, void *data)")
|
|
||||||
def _push_update_reference_cb(ref, msg, data):
|
|
||||||
self = ffi.from_handle(data)
|
|
||||||
|
|
||||||
if not hasattr(self, 'push_update_reference') or not self.push_update_reference:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
try:
|
|
||||||
refname = ffi.string(ref)
|
|
||||||
message = maybe_string(msg)
|
|
||||||
self.push_update_reference(refname, message)
|
|
||||||
except Exception as e:
|
|
||||||
self._stored_exception = e
|
|
||||||
return C.GIT_EUSER
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
@ffi.callback('int (*credentials)(git_cred **cred, const char *url,'
|
|
||||||
'const char *username_from_url, unsigned int allowed_types,'
|
|
||||||
'void *data)')
|
|
||||||
def _credentials_cb(cred_out, url, username, allowed, data):
|
|
||||||
self = ffi.from_handle(data)
|
|
||||||
|
|
||||||
if not hasattr(self, 'credentials') or not self.credentials:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
try:
|
|
||||||
ccred = get_credentials(self.credentials, url, username, allowed)
|
|
||||||
cred_out[0] = ccred[0]
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self._stored_exception = e
|
|
||||||
return C.GIT_EUSER
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def get_credentials(fn, url, username, allowed):
|
def get_credentials(fn, url, username, allowed):
|
||||||
"""Call fn and return the credentials object"""
|
"""Call fn and return the credentials object"""
|
||||||
@ -351,23 +445,24 @@ def get_credentials(fn, url, username, allowed):
|
|||||||
|
|
||||||
creds = fn(url_str, username_str, allowed)
|
creds = fn(url_str, username_str, allowed)
|
||||||
|
|
||||||
if not hasattr(creds, 'credential_type') \
|
credential_type = getattr(creds, 'credential_type', None)
|
||||||
or not hasattr(creds, 'credential_tuple'):
|
credential_tuple = getattr(creds, 'credential_tuple', None)
|
||||||
|
if not credential_type or not credential_tuple:
|
||||||
raise TypeError("credential does not implement interface")
|
raise TypeError("credential does not implement interface")
|
||||||
|
|
||||||
cred_type = creds.credential_type
|
cred_type = credential_type
|
||||||
|
|
||||||
if not (allowed & cred_type):
|
if not (allowed & cred_type):
|
||||||
raise TypeError("invalid credential type")
|
raise TypeError("invalid credential type")
|
||||||
|
|
||||||
ccred = ffi.new('git_cred **')
|
ccred = ffi.new('git_cred **')
|
||||||
if cred_type == C.GIT_CREDTYPE_USERPASS_PLAINTEXT:
|
if cred_type == C.GIT_CREDTYPE_USERPASS_PLAINTEXT:
|
||||||
name, passwd = creds.credential_tuple
|
name, passwd = credential_tuple
|
||||||
err = C.git_cred_userpass_plaintext_new(ccred, to_bytes(name),
|
err = C.git_cred_userpass_plaintext_new(ccred, to_bytes(name),
|
||||||
to_bytes(passwd))
|
to_bytes(passwd))
|
||||||
|
|
||||||
elif cred_type == C.GIT_CREDTYPE_SSH_KEY:
|
elif cred_type == C.GIT_CREDTYPE_SSH_KEY:
|
||||||
name, pubkey, privkey, passphrase = creds.credential_tuple
|
name, pubkey, privkey, passphrase = credential_tuple
|
||||||
if pubkey is None and privkey is None:
|
if pubkey is None and privkey is None:
|
||||||
err = C.git_cred_ssh_key_from_agent(ccred, to_bytes(name))
|
err = C.git_cred_ssh_key_from_agent(ccred, to_bytes(name))
|
||||||
else:
|
else:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -32,17 +32,21 @@ from __future__ import absolute_import
|
|||||||
from string import hexdigits
|
from string import hexdigits
|
||||||
import sys, tarfile
|
import sys, tarfile
|
||||||
from time import time
|
from time import time
|
||||||
|
|
||||||
if sys.version_info[0] < 3:
|
if sys.version_info[0] < 3:
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
else:
|
else:
|
||||||
from io import BytesIO as StringIO
|
from io import BytesIO as StringIO
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
# Import from pygit2
|
# Import from pygit2
|
||||||
from _pygit2 import Repository as _Repository
|
from _pygit2 import Repository as _Repository, init_file_backend
|
||||||
from _pygit2 import Oid, GIT_OID_HEXSZ, GIT_OID_MINPREFIXLEN
|
from _pygit2 import Oid, GIT_OID_HEXSZ, GIT_OID_MINPREFIXLEN
|
||||||
from _pygit2 import GIT_CHECKOUT_SAFE, GIT_CHECKOUT_RECREATE_MISSING, GIT_DIFF_NORMAL
|
from _pygit2 import GIT_CHECKOUT_SAFE, GIT_CHECKOUT_RECREATE_MISSING, GIT_DIFF_NORMAL
|
||||||
from _pygit2 import GIT_FILEMODE_LINK
|
from _pygit2 import GIT_FILEMODE_LINK
|
||||||
from _pygit2 import Reference, Tree, Commit, Blob
|
from _pygit2 import GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE, GIT_BRANCH_ALL
|
||||||
|
from _pygit2 import Reference, Tree, Commit, Blob, Signature
|
||||||
|
|
||||||
from .config import Config
|
from .config import Config
|
||||||
from .errors import check_error
|
from .errors import check_error
|
||||||
@ -54,21 +58,11 @@ from .utils import to_bytes, is_string
|
|||||||
from .submodule import Submodule
|
from .submodule import Submodule
|
||||||
|
|
||||||
|
|
||||||
class Repository(_Repository):
|
class BaseRepository(_Repository):
|
||||||
|
def __init__(self, backend, *args, **kwargs):
|
||||||
def __init__(self, *args, **kwargs):
|
super(BaseRepository, self).__init__(backend, *args, **kwargs)
|
||||||
super(Repository, self).__init__(*args, **kwargs)
|
|
||||||
self._common_init()
|
self._common_init()
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _from_c(cls, ptr, owned):
|
|
||||||
cptr = ffi.new('git_repository **')
|
|
||||||
cptr[0] = ptr
|
|
||||||
repo = cls.__new__(cls)
|
|
||||||
super(cls, repo)._from_c(bytes(ffi.buffer(cptr)[:]), owned)
|
|
||||||
repo._common_init()
|
|
||||||
return repo
|
|
||||||
|
|
||||||
def _common_init(self):
|
def _common_init(self):
|
||||||
self.remotes = RemoteCollection(self)
|
self.remotes = RemoteCollection(self)
|
||||||
|
|
||||||
@ -275,11 +269,6 @@ class Repository(_Repository):
|
|||||||
oid = reference.resolve().target
|
oid = reference.resolve().target
|
||||||
treeish = self[oid]
|
treeish = self[oid]
|
||||||
self.checkout_tree(treeish, **kwargs)
|
self.checkout_tree(treeish, **kwargs)
|
||||||
head = self.lookup_reference('HEAD')
|
|
||||||
if head.type == C.GIT_REF_SYMBOLIC:
|
|
||||||
from_ = self.head.shorthand
|
|
||||||
else:
|
|
||||||
from_ = head.target.hex
|
|
||||||
|
|
||||||
self.set_head(refname)
|
self.set_head(refname)
|
||||||
|
|
||||||
@ -318,8 +307,23 @@ class Repository(_Repository):
|
|||||||
|
|
||||||
Keyword arguments:
|
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
|
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
|
flag
|
||||||
a GIT_DIFF_* constant
|
a GIT_DIFF_* constant
|
||||||
@ -481,6 +485,7 @@ class Repository(_Repository):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def _merge_options(favor):
|
def _merge_options(favor):
|
||||||
"""Return a 'git_merge_opts *'"""
|
"""Return a 'git_merge_opts *'"""
|
||||||
|
|
||||||
def favor_to_enum(favor):
|
def favor_to_enum(favor):
|
||||||
if favor == 'normal':
|
if favor == 'normal':
|
||||||
return C.GIT_MERGE_FILE_FAVOR_NORMAL
|
return C.GIT_MERGE_FILE_FAVOR_NORMAL
|
||||||
@ -637,6 +642,196 @@ class Repository(_Repository):
|
|||||||
|
|
||||||
return Index.from_c(self, cindex)
|
return Index.from_c(self, cindex)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Describe
|
||||||
|
#
|
||||||
|
def describe(self, committish=None, max_candidates_tags=None,
|
||||||
|
describe_strategy=None, pattern=None,
|
||||||
|
only_follow_first_parent=None,
|
||||||
|
show_commit_oid_as_fallback=None, abbreviated_size=None,
|
||||||
|
always_use_long_format=None, dirty_suffix=None):
|
||||||
|
"""Describe a commit-ish or the current working tree.
|
||||||
|
|
||||||
|
:param committish: Commit-ish object or object name to describe, or
|
||||||
|
`None` to describe the current working tree.
|
||||||
|
:type committish: `str`, :class:`~.Reference`, or :class:`~.Commit`
|
||||||
|
|
||||||
|
:param int max_candidates_tags: The number of candidate tags to
|
||||||
|
consider. Increasing above 10 will take slightly longer but may
|
||||||
|
produce a more accurate result. A value of 0 will cause only exact
|
||||||
|
matches to be output.
|
||||||
|
:param int describe_strategy: A GIT_DESCRIBE_* constant.
|
||||||
|
:param str pattern: Only consider tags matching the given `glob(7)`
|
||||||
|
pattern, excluding the "refs/tags/" prefix.
|
||||||
|
:param bool only_follow_first_parent: Follow only the first parent
|
||||||
|
commit upon seeing a merge commit.
|
||||||
|
:param bool show_commit_oid_as_fallback: Show uniquely abbreviated
|
||||||
|
commit object as fallback.
|
||||||
|
:param int abbreviated_size: The minimum number of hexadecimal digits
|
||||||
|
to show for abbreviated object names. A value of 0 will suppress
|
||||||
|
long format, only showing the closest tag.
|
||||||
|
:param bool always_use_long_format: Always output the long format (the
|
||||||
|
nearest tag, the number of commits, and the abbrevated commit name)
|
||||||
|
even when the committish matches a tag.
|
||||||
|
:param str dirty_suffix: A string to append if the working tree is
|
||||||
|
dirty.
|
||||||
|
|
||||||
|
:returns: The description.
|
||||||
|
:rtype: `str`
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
repo.describe(pattern='public/*', dirty_suffix='-dirty')
|
||||||
|
"""
|
||||||
|
|
||||||
|
options = ffi.new('git_describe_options *')
|
||||||
|
C.git_describe_init_options(options, C.GIT_DESCRIBE_OPTIONS_VERSION)
|
||||||
|
|
||||||
|
if max_candidates_tags is not None:
|
||||||
|
options.max_candidates_tags = max_candidates_tags
|
||||||
|
if describe_strategy is not None:
|
||||||
|
options.describe_strategy = describe_strategy
|
||||||
|
if pattern:
|
||||||
|
# The returned pointer object has ownership on the allocated
|
||||||
|
# memory. Make sure it is kept alive until git_describe_commit() or
|
||||||
|
# git_describe_workdir() are called below.
|
||||||
|
pattern_char = ffi.new('char[]', to_bytes(pattern))
|
||||||
|
options.pattern = pattern_char
|
||||||
|
if only_follow_first_parent is not None:
|
||||||
|
options.only_follow_first_parent = only_follow_first_parent
|
||||||
|
if show_commit_oid_as_fallback is not None:
|
||||||
|
options.show_commit_oid_as_fallback = show_commit_oid_as_fallback
|
||||||
|
|
||||||
|
result = ffi.new('git_describe_result **')
|
||||||
|
if committish:
|
||||||
|
if is_string(committish):
|
||||||
|
committish = self.revparse_single(committish)
|
||||||
|
|
||||||
|
commit = committish.peel(Commit)
|
||||||
|
|
||||||
|
cptr = ffi.new('git_object **')
|
||||||
|
ffi.buffer(cptr)[:] = commit._pointer[:]
|
||||||
|
|
||||||
|
err = C.git_describe_commit(result, cptr[0], options)
|
||||||
|
else:
|
||||||
|
err = C.git_describe_workdir(result, self._repo, options)
|
||||||
|
check_error(err)
|
||||||
|
|
||||||
|
try:
|
||||||
|
format_options = ffi.new('git_describe_format_options *')
|
||||||
|
C.git_describe_init_format_options(format_options, C.GIT_DESCRIBE_FORMAT_OPTIONS_VERSION)
|
||||||
|
|
||||||
|
if abbreviated_size is not None:
|
||||||
|
format_options.abbreviated_size = abbreviated_size
|
||||||
|
if always_use_long_format is not None:
|
||||||
|
format_options.always_use_long_format = always_use_long_format
|
||||||
|
dirty_ptr = None
|
||||||
|
if dirty_suffix:
|
||||||
|
dirty_ptr = ffi.new('char[]', to_bytes(dirty_suffix))
|
||||||
|
format_options.dirty_suffix = dirty_ptr
|
||||||
|
|
||||||
|
buf = ffi.new('git_buf *', (ffi.NULL, 0))
|
||||||
|
|
||||||
|
err = C.git_describe_format(buf, result[0], format_options)
|
||||||
|
check_error(err)
|
||||||
|
|
||||||
|
try:
|
||||||
|
return ffi.string(buf.ptr).decode('utf-8')
|
||||||
|
finally:
|
||||||
|
C.git_buf_free(buf)
|
||||||
|
finally:
|
||||||
|
C.git_describe_result_free(result[0])
|
||||||
|
|
||||||
|
#
|
||||||
|
# Stash
|
||||||
|
#
|
||||||
|
def stash(self, stasher, message=None, keep_index=False,
|
||||||
|
include_untracked=False, include_ignored=False):
|
||||||
|
"""Save changes to the working directory to the stash.
|
||||||
|
|
||||||
|
:param Signature stasher: The identity of the person doing the stashing.
|
||||||
|
:param str message: An optional description of stashed state.
|
||||||
|
:param bool keep_index: Leave changes already added to the index
|
||||||
|
in the working directory.
|
||||||
|
:param bool include_untracked: Also stash untracked files.
|
||||||
|
:param bool include_ignored: Also stash ignored files.
|
||||||
|
|
||||||
|
:returns: The Oid of the stash merge commit.
|
||||||
|
:rtype: Oid
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
>>> repo = pygit2.Repsitory('.')
|
||||||
|
>>> repo.stash(repo.default_signature(), 'WIP: stashing')
|
||||||
|
"""
|
||||||
|
|
||||||
|
if message is not None:
|
||||||
|
stash_msg = ffi.new('char[]', to_bytes(message)) if message else ffi.NULL
|
||||||
|
else:
|
||||||
|
stash_msg = ffi.NULL
|
||||||
|
|
||||||
|
flags = 0
|
||||||
|
flags |= keep_index * C.GIT_STASH_KEEP_INDEX
|
||||||
|
flags |= include_untracked * C.GIT_STASH_INCLUDE_UNTRACKED
|
||||||
|
flags |= include_ignored * C.GIT_STASH_INCLUDE_IGNORED
|
||||||
|
|
||||||
|
stasher_cptr = ffi.new('git_signature **')
|
||||||
|
ffi.buffer(stasher_cptr)[:] = stasher._pointer[:]
|
||||||
|
|
||||||
|
coid = ffi.new('git_oid *')
|
||||||
|
err = C.git_stash_save(coid, self._repo, stasher_cptr[0], stash_msg, flags)
|
||||||
|
check_error(err)
|
||||||
|
|
||||||
|
return Oid(raw=bytes(ffi.buffer(coid)[:]))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _stash_args_to_options(reinstate_index=False, **kwargs):
|
||||||
|
stash_opts = ffi.new('git_stash_apply_options *')
|
||||||
|
check_error(C.git_stash_apply_init_options(stash_opts, 1))
|
||||||
|
|
||||||
|
flags = reinstate_index * C.GIT_STASH_APPLY_REINSTATE_INDEX
|
||||||
|
stash_opts.flags = flags
|
||||||
|
|
||||||
|
copts, refs = Repository._checkout_args_to_options(**kwargs)
|
||||||
|
stash_opts.checkout_options = copts[0]
|
||||||
|
|
||||||
|
return stash_opts
|
||||||
|
|
||||||
|
def stash_apply(self, index=0, **kwargs):
|
||||||
|
"""Apply a stashed state in the stash list to the working directory.
|
||||||
|
|
||||||
|
:param int index: The position within the stash list of the stash to apply.
|
||||||
|
0 is the most recent stash.
|
||||||
|
:param bool reinstate_index: Try to reinstate stashed changes to the index.
|
||||||
|
|
||||||
|
The checkout options may be customized using the same arguments taken by
|
||||||
|
Repository.checkout().
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
>>> repo = pygit2.Repsitory('.')
|
||||||
|
>>> repo.stash(repo.default_signature(), 'WIP: stashing')
|
||||||
|
>>> repo.stash_apply(strategy=GIT_CHECKOUT_ALLOW_CONFLICTS)
|
||||||
|
"""
|
||||||
|
stash_opts = Repository._stash_args_to_options(**kwargs)
|
||||||
|
check_error(C.git_stash_apply(self._repo, index, stash_opts))
|
||||||
|
|
||||||
|
def stash_drop(self, index=0):
|
||||||
|
"""Remove a stashed state from the stash list.
|
||||||
|
|
||||||
|
:param int index: The position within the stash list of the stash to remove.
|
||||||
|
0 is the most recent stash.
|
||||||
|
"""
|
||||||
|
check_error(C.git_stash_drop(self._repo, index))
|
||||||
|
|
||||||
|
def stash_pop(self, index=0, **kwargs):
|
||||||
|
"""Apply a stashed state and remove it from the stash list.
|
||||||
|
|
||||||
|
For arguments, see Repository.stash_apply().
|
||||||
|
"""
|
||||||
|
stash_opts = Repository._stash_args_to_options(**kwargs)
|
||||||
|
check_error(C.git_stash_pop(self._repo, index, stash_opts))
|
||||||
|
|
||||||
#
|
#
|
||||||
# Utility for writing a tree into an archive
|
# Utility for writing a tree into an archive
|
||||||
#
|
#
|
||||||
@ -665,7 +860,7 @@ class Repository(_Repository):
|
|||||||
>>> import tarfile, pygit2
|
>>> import tarfile, pygit2
|
||||||
>>>> with tarfile.open('foo.tar', 'w') as archive:
|
>>>> with tarfile.open('foo.tar', 'w') as archive:
|
||||||
>>>> repo = pygit2.Repsitory('.')
|
>>>> repo = pygit2.Repsitory('.')
|
||||||
>>>> repo.write_archive(archive, repo.head.target)
|
>>>> repo.write_archive(repo.head.target, archive)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Try to get a tree form whatever we got
|
# Try to get a tree form whatever we got
|
||||||
@ -699,8 +894,8 @@ class Repository(_Repository):
|
|||||||
info.mtime = timestamp
|
info.mtime = timestamp
|
||||||
info.uname = info.gname = 'root' # just because git does this
|
info.uname = info.gname = 'root' # just because git does this
|
||||||
if entry.mode == GIT_FILEMODE_LINK:
|
if entry.mode == GIT_FILEMODE_LINK:
|
||||||
info.type = archive.SYMTYPE
|
info.type = tarfile.SYMTYPE
|
||||||
info.linkname = content
|
info.linkname = content.decode("utf-8")
|
||||||
info.mode = 0o777 # symlinks get placeholder
|
info.mode = 0o777 # symlinks get placeholder
|
||||||
info.size = 0
|
info.size = 0
|
||||||
archive.addfile(info)
|
archive.addfile(info)
|
||||||
@ -805,3 +1000,130 @@ class Repository(_Repository):
|
|||||||
|
|
||||||
err = C.git_repository_set_ident(self._repo, to_bytes(name), to_bytes(email))
|
err = C.git_repository_set_ident(self._repo, to_bytes(name), to_bytes(email))
|
||||||
check_error(err)
|
check_error(err)
|
||||||
|
|
||||||
|
def revert_commit(self, revert_commit, our_commit, mainline=0):
|
||||||
|
"""Reverts the given Commit against the given "our" Commit,
|
||||||
|
producing an Index that reflects the result of the revert.
|
||||||
|
|
||||||
|
Arguments
|
||||||
|
|
||||||
|
revert_commit
|
||||||
|
The Commit to revert
|
||||||
|
our_commit
|
||||||
|
The Commit to revert against (eg, HEAD)
|
||||||
|
mainline
|
||||||
|
The parent of the revert Commit, if it is a merge (i.e. 1, 2)
|
||||||
|
|
||||||
|
Returns an Index with the result of the revert.
|
||||||
|
"""
|
||||||
|
cindex = ffi.new('git_index **')
|
||||||
|
revert_commit_ptr = ffi.new('git_commit **')
|
||||||
|
our_commit_ptr = ffi.new('git_commit **')
|
||||||
|
|
||||||
|
ffi.buffer(revert_commit_ptr)[:] = revert_commit._pointer[:]
|
||||||
|
ffi.buffer(our_commit_ptr)[:] = our_commit._pointer[:]
|
||||||
|
|
||||||
|
opts = ffi.new('git_merge_options *')
|
||||||
|
err = C.git_merge_init_options(opts, C.GIT_MERGE_OPTIONS_VERSION)
|
||||||
|
check_error(err)
|
||||||
|
|
||||||
|
err = C.git_revert_commit(
|
||||||
|
cindex, self._repo, revert_commit_ptr[0], our_commit_ptr[0], mainline, opts
|
||||||
|
)
|
||||||
|
check_error(err)
|
||||||
|
|
||||||
|
return Index.from_c(self, cindex)
|
||||||
|
|
||||||
|
|
||||||
|
class Branches(object):
|
||||||
|
def __init__(self, repository, flag=GIT_BRANCH_ALL):
|
||||||
|
self._repository = repository
|
||||||
|
self._flag = flag
|
||||||
|
|
||||||
|
if flag == GIT_BRANCH_ALL:
|
||||||
|
self.local = Branches(repository, flag=GIT_BRANCH_LOCAL)
|
||||||
|
self.remote = Branches(repository, flag=GIT_BRANCH_REMOTE)
|
||||||
|
|
||||||
|
def __getitem__(self, name):
|
||||||
|
branch = None
|
||||||
|
if self._flag & GIT_BRANCH_LOCAL:
|
||||||
|
branch = self._repository.lookup_branch(name, GIT_BRANCH_LOCAL)
|
||||||
|
|
||||||
|
if branch is None and self._flag & GIT_BRANCH_REMOTE:
|
||||||
|
branch = self._repository.lookup_branch(name, GIT_BRANCH_REMOTE)
|
||||||
|
|
||||||
|
if branch is None:
|
||||||
|
raise KeyError('Branch not found: {}'.format(name))
|
||||||
|
|
||||||
|
return branch
|
||||||
|
|
||||||
|
def get(self, key):
|
||||||
|
try:
|
||||||
|
return self[key]
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
for branch_name in self._repository.listall_branches(self._flag):
|
||||||
|
yield branch_name
|
||||||
|
|
||||||
|
def create(self, name, commit, force=False):
|
||||||
|
return self._repository.create_branch(name, commit, force)
|
||||||
|
|
||||||
|
def delete(self, name):
|
||||||
|
self[name].delete()
|
||||||
|
|
||||||
|
def __contains__(self, name):
|
||||||
|
return self.get(name) is not None
|
||||||
|
|
||||||
|
|
||||||
|
class References(object):
|
||||||
|
def __init__(self, repository):
|
||||||
|
self._repository = repository
|
||||||
|
|
||||||
|
def __getitem__(self, name):
|
||||||
|
return self._repository.lookup_reference(name)
|
||||||
|
|
||||||
|
def get(self, key):
|
||||||
|
try:
|
||||||
|
return self[key]
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
for ref_name in self._repository.listall_references():
|
||||||
|
yield ref_name
|
||||||
|
|
||||||
|
def create(self, name, target, force=False):
|
||||||
|
return self._repository.create_reference(name, target, force)
|
||||||
|
|
||||||
|
def delete(self, name):
|
||||||
|
self[name].delete()
|
||||||
|
|
||||||
|
def __contains__(self, name):
|
||||||
|
return self.get(name) is not None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def objects(self):
|
||||||
|
return self._repository.listall_reference_objects()
|
||||||
|
|
||||||
|
|
||||||
|
class Repository(BaseRepository):
|
||||||
|
def __init__(self, path, *args, **kwargs):
|
||||||
|
if not isinstance(path, six.string_types):
|
||||||
|
path = path.decode('utf-8')
|
||||||
|
|
||||||
|
path_backend = init_file_backend(path)
|
||||||
|
super(Repository, self).__init__(backend=path_backend, *args, **kwargs)
|
||||||
|
|
||||||
|
self.branches = Branches(self)
|
||||||
|
self.references = References(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _from_c(cls, ptr, owned):
|
||||||
|
cptr = ffi.new('git_repository **')
|
||||||
|
cptr[0] = ptr
|
||||||
|
repo = cls.__new__(cls)
|
||||||
|
super(cls, repo)._from_c(bytes(ffi.buffer(cptr)[:]), owned)
|
||||||
|
repo._common_init()
|
||||||
|
return repo
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -28,6 +28,11 @@
|
|||||||
from _pygit2 import option
|
from _pygit2 import option
|
||||||
from _pygit2 import GIT_OPT_GET_SEARCH_PATH, GIT_OPT_SET_SEARCH_PATH
|
from _pygit2 import GIT_OPT_GET_SEARCH_PATH, GIT_OPT_SET_SEARCH_PATH
|
||||||
from _pygit2 import GIT_OPT_GET_MWINDOW_SIZE, GIT_OPT_SET_MWINDOW_SIZE
|
from _pygit2 import GIT_OPT_GET_MWINDOW_SIZE, GIT_OPT_SET_MWINDOW_SIZE
|
||||||
|
from _pygit2 import GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, GIT_OPT_SET_MWINDOW_MAPPED_LIMIT
|
||||||
|
from _pygit2 import GIT_OPT_SET_CACHE_OBJECT_LIMIT
|
||||||
|
from _pygit2 import GIT_OPT_GET_CACHED_MEMORY
|
||||||
|
from _pygit2 import GIT_OPT_ENABLE_CACHING
|
||||||
|
from _pygit2 import GIT_OPT_SET_CACHE_MAX_SIZE
|
||||||
|
|
||||||
|
|
||||||
class SearchPathList(object):
|
class SearchPathList(object):
|
||||||
@ -64,3 +69,36 @@ class Settings(object):
|
|||||||
@mwindow_size.setter
|
@mwindow_size.setter
|
||||||
def mwindow_size(self, value):
|
def mwindow_size(self, value):
|
||||||
option(GIT_OPT_SET_MWINDOW_SIZE, value)
|
option(GIT_OPT_SET_MWINDOW_SIZE, value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mwindow_mapped_limit(self):
|
||||||
|
"""Mwindow mapped limit"""
|
||||||
|
return option(GIT_OPT_GET_MWINDOW_MAPPED_LIMIT)
|
||||||
|
|
||||||
|
@mwindow_mapped_limit.setter
|
||||||
|
def mwindow_mapped_limit(self, value):
|
||||||
|
"""Mwindow mapped limit"""
|
||||||
|
return option(GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, value)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cached_memory(self):
|
||||||
|
"""Maximum mmap window size"""
|
||||||
|
return option(GIT_OPT_GET_CACHED_MEMORY)
|
||||||
|
|
||||||
|
def enable_caching(self, value=True):
|
||||||
|
return option(GIT_OPT_ENABLE_CACHING, value)
|
||||||
|
|
||||||
|
def cache_max_size(self, value):
|
||||||
|
return option(GIT_OPT_SET_CACHE_MAX_SIZE, value)
|
||||||
|
|
||||||
|
def cache_object_limit(self, object_type, value):
|
||||||
|
"""Set the maximum data size for the given type of object to be
|
||||||
|
considered eligible for caching in memory.
|
||||||
|
|
||||||
|
Setting to value to zero means that that type of object will not
|
||||||
|
be cached. Defaults to 0 for GIT_OBJ_BLOB (i.e. won't cache
|
||||||
|
blobs) and 4k for GIT_OBJ_COMMIT, GIT_OBJ_TREE, and GIT_OBJ_TAG.
|
||||||
|
"""
|
||||||
|
return option(GIT_OPT_SET_CACHE_OBJECT_LIMIT, object_type, value)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
129
setup.py
129
setup.py
@ -1,7 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# coding: UTF-8
|
# coding: UTF-8
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -45,22 +45,26 @@ from subprocess import Popen, PIPE
|
|||||||
import sys
|
import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
# Get cffi major version
|
||||||
|
try:
|
||||||
|
import cffi
|
||||||
|
except ImportError:
|
||||||
|
cffi_major_version = None
|
||||||
|
else:
|
||||||
|
cffi_major_version = cffi.__version_info__[0]
|
||||||
|
|
||||||
# Import stuff from pygit2/_utils.py without loading the whole pygit2 package
|
# Import stuff from pygit2/_utils.py without loading the whole pygit2 package
|
||||||
sys.path.insert(0, 'pygit2')
|
sys.path.insert(0, 'pygit2')
|
||||||
from _utils import __version__, get_libgit2_paths, get_ffi
|
from _build import __version__, get_libgit2_paths
|
||||||
|
if cffi_major_version == 0:
|
||||||
|
from _run import ffi, preamble, C_KEYWORDS
|
||||||
|
ffi.verify(preamble, **C_KEYWORDS)
|
||||||
del sys.path[0]
|
del sys.path[0]
|
||||||
|
|
||||||
# Python 2 support
|
|
||||||
# See https://github.com/libgit2/pygit2/pull/180 for a discussion about this.
|
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
u = lambda s: unicode(s, 'utf-8')
|
|
||||||
else:
|
|
||||||
u = str
|
|
||||||
|
|
||||||
|
|
||||||
libgit2_bin, libgit2_include, libgit2_lib = get_libgit2_paths()
|
libgit2_bin, libgit2_include, libgit2_lib = get_libgit2_paths()
|
||||||
|
|
||||||
pygit2_exts = [os.path.join('src', name) for name in listdir('src')
|
pygit2_exts = [os.path.join('src', name) for name in sorted(listdir('src'))
|
||||||
if name.endswith('.c')]
|
if name.endswith('.c')]
|
||||||
|
|
||||||
|
|
||||||
@ -95,19 +99,43 @@ class TestCommand(Command):
|
|||||||
unittest.main(None, defaultTest='test.test_suite', argv=test_argv)
|
unittest.main(None, defaultTest='test.test_suite', argv=test_argv)
|
||||||
|
|
||||||
|
|
||||||
class CFFIBuild(build):
|
class sdist_files_from_git(sdist):
|
||||||
"""Hack to combat the chicken and egg problem that we need cffi
|
def get_file_list(self):
|
||||||
to add cffi as an extension.
|
popen = Popen(['git', 'ls-files'], stdout=PIPE, stderr=PIPE,
|
||||||
"""
|
universal_newlines=True)
|
||||||
def finalize_options(self):
|
stdoutdata, stderrdata = popen.communicate()
|
||||||
ffi, C = get_ffi()
|
if popen.returncode != 0:
|
||||||
self.distribution.ext_modules.append(ffi.verifier.get_extension())
|
print(stderrdata)
|
||||||
build.finalize_options(self)
|
sys.exit()
|
||||||
|
|
||||||
|
for line in stdoutdata.splitlines():
|
||||||
|
# Skip hidden files at the root
|
||||||
|
if line[0] == '.':
|
||||||
|
continue
|
||||||
|
self.filelist.append(line)
|
||||||
|
|
||||||
|
# Ok
|
||||||
|
self.filelist.sort()
|
||||||
|
self.filelist.remove_duplicates()
|
||||||
|
self.write_manifest()
|
||||||
|
|
||||||
|
|
||||||
class BuildWithDLLs(CFFIBuild):
|
classifiers = [
|
||||||
|
"Development Status :: 3 - Alpha",
|
||||||
|
"Intended Audience :: Developers",
|
||||||
|
"Topic :: Software Development :: Version Control"]
|
||||||
|
|
||||||
# On Windows, we install the git2.dll too.
|
with codecs.open('README.rst', 'r', 'utf-8') as readme:
|
||||||
|
long_description = readme.read()
|
||||||
|
|
||||||
|
cmdclass = {
|
||||||
|
'test': TestCommand,
|
||||||
|
'sdist': sdist_files_from_git,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# On Windows, we install the git2.dll too.
|
||||||
|
class BuildWithDLLs(build):
|
||||||
def _get_dlls(self):
|
def _get_dlls(self):
|
||||||
# return a list of (FQ-in-name, relative-out-name) tuples.
|
# return a list of (FQ-in-name, relative-out-name) tuples.
|
||||||
ret = []
|
ret = []
|
||||||
@ -133,45 +161,27 @@ class BuildWithDLLs(CFFIBuild):
|
|||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
build.run(self)
|
build.run(self)
|
||||||
# On Windows we package up the dlls with the plugin.
|
|
||||||
for s, d in self._get_dlls():
|
for s, d in self._get_dlls():
|
||||||
self.copy_file(s, d)
|
self.copy_file(s, d)
|
||||||
|
|
||||||
|
# On Windows we package up the dlls with the plugin.
|
||||||
|
if os.name == 'nt':
|
||||||
|
cmdclass['build'] = BuildWithDLLs
|
||||||
|
|
||||||
class sdist_files_from_git(sdist):
|
extra_args = {
|
||||||
def get_file_list(self):
|
'ext_modules': [
|
||||||
popen = Popen(['git', 'ls-files'], stdout=PIPE, stderr=PIPE)
|
Extension('_pygit2', pygit2_exts, libraries=['git2'],
|
||||||
stdoutdata, stderrdata = popen.communicate()
|
include_dirs=[libgit2_include],
|
||||||
if popen.returncode != 0:
|
library_dirs=[libgit2_lib]),
|
||||||
print(stderrdata)
|
# FFI is added in the build step
|
||||||
sys.exit()
|
],
|
||||||
|
}
|
||||||
|
|
||||||
for line in stdoutdata.splitlines():
|
if cffi_major_version == 0:
|
||||||
# Skip hidden files at the root
|
extra_args['ext_modules'].append(ffi.verifier.get_extension())
|
||||||
if line[0] == '.':
|
else:
|
||||||
continue
|
extra_args['cffi_modules'] = ['pygit2/_run.py:ffi']
|
||||||
self.filelist.append(line)
|
|
||||||
|
|
||||||
# Ok
|
|
||||||
self.filelist.sort()
|
|
||||||
self.filelist.remove_duplicates()
|
|
||||||
self.write_manifest()
|
|
||||||
|
|
||||||
classifiers = [
|
|
||||||
"Development Status :: 3 - Alpha",
|
|
||||||
"Intended Audience :: Developers",
|
|
||||||
"Topic :: Software Development :: Version Control"]
|
|
||||||
|
|
||||||
|
|
||||||
with codecs.open('README.rst', 'r', 'utf-8') as readme:
|
|
||||||
long_description = readme.read()
|
|
||||||
|
|
||||||
|
|
||||||
cmdclass = {
|
|
||||||
'build': BuildWithDLLs if os.name == 'nt' else CFFIBuild,
|
|
||||||
'test': TestCommand,
|
|
||||||
'sdist': sdist_files_from_git,
|
|
||||||
}
|
|
||||||
|
|
||||||
setup(name='pygit2',
|
setup(name='pygit2',
|
||||||
description='Python bindings for libgit2.',
|
description='Python bindings for libgit2.',
|
||||||
@ -180,18 +190,13 @@ setup(name='pygit2',
|
|||||||
url='http://github.com/libgit2/pygit2',
|
url='http://github.com/libgit2/pygit2',
|
||||||
classifiers=classifiers,
|
classifiers=classifiers,
|
||||||
license='GPLv2 with linking exception',
|
license='GPLv2 with linking exception',
|
||||||
maintainer=u('J. David Ibáñez'),
|
maintainer=u'J. David Ibáñez',
|
||||||
maintainer_email='jdavid.ibp@gmail.com',
|
maintainer_email='jdavid.ibp@gmail.com',
|
||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
packages=['pygit2'],
|
packages=['pygit2'],
|
||||||
package_data={'pygit2': ['decl.h']},
|
package_data={'pygit2': ['decl.h']},
|
||||||
setup_requires=['cffi'],
|
setup_requires=['cffi'],
|
||||||
install_requires=['cffi'],
|
install_requires=['cffi', 'six'],
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
ext_modules=[
|
cmdclass=cmdclass,
|
||||||
Extension('_pygit2', pygit2_exts, libraries=['git2'],
|
**extra_args)
|
||||||
include_dirs=[libgit2_include],
|
|
||||||
library_dirs=[libgit2_lib]),
|
|
||||||
# FFI is added in the build step
|
|
||||||
],
|
|
||||||
cmdclass=cmdclass)
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -133,7 +133,7 @@ PyDoc_STRVAR(Blob_size__doc__, "Size.");
|
|||||||
PyObject *
|
PyObject *
|
||||||
Blob_size__get__(Blob *self)
|
Blob_size__get__(Blob *self)
|
||||||
{
|
{
|
||||||
return PyLong_FromLongLong(git_blob_rawsize(self->blob));
|
return PyInt_FromLongLong(git_blob_rawsize(self->blob));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
25
src/branch.c
25
src/branch.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -81,6 +81,28 @@ Branch_is_head(Branch *self)
|
|||||||
return Error_set(err);
|
return Error_set(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(Branch_is_checked_out__doc__,
|
||||||
|
"is_checked_out()\n"
|
||||||
|
"\n"
|
||||||
|
"True if branch is checked out by any repo connected to the current one, "
|
||||||
|
" False otherwise.");
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
Branch_is_checked_out(Branch *self)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
CHECK_REFERENCE(self);
|
||||||
|
|
||||||
|
err = git_branch_is_checked_out(self->reference);
|
||||||
|
if (err == 1)
|
||||||
|
Py_RETURN_TRUE;
|
||||||
|
else if (err == 0)
|
||||||
|
Py_RETURN_FALSE;
|
||||||
|
else
|
||||||
|
return Error_set(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Branch_rename__doc__,
|
PyDoc_STRVAR(Branch_rename__doc__,
|
||||||
"rename(name, force=False)\n"
|
"rename(name, force=False)\n"
|
||||||
@ -234,6 +256,7 @@ Branch_upstream_name__get__(Branch *self)
|
|||||||
PyMethodDef Branch_methods[] = {
|
PyMethodDef Branch_methods[] = {
|
||||||
METHOD(Branch, delete, METH_NOARGS),
|
METHOD(Branch, delete, METH_NOARGS),
|
||||||
METHOD(Branch, is_head, METH_NOARGS),
|
METHOD(Branch, is_head, METH_NOARGS),
|
||||||
|
METHOD(Branch, is_checked_out, METH_NOARGS),
|
||||||
METHOD(Branch, rename, METH_VARARGS),
|
METHOD(Branch, rename, METH_VARARGS),
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
PyObject* Branch_delete(Branch *self, PyObject *args);
|
PyObject* Branch_delete(Branch *self, PyObject *args);
|
||||||
PyObject* Branch_is_head(Branch *self);
|
PyObject* Branch_is_head(Branch *self);
|
||||||
|
PyObject* Branch_is_checked_out(Branch *self);
|
||||||
PyObject* Branch_move(Branch *self, PyObject *args);
|
PyObject* Branch_move(Branch *self, PyObject *args);
|
||||||
|
|
||||||
PyObject* wrap_branch(git_reference *c_reference, Repository *repo);
|
PyObject* wrap_branch(git_reference *c_reference, Repository *repo);
|
||||||
|
14
src/commit.c
14
src/commit.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -35,6 +35,7 @@
|
|||||||
#include "oid.h"
|
#include "oid.h"
|
||||||
|
|
||||||
extern PyTypeObject TreeType;
|
extern PyTypeObject TreeType;
|
||||||
|
extern PyObject *GitError;
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Commit_message_encoding__doc__, "Message encoding.");
|
PyDoc_STRVAR(Commit_message_encoding__doc__, "Message encoding.");
|
||||||
@ -79,7 +80,7 @@ PyDoc_STRVAR(Commit_commit_time__doc__, "Commit time.");
|
|||||||
PyObject *
|
PyObject *
|
||||||
Commit_commit_time__get__(Commit *commit)
|
Commit_commit_time__get__(Commit *commit)
|
||||||
{
|
{
|
||||||
return PyLong_FromLongLong(git_commit_time(commit->commit));
|
return PyInt_FromLongLong(git_commit_time(commit->commit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ PyDoc_STRVAR(Commit_commit_time_offset__doc__, "Commit time offset.");
|
|||||||
PyObject *
|
PyObject *
|
||||||
Commit_commit_time_offset__get__(Commit *commit)
|
Commit_commit_time_offset__get__(Commit *commit)
|
||||||
{
|
{
|
||||||
return PyLong_FromLong(git_commit_time_offset(commit->commit));
|
return PyInt_FromLong(git_commit_time_offset(commit->commit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -131,8 +132,11 @@ Commit_tree__get__(Commit *commit)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = git_commit_tree(&tree, commit->commit);
|
err = git_commit_tree(&tree, commit->commit);
|
||||||
if (err == GIT_ENOTFOUND)
|
if (err == GIT_ENOTFOUND) {
|
||||||
Py_RETURN_NONE;
|
char tree_id[GIT_OID_HEXSZ + 1] = { 0 };
|
||||||
|
git_oid_fmt(tree_id, git_commit_tree_id(commit->commit));
|
||||||
|
return PyErr_Format(GitError, "Unable to read tree %s", tree_id);
|
||||||
|
}
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return Error_set(err);
|
return Error_set(err);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
17
src/diff.c
17
src/diff.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -482,7 +482,8 @@ Diff_len(Diff *self)
|
|||||||
return (Py_ssize_t)git_diff_num_deltas(self->diff);
|
return (Py_ssize_t)git_diff_num_deltas(self->diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(Diff_patch__doc__, "Patch diff string.");
|
PyDoc_STRVAR(Diff_patch__doc__,
|
||||||
|
"Patch diff string. Can be None in some cases, such as empty commits.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Diff_patch__get__(Diff *self)
|
Diff_patch__get__(Diff *self)
|
||||||
@ -586,7 +587,7 @@ PyDoc_STRVAR(DiffStats_insertions__doc__, "Total number of insertions");
|
|||||||
PyObject *
|
PyObject *
|
||||||
DiffStats_insertions__get__(DiffStats *self)
|
DiffStats_insertions__get__(DiffStats *self)
|
||||||
{
|
{
|
||||||
return PyLong_FromSize_t(git_diff_stats_insertions(self->stats));
|
return PyInt_FromSize_t(git_diff_stats_insertions(self->stats));
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(DiffStats_deletions__doc__, "Total number of deletions");
|
PyDoc_STRVAR(DiffStats_deletions__doc__, "Total number of deletions");
|
||||||
@ -594,7 +595,7 @@ PyDoc_STRVAR(DiffStats_deletions__doc__, "Total number of deletions");
|
|||||||
PyObject *
|
PyObject *
|
||||||
DiffStats_deletions__get__(DiffStats *self)
|
DiffStats_deletions__get__(DiffStats *self)
|
||||||
{
|
{
|
||||||
return PyLong_FromSize_t(git_diff_stats_deletions(self->stats));
|
return PyInt_FromSize_t(git_diff_stats_deletions(self->stats));
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(DiffStats_files_changed__doc__, "Total number of files changed");
|
PyDoc_STRVAR(DiffStats_files_changed__doc__, "Total number of files changed");
|
||||||
@ -602,7 +603,7 @@ PyDoc_STRVAR(DiffStats_files_changed__doc__, "Total number of files changed");
|
|||||||
PyObject *
|
PyObject *
|
||||||
DiffStats_files_changed__get__(DiffStats *self)
|
DiffStats_files_changed__get__(DiffStats *self)
|
||||||
{
|
{
|
||||||
return PyLong_FromSize_t(git_diff_stats_files_changed(self->stats));
|
return PyInt_FromSize_t(git_diff_stats_files_changed(self->stats));
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(DiffStats_format__doc__,
|
PyDoc_STRVAR(DiffStats_format__doc__,
|
||||||
@ -804,10 +805,10 @@ Diff_getitem(Diff *self, PyObject *value)
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (!PyLong_Check(value))
|
if (!PyInt_Check(value))
|
||||||
return NULL;
|
return NULL; /* FIXME Raise error */
|
||||||
|
|
||||||
i = PyLong_AsUnsignedLong(value);
|
i = PyInt_AsSize_t(value);
|
||||||
return diff_get_patch_byindex(self->diff, i);
|
return diff_get_patch_byindex(self->diff, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -126,3 +126,10 @@ Error_set_oid(int err, const git_oid *oid, size_t len)
|
|||||||
hex[len] = '\0';
|
hex[len] = '\0';
|
||||||
return Error_set_str(err, hex);
|
return Error_set_str(err, hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
Error_type_error(const char *format, PyObject *value)
|
||||||
|
{
|
||||||
|
PyErr_Format(PyExc_TypeError, format, Py_TYPE(value)->tp_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -37,5 +37,6 @@ PyObject* Error_set(int err);
|
|||||||
PyObject* Error_set_exc(PyObject* exception);
|
PyObject* Error_set_exc(PyObject* exception);
|
||||||
PyObject* Error_set_str(int err, const char *str);
|
PyObject* Error_set_str(int err, const char *str);
|
||||||
PyObject* Error_set_oid(int err, const git_oid *oid, size_t len);
|
PyObject* Error_set_oid(int err, const git_oid *oid, size_t len);
|
||||||
|
PyObject* Error_type_error(const char *format, PyObject *value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
13
src/object.c
13
src/object.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -97,7 +97,7 @@ PyDoc_STRVAR(Object_type__doc__,
|
|||||||
PyObject *
|
PyObject *
|
||||||
Object_type__get__(Object *self)
|
Object_type__get__(Object *self)
|
||||||
{
|
{
|
||||||
return PyLong_FromLong(git_object_type(self->obj));
|
return PyInt_FromLong(git_object_type(self->obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(Object__pointer__doc__, "Get the object's pointer. For internal use only.");
|
PyDoc_STRVAR(Object__pointer__doc__, "Get the object's pointer. For internal use only.");
|
||||||
@ -143,14 +143,15 @@ PyDoc_STRVAR(Object_peel__doc__,
|
|||||||
PyObject *
|
PyObject *
|
||||||
Object_peel(Object *self, PyObject *py_type)
|
Object_peel(Object *self, PyObject *py_type)
|
||||||
{
|
{
|
||||||
int type = -1, err;
|
int err;
|
||||||
|
git_otype otype;
|
||||||
git_object *peeled;
|
git_object *peeled;
|
||||||
|
|
||||||
type = py_object_to_object_type(py_type);
|
otype = py_object_to_otype(py_type);
|
||||||
if (type == -1)
|
if (otype == GIT_OBJ_BAD)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err = git_object_peel(&peeled, self->obj, (git_otype)type);
|
err = git_object_peel(&peeled, self->obj, otype);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return Error_set(err);
|
return Error_set(err);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -209,8 +209,10 @@ Oid_init(Oid *self, PyObject *args, PyObject *kw)
|
|||||||
Py_hash_t
|
Py_hash_t
|
||||||
Oid_hash(PyObject *oid)
|
Oid_hash(PyObject *oid)
|
||||||
{
|
{
|
||||||
/* TODO Randomize (use _Py_HashSecret) to avoid collission DoS attacks? */
|
PyObject *py_oid = git_oid_to_py_str(&((Oid *)oid)->oid);
|
||||||
return *(Py_hash_t*) ((Oid*)oid)->oid.id;
|
Py_hash_t ret = PyObject_Hash(py_oid);
|
||||||
|
Py_DECREF(py_oid);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
182
src/options.c
182
src/options.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -65,10 +65,11 @@ option(PyObject *self, PyObject *args)
|
|||||||
if (!py_option)
|
if (!py_option)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyLong_Check(py_option))
|
if (!PyInt_Check(py_option))
|
||||||
goto on_non_integer;
|
return Error_type_error(
|
||||||
|
"option should be an integer, got %.200s", py_option);
|
||||||
|
|
||||||
option = PyLong_AsLong(py_option);
|
option = PyInt_AsLong(py_option);
|
||||||
|
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case GIT_OPT_GET_SEARCH_PATH:
|
case GIT_OPT_GET_SEARCH_PATH:
|
||||||
@ -79,11 +80,11 @@ option(PyObject *self, PyObject *args)
|
|||||||
if (!py_level)
|
if (!py_level)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyLong_Check(py_level))
|
if (!PyInt_Check(py_level))
|
||||||
goto on_non_integer;
|
return Error_type_error(
|
||||||
|
"level should be an integer, got %.200s", py_level);
|
||||||
|
|
||||||
return get_search_path(PyLong_AsLong(py_level));
|
return get_search_path(PyInt_AsLong(py_level));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case GIT_OPT_SET_SEARCH_PATH:
|
case GIT_OPT_SET_SEARCH_PATH:
|
||||||
@ -100,23 +101,22 @@ option(PyObject *self, PyObject *args)
|
|||||||
if (!py_path)
|
if (!py_path)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyLong_Check(py_level))
|
if (!PyInt_Check(py_level))
|
||||||
goto on_non_integer;
|
return Error_type_error(
|
||||||
|
"level should be an integer, got %.200s", py_level);
|
||||||
|
|
||||||
path = py_str_borrow_c_str(&tpath, py_path, NULL);
|
path = py_str_borrow_c_str(&tpath, py_path, NULL);
|
||||||
if (!path)
|
if (!path)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err = git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, PyLong_AsLong(py_level), path);
|
err = git_libgit2_opts(
|
||||||
|
GIT_OPT_SET_SEARCH_PATH, PyInt_AsLong(py_level), path);
|
||||||
Py_DECREF(tpath);
|
Py_DECREF(tpath);
|
||||||
|
|
||||||
if (err < 0) {
|
if (err < 0)
|
||||||
Error_set(err);
|
return Error_set(err);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case GIT_OPT_GET_MWINDOW_SIZE:
|
case GIT_OPT_GET_MWINDOW_SIZE:
|
||||||
@ -124,14 +124,10 @@ option(PyObject *self, PyObject *args)
|
|||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
error = git_libgit2_opts(GIT_OPT_GET_MWINDOW_SIZE, &size);
|
error = git_libgit2_opts(GIT_OPT_GET_MWINDOW_SIZE, &size);
|
||||||
if (error < 0) {
|
if (error < 0)
|
||||||
Error_set(error);
|
return Error_set(error);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PyLong_FromSize_t(size);
|
return PyInt_FromSize_t(size);
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case GIT_OPT_SET_MWINDOW_SIZE:
|
case GIT_OPT_SET_MWINDOW_SIZE:
|
||||||
@ -143,25 +139,141 @@ option(PyObject *self, PyObject *args)
|
|||||||
if (!py_size)
|
if (!py_size)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!PyLong_Check(py_size))
|
if (!PyInt_Check(py_size))
|
||||||
goto on_non_integer;
|
return Error_type_error(
|
||||||
|
"size should be an integer, got %.200s", py_size);
|
||||||
|
|
||||||
size = PyLong_AsSize_t(py_size);
|
size = PyInt_AsSize_t(py_size);
|
||||||
error = git_libgit2_opts(GIT_OPT_SET_MWINDOW_SIZE, size);
|
error = git_libgit2_opts(GIT_OPT_SET_MWINDOW_SIZE, size);
|
||||||
if (error < 0) {
|
if (error < 0)
|
||||||
Error_set(error);
|
return Error_set(error);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GIT_OPT_GET_MWINDOW_MAPPED_LIMIT:
|
||||||
|
{
|
||||||
|
size_t limit;
|
||||||
|
|
||||||
|
error = git_libgit2_opts(GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, &limit);
|
||||||
|
if (error < 0)
|
||||||
|
return Error_set(error);
|
||||||
|
|
||||||
|
return PyInt_FromSize_t(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
case GIT_OPT_SET_MWINDOW_MAPPED_LIMIT:
|
||||||
|
{
|
||||||
|
size_t limit;
|
||||||
|
PyObject *py_limit;
|
||||||
|
|
||||||
|
py_limit = PyTuple_GetItem(args, 1);
|
||||||
|
if (!py_limit)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (PyInt_Check(py_limit)) {
|
||||||
|
limit = PyInt_AsSize_t(py_limit);
|
||||||
|
} else if (PyLong_Check(py_limit)) {
|
||||||
|
limit = PyLong_AsSize_t(py_limit);
|
||||||
|
} else {
|
||||||
|
return Error_type_error(
|
||||||
|
"limit should be an integer, got %.200s", py_limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
error = git_libgit2_opts(GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, limit);
|
||||||
|
if (error < 0)
|
||||||
|
return Error_set(error);
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GIT_OPT_SET_CACHE_OBJECT_LIMIT:
|
||||||
|
{
|
||||||
|
size_t limit;
|
||||||
|
int object_type;
|
||||||
|
PyObject *py_object_type, *py_limit;
|
||||||
|
|
||||||
|
py_object_type = PyTuple_GetItem(args, 1);
|
||||||
|
if (!py_object_type)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
py_limit = PyTuple_GetItem(args, 2);
|
||||||
|
if (!py_limit)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!PyInt_Check(py_limit))
|
||||||
|
return Error_type_error(
|
||||||
|
"limit should be an integer, got %.200s", py_limit);
|
||||||
|
|
||||||
|
object_type = PyInt_AsLong(py_object_type);
|
||||||
|
limit = PyInt_AsSize_t(py_limit);
|
||||||
|
error = git_libgit2_opts(
|
||||||
|
GIT_OPT_SET_CACHE_OBJECT_LIMIT, object_type, limit);
|
||||||
|
|
||||||
|
if (error < 0)
|
||||||
|
return Error_set(error);
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GIT_OPT_SET_CACHE_MAX_SIZE:
|
||||||
|
{
|
||||||
|
size_t max_size;
|
||||||
|
PyObject *py_max_size;
|
||||||
|
|
||||||
|
py_max_size = PyTuple_GetItem(args, 1);
|
||||||
|
if (!py_max_size)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!PyInt_Check(py_max_size))
|
||||||
|
return Error_type_error(
|
||||||
|
"max_size should be an integer, got %.200s", py_max_size);
|
||||||
|
|
||||||
|
max_size = PyInt_AsSize_t(py_max_size);
|
||||||
|
error = git_libgit2_opts(GIT_OPT_SET_CACHE_MAX_SIZE, max_size);
|
||||||
|
if (error < 0)
|
||||||
|
return Error_set(error);
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GIT_OPT_ENABLE_CACHING:
|
||||||
|
{
|
||||||
|
int flag;
|
||||||
|
PyObject *py_flag;
|
||||||
|
|
||||||
|
py_flag = PyTuple_GetItem(args, 1);
|
||||||
|
|
||||||
|
if (!PyInt_Check(py_flag))
|
||||||
|
return Error_type_error(
|
||||||
|
"flag should be an integer, got %.200s", py_flag);
|
||||||
|
|
||||||
|
flag = PyInt_AsSize_t(py_flag);
|
||||||
|
error = git_libgit2_opts(GIT_OPT_ENABLE_CACHING, flag);
|
||||||
|
if (error < 0)
|
||||||
|
return Error_set(error);
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
case GIT_OPT_GET_CACHED_MEMORY:
|
||||||
|
{
|
||||||
|
size_t current;
|
||||||
|
size_t allowed;
|
||||||
|
PyObject* tup = PyTuple_New(2);
|
||||||
|
|
||||||
|
error = git_libgit2_opts(GIT_OPT_GET_CACHED_MEMORY, ¤t, &allowed);
|
||||||
|
if (error < 0)
|
||||||
|
return Error_set(error);
|
||||||
|
|
||||||
|
PyTuple_SetItem(tup, 0, PyInt_FromLong(current));
|
||||||
|
PyTuple_SetItem(tup, 1, PyInt_FromLong(allowed));
|
||||||
|
|
||||||
|
return tup;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyErr_SetString(PyExc_ValueError, "unknown/unsupported option value");
|
PyErr_SetString(PyExc_ValueError, "unknown/unsupported option value");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
on_non_integer:
|
|
||||||
PyErr_SetString(PyExc_TypeError, "option is not an integer");
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
60
src/pygit2.c
60
src/pygit2.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -144,7 +144,44 @@ hash(PyObject *self, PyObject *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyDoc_STRVAR(init_file_backend__doc__,
|
||||||
|
"init_file_backend(path) -> object\n"
|
||||||
|
"\n"
|
||||||
|
"open repo backend given path.");
|
||||||
|
PyObject *
|
||||||
|
init_file_backend(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
const char* path = NULL;
|
||||||
|
int err = GIT_OK;
|
||||||
|
git_repository *repository = NULL;
|
||||||
|
if (!PyArg_ParseTuple(args, "s", &path)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = git_repository_open(&repository, path);
|
||||||
|
if (err < 0) {
|
||||||
|
Error_set_str(err, path);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PyCapsule_New(repository, "backend", NULL);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (repository) {
|
||||||
|
git_repository_free(repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == GIT_ENOTFOUND) {
|
||||||
|
PyErr_Format(GitError, "Repository not found at %s", path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PyMethodDef module_methods[] = {
|
PyMethodDef module_methods[] = {
|
||||||
|
{"init_file_backend", init_file_backend, METH_VARARGS,
|
||||||
|
init_file_backend__doc__},
|
||||||
{"discover_repository", discover_repository, METH_VARARGS,
|
{"discover_repository", discover_repository, METH_VARARGS,
|
||||||
discover_repository__doc__},
|
discover_repository__doc__},
|
||||||
{"hashfile", hashfile, METH_VARARGS, hashfile__doc__},
|
{"hashfile", hashfile, METH_VARARGS, hashfile__doc__},
|
||||||
@ -170,6 +207,12 @@ moduleinit(PyObject* m)
|
|||||||
ADD_CONSTANT_INT(m, GIT_OPT_SET_SEARCH_PATH);
|
ADD_CONSTANT_INT(m, GIT_OPT_SET_SEARCH_PATH);
|
||||||
ADD_CONSTANT_INT(m, GIT_OPT_GET_MWINDOW_SIZE);
|
ADD_CONSTANT_INT(m, GIT_OPT_GET_MWINDOW_SIZE);
|
||||||
ADD_CONSTANT_INT(m, GIT_OPT_SET_MWINDOW_SIZE);
|
ADD_CONSTANT_INT(m, GIT_OPT_SET_MWINDOW_SIZE);
|
||||||
|
ADD_CONSTANT_INT(m, GIT_OPT_GET_MWINDOW_MAPPED_LIMIT);
|
||||||
|
ADD_CONSTANT_INT(m, GIT_OPT_SET_MWINDOW_MAPPED_LIMIT);
|
||||||
|
ADD_CONSTANT_INT(m, GIT_OPT_SET_CACHE_OBJECT_LIMIT);
|
||||||
|
ADD_CONSTANT_INT(m, GIT_OPT_GET_CACHED_MEMORY);
|
||||||
|
ADD_CONSTANT_INT(m, GIT_OPT_ENABLE_CACHING);
|
||||||
|
ADD_CONSTANT_INT(m, GIT_OPT_SET_CACHE_MAX_SIZE);
|
||||||
|
|
||||||
/* Errors */
|
/* Errors */
|
||||||
GitError = PyErr_NewException("_pygit2.GitError", NULL, NULL);
|
GitError = PyErr_NewException("_pygit2.GitError", NULL, NULL);
|
||||||
@ -260,6 +303,7 @@ moduleinit(PyObject* m)
|
|||||||
ADD_TYPE(m, Branch)
|
ADD_TYPE(m, Branch)
|
||||||
ADD_CONSTANT_INT(m, GIT_BRANCH_LOCAL)
|
ADD_CONSTANT_INT(m, GIT_BRANCH_LOCAL)
|
||||||
ADD_CONSTANT_INT(m, GIT_BRANCH_REMOTE)
|
ADD_CONSTANT_INT(m, GIT_BRANCH_REMOTE)
|
||||||
|
ADD_CONSTANT_INT(m, GIT_BRANCH_ALL)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Index & Working copy
|
* Index & Working copy
|
||||||
@ -323,6 +367,7 @@ moduleinit(PyObject* m)
|
|||||||
ADD_CONSTANT_INT(m, GIT_DIFF_IGNORE_CASE)
|
ADD_CONSTANT_INT(m, GIT_DIFF_IGNORE_CASE)
|
||||||
ADD_CONSTANT_INT(m, GIT_DIFF_SHOW_UNTRACKED_CONTENT)
|
ADD_CONSTANT_INT(m, GIT_DIFF_SHOW_UNTRACKED_CONTENT)
|
||||||
ADD_CONSTANT_INT(m, GIT_DIFF_SKIP_BINARY_CHECK)
|
ADD_CONSTANT_INT(m, GIT_DIFF_SKIP_BINARY_CHECK)
|
||||||
|
ADD_CONSTANT_INT(m, GIT_DIFF_SHOW_BINARY)
|
||||||
ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_TYPECHANGE)
|
ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_TYPECHANGE)
|
||||||
ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_TYPECHANGE_TREES)
|
ADD_CONSTANT_INT(m, GIT_DIFF_INCLUDE_TYPECHANGE_TREES)
|
||||||
ADD_CONSTANT_INT(m, GIT_DIFF_RECURSE_IGNORED_DIRS)
|
ADD_CONSTANT_INT(m, GIT_DIFF_RECURSE_IGNORED_DIRS)
|
||||||
@ -380,6 +425,19 @@ moduleinit(PyObject* m)
|
|||||||
ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_FASTFORWARD)
|
ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_FASTFORWARD)
|
||||||
ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_UNBORN)
|
ADD_CONSTANT_INT(m, GIT_MERGE_ANALYSIS_UNBORN)
|
||||||
|
|
||||||
|
/* Describe */
|
||||||
|
ADD_CONSTANT_INT(m, GIT_DESCRIBE_DEFAULT);
|
||||||
|
ADD_CONSTANT_INT(m, GIT_DESCRIBE_TAGS);
|
||||||
|
ADD_CONSTANT_INT(m, GIT_DESCRIBE_ALL);
|
||||||
|
|
||||||
|
/* Stash */
|
||||||
|
ADD_CONSTANT_INT(m, GIT_STASH_DEFAULT);
|
||||||
|
ADD_CONSTANT_INT(m, GIT_STASH_KEEP_INDEX);
|
||||||
|
ADD_CONSTANT_INT(m, GIT_STASH_INCLUDE_UNTRACKED);
|
||||||
|
ADD_CONSTANT_INT(m, GIT_STASH_INCLUDE_IGNORED);
|
||||||
|
ADD_CONSTANT_INT(m, GIT_STASH_APPLY_DEFAULT);
|
||||||
|
ADD_CONSTANT_INT(m, GIT_STASH_APPLY_REINSTATE_INDEX);
|
||||||
|
|
||||||
/* Global initialization of libgit2 */
|
/* Global initialization of libgit2 */
|
||||||
git_libgit2_init();
|
git_libgit2_init();
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -325,7 +325,7 @@ Reference_type__get__(Reference *self)
|
|||||||
|
|
||||||
CHECK_REFERENCE(self);
|
CHECK_REFERENCE(self);
|
||||||
c_type = git_reference_type(self->reference);
|
c_type = git_reference_type(self->reference);
|
||||||
return PyLong_FromLong(c_type);
|
return PyInt_FromLong(c_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -379,7 +379,8 @@ PyDoc_STRVAR(Reference_peel__doc__,
|
|||||||
PyObject *
|
PyObject *
|
||||||
Reference_peel(Reference *self, PyObject *args)
|
Reference_peel(Reference *self, PyObject *args)
|
||||||
{
|
{
|
||||||
int err, type;
|
int err;
|
||||||
|
git_otype otype;
|
||||||
git_object *obj;
|
git_object *obj;
|
||||||
PyObject *py_type = Py_None;
|
PyObject *py_type = Py_None;
|
||||||
|
|
||||||
@ -388,11 +389,11 @@ Reference_peel(Reference *self, PyObject *args)
|
|||||||
if (!PyArg_ParseTuple(args, "|O", &py_type))
|
if (!PyArg_ParseTuple(args, "|O", &py_type))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
type = py_object_to_object_type(py_type);
|
otype = py_object_to_otype(py_type);
|
||||||
if (type == -1)
|
if (otype == GIT_OBJ_BAD)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err = git_reference_peel(&obj, self->reference, type);
|
err = git_reference_peel(&obj, self->reference, otype);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return Error_set(err);
|
return Error_set(err);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
318
src/repository.c
318
src/repository.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -88,8 +88,7 @@ wrap_repository(git_repository *c_repo)
|
|||||||
int
|
int
|
||||||
Repository_init(Repository *self, PyObject *args, PyObject *kwds)
|
Repository_init(Repository *self, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
char *path;
|
PyObject *backend;
|
||||||
int err;
|
|
||||||
|
|
||||||
if (kwds && PyDict_Size(kwds) > 0) {
|
if (kwds && PyDict_Size(kwds) > 0) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
@ -97,15 +96,16 @@ Repository_init(Repository *self, PyObject *args, PyObject *kwds)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s", &path))
|
if (!PyArg_ParseTuple(args, "O", &backend)) {
|
||||||
return -1;
|
|
||||||
|
|
||||||
err = git_repository_open(&self->repo, path);
|
|
||||||
if (err < 0) {
|
|
||||||
Error_set_str(err, path);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->repo = PyCapsule_GetPointer(backend, "backend");
|
||||||
|
if (self->repo == NULL) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"Repository unable to unpack backend.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
self->owned = 1;
|
self->owned = 1;
|
||||||
self->config = NULL;
|
self->config = NULL;
|
||||||
self->index = NULL;
|
self->index = NULL;
|
||||||
@ -349,6 +349,26 @@ Repository_lookup_branch(Repository *self, PyObject *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyDoc_STRVAR(Repository_path_is_ignored__doc__,
|
||||||
|
"Check if a path is ignored in the repository.");
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
Repository_path_is_ignored(Repository *self, PyObject *args)
|
||||||
|
{
|
||||||
|
int ignored;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "s", &path))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
git_ignore_path_is_ignored(&ignored, self->repo, path);
|
||||||
|
if (ignored == 1)
|
||||||
|
Py_RETURN_TRUE;
|
||||||
|
|
||||||
|
Py_RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_revparse_single__doc__,
|
PyDoc_STRVAR(Repository_revparse_single__doc__,
|
||||||
"revparse_single(revision) -> Object\n"
|
"revparse_single(revision) -> Object\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -842,6 +862,86 @@ Repository_create_blob_fromdisk(Repository *self, PyObject *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define BUFSIZE 4096
|
||||||
|
|
||||||
|
PyDoc_STRVAR(Repository_create_blob_fromiobase__doc__,
|
||||||
|
"create_blob_fromiobase(io.IOBase) -> Oid\n"
|
||||||
|
"\n"
|
||||||
|
"Create a new blob from an IOBase object.");
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
Repository_create_blob_fromiobase(Repository *self, PyObject *py_file)
|
||||||
|
{
|
||||||
|
git_writestream *stream;
|
||||||
|
git_oid oid;
|
||||||
|
PyObject *py_is_readable;
|
||||||
|
int is_readable;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
py_is_readable = PyObject_CallMethod(py_file, "readable", NULL);
|
||||||
|
if (!py_is_readable) {
|
||||||
|
if (PyErr_ExceptionMatches(PyExc_AttributeError))
|
||||||
|
PyErr_SetObject(PyExc_TypeError, py_file);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_readable = PyObject_IsTrue(py_is_readable);
|
||||||
|
Py_DECREF(py_is_readable);
|
||||||
|
|
||||||
|
if (!is_readable) {
|
||||||
|
Py_DECREF(py_file);
|
||||||
|
PyErr_SetString(PyExc_TypeError, "expected readable IO type");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = git_blob_create_fromstream(&stream, self->repo, NULL);
|
||||||
|
if (err < 0)
|
||||||
|
return Error_set(err);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
PyObject *py_bytes;
|
||||||
|
char *bytes;
|
||||||
|
Py_ssize_t size;
|
||||||
|
|
||||||
|
py_bytes = PyObject_CallMethod(py_file, "read", "i", 4096);
|
||||||
|
if (!py_bytes)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (py_bytes == Py_None) {
|
||||||
|
Py_DECREF(py_bytes);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyBytes_AsStringAndSize(py_bytes, &bytes, &size)) {
|
||||||
|
Py_DECREF(py_bytes);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
Py_DECREF(py_bytes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = stream->write(stream, bytes, size);
|
||||||
|
Py_DECREF(py_bytes);
|
||||||
|
if (err < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (err < 0) {
|
||||||
|
stream->free(stream);
|
||||||
|
return Error_set(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
err = git_blob_create_fromstream_commit(&oid, stream);
|
||||||
|
if (err < 0)
|
||||||
|
return Error_set(err);
|
||||||
|
|
||||||
|
return git_oid_to_python(&oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_create_commit__doc__,
|
PyDoc_STRVAR(Repository_create_commit__doc__,
|
||||||
"create_commit(reference_name, author, committer, message, tree, parents[, encoding]) -> Oid\n"
|
"create_commit(reference_name, author, committer, message, tree, parents[, encoding]) -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -1041,6 +1141,56 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyDoc_STRVAR(Repository_listall_reference_objects__doc__,
|
||||||
|
"listall_reference_objects() -> [Reference, ...]\n"
|
||||||
|
"\n"
|
||||||
|
"Return a list with all the reference objects in the repository.");
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
Repository_listall_reference_objects(Repository *self, PyObject *args)
|
||||||
|
{
|
||||||
|
git_reference_iterator *iter;
|
||||||
|
git_reference *ref = NULL;
|
||||||
|
int err;
|
||||||
|
PyObject *list;
|
||||||
|
|
||||||
|
list = PyList_New(0);
|
||||||
|
if (list == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ((err = git_reference_iterator_new(&iter, self->repo)) < 0)
|
||||||
|
return Error_set(err);
|
||||||
|
|
||||||
|
while ((err = git_reference_next(&ref, iter)) == 0) {
|
||||||
|
PyObject *py_ref = wrap_reference(ref, self);
|
||||||
|
if (py_ref == NULL)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
err = PyList_Append(list, py_ref);
|
||||||
|
Py_DECREF(py_ref);
|
||||||
|
|
||||||
|
if (err < 0)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
git_reference_iterator_free(iter);
|
||||||
|
if (err == GIT_ITEROVER)
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
if (err < 0) {
|
||||||
|
Py_CLEAR(list);
|
||||||
|
return Error_set(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
|
||||||
|
error:
|
||||||
|
git_reference_iterator_free(iter);
|
||||||
|
Py_CLEAR(list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_listall_branches__doc__,
|
PyDoc_STRVAR(Repository_listall_branches__doc__,
|
||||||
"listall_branches([flag]) -> [str, ...]\n"
|
"listall_branches([flag]) -> [str, ...]\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -1137,6 +1287,141 @@ Repository_listall_submodules(Repository *self, PyObject *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyDoc_STRVAR(Repository_init_submodules__doc__,
|
||||||
|
"init_submodule(submodules=None, overwrite=False)\n"
|
||||||
|
"\n"
|
||||||
|
"Initialize all submodules in repository.\n"
|
||||||
|
"submodules: List of submodules to initialize. Default argument initializes all submodules.\n"
|
||||||
|
"overwrite: Flag indicating if initialization should overwrite submodule entries.\n");
|
||||||
|
|
||||||
|
static int foreach_sub_init_cb(git_submodule *submodule, const char *name, void *payload)
|
||||||
|
{
|
||||||
|
return git_submodule_init(submodule, *(int*)payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
Repository_init_submodules(Repository* self, PyObject *args, PyObject *kwds)
|
||||||
|
{
|
||||||
|
PyObject *list = Py_None;
|
||||||
|
PyObject *oflag = Py_False;
|
||||||
|
char *kwlist[] = {"submodules", "overwrite", NULL};
|
||||||
|
int err, fflag;
|
||||||
|
PyObject *iter, *subpath, *next;
|
||||||
|
const char *c_subpath;
|
||||||
|
git_submodule *submodule;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist, &list, &oflag))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fflag = PyObject_IsTrue(oflag);
|
||||||
|
|
||||||
|
if (fflag != 0 && fflag != 1)
|
||||||
|
fflag = 0;
|
||||||
|
|
||||||
|
//Init all submodules listed in repository
|
||||||
|
if (list == Py_None) {
|
||||||
|
err = git_submodule_foreach(self->repo, foreach_sub_init_cb, &fflag);
|
||||||
|
if (err != 0)
|
||||||
|
return Error_set(err);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = PyObject_GetIter(list);
|
||||||
|
if (!iter)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
next = PyIter_Next(iter);
|
||||||
|
if (!next)
|
||||||
|
break;
|
||||||
|
|
||||||
|
c_subpath = py_str_borrow_c_str(&subpath, next, NULL);
|
||||||
|
|
||||||
|
git_submodule_lookup(&submodule, self->repo, c_subpath);
|
||||||
|
Py_DECREF(subpath);
|
||||||
|
if (!submodule) {
|
||||||
|
PyErr_SetString(PyExc_KeyError,
|
||||||
|
"Submodule does not exist");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = git_submodule_init(submodule, fflag);
|
||||||
|
if (err != 0) {
|
||||||
|
return Error_set(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(Repository_update_submodules__doc__,
|
||||||
|
"update_submodules(submodules=None, init=False)\n"
|
||||||
|
"\n"
|
||||||
|
"Updates the specified submodules, or all if None are specified\n"
|
||||||
|
"init: Flag indicating if submodules should be automatically initialized if necessary.\n");
|
||||||
|
|
||||||
|
static int foreach_sub_update_cb(git_submodule *submodule, const char *name, void *payload)
|
||||||
|
{
|
||||||
|
git_submodule_update_options opts = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
|
||||||
|
return git_submodule_update(submodule, *(int*)payload, &opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
Repository_update_submodules(Repository *self, PyObject *args, PyObject *kwds)
|
||||||
|
{
|
||||||
|
PyObject *list = Py_None;
|
||||||
|
PyObject *py_init = Py_False;
|
||||||
|
PyObject *iter, *next, *subpath;
|
||||||
|
int init, err;
|
||||||
|
const char *c_subpath;
|
||||||
|
git_submodule *submodule;
|
||||||
|
git_submodule_update_options opts = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
|
||||||
|
|
||||||
|
char *kwlist[] = {"submodules", "init", NULL};
|
||||||
|
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist, &list, &py_init))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
init = PyObject_IsTrue(py_init);
|
||||||
|
|
||||||
|
if (init != 0 && init != 1)
|
||||||
|
init = 0;
|
||||||
|
|
||||||
|
if (list == Py_None) {
|
||||||
|
err = git_submodule_foreach(self->repo, foreach_sub_update_cb, &init);
|
||||||
|
if (err != 0)
|
||||||
|
return Error_set(err);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
iter = PyObject_GetIter(list);
|
||||||
|
if (!iter)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
next = PyIter_Next(iter);
|
||||||
|
if (!next)
|
||||||
|
break;
|
||||||
|
|
||||||
|
c_subpath = py_str_borrow_c_str(&subpath, next, NULL);
|
||||||
|
|
||||||
|
git_submodule_lookup(&submodule, self->repo, c_subpath);
|
||||||
|
Py_DECREF(subpath);
|
||||||
|
if (!submodule) {
|
||||||
|
PyErr_SetString(PyExc_KeyError,
|
||||||
|
"Submodule does not exist");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = git_submodule_update(submodule, init, &opts);
|
||||||
|
if (err != 0) {
|
||||||
|
return Error_set(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_lookup_reference__doc__,
|
PyDoc_STRVAR(Repository_lookup_reference__doc__,
|
||||||
"lookup_reference(name) -> Reference\n"
|
"lookup_reference(name) -> Reference\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -1278,7 +1563,7 @@ Repository_status(Repository *self)
|
|||||||
path = entry->head_to_index->old_file.path;
|
path = entry->head_to_index->old_file.path;
|
||||||
else
|
else
|
||||||
path = entry->index_to_workdir->old_file.path;
|
path = entry->index_to_workdir->old_file.path;
|
||||||
status = PyLong_FromLong((long) entry->status);
|
status = PyInt_FromLong((long) entry->status);
|
||||||
|
|
||||||
err = PyDict_SetItemString(dict, path, status);
|
err = PyDict_SetItemString(dict, path, status);
|
||||||
Py_CLEAR(status);
|
Py_CLEAR(status);
|
||||||
@ -1320,7 +1605,7 @@ Repository_status_file(Repository *self, PyObject *value)
|
|||||||
free(path);
|
free(path);
|
||||||
return err_obj;
|
return err_obj;
|
||||||
}
|
}
|
||||||
return PyLong_FromLong(status);
|
return PyInt_FromLong(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1493,8 +1778,8 @@ PyDoc_STRVAR(Repository_reset__doc__,
|
|||||||
"\n"
|
"\n"
|
||||||
"Resets current head to the provided oid.\n"
|
"Resets current head to the provided oid.\n"
|
||||||
"reset_type:\n"
|
"reset_type:\n"
|
||||||
"GIT_RESET_SOFT: resets head to point to oid, but does not modfy working copy, and leaves the changes in the index.\n"
|
"GIT_RESET_SOFT: resets head to point to oid, but does not modify working copy, and leaves the changes in the index.\n"
|
||||||
"GIT_RESET_MIXED: resets head to point to oid, but does not modfy working copy. It empties the index too.\n"
|
"GIT_RESET_MIXED: resets head to point to oid, but does not modify working copy. It empties the index too.\n"
|
||||||
"GIT_RESET_HARD: resets head to point to oid, and resets too the working copy and the content of the index.\n");
|
"GIT_RESET_HARD: resets head to point to oid, and resets too the working copy and the content of the index.\n");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
@ -1547,6 +1832,7 @@ PyMethodDef Repository_methods[] = {
|
|||||||
METHOD(Repository, create_blob, METH_VARARGS),
|
METHOD(Repository, create_blob, METH_VARARGS),
|
||||||
METHOD(Repository, create_blob_fromworkdir, METH_VARARGS),
|
METHOD(Repository, create_blob_fromworkdir, METH_VARARGS),
|
||||||
METHOD(Repository, create_blob_fromdisk, METH_VARARGS),
|
METHOD(Repository, create_blob_fromdisk, METH_VARARGS),
|
||||||
|
METHOD(Repository, create_blob_fromiobase, METH_O),
|
||||||
METHOD(Repository, create_commit, METH_VARARGS),
|
METHOD(Repository, create_commit, METH_VARARGS),
|
||||||
METHOD(Repository, create_tag, METH_VARARGS),
|
METHOD(Repository, create_tag, METH_VARARGS),
|
||||||
METHOD(Repository, TreeBuilder, METH_VARARGS),
|
METHOD(Repository, TreeBuilder, METH_VARARGS),
|
||||||
@ -1560,7 +1846,10 @@ PyMethodDef Repository_methods[] = {
|
|||||||
METHOD(Repository, create_reference_direct, METH_VARARGS),
|
METHOD(Repository, create_reference_direct, METH_VARARGS),
|
||||||
METHOD(Repository, create_reference_symbolic, METH_VARARGS),
|
METHOD(Repository, create_reference_symbolic, METH_VARARGS),
|
||||||
METHOD(Repository, listall_references, METH_NOARGS),
|
METHOD(Repository, listall_references, METH_NOARGS),
|
||||||
|
METHOD(Repository, listall_reference_objects, METH_NOARGS),
|
||||||
METHOD(Repository, listall_submodules, METH_NOARGS),
|
METHOD(Repository, listall_submodules, METH_NOARGS),
|
||||||
|
METHOD(Repository, init_submodules, METH_VARARGS | METH_KEYWORDS),
|
||||||
|
METHOD(Repository, update_submodules, METH_VARARGS | METH_KEYWORDS),
|
||||||
METHOD(Repository, lookup_reference, METH_O),
|
METHOD(Repository, lookup_reference, METH_O),
|
||||||
METHOD(Repository, revparse_single, METH_O),
|
METHOD(Repository, revparse_single, METH_O),
|
||||||
METHOD(Repository, status, METH_NOARGS),
|
METHOD(Repository, status, METH_NOARGS),
|
||||||
@ -1570,6 +1859,7 @@ PyMethodDef Repository_methods[] = {
|
|||||||
METHOD(Repository, lookup_note, METH_VARARGS),
|
METHOD(Repository, lookup_note, METH_VARARGS),
|
||||||
METHOD(Repository, git_object_lookup_prefix, METH_O),
|
METHOD(Repository, git_object_lookup_prefix, METH_O),
|
||||||
METHOD(Repository, lookup_branch, METH_VARARGS),
|
METHOD(Repository, lookup_branch, METH_VARARGS),
|
||||||
|
METHOD(Repository, path_is_ignored, METH_VARARGS),
|
||||||
METHOD(Repository, listall_branches, METH_VARARGS),
|
METHOD(Repository, listall_branches, METH_VARARGS),
|
||||||
METHOD(Repository, create_branch, METH_VARARGS),
|
METHOD(Repository, create_branch, METH_VARARGS),
|
||||||
METHOD(Repository, reset, METH_VARARGS),
|
METHOD(Repository, reset, METH_VARARGS),
|
||||||
@ -1594,7 +1884,7 @@ PyGetSetDef Repository_getseters[] = {
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository__doc__,
|
PyDoc_STRVAR(Repository__doc__,
|
||||||
"Repository(path) -> Repository\n"
|
"Repository(backend) -> Repository\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Git repository.");
|
"Git repository.");
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -58,6 +58,8 @@ PyObject* Repository_create_commit(Repository *self, PyObject *args);
|
|||||||
PyObject* Repository_create_tag(Repository *self, PyObject *args);
|
PyObject* Repository_create_tag(Repository *self, PyObject *args);
|
||||||
PyObject* Repository_create_branch(Repository *self, PyObject *args);
|
PyObject* Repository_create_branch(Repository *self, PyObject *args);
|
||||||
PyObject* Repository_listall_references(Repository *self, PyObject *args);
|
PyObject* Repository_listall_references(Repository *self, PyObject *args);
|
||||||
|
PyObject* Repository_listall_reference_objects(Repository *self,
|
||||||
|
PyObject *args);
|
||||||
PyObject* Repository_listall_branches(Repository *self, PyObject *args);
|
PyObject* Repository_listall_branches(Repository *self, PyObject *args);
|
||||||
PyObject* Repository_lookup_reference(Repository *self, PyObject *py_name);
|
PyObject* Repository_lookup_reference(Repository *self, PyObject *py_name);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -38,7 +38,7 @@ Signature_init(Signature *self, PyObject *args, PyObject *kwds)
|
|||||||
{
|
{
|
||||||
char *keywords[] = {"name", "email", "time", "offset", "encoding", NULL};
|
char *keywords[] = {"name", "email", "time", "offset", "encoding", NULL};
|
||||||
PyObject *py_name, *tname;
|
PyObject *py_name, *tname;
|
||||||
char *email, *encoding = "ascii";
|
char *email, *encoding = "utf-8";
|
||||||
const char *name;
|
const char *name;
|
||||||
long long time = -1;
|
long long time = -1;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
@ -96,10 +96,10 @@ Signature_dealloc(Signature *self)
|
|||||||
|
|
||||||
PyDoc_STRVAR(Signature__pointer__doc__, "Get the signature's pointer. For internal use only.");
|
PyDoc_STRVAR(Signature__pointer__doc__, "Get the signature's pointer. For internal use only.");
|
||||||
PyObject *
|
PyObject *
|
||||||
Signature__pointer__get__(Repository *self)
|
Signature__pointer__get__(Signature *self)
|
||||||
{
|
{
|
||||||
/* Bytes means a raw buffer */
|
/* Bytes means a raw buffer */
|
||||||
return PyBytes_FromStringAndSize((char *) &self->repo, sizeof(git_repository *));
|
return PyBytes_FromStringAndSize((char *) &self->signature, sizeof(git_signature *));
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(Signature__encoding__doc__, "Encoding.");
|
PyDoc_STRVAR(Signature__encoding__doc__, "Encoding.");
|
||||||
@ -158,7 +158,7 @@ PyDoc_STRVAR(Signature_time__doc__, "Unix time.");
|
|||||||
PyObject *
|
PyObject *
|
||||||
Signature_time__get__(Signature *self)
|
Signature_time__get__(Signature *self)
|
||||||
{
|
{
|
||||||
return PyLong_FromLongLong(self->signature->when.time);
|
return PyInt_FromLongLong(self->signature->when.time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ PyDoc_STRVAR(Signature_offset__doc__, "Offset from UTC in minutes.");
|
|||||||
PyObject *
|
PyObject *
|
||||||
Signature_offset__get__(Signature *self)
|
Signature_offset__get__(Signature *self)
|
||||||
{
|
{
|
||||||
return PyLong_FromLong(self->signature->when.offset);
|
return PyInt_FromLong(self->signature->when.offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyGetSetDef Signature_getseters[] = {
|
PyGetSetDef Signature_getseters[] = {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -111,7 +111,11 @@ PyDoc_STRVAR(Tag__message__doc__, "Tag message (bytes).");
|
|||||||
PyObject *
|
PyObject *
|
||||||
Tag__message__get__(Tag *self)
|
Tag__message__get__(Tag *self)
|
||||||
{
|
{
|
||||||
return PyBytes_FromString(git_tag_message(self->tag));
|
const char *message;
|
||||||
|
message = git_tag_message(self->tag);
|
||||||
|
if (!message)
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
return PyBytes_FromString(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyMethodDef Tag_methods[] = {
|
PyMethodDef Tag_methods[] = {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
28
src/tree.c
28
src/tree.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -54,7 +54,7 @@ PyDoc_STRVAR(TreeEntry_filemode__doc__, "Filemode.");
|
|||||||
PyObject *
|
PyObject *
|
||||||
TreeEntry_filemode__get__(TreeEntry *self)
|
TreeEntry_filemode__get__(TreeEntry *self)
|
||||||
{
|
{
|
||||||
return PyLong_FromLong(git_tree_entry_filemode(self->entry));
|
return PyInt_FromLong(git_tree_entry_filemode(self->entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -67,6 +67,24 @@ TreeEntry_name__get__(TreeEntry *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyDoc_STRVAR(TreeEntry__name__doc__, "Name (bytes).");
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
TreeEntry__name__get__(TreeEntry *self)
|
||||||
|
{
|
||||||
|
return PyBytes_FromString(git_tree_entry_name(self->entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PyDoc_STRVAR(TreeEntry_type__doc__, "Type.");
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
TreeEntry_type__get__(TreeEntry *self)
|
||||||
|
{
|
||||||
|
return to_path(git_object_type2string(git_tree_entry_type(self->entry)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(TreeEntry_id__doc__, "Object id.");
|
PyDoc_STRVAR(TreeEntry_id__doc__, "Object id.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
@ -168,9 +186,11 @@ TreeEntry_repr(TreeEntry *self)
|
|||||||
PyGetSetDef TreeEntry_getseters[] = {
|
PyGetSetDef TreeEntry_getseters[] = {
|
||||||
GETTER(TreeEntry, filemode),
|
GETTER(TreeEntry, filemode),
|
||||||
GETTER(TreeEntry, name),
|
GETTER(TreeEntry, name),
|
||||||
|
GETTER(TreeEntry, _name),
|
||||||
GETTER(TreeEntry, oid),
|
GETTER(TreeEntry, oid),
|
||||||
GETTER(TreeEntry, id),
|
GETTER(TreeEntry, id),
|
||||||
GETTER(TreeEntry, hex),
|
GETTER(TreeEntry, hex),
|
||||||
|
GETTER(TreeEntry, type),
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -270,7 +290,7 @@ Tree_fix_index(Tree *self, PyObject *py_index)
|
|||||||
size_t len;
|
size_t len;
|
||||||
long slen;
|
long slen;
|
||||||
|
|
||||||
index = PyLong_AsLong(py_index);
|
index = PyInt_AsLong(py_index);
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -339,7 +359,7 @@ Tree_getitem(Tree *self, PyObject *value)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* Case 1: integer */
|
/* Case 1: integer */
|
||||||
if (PyLong_Check(value))
|
if (PyInt_Check(value))
|
||||||
return Tree_getitem_by_index(self, value);
|
return Tree_getitem_by_index(self, value);
|
||||||
|
|
||||||
/* Case 2: byte or text string */
|
/* Case 2: byte or text string */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -32,8 +32,8 @@
|
|||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
|
|
||||||
#if !(LIBGIT2_VER_MAJOR == 0 && LIBGIT2_VER_MINOR == 23)
|
#if !(LIBGIT2_VER_MAJOR == 0 && LIBGIT2_VER_MINOR == 26)
|
||||||
#error You need a compatible libgit2 version (v0.23.x)
|
#error You need a compatible libgit2 version (v0.26.x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
56
src/utils.c
56
src/utils.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -83,8 +83,7 @@ py_str_borrow_c_str(PyObject **tvalue, PyObject *value, const char *encoding)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Type error */
|
/* Type error */
|
||||||
PyErr_Format(PyExc_TypeError, "unexpected %.200s",
|
Error_type_error("unexpected %.200s", value);
|
||||||
Py_TYPE(value)->tp_name);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +93,7 @@ py_str_borrow_c_str(PyObject **tvalue, PyObject *value, const char *encoding)
|
|||||||
PyObject *
|
PyObject *
|
||||||
get_pylist_from_git_strarray(git_strarray *strarray)
|
get_pylist_from_git_strarray(git_strarray *strarray)
|
||||||
{
|
{
|
||||||
int index;
|
size_t index;
|
||||||
PyObject *new_list;
|
PyObject *new_list;
|
||||||
|
|
||||||
new_list = PyList_New(strarray->count);
|
new_list = PyList_New(strarray->count);
|
||||||
@ -161,40 +160,39 @@ on_error:
|
|||||||
static git_otype
|
static git_otype
|
||||||
py_type_to_git_type(PyTypeObject *py_type)
|
py_type_to_git_type(PyTypeObject *py_type)
|
||||||
{
|
{
|
||||||
git_otype type = GIT_OBJ_BAD;
|
if (py_type == &CommitType)
|
||||||
|
return GIT_OBJ_COMMIT;
|
||||||
|
else if (py_type == &TreeType)
|
||||||
|
return GIT_OBJ_TREE;
|
||||||
|
else if (py_type == &BlobType)
|
||||||
|
return GIT_OBJ_BLOB;
|
||||||
|
else if (py_type == &TagType)
|
||||||
|
return GIT_OBJ_TAG;
|
||||||
|
|
||||||
if (py_type == &CommitType) {
|
PyErr_SetString(PyExc_ValueError, "invalid target type");
|
||||||
type = GIT_OBJ_COMMIT;
|
return GIT_OBJ_BAD; /* -1 */
|
||||||
} else if (py_type == &TreeType) {
|
|
||||||
type = GIT_OBJ_TREE;
|
|
||||||
} else if (py_type == &BlobType) {
|
|
||||||
type = GIT_OBJ_BLOB;
|
|
||||||
} else if (py_type == &TagType) {
|
|
||||||
type = GIT_OBJ_TAG;
|
|
||||||
}
|
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
git_otype
|
||||||
py_object_to_object_type(PyObject *py_type)
|
py_object_to_otype(PyObject *py_type)
|
||||||
{
|
{
|
||||||
int type = -1;
|
long value;
|
||||||
|
|
||||||
if (py_type == Py_None)
|
if (py_type == Py_None)
|
||||||
return GIT_OBJ_ANY;
|
return GIT_OBJ_ANY;
|
||||||
|
|
||||||
if (PyLong_Check(py_type)) {
|
if (PyInt_Check(py_type)) {
|
||||||
type = PyLong_AsLong(py_type);
|
value = PyInt_AsLong(py_type);
|
||||||
if (type == -1 && PyErr_Occurred())
|
if (value == -1 && PyErr_Occurred())
|
||||||
return -1;
|
return GIT_OBJ_BAD;
|
||||||
} else if (PyType_Check(py_type)) {
|
|
||||||
type = py_type_to_git_type((PyTypeObject *) py_type);
|
/* TODO Check whether the value is a valid value */
|
||||||
|
return (git_otype)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == -1) {
|
if (PyType_Check(py_type))
|
||||||
|
return py_type_to_git_type((PyTypeObject *) py_type);
|
||||||
|
|
||||||
PyErr_SetString(PyExc_ValueError, "invalid target type");
|
PyErr_SetString(PyExc_ValueError, "invalid target type");
|
||||||
}
|
return GIT_OBJ_BAD; /* -1 */
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
}
|
||||||
|
37
src/utils.h
37
src/utils.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -40,14 +40,17 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Python 2 support */
|
/* Python 2 support */
|
||||||
|
#ifndef Py_hash_t
|
||||||
|
#define Py_hash_t long
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PyLong_AsSize_t
|
||||||
|
#define PyLong_AsSize_t (size_t)PyLong_AsSsize_t
|
||||||
|
#endif
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION == 2
|
#if PY_MAJOR_VERSION == 2
|
||||||
#define PyLong_FromSize_t PyInt_FromSize_t
|
#define PyInt_AsSize_t (size_t)PyInt_AsLong
|
||||||
#define PyLong_AsSize_t (size_t)PyInt_AsSsize_t
|
#define PyInt_FromLongLong PyInt_FromLong
|
||||||
#define PyLong_AsLong PyInt_AsLong
|
|
||||||
#undef PyLong_Check
|
|
||||||
#define PyLong_Check PyInt_Check
|
|
||||||
#define PyLong_FromLong PyInt_FromLong
|
|
||||||
#define PyInteger_Type PyInt_Type
|
|
||||||
#define PyBytes_AS_STRING PyString_AS_STRING
|
#define PyBytes_AS_STRING PyString_AS_STRING
|
||||||
#define PyBytes_AsString PyString_AsString
|
#define PyBytes_AsString PyString_AsString
|
||||||
#define PyBytes_AsStringAndSize PyString_AsStringAndSize
|
#define PyBytes_AsStringAndSize PyString_AsStringAndSize
|
||||||
@ -58,20 +61,18 @@
|
|||||||
#define to_path(x) to_bytes(x)
|
#define to_path(x) to_bytes(x)
|
||||||
#define to_encoding(x) to_bytes(x)
|
#define to_encoding(x) to_bytes(x)
|
||||||
#else
|
#else
|
||||||
#define PyInteger_Type PyLong_Type
|
#define PyInt_Check PyLong_Check
|
||||||
|
#define PyInt_FromSize_t PyLong_FromSize_t
|
||||||
|
#define PyInt_FromLong PyLong_FromLong
|
||||||
|
#define PyInt_FromLongLong PyLong_FromLongLong
|
||||||
|
#define PyInt_AsLong PyLong_AsLong
|
||||||
|
#define PyInt_AsSize_t PyLong_AsSize_t
|
||||||
|
|
||||||
#define to_path(x) to_unicode(x, Py_FileSystemDefaultEncoding, "strict")
|
#define to_path(x) to_unicode(x, Py_FileSystemDefaultEncoding, "strict")
|
||||||
#define to_encoding(x) PyUnicode_DecodeASCII(x, strlen(x), "strict")
|
#define to_encoding(x) PyUnicode_DecodeASCII(x, strlen(x), "strict")
|
||||||
#define PyString_FromFormat(s, ...) PyUnicode_FromFormat(s, __VA_ARGS__)
|
#define PyString_FromFormat(s, ...) PyUnicode_FromFormat(s, __VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PYPY_VERSION
|
|
||||||
#define PyLong_AsSize_t (size_t)PyLong_AsUnsignedLong
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef Py_hash_t
|
|
||||||
#define Py_hash_t long
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define CHECK_REFERENCE(self)\
|
#define CHECK_REFERENCE(self)\
|
||||||
if (self->reference == NULL) {\
|
if (self->reference == NULL) {\
|
||||||
@ -120,7 +121,7 @@ const char *py_str_borrow_c_str(PyObject **tvaue, PyObject *value, const char *e
|
|||||||
PyObject * get_pylist_from_git_strarray(git_strarray *strarray);
|
PyObject * get_pylist_from_git_strarray(git_strarray *strarray);
|
||||||
int get_strarraygit_from_pylist(git_strarray *array, PyObject *pylist);
|
int get_strarraygit_from_pylist(git_strarray *array, PyObject *pylist);
|
||||||
|
|
||||||
int py_object_to_object_type(PyObject *py_type);
|
int py_object_to_otype(PyObject *py_type);
|
||||||
|
|
||||||
#define py_path_to_c_str(py_path) \
|
#define py_path_to_c_str(py_path) \
|
||||||
py_str_to_c_str(py_path, Py_FileSystemDefaultEncoding)
|
py_str_to_c_str(py_path, Py_FileSystemDefaultEncoding)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
@ -98,13 +98,13 @@ PyDoc_STRVAR(Walker_sort__doc__,
|
|||||||
PyObject *
|
PyObject *
|
||||||
Walker_sort(Walker *self, PyObject *py_sort_mode)
|
Walker_sort(Walker *self, PyObject *py_sort_mode)
|
||||||
{
|
{
|
||||||
int sort_mode;
|
long sort_mode;
|
||||||
|
|
||||||
sort_mode = (int)PyLong_AsLong(py_sort_mode);
|
sort_mode = PyInt_AsLong(py_sort_mode);
|
||||||
if (sort_mode == -1 && PyErr_Occurred())
|
if (sort_mode == -1 && PyErr_Occurred())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
git_revwalk_sorting(self->walk, sort_mode);
|
git_revwalk_sorting(self->walk, (unsigned int)sort_mode);
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 The pygit2 contributors
|
* Copyright 2010-2017 The pygit2 contributors
|
||||||
*
|
*
|
||||||
* This file is free software; you can redistribute it and/or modify
|
* This file is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License, version 2,
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
BIN
test/data/binaryfilerepo.tar
Normal file
BIN
test/data/binaryfilerepo.tar
Normal file
Binary file not shown.
Binary file not shown.
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -30,6 +30,7 @@
|
|||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from os.path import dirname, join
|
from os.path import dirname, join
|
||||||
|
import io
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import pygit2
|
import pygit2
|
||||||
@ -112,6 +113,19 @@ class BlobTest(utils.RepoTestCase):
|
|||||||
self.assertTrue(isinstance(blob, pygit2.Blob))
|
self.assertTrue(isinstance(blob, pygit2.Blob))
|
||||||
self.assertEqual(pygit2.GIT_OBJ_BLOB, blob.type)
|
self.assertEqual(pygit2.GIT_OBJ_BLOB, blob.type)
|
||||||
|
|
||||||
|
def test_create_blob_fromiobase(self):
|
||||||
|
self.assertRaises(TypeError, self.repo.create_blob_fromiobase, 'bad type')
|
||||||
|
|
||||||
|
f = io.BytesIO(BLOB_CONTENT)
|
||||||
|
blob_oid = self.repo.create_blob_fromiobase(f)
|
||||||
|
blob = self.repo[blob_oid]
|
||||||
|
|
||||||
|
self.assertTrue(isinstance(blob, pygit2.Blob))
|
||||||
|
self.assertEqual(pygit2.GIT_OBJ_BLOB, blob.type)
|
||||||
|
|
||||||
|
self.assertEqual(blob_oid, blob.id)
|
||||||
|
self.assertEqual(BLOB_SHA, blob_oid.hex)
|
||||||
|
|
||||||
def test_diff_blob(self):
|
def test_diff_blob(self):
|
||||||
blob = self.repo[BLOB_SHA]
|
blob = self.repo[BLOB_SHA]
|
||||||
old_blob = self.repo['3b18e512dba79e4c8300dd08aeb37f8e728b8dad']
|
old_blob = self.repo['3b18e512dba79e4c8300dd08aeb37f8e728b8dad']
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -39,6 +39,135 @@ I18N_LAST_COMMIT = '5470a671a80ac3789f1a6a8cefbcf43ce7af0563'
|
|||||||
ORIGIN_MASTER_COMMIT = '784855caf26449a1914d2cf62d12b9374d76ae78'
|
ORIGIN_MASTER_COMMIT = '784855caf26449a1914d2cf62d12b9374d76ae78'
|
||||||
|
|
||||||
|
|
||||||
|
class BranchesObjectTestCase(utils.RepoTestCase):
|
||||||
|
def test_lookup_branch_local(self):
|
||||||
|
branch = self.repo.branches['master']
|
||||||
|
self.assertEqual(branch.target.hex, LAST_COMMIT)
|
||||||
|
|
||||||
|
branch = self.repo.branches.local['i18n']
|
||||||
|
self.assertEqual(branch.target.hex, I18N_LAST_COMMIT)
|
||||||
|
|
||||||
|
self.assertTrue(self.repo.branches.get('not-exists') is None)
|
||||||
|
|
||||||
|
self.assertRaises(KeyError, lambda: self.repo.branches['not-exists'])
|
||||||
|
|
||||||
|
def test_listall_branches(self):
|
||||||
|
branches = sorted(self.repo.branches)
|
||||||
|
self.assertEqual(branches, ['i18n', 'master'])
|
||||||
|
|
||||||
|
def test_create_branch(self):
|
||||||
|
commit = self.repo[LAST_COMMIT]
|
||||||
|
reference = self.repo.branches.create('version1', commit)
|
||||||
|
self.assertTrue('version1' in self.repo.branches)
|
||||||
|
reference = self.repo.branches['version1']
|
||||||
|
self.assertEqual(reference.target.hex, LAST_COMMIT)
|
||||||
|
|
||||||
|
# try to create existing reference
|
||||||
|
self.assertRaises(ValueError,
|
||||||
|
lambda: self.repo.branches.create('version1', commit))
|
||||||
|
|
||||||
|
# try to create existing reference with force
|
||||||
|
reference = self.repo.branches.create('version1', commit, True)
|
||||||
|
self.assertEqual(reference.target.hex, LAST_COMMIT)
|
||||||
|
|
||||||
|
def test_delete(self):
|
||||||
|
self.repo.branches.delete('i18n')
|
||||||
|
|
||||||
|
self.assertTrue(self.repo.branches.get('i18n') is None)
|
||||||
|
|
||||||
|
def test_cant_delete_master(self):
|
||||||
|
self.assertRaises(pygit2.GitError, lambda: self.repo.branches.delete('master'))
|
||||||
|
|
||||||
|
def test_branch_is_head_returns_true_if_branch_is_head(self):
|
||||||
|
branch = self.repo.branches.get('master')
|
||||||
|
self.assertTrue(branch.is_head())
|
||||||
|
|
||||||
|
def test_branch_is_head_returns_false_if_branch_is_not_head(self):
|
||||||
|
branch = self.repo.branches.get('i18n')
|
||||||
|
self.assertFalse(branch.is_head())
|
||||||
|
|
||||||
|
def test_branch_rename_succeeds(self):
|
||||||
|
new_branch = self.repo.branches['i18n'].rename('new-branch')
|
||||||
|
self.assertEqual(new_branch.target.hex, I18N_LAST_COMMIT)
|
||||||
|
|
||||||
|
new_branch_2 = self.repo.branches.get('new-branch')
|
||||||
|
self.assertEqual(new_branch_2.target.hex, I18N_LAST_COMMIT)
|
||||||
|
|
||||||
|
def test_branch_rename_fails_if_destination_already_exists(self):
|
||||||
|
original_branch = self.repo.branches.get('i18n')
|
||||||
|
self.assertRaises(ValueError, lambda: original_branch.rename('master'))
|
||||||
|
|
||||||
|
def test_branch_rename_not_fails_if_force_is_true(self):
|
||||||
|
original_branch = self.repo.branches.get('master')
|
||||||
|
new_branch = original_branch.rename('i18n', True)
|
||||||
|
self.assertEqual(new_branch.target.hex, LAST_COMMIT)
|
||||||
|
|
||||||
|
def test_branch_rename_fails_with_invalid_names(self):
|
||||||
|
original_branch = self.repo.branches.get('i18n')
|
||||||
|
self.assertRaises(ValueError,
|
||||||
|
lambda: original_branch.rename('abc@{123'))
|
||||||
|
|
||||||
|
def test_branch_name(self):
|
||||||
|
branch = self.repo.branches.get('master')
|
||||||
|
self.assertEqual(branch.branch_name, 'master')
|
||||||
|
self.assertEqual(branch.name, 'refs/heads/master')
|
||||||
|
|
||||||
|
branch = self.repo.branches.get('i18n')
|
||||||
|
self.assertEqual(branch.branch_name, 'i18n')
|
||||||
|
self.assertEqual(branch.name, 'refs/heads/i18n')
|
||||||
|
|
||||||
|
|
||||||
|
class BranchesObjectEmptyRepoTestCase(utils.EmptyRepoTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(utils.EmptyRepoTestCase, self).setUp()
|
||||||
|
|
||||||
|
remote = self.repo.remotes[0]
|
||||||
|
remote.fetch()
|
||||||
|
|
||||||
|
def test_lookup_branch_remote(self):
|
||||||
|
branch = self.repo.branches.remote.get('origin/master')
|
||||||
|
self.assertEqual(branch.target.hex, ORIGIN_MASTER_COMMIT)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
self.repo.branches.remote.get('origin/not-exists') is None)
|
||||||
|
|
||||||
|
def test_listall_branches(self):
|
||||||
|
branches = sorted(self.repo.branches.remote)
|
||||||
|
self.assertEqual(branches, ['origin/master'])
|
||||||
|
|
||||||
|
def test_branch_remote_name(self):
|
||||||
|
self.repo.remotes[0].fetch()
|
||||||
|
branch = self.repo.branches.remote['origin/master']
|
||||||
|
self.assertEqual(branch.remote_name, 'origin')
|
||||||
|
|
||||||
|
def test_branch_upstream(self):
|
||||||
|
self.repo.remotes[0].fetch()
|
||||||
|
remote_master = self.repo.branches.remote['origin/master']
|
||||||
|
master = self.repo.branches.create('master',
|
||||||
|
self.repo[remote_master.target.hex])
|
||||||
|
|
||||||
|
self.assertTrue(master.upstream is None)
|
||||||
|
master.upstream = remote_master
|
||||||
|
self.assertEqual(master.upstream.branch_name, 'origin/master')
|
||||||
|
|
||||||
|
def set_bad_upstream():
|
||||||
|
master.upstream = 2.5
|
||||||
|
|
||||||
|
self.assertRaises(TypeError, set_bad_upstream)
|
||||||
|
|
||||||
|
master.upstream = None
|
||||||
|
self.assertTrue(master.upstream is None)
|
||||||
|
|
||||||
|
def test_branch_upstream_name(self):
|
||||||
|
self.repo.remotes[0].fetch()
|
||||||
|
remote_master = self.repo.branches.remote['origin/master']
|
||||||
|
master = self.repo.branches.create('master',
|
||||||
|
self.repo[remote_master.target.hex])
|
||||||
|
|
||||||
|
master.upstream = remote_master
|
||||||
|
self.assertEqual(master.upstream_name, 'refs/remotes/origin/master')
|
||||||
|
|
||||||
|
|
||||||
class BranchesTestCase(utils.RepoTestCase):
|
class BranchesTestCase(utils.RepoTestCase):
|
||||||
def test_lookup_branch_local(self):
|
def test_lookup_branch_local(self):
|
||||||
branch = self.repo.lookup_branch('master')
|
branch = self.repo.lookup_branch('master')
|
||||||
@ -88,6 +217,14 @@ class BranchesTestCase(utils.RepoTestCase):
|
|||||||
branch = self.repo.lookup_branch('i18n')
|
branch = self.repo.lookup_branch('i18n')
|
||||||
self.assertFalse(branch.is_head())
|
self.assertFalse(branch.is_head())
|
||||||
|
|
||||||
|
def test_branch_is_checked_out_returns_true_if_branch_is_checked_out(self):
|
||||||
|
branch = self.repo.lookup_branch('master')
|
||||||
|
self.assertTrue(branch.is_checked_out())
|
||||||
|
|
||||||
|
def test_branch_is_checked_out_returns_false_if_branch_is_not_checked_out(self):
|
||||||
|
branch = self.repo.lookup_branch('i18n')
|
||||||
|
self.assertFalse(branch.is_checked_out())
|
||||||
|
|
||||||
def test_branch_rename_succeeds(self):
|
def test_branch_rename_succeeds(self):
|
||||||
original_branch = self.repo.lookup_branch('i18n')
|
original_branch = self.repo.lookup_branch('i18n')
|
||||||
new_branch = original_branch.rename('new-branch')
|
new_branch = original_branch.rename('new-branch')
|
||||||
@ -159,6 +296,7 @@ class BranchesEmptyRepoTestCase(utils.EmptyRepoTestCase):
|
|||||||
|
|
||||||
def set_bad_upstream():
|
def set_bad_upstream():
|
||||||
master.upstream = 2.5
|
master.upstream = 2.5
|
||||||
|
|
||||||
self.assertRaises(TypeError, set_bad_upstream)
|
self.assertRaises(TypeError, set_bad_upstream)
|
||||||
|
|
||||||
master.upstream = None
|
master.upstream = None
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -97,7 +97,7 @@ class ConfigTest(utils.RepoTestCase):
|
|||||||
|
|
||||||
self.assertRaises(TypeError, lambda: config[()])
|
self.assertRaises(TypeError, lambda: config[()])
|
||||||
self.assertRaises(TypeError, lambda: config[-4])
|
self.assertRaises(TypeError, lambda: config[-4])
|
||||||
self.assertRaisesWithArg(ValueError, "Invalid config item name 'abc'",
|
self.assertRaisesWithArg(ValueError, "invalid config item name 'abc'",
|
||||||
lambda: config['abc'])
|
lambda: config['abc'])
|
||||||
self.assertRaisesWithArg(KeyError, 'abc.def',
|
self.assertRaisesWithArg(KeyError, 'abc.def',
|
||||||
lambda: config['abc.def'])
|
lambda: config['abc.def'])
|
||||||
@ -153,7 +153,7 @@ class ConfigTest(utils.RepoTestCase):
|
|||||||
new_file.write("[this]\n\tthat = foobar\n\tthat = foobeer\n")
|
new_file.write("[this]\n\tthat = foobar\n\tthat = foobeer\n")
|
||||||
new_file.close()
|
new_file.close()
|
||||||
|
|
||||||
config.add_file(CONFIG_FILENAME, 5)
|
config.add_file(CONFIG_FILENAME, 6)
|
||||||
self.assertTrue('this.that' in config)
|
self.assertTrue('this.that' in config)
|
||||||
l = config.get_multivar('this.that', 'foo.*')
|
l = config.get_multivar('this.that', 'foo.*')
|
||||||
self.assertEqual(2, len(list(l)))
|
self.assertEqual(2, len(list(l)))
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -70,32 +70,37 @@ class CredentialCreateTest(utils.NoRepoTestCase):
|
|||||||
|
|
||||||
class CredentialCallback(utils.RepoTestCase):
|
class CredentialCallback(utils.RepoTestCase):
|
||||||
def test_callback(self):
|
def test_callback(self):
|
||||||
def credentials_cb(url, username, allowed):
|
class MyCallbacks(pygit2.RemoteCallbacks):
|
||||||
|
@staticmethod
|
||||||
|
def credentials(url, username, allowed):
|
||||||
self.assertTrue(allowed & GIT_CREDTYPE_USERPASS_PLAINTEXT)
|
self.assertTrue(allowed & GIT_CREDTYPE_USERPASS_PLAINTEXT)
|
||||||
raise Exception("I don't know the password")
|
raise Exception("I don't know the password")
|
||||||
|
|
||||||
remote = self.repo.create_remote("github", "https://github.com/github/github")
|
url = "https://github.com/github/github"
|
||||||
remote.credentials = credentials_cb
|
remote = self.repo.create_remote("github", url)
|
||||||
|
|
||||||
self.assertRaises(Exception, remote.fetch)
|
self.assertRaises(Exception, lambda: remote.fetch(callbacks=MyCallbacks()))
|
||||||
|
|
||||||
def test_bad_cred_type(self):
|
def test_bad_cred_type(self):
|
||||||
def credentials_cb(url, username, allowed):
|
class MyCallbacks(pygit2.RemoteCallbacks):
|
||||||
|
@staticmethod
|
||||||
|
def credentials(url, username, allowed):
|
||||||
self.assertTrue(allowed & GIT_CREDTYPE_USERPASS_PLAINTEXT)
|
self.assertTrue(allowed & GIT_CREDTYPE_USERPASS_PLAINTEXT)
|
||||||
return Keypair("git", "foo.pub", "foo", "sekkrit")
|
return Keypair("git", "foo.pub", "foo", "sekkrit")
|
||||||
|
|
||||||
remote = self.repo.create_remote("github", "https://github.com/github/github")
|
url = "https://github.com/github/github"
|
||||||
remote.credentials = credentials_cb
|
remote = self.repo.create_remote("github", url)
|
||||||
|
self.assertRaises(TypeError, lambda: remote.fetch(callbacks=MyCallbacks()))
|
||||||
self.assertRaises(TypeError, remote.fetch)
|
|
||||||
|
|
||||||
class CallableCredentialTest(utils.RepoTestCase):
|
class CallableCredentialTest(utils.RepoTestCase):
|
||||||
|
|
||||||
def test_user_pass(self):
|
def test_user_pass(self):
|
||||||
remote = self.repo.create_remote("bb", "https://bitbucket.org/libgit2/testgitrepository.git")
|
credentials = UserPass("libgit2", "libgit2")
|
||||||
remote.credentials = UserPass("libgit2", "libgit2")
|
callbacks = pygit2.RemoteCallbacks(credentials=credentials)
|
||||||
|
|
||||||
remote.fetch()
|
url = "https://bitbucket.org/libgit2/testgitrepository.git"
|
||||||
|
remote = self.repo.create_remote("bb", url)
|
||||||
|
remote.fetch(callbacks=callbacks)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
106
test/test_describe.py
Normal file
106
test/test_describe.py
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
|
#
|
||||||
|
# This file is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
# as published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# In addition to the permissions in the GNU General Public License,
|
||||||
|
# the authors give you unlimited permission to link the compiled
|
||||||
|
# version of this file into combinations with other programs,
|
||||||
|
# and to distribute those combinations without any restriction
|
||||||
|
# coming from the use of this file. (The General Public License
|
||||||
|
# restrictions do apply in other respects; for example, they cover
|
||||||
|
# modification of the file, and distribution when not linked into
|
||||||
|
# a combined executable.)
|
||||||
|
#
|
||||||
|
# This file is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
"""Tests for describing commits."""
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from pygit2 import GIT_DESCRIBE_DEFAULT, GIT_DESCRIBE_TAGS, GIT_DESCRIBE_ALL
|
||||||
|
import pygit2
|
||||||
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
|
def add_tag(repo, name, target):
|
||||||
|
message = 'Example tag.\n'
|
||||||
|
tagger = pygit2.Signature('John Doe', 'jdoe@example.com', 12347, 0)
|
||||||
|
|
||||||
|
sha = repo.create_tag(name, target, pygit2.GIT_OBJ_COMMIT, tagger, message)
|
||||||
|
return sha
|
||||||
|
|
||||||
|
|
||||||
|
class DescribeTest(utils.RepoTestCase):
|
||||||
|
|
||||||
|
def test_describe(self):
|
||||||
|
add_tag(self.repo, 'thetag', '4ec4389a8068641da2d6578db0419484972284c8')
|
||||||
|
self.assertEqual('thetag-2-g2be5719', self.repo.describe())
|
||||||
|
|
||||||
|
def test_describe_without_ref(self):
|
||||||
|
self.assertRaises(pygit2.GitError, self.repo.describe)
|
||||||
|
|
||||||
|
def test_describe_default_oid(self):
|
||||||
|
self.assertEqual('2be5719', self.repo.describe(show_commit_oid_as_fallback=True))
|
||||||
|
|
||||||
|
def test_describe_strategies(self):
|
||||||
|
self.assertEqual('heads/master', self.repo.describe(describe_strategy=GIT_DESCRIBE_ALL))
|
||||||
|
|
||||||
|
self.repo.create_reference('refs/tags/thetag', '4ec4389a8068641da2d6578db0419484972284c8')
|
||||||
|
self.assertRaises(KeyError, self.repo.describe)
|
||||||
|
self.assertEqual('thetag-2-g2be5719', self.repo.describe(describe_strategy=GIT_DESCRIBE_TAGS))
|
||||||
|
|
||||||
|
def test_describe_pattern(self):
|
||||||
|
add_tag(self.repo, 'private/tag1', '5ebeeebb320790caf276b9fc8b24546d63316533')
|
||||||
|
add_tag(self.repo, 'public/tag2', '4ec4389a8068641da2d6578db0419484972284c8')
|
||||||
|
|
||||||
|
self.assertEqual('public/tag2-2-g2be5719', self.repo.describe(pattern='public/*'))
|
||||||
|
|
||||||
|
def test_describe_committish(self):
|
||||||
|
add_tag(self.repo, 'thetag', 'acecd5ea2924a4b900e7e149496e1f4b57976e51')
|
||||||
|
self.assertEqual('thetag-4-g2be5719', self.repo.describe(committish='HEAD'))
|
||||||
|
self.assertEqual('thetag-1-g5ebeeeb', self.repo.describe(committish='HEAD^'))
|
||||||
|
|
||||||
|
self.assertEqual('thetag-4-g2be5719', self.repo.describe(committish=self.repo.head))
|
||||||
|
|
||||||
|
self.assertEqual('thetag-1-g6aaa262', self.repo.describe(committish='6aaa262e655dd54252e5813c8e5acd7780ed097d'))
|
||||||
|
self.assertEqual('thetag-1-g6aaa262', self.repo.describe(committish='6aaa262'))
|
||||||
|
|
||||||
|
def test_describe_follows_first_branch_only(self):
|
||||||
|
add_tag(self.repo, 'thetag', '4ec4389a8068641da2d6578db0419484972284c8')
|
||||||
|
self.assertRaises(KeyError, self.repo.describe, only_follow_first_parent=True)
|
||||||
|
|
||||||
|
def test_describe_abbreviated_size(self):
|
||||||
|
add_tag(self.repo, 'thetag', '4ec4389a8068641da2d6578db0419484972284c8')
|
||||||
|
self.assertEqual('thetag-2-g2be5719152d4f82c', self.repo.describe(abbreviated_size=16))
|
||||||
|
self.assertEqual('thetag', self.repo.describe(abbreviated_size=0))
|
||||||
|
|
||||||
|
def test_describe_long_format(self):
|
||||||
|
add_tag(self.repo, 'thetag', '2be5719152d4f82c7302b1c0932d8e5f0a4a0e98')
|
||||||
|
self.assertEqual('thetag-0-g2be5719', self.repo.describe(always_use_long_format=True))
|
||||||
|
|
||||||
|
|
||||||
|
class DescribeDirtyWorkdirTest(utils.DirtyRepoTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(utils.DirtyRepoTestCase, self).setUp()
|
||||||
|
add_tag(self.repo, 'thetag', 'a763aa560953e7cfb87ccbc2f536d665aa4dff22')
|
||||||
|
|
||||||
|
def test_describe(self):
|
||||||
|
self.assertEqual('thetag', self.repo.describe())
|
||||||
|
|
||||||
|
def test_describe_with_dirty_suffix(self):
|
||||||
|
self.assertEqual('thetag-dirty', self.repo.describe(dirty_suffix='-dirty'))
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -33,6 +33,7 @@ import unittest
|
|||||||
import pygit2
|
import pygit2
|
||||||
from pygit2 import GIT_DIFF_INCLUDE_UNMODIFIED
|
from pygit2 import GIT_DIFF_INCLUDE_UNMODIFIED
|
||||||
from pygit2 import GIT_DIFF_IGNORE_WHITESPACE, GIT_DIFF_IGNORE_WHITESPACE_EOL
|
from pygit2 import GIT_DIFF_IGNORE_WHITESPACE, GIT_DIFF_IGNORE_WHITESPACE_EOL
|
||||||
|
from pygit2 import GIT_DIFF_SHOW_BINARY
|
||||||
from pygit2 import GIT_DELTA_RENAMED
|
from pygit2 import GIT_DELTA_RENAMED
|
||||||
from . import utils
|
from . import utils
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
@ -63,6 +64,22 @@ index 297efb8..0000000
|
|||||||
-c/d contents
|
-c/d contents
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
PATCH_BINARY = """diff --git a/binary_file b/binary_file
|
||||||
|
index 86e5c10..b835d73 100644
|
||||||
|
Binary files a/binary_file and b/binary_file differ
|
||||||
|
"""
|
||||||
|
|
||||||
|
PATCH_BINARY_SHOW = """diff --git a/binary_file b/binary_file
|
||||||
|
index 86e5c1008b5ce635d3e3fffa4434c5eccd8f00b6..b835d73543244b6694f36a8c5dfdffb71b153db7 100644
|
||||||
|
GIT binary patch
|
||||||
|
literal 8
|
||||||
|
Pc${NM%FIhFs^kIy3n&7R
|
||||||
|
|
||||||
|
literal 8
|
||||||
|
Pc${NM&PdElPvrst3ey5{
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
DIFF_HEAD_TO_INDEX_EXPECTED = [
|
DIFF_HEAD_TO_INDEX_EXPECTED = [
|
||||||
'staged_changes',
|
'staged_changes',
|
||||||
'staged_changes_file_deleted',
|
'staged_changes_file_deleted',
|
||||||
@ -308,5 +325,15 @@ class DiffTest(utils.BareRepoTestCase):
|
|||||||
width=80)
|
width=80)
|
||||||
self.assertEqual(STATS_EXPECTED, formatted)
|
self.assertEqual(STATS_EXPECTED, formatted)
|
||||||
|
|
||||||
|
|
||||||
|
class BinaryDiffTest(utils.BinaryFileRepoTestCase):
|
||||||
|
def test_binary_diff(self):
|
||||||
|
repo = self.repo
|
||||||
|
diff = repo.diff('HEAD', 'HEAD^')
|
||||||
|
self.assertEqual(PATCH_BINARY, diff.patch)
|
||||||
|
diff = repo.diff('HEAD', 'HEAD^', flags=GIT_DIFF_SHOW_BINARY)
|
||||||
|
self.assertEqual(PATCH_BINARY_SHOW, diff.patch)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -31,24 +31,81 @@ from __future__ import absolute_import
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import unittest
|
import unittest
|
||||||
import pygit2
|
import pygit2
|
||||||
from pygit2 import GIT_OPT_GET_MWINDOW_SIZE, GIT_OPT_SET_MWINDOW_SIZE
|
from pygit2 import (
|
||||||
from pygit2 import GIT_OPT_GET_SEARCH_PATH, GIT_OPT_SET_SEARCH_PATH
|
GIT_OBJ_BLOB,
|
||||||
from pygit2 import GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_XDG, GIT_CONFIG_LEVEL_GLOBAL
|
GIT_OPT_GET_MWINDOW_SIZE, GIT_OPT_SET_MWINDOW_SIZE,
|
||||||
|
GIT_OPT_GET_SEARCH_PATH, GIT_OPT_SET_SEARCH_PATH,
|
||||||
|
GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, GIT_OPT_SET_MWINDOW_MAPPED_LIMIT,
|
||||||
|
GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_XDG, GIT_CONFIG_LEVEL_GLOBAL,
|
||||||
|
GIT_OPT_SET_CACHE_OBJECT_LIMIT,
|
||||||
|
GIT_OPT_GET_CACHED_MEMORY,
|
||||||
|
GIT_OPT_ENABLE_CACHING,
|
||||||
|
)
|
||||||
from pygit2 import option
|
from pygit2 import option
|
||||||
from . import utils
|
from . import utils
|
||||||
|
|
||||||
class OptionsTest(utils.NoRepoTestCase):
|
class OptionsTest(utils.NoRepoTestCase):
|
||||||
|
|
||||||
|
def __option(self, getter, setter, value):
|
||||||
|
old_value = option(getter)
|
||||||
|
option(setter, value)
|
||||||
|
self.assertEqual(value, option(getter))
|
||||||
|
# Reset to avoid side effects in later tests
|
||||||
|
option(setter, old_value)
|
||||||
|
|
||||||
|
def __proxy(self, name, value):
|
||||||
|
old_value = getattr(pygit2.settings, name)
|
||||||
|
setattr(pygit2.settings, name, value)
|
||||||
|
self.assertEqual(value, getattr(pygit2.settings, name))
|
||||||
|
# Reset to avoid side effects in later tests
|
||||||
|
setattr(pygit2.settings, name, old_value)
|
||||||
|
|
||||||
def test_mwindow_size(self):
|
def test_mwindow_size(self):
|
||||||
new_size = 200 * 1024
|
self.__option(
|
||||||
option(GIT_OPT_SET_MWINDOW_SIZE, new_size)
|
GIT_OPT_GET_MWINDOW_SIZE,
|
||||||
self.assertEqual(new_size, option(GIT_OPT_GET_MWINDOW_SIZE))
|
GIT_OPT_SET_MWINDOW_SIZE,
|
||||||
|
200 * 1024)
|
||||||
|
|
||||||
def test_mwindow_size_proxy(self):
|
def test_mwindow_size_proxy(self):
|
||||||
new_size = 300 * 1024
|
self.__proxy('mwindow_size', 300 * 1024)
|
||||||
pygit2.settings.mwindow_size = new_size
|
|
||||||
|
|
||||||
self.assertEqual(new_size, pygit2.settings.mwindow_size)
|
def test_mwindow_mapped_limit_200(self):
|
||||||
|
self.__option(
|
||||||
|
GIT_OPT_GET_MWINDOW_MAPPED_LIMIT,
|
||||||
|
GIT_OPT_SET_MWINDOW_MAPPED_LIMIT,
|
||||||
|
200 * 1024)
|
||||||
|
|
||||||
|
def test_mwindow_mapped_limit_300(self):
|
||||||
|
self.__proxy('mwindow_mapped_limit', 300 * 1024)
|
||||||
|
|
||||||
|
def test_cache_object_limit(self):
|
||||||
|
new_limit = 2 * 1024
|
||||||
|
option(GIT_OPT_SET_CACHE_OBJECT_LIMIT, GIT_OBJ_BLOB, new_limit)
|
||||||
|
|
||||||
|
def test_cache_object_limit_proxy(self):
|
||||||
|
new_limit = 4 * 1024
|
||||||
|
pygit2.settings.cache_object_limit(GIT_OBJ_BLOB, new_limit)
|
||||||
|
|
||||||
|
def test_cached_memory(self):
|
||||||
|
value = option(GIT_OPT_GET_CACHED_MEMORY)
|
||||||
|
self.assertEqual(value[1], 256 * 1024**2)
|
||||||
|
|
||||||
|
def test_cached_memory_proxy(self):
|
||||||
|
self.assertEqual(pygit2.settings.cached_memory[1], 256 * 1024**2)
|
||||||
|
|
||||||
|
def test_enable_cache(self):
|
||||||
|
option(GIT_OPT_ENABLE_CACHING, False)
|
||||||
|
option(GIT_OPT_ENABLE_CACHING, True)
|
||||||
|
|
||||||
|
def test_enable_cache_proxy(self):
|
||||||
|
pygit2.settings.enable_caching(False)
|
||||||
|
pygit2.settings.enable_caching(True)
|
||||||
|
|
||||||
|
def test_cache_max_size_proxy(self):
|
||||||
|
pygit2.settings.cache_max_size(128 * 1024**2)
|
||||||
|
self.assertEqual(pygit2.settings.cached_memory[1], 128 * 1024**2)
|
||||||
|
pygit2.settings.cache_max_size(256 * 1024**2)
|
||||||
|
self.assertEqual(pygit2.settings.cached_memory[1], 256 * 1024**2)
|
||||||
|
|
||||||
def test_search_path(self):
|
def test_search_path(self):
|
||||||
paths = [(GIT_CONFIG_LEVEL_GLOBAL, '/tmp/global'),
|
paths = [(GIT_CONFIG_LEVEL_GLOBAL, '/tmp/global'),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -35,12 +35,213 @@ from pygit2 import GitError, GIT_REF_OID, GIT_REF_SYMBOLIC, Signature
|
|||||||
from pygit2 import Commit, Tree
|
from pygit2 import Commit, Tree
|
||||||
from . import utils
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
LAST_COMMIT = '2be5719152d4f82c7302b1c0932d8e5f0a4a0e98'
|
LAST_COMMIT = '2be5719152d4f82c7302b1c0932d8e5f0a4a0e98'
|
||||||
|
|
||||||
|
|
||||||
|
class ReferencesObjectTest(utils.RepoTestCase):
|
||||||
|
def test_list_all_reference_objects(self):
|
||||||
|
repo = self.repo
|
||||||
|
|
||||||
|
refs = [(ref.name, ref.target.hex)
|
||||||
|
for ref in repo.references.objects]
|
||||||
|
self.assertEqual(sorted(refs),
|
||||||
|
[('refs/heads/i18n',
|
||||||
|
'5470a671a80ac3789f1a6a8cefbcf43ce7af0563'),
|
||||||
|
('refs/heads/master',
|
||||||
|
'2be5719152d4f82c7302b1c0932d8e5f0a4a0e98')])
|
||||||
|
|
||||||
|
def test_list_all_references(self):
|
||||||
|
repo = self.repo
|
||||||
|
|
||||||
|
# Without argument
|
||||||
|
self.assertEqual(sorted(repo.references),
|
||||||
|
['refs/heads/i18n', 'refs/heads/master'])
|
||||||
|
|
||||||
|
# We add a symbolic reference
|
||||||
|
repo.create_reference('refs/tags/version1', 'refs/heads/master')
|
||||||
|
self.assertEqual(sorted(repo.references),
|
||||||
|
['refs/heads/i18n', 'refs/heads/master',
|
||||||
|
'refs/tags/version1'])
|
||||||
|
|
||||||
|
def test_head(self):
|
||||||
|
head = self.repo.head
|
||||||
|
self.assertEqual(LAST_COMMIT, self.repo[head.target].hex)
|
||||||
|
|
||||||
|
def test_lookup_reference(self):
|
||||||
|
repo = self.repo
|
||||||
|
|
||||||
|
refname = 'refs/foo'
|
||||||
|
# Raise KeyError ?
|
||||||
|
self.assertRaises(KeyError, lambda: self.repo.references[refname])
|
||||||
|
|
||||||
|
# Return None ?
|
||||||
|
self.assertIsNone(self.repo.references.get(refname))
|
||||||
|
|
||||||
|
# Test a lookup
|
||||||
|
reference = repo.references.get('refs/heads/master')
|
||||||
|
self.assertEqual(reference.name, 'refs/heads/master')
|
||||||
|
|
||||||
|
def test_reference_get_sha(self):
|
||||||
|
reference = self.repo.references['refs/heads/master']
|
||||||
|
self.assertEqual(reference.target.hex, LAST_COMMIT)
|
||||||
|
|
||||||
|
def test_reference_set_sha(self):
|
||||||
|
NEW_COMMIT = '5ebeeebb320790caf276b9fc8b24546d63316533'
|
||||||
|
reference = self.repo.references.get('refs/heads/master')
|
||||||
|
reference.set_target(NEW_COMMIT)
|
||||||
|
self.assertEqual(reference.target.hex, NEW_COMMIT)
|
||||||
|
|
||||||
|
def test_reference_set_sha_prefix(self):
|
||||||
|
NEW_COMMIT = '5ebeeebb320790caf276b9fc8b24546d63316533'
|
||||||
|
reference = self.repo.references.get('refs/heads/master')
|
||||||
|
reference.set_target(NEW_COMMIT[0:6])
|
||||||
|
self.assertEqual(reference.target.hex, NEW_COMMIT)
|
||||||
|
|
||||||
|
def test_reference_get_type(self):
|
||||||
|
reference = self.repo.references.get('refs/heads/master')
|
||||||
|
self.assertEqual(reference.type, GIT_REF_OID)
|
||||||
|
|
||||||
|
def test_get_target(self):
|
||||||
|
reference = self.repo.references.get('HEAD')
|
||||||
|
self.assertEqual(reference.target, 'refs/heads/master')
|
||||||
|
|
||||||
|
def test_set_target(self):
|
||||||
|
reference = self.repo.references.get('HEAD')
|
||||||
|
self.assertEqual(reference.target, 'refs/heads/master')
|
||||||
|
reference.set_target('refs/heads/i18n')
|
||||||
|
self.assertEqual(reference.target, 'refs/heads/i18n')
|
||||||
|
|
||||||
|
def test_get_shorthand(self):
|
||||||
|
reference = self.repo.references.get('refs/heads/master')
|
||||||
|
self.assertEqual(reference.shorthand, 'master')
|
||||||
|
reference = self.repo.references.create('refs/remotes/origin/master', LAST_COMMIT)
|
||||||
|
self.assertEqual(reference.shorthand, 'origin/master')
|
||||||
|
|
||||||
|
def test_set_target_with_message(self):
|
||||||
|
reference = self.repo.references.get('HEAD')
|
||||||
|
self.assertEqual(reference.target, 'refs/heads/master')
|
||||||
|
sig = Signature('foo', 'bar')
|
||||||
|
self.repo.set_ident('foo', 'bar')
|
||||||
|
msg = 'Hello log'
|
||||||
|
reference.set_target('refs/heads/i18n', message=msg)
|
||||||
|
self.assertEqual(reference.target, 'refs/heads/i18n')
|
||||||
|
self.assertEqual(list(reference.log())[0].message, msg)
|
||||||
|
self.assertEqualSignature(list(reference.log())[0].committer, sig)
|
||||||
|
|
||||||
|
def test_delete(self):
|
||||||
|
repo = self.repo
|
||||||
|
|
||||||
|
# We add a tag as a new reference that points to "origin/master"
|
||||||
|
reference = repo.references.create('refs/tags/version1', LAST_COMMIT)
|
||||||
|
self.assertTrue('refs/tags/version1' in repo.references)
|
||||||
|
|
||||||
|
# And we delete it
|
||||||
|
reference.delete()
|
||||||
|
self.assertFalse('refs/tags/version1' in repo.references)
|
||||||
|
|
||||||
|
# Access the deleted reference
|
||||||
|
self.assertRaises(GitError, getattr, reference, 'name')
|
||||||
|
self.assertRaises(GitError, getattr, reference, 'type')
|
||||||
|
self.assertRaises(GitError, getattr, reference, 'target')
|
||||||
|
self.assertRaises(GitError, reference.delete)
|
||||||
|
self.assertRaises(GitError, reference.resolve)
|
||||||
|
self.assertRaises(GitError, reference.rename, "refs/tags/version2")
|
||||||
|
|
||||||
|
def test_rename(self):
|
||||||
|
# We add a tag as a new reference that points to "origin/master"
|
||||||
|
reference = self.repo.references.create('refs/tags/version1',
|
||||||
|
LAST_COMMIT)
|
||||||
|
self.assertEqual(reference.name, 'refs/tags/version1')
|
||||||
|
reference.rename('refs/tags/version2')
|
||||||
|
self.assertEqual(reference.name, 'refs/tags/version2')
|
||||||
|
|
||||||
|
# def test_reload(self):
|
||||||
|
# name = 'refs/tags/version1'
|
||||||
|
|
||||||
|
# repo = self.repo
|
||||||
|
# ref = repo.create_reference(name, "refs/heads/master", symbolic=True)
|
||||||
|
# ref2 = repo.lookup_reference(name)
|
||||||
|
# ref.delete()
|
||||||
|
# self.assertEqual(ref2.name, name)
|
||||||
|
# self.assertRaises(KeyError, ref2.reload)
|
||||||
|
# self.assertRaises(GitError, getattr, ref2, 'name')
|
||||||
|
|
||||||
|
|
||||||
|
def test_reference_resolve(self):
|
||||||
|
reference = self.repo.references.get('HEAD')
|
||||||
|
self.assertEqual(reference.type, GIT_REF_SYMBOLIC)
|
||||||
|
reference = reference.resolve()
|
||||||
|
self.assertEqual(reference.type, GIT_REF_OID)
|
||||||
|
self.assertEqual(reference.target.hex, LAST_COMMIT)
|
||||||
|
|
||||||
|
def test_reference_resolve_identity(self):
|
||||||
|
head = self.repo.references.get('HEAD')
|
||||||
|
ref = head.resolve()
|
||||||
|
self.assertTrue(ref.resolve() is ref)
|
||||||
|
|
||||||
|
def test_create_reference(self):
|
||||||
|
# We add a tag as a new reference that points to "origin/master"
|
||||||
|
reference = self.repo.references.create('refs/tags/version1',
|
||||||
|
LAST_COMMIT)
|
||||||
|
refs = self.repo.references
|
||||||
|
self.assertTrue('refs/tags/version1' in refs)
|
||||||
|
reference = self.repo.references.get('refs/tags/version1')
|
||||||
|
self.assertEqual(reference.target.hex, LAST_COMMIT)
|
||||||
|
|
||||||
|
# try to create existing reference
|
||||||
|
self.assertRaises(ValueError, self.repo.references.create,
|
||||||
|
'refs/tags/version1', LAST_COMMIT)
|
||||||
|
|
||||||
|
# try to create existing reference with force
|
||||||
|
reference = self.repo.references.create('refs/tags/version1',
|
||||||
|
LAST_COMMIT, force=True)
|
||||||
|
self.assertEqual(reference.target.hex, LAST_COMMIT)
|
||||||
|
|
||||||
|
def test_create_symbolic_reference(self):
|
||||||
|
repo = self.repo
|
||||||
|
# We add a tag as a new symbolic reference that always points to
|
||||||
|
# "refs/heads/master"
|
||||||
|
reference = repo.references.create('refs/tags/beta',
|
||||||
|
'refs/heads/master')
|
||||||
|
self.assertEqual(reference.type, GIT_REF_SYMBOLIC)
|
||||||
|
self.assertEqual(reference.target, 'refs/heads/master')
|
||||||
|
|
||||||
|
# try to create existing symbolic reference
|
||||||
|
self.assertRaises(ValueError, repo.references.create,
|
||||||
|
'refs/tags/beta', 'refs/heads/master')
|
||||||
|
|
||||||
|
# try to create existing symbolic reference with force
|
||||||
|
reference = repo.references.create('refs/tags/beta',
|
||||||
|
'refs/heads/master', force=True)
|
||||||
|
self.assertEqual(reference.type, GIT_REF_SYMBOLIC)
|
||||||
|
self.assertEqual(reference.target, 'refs/heads/master')
|
||||||
|
|
||||||
|
# def test_packall_references(self):
|
||||||
|
# self.repo.packall_references()
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_object(self):
|
||||||
|
repo = self.repo
|
||||||
|
ref = repo.references.get('refs/heads/master')
|
||||||
|
self.assertEqual(repo[ref.target].id, ref.get_object().id)
|
||||||
|
|
||||||
|
def test_peel(self):
|
||||||
|
ref = self.repo.references.get('refs/heads/master')
|
||||||
|
commit = ref.peel(Commit)
|
||||||
|
self.assertEqual(commit.tree.id, ref.peel(Tree).id)
|
||||||
|
|
||||||
|
|
||||||
class ReferencesTest(utils.RepoTestCase):
|
class ReferencesTest(utils.RepoTestCase):
|
||||||
|
def test_list_all_reference_objects(self):
|
||||||
|
repo = self.repo
|
||||||
|
|
||||||
|
refs = [(ref.name, ref.target.hex)
|
||||||
|
for ref in repo.listall_reference_objects()]
|
||||||
|
self.assertEqual(sorted(refs),
|
||||||
|
[('refs/heads/i18n',
|
||||||
|
'5470a671a80ac3789f1a6a8cefbcf43ce7af0563'),
|
||||||
|
('refs/heads/master',
|
||||||
|
'2be5719152d4f82c7302b1c0932d8e5f0a4a0e98')])
|
||||||
|
|
||||||
def test_list_all_references(self):
|
def test_list_all_references(self):
|
||||||
repo = self.repo
|
repo = self.repo
|
||||||
@ -69,12 +270,10 @@ class ReferencesTest(utils.RepoTestCase):
|
|||||||
reference = repo.lookup_reference('refs/heads/master')
|
reference = repo.lookup_reference('refs/heads/master')
|
||||||
self.assertEqual(reference.name, 'refs/heads/master')
|
self.assertEqual(reference.name, 'refs/heads/master')
|
||||||
|
|
||||||
|
|
||||||
def test_reference_get_sha(self):
|
def test_reference_get_sha(self):
|
||||||
reference = self.repo.lookup_reference('refs/heads/master')
|
reference = self.repo.lookup_reference('refs/heads/master')
|
||||||
self.assertEqual(reference.target.hex, LAST_COMMIT)
|
self.assertEqual(reference.target.hex, LAST_COMMIT)
|
||||||
|
|
||||||
|
|
||||||
def test_reference_set_sha(self):
|
def test_reference_set_sha(self):
|
||||||
NEW_COMMIT = '5ebeeebb320790caf276b9fc8b24546d63316533'
|
NEW_COMMIT = '5ebeeebb320790caf276b9fc8b24546d63316533'
|
||||||
reference = self.repo.lookup_reference('refs/heads/master')
|
reference = self.repo.lookup_reference('refs/heads/master')
|
||||||
@ -87,17 +286,14 @@ class ReferencesTest(utils.RepoTestCase):
|
|||||||
reference.set_target(NEW_COMMIT[0:6])
|
reference.set_target(NEW_COMMIT[0:6])
|
||||||
self.assertEqual(reference.target.hex, NEW_COMMIT)
|
self.assertEqual(reference.target.hex, NEW_COMMIT)
|
||||||
|
|
||||||
|
|
||||||
def test_reference_get_type(self):
|
def test_reference_get_type(self):
|
||||||
reference = self.repo.lookup_reference('refs/heads/master')
|
reference = self.repo.lookup_reference('refs/heads/master')
|
||||||
self.assertEqual(reference.type, GIT_REF_OID)
|
self.assertEqual(reference.type, GIT_REF_OID)
|
||||||
|
|
||||||
|
|
||||||
def test_get_target(self):
|
def test_get_target(self):
|
||||||
reference = self.repo.lookup_reference('HEAD')
|
reference = self.repo.lookup_reference('HEAD')
|
||||||
self.assertEqual(reference.target, 'refs/heads/master')
|
self.assertEqual(reference.target, 'refs/heads/master')
|
||||||
|
|
||||||
|
|
||||||
def test_set_target(self):
|
def test_set_target(self):
|
||||||
reference = self.repo.lookup_reference('HEAD')
|
reference = self.repo.lookup_reference('HEAD')
|
||||||
self.assertEqual(reference.target, 'refs/heads/master')
|
self.assertEqual(reference.target, 'refs/heads/master')
|
||||||
@ -140,7 +336,6 @@ class ReferencesTest(utils.RepoTestCase):
|
|||||||
self.assertRaises(GitError, reference.resolve)
|
self.assertRaises(GitError, reference.resolve)
|
||||||
self.assertRaises(GitError, reference.rename, "refs/tags/version2")
|
self.assertRaises(GitError, reference.rename, "refs/tags/version2")
|
||||||
|
|
||||||
|
|
||||||
def test_rename(self):
|
def test_rename(self):
|
||||||
# We add a tag as a new reference that points to "origin/master"
|
# We add a tag as a new reference that points to "origin/master"
|
||||||
reference = self.repo.create_reference('refs/tags/version1',
|
reference = self.repo.create_reference('refs/tags/version1',
|
||||||
@ -149,17 +344,16 @@ class ReferencesTest(utils.RepoTestCase):
|
|||||||
reference.rename('refs/tags/version2')
|
reference.rename('refs/tags/version2')
|
||||||
self.assertEqual(reference.name, 'refs/tags/version2')
|
self.assertEqual(reference.name, 'refs/tags/version2')
|
||||||
|
|
||||||
|
# def test_reload(self):
|
||||||
|
# name = 'refs/tags/version1'
|
||||||
|
|
||||||
# def test_reload(self):
|
# repo = self.repo
|
||||||
# name = 'refs/tags/version1'
|
# ref = repo.create_reference(name, "refs/heads/master", symbolic=True)
|
||||||
|
# ref2 = repo.lookup_reference(name)
|
||||||
# repo = self.repo
|
# ref.delete()
|
||||||
# ref = repo.create_reference(name, "refs/heads/master", symbolic=True)
|
# self.assertEqual(ref2.name, name)
|
||||||
# ref2 = repo.lookup_reference(name)
|
# self.assertRaises(KeyError, ref2.reload)
|
||||||
# ref.delete()
|
# self.assertRaises(GitError, getattr, ref2, 'name')
|
||||||
# self.assertEqual(ref2.name, name)
|
|
||||||
# self.assertRaises(KeyError, ref2.reload)
|
|
||||||
# self.assertRaises(GitError, getattr, ref2, 'name')
|
|
||||||
|
|
||||||
|
|
||||||
def test_reference_resolve(self):
|
def test_reference_resolve(self):
|
||||||
@ -169,13 +363,11 @@ class ReferencesTest(utils.RepoTestCase):
|
|||||||
self.assertEqual(reference.type, GIT_REF_OID)
|
self.assertEqual(reference.type, GIT_REF_OID)
|
||||||
self.assertEqual(reference.target.hex, LAST_COMMIT)
|
self.assertEqual(reference.target.hex, LAST_COMMIT)
|
||||||
|
|
||||||
|
|
||||||
def test_reference_resolve_identity(self):
|
def test_reference_resolve_identity(self):
|
||||||
head = self.repo.lookup_reference('HEAD')
|
head = self.repo.lookup_reference('HEAD')
|
||||||
ref = head.resolve()
|
ref = head.resolve()
|
||||||
self.assertTrue(ref.resolve() is ref)
|
self.assertTrue(ref.resolve() is ref)
|
||||||
|
|
||||||
|
|
||||||
def test_create_reference(self):
|
def test_create_reference(self):
|
||||||
# We add a tag as a new reference that points to "origin/master"
|
# We add a tag as a new reference that points to "origin/master"
|
||||||
reference = self.repo.create_reference('refs/tags/version1',
|
reference = self.repo.create_reference('refs/tags/version1',
|
||||||
@ -194,7 +386,6 @@ class ReferencesTest(utils.RepoTestCase):
|
|||||||
LAST_COMMIT, force=True)
|
LAST_COMMIT, force=True)
|
||||||
self.assertEqual(reference.target.hex, LAST_COMMIT)
|
self.assertEqual(reference.target.hex, LAST_COMMIT)
|
||||||
|
|
||||||
|
|
||||||
def test_create_symbolic_reference(self):
|
def test_create_symbolic_reference(self):
|
||||||
repo = self.repo
|
repo = self.repo
|
||||||
# We add a tag as a new symbolic reference that always points to
|
# We add a tag as a new symbolic reference that always points to
|
||||||
@ -204,7 +395,6 @@ class ReferencesTest(utils.RepoTestCase):
|
|||||||
self.assertEqual(reference.type, GIT_REF_SYMBOLIC)
|
self.assertEqual(reference.type, GIT_REF_SYMBOLIC)
|
||||||
self.assertEqual(reference.target, 'refs/heads/master')
|
self.assertEqual(reference.target, 'refs/heads/master')
|
||||||
|
|
||||||
|
|
||||||
# try to create existing symbolic reference
|
# try to create existing symbolic reference
|
||||||
self.assertRaises(ValueError, repo.create_reference,
|
self.assertRaises(ValueError, repo.create_reference,
|
||||||
'refs/tags/beta', 'refs/heads/master')
|
'refs/tags/beta', 'refs/heads/master')
|
||||||
@ -215,9 +405,8 @@ class ReferencesTest(utils.RepoTestCase):
|
|||||||
self.assertEqual(reference.type, GIT_REF_SYMBOLIC)
|
self.assertEqual(reference.type, GIT_REF_SYMBOLIC)
|
||||||
self.assertEqual(reference.target, 'refs/heads/master')
|
self.assertEqual(reference.target, 'refs/heads/master')
|
||||||
|
|
||||||
|
# def test_packall_references(self):
|
||||||
# def test_packall_references(self):
|
# self.repo.packall_references()
|
||||||
# self.repo.packall_references()
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_object(self):
|
def test_get_object(self):
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2010-2014 The pygit2 contributors
|
# Copyright 2010-2017 The pygit2 contributors
|
||||||
#
|
#
|
||||||
# This file is free software; you can redistribute it and/or modify
|
# This file is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License, version 2,
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
@ -33,6 +33,7 @@ import pygit2
|
|||||||
import sys
|
import sys
|
||||||
from pygit2 import Oid
|
from pygit2 import Oid
|
||||||
from . import utils
|
from . import utils
|
||||||
|
import gc
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import __pypy__
|
import __pypy__
|
||||||
@ -188,21 +189,6 @@ class RepositoryTest(utils.RepoTestCase):
|
|||||||
end = sys.getrefcount(self.repo)
|
end = sys.getrefcount(self.repo)
|
||||||
self.assertEqual(start, end)
|
self.assertEqual(start, end)
|
||||||
|
|
||||||
def test_remote_callback_typecheck(self):
|
|
||||||
remote = self.repo.remotes[0]
|
|
||||||
remote.progress = 5
|
|
||||||
self.assertRaises(TypeError, remote, 'fetch')
|
|
||||||
|
|
||||||
remote = self.repo.remotes[0]
|
|
||||||
remote.transfer_progress = 5
|
|
||||||
self.assertRaises(TypeError, remote, 'fetch')
|
|
||||||
|
|
||||||
remote = self.repo.remotes[0]
|
|
||||||
remote.update_tips = 5
|
|
||||||
self.assertRaises(TypeError, remote, 'fetch')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class EmptyRepositoryTest(utils.EmptyRepoTestCase):
|
class EmptyRepositoryTest(utils.EmptyRepoTestCase):
|
||||||
def test_fetch(self):
|
def test_fetch(self):
|
||||||
remote = self.repo.remotes[0]
|
remote = self.repo.remotes[0]
|
||||||
@ -212,31 +198,37 @@ class EmptyRepositoryTest(utils.EmptyRepoTestCase):
|
|||||||
self.assertEqual(stats.received_objects, REMOTE_REPO_OBJECTS)
|
self.assertEqual(stats.received_objects, REMOTE_REPO_OBJECTS)
|
||||||
|
|
||||||
def test_transfer_progress(self):
|
def test_transfer_progress(self):
|
||||||
self.tp = None
|
class MyCallbacks(pygit2.RemoteCallbacks):
|
||||||
def tp_cb(stats):
|
def transfer_progress(self, stats):
|
||||||
self.tp = stats
|
self.tp = stats
|
||||||
|
|
||||||
|
callbacks = MyCallbacks()
|
||||||
remote = self.repo.remotes[0]
|
remote = self.repo.remotes[0]
|
||||||
remote.transfer_progress = tp_cb
|
stats = remote.fetch(callbacks=callbacks)
|
||||||
stats = remote.fetch()
|
self.assertEqual(stats.received_bytes, callbacks.tp.received_bytes)
|
||||||
self.assertEqual(stats.received_bytes, self.tp.received_bytes)
|
self.assertEqual(stats.indexed_objects, callbacks.tp.indexed_objects)
|
||||||
self.assertEqual(stats.indexed_objects, self.tp.indexed_objects)
|
self.assertEqual(stats.received_objects, callbacks.tp.received_objects)
|
||||||
self.assertEqual(stats.received_objects, self.tp.received_objects)
|
|
||||||
|
|
||||||
def test_update_tips(self):
|
def test_update_tips(self):
|
||||||
remote = self.repo.remotes[0]
|
remote = self.repo.remotes[0]
|
||||||
self.i = 0
|
tips = [('refs/remotes/origin/master', Oid(hex='0'*40),
|
||||||
self.tips = [('refs/remotes/origin/master', Oid(hex='0'*40),
|
|
||||||
Oid(hex='784855caf26449a1914d2cf62d12b9374d76ae78')),
|
Oid(hex='784855caf26449a1914d2cf62d12b9374d76ae78')),
|
||||||
('refs/tags/root', Oid(hex='0'*40),
|
('refs/tags/root', Oid(hex='0'*40),
|
||||||
Oid(hex='3d2962987c695a29f1f80b6c3aa4ec046ef44369'))]
|
Oid(hex='3d2962987c695a29f1f80b6c3aa4ec046ef44369'))]
|
||||||
|
|
||||||
def ut_cb(name, old, new):
|
class MyCallbacks(pygit2.RemoteCallbacks):
|
||||||
self.assertEqual(self.tips[self.i], (name, old, new))
|
def __init__(self, test_self, tips):
|
||||||
|
self.test = test_self
|
||||||
|
self.tips = tips
|
||||||
|
self.i = 0
|
||||||
|
|
||||||
|
def update_tips(self, name, old, new):
|
||||||
|
self.test.assertEqual(self.tips[self.i], (name, old, new))
|
||||||
self.i += 1
|
self.i += 1
|
||||||
|
|
||||||
remote.update_tips = ut_cb
|
callbacks = MyCallbacks(self, tips)
|
||||||
remote.fetch()
|
remote.fetch(callbacks=callbacks)
|
||||||
|
self.assertTrue(callbacks.i > 0)
|
||||||
|
|
||||||
class PushTestCase(unittest.TestCase):
|
class PushTestCase(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -247,6 +239,11 @@ class PushTestCase(unittest.TestCase):
|
|||||||
self.remote = self.clone.create_remote('origin', self.origin.path)
|
self.remote = self.clone.create_remote('origin', self.origin.path)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
self.origin = None
|
||||||
|
self.clone = None
|
||||||
|
self.remote = None
|
||||||
|
gc.collect()
|
||||||
|
|
||||||
self.origin_ctxtmgr.__exit__(None, None, None)
|
self.origin_ctxtmgr.__exit__(None, None, None)
|
||||||
self.clone_ctxtmgr.__exit__(None, None, None)
|
self.clone_ctxtmgr.__exit__(None, None, None)
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user