Merge remote-tracking branch 'upstream/master' into features/diff_refactoring
Conflicts: src/tree.c
This commit is contained in:
@@ -20,9 +20,9 @@ Pygit2 links:
|
|||||||
Quick install guide
|
Quick install guide
|
||||||
===================
|
===================
|
||||||
|
|
||||||
1. Checkout libgi2 v0.18.0::
|
1. Checkout the libgit2 stable branch::
|
||||||
|
|
||||||
$ git clone git://github.com/libgit2/libgit2.git -b v0.18.0
|
$ git clone git://github.com/libgit2/libgit2.git -b master
|
||||||
|
|
||||||
2. Build and install libgit2
|
2. Build and install libgit2
|
||||||
https://github.com/libgit2/libgit2/#building-libgit2---using-cmake
|
https://github.com/libgit2/libgit2/#building-libgit2---using-cmake
|
||||||
|
24
docs/general.rst
Normal file
24
docs/general.rst
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
**********************************************************************
|
||||||
|
General
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
.. contents:: Contents
|
||||||
|
:local:
|
||||||
|
|
||||||
|
|
||||||
|
Constants
|
||||||
|
=========
|
||||||
|
|
||||||
|
.. py:data:: LIBGIT2_VER_MAJOR
|
||||||
|
.. py:data:: LIBGIT2_VER_MINOR
|
||||||
|
.. py:data:: LIBGIT2_VER_REVISION
|
||||||
|
.. py:data:: LIBGIT2_VER_VERSION
|
||||||
|
|
||||||
|
|
||||||
|
Errors
|
||||||
|
======
|
||||||
|
|
||||||
|
.. autoexception:: pygit2.GitError
|
||||||
|
:members:
|
||||||
|
:show-inheritance:
|
||||||
|
:undoc-members:
|
@@ -22,32 +22,27 @@ Pygit2 links:
|
|||||||
Start:
|
Start:
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 1
|
||||||
|
|
||||||
install
|
install
|
||||||
|
|
||||||
Usage guide:
|
Usage guide:
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 1
|
||||||
|
|
||||||
|
general
|
||||||
repository
|
repository
|
||||||
|
oid
|
||||||
objects
|
objects
|
||||||
references
|
references
|
||||||
revparse
|
revparse
|
||||||
log
|
log
|
||||||
working-copy
|
working-copy
|
||||||
diff
|
diff
|
||||||
|
merge
|
||||||
config
|
config
|
||||||
remotes
|
remotes
|
||||||
errors
|
|
||||||
|
|
||||||
More:
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
utils
|
|
||||||
|
|
||||||
|
|
||||||
Indices and tables
|
Indices and tables
|
||||||
|
@@ -6,8 +6,10 @@ How to Install
|
|||||||
.. contents::
|
.. contents::
|
||||||
|
|
||||||
|
|
||||||
First you need to install the latest version of libgit2. You can find
|
First you need to install the latest release of libgit2. If you clone
|
||||||
platform-specific instructions to build the library in the libgit2 website:
|
the repository, make sure to use the ``master`` branch. You can find
|
||||||
|
platform-specific instructions to build the library in the libgit2
|
||||||
|
website:
|
||||||
|
|
||||||
http://libgit2.github.com
|
http://libgit2.github.com
|
||||||
|
|
||||||
@@ -55,7 +57,7 @@ instructions in the libgit2 ``README.md``):
|
|||||||
|
|
||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
$ git clone git://github.com/libgit2/libgit2.git
|
$ git clone -b master git://github.com/libgit2/libgit2.git
|
||||||
$ mkdir libgit2/build
|
$ mkdir libgit2/build
|
||||||
$ cd libgit2/build
|
$ cd libgit2/build
|
||||||
$ cmake ..
|
$ cmake ..
|
||||||
@@ -105,7 +107,7 @@ from a bash shell:
|
|||||||
.. code-block:: sh
|
.. code-block:: sh
|
||||||
|
|
||||||
$ export LIBGIT2=C:/Dev/libgit2
|
$ export LIBGIT2=C:/Dev/libgit2
|
||||||
$ git clone git://github.com/libgit2/libgit2.git
|
$ git clone -b master git://github.com/libgit2/libgit2.git
|
||||||
$ cd libgit2
|
$ cd libgit2
|
||||||
$ mkdir build
|
$ mkdir build
|
||||||
$ cd build
|
$ cd build
|
||||||
|
@@ -1,8 +1,5 @@
|
|||||||
**********************************************************************
|
**********************************************************************
|
||||||
Errors
|
Merge
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
.. autoexception:: pygit2.GitError
|
.. automethod:: pygit2.Repository.merge_base
|
||||||
:members:
|
|
||||||
:show-inheritance:
|
|
||||||
:undoc-members:
|
|
320
docs/objects.rst
320
docs/objects.rst
@@ -1,92 +1,80 @@
|
|||||||
**********************************************************************
|
**********************************************************************
|
||||||
Git objects
|
Git Objects
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
|
||||||
|
There are four types of Git objects: blobs, trees, commits and tags. For each
|
||||||
|
one pygit2 has a type, and all four types inherit from the base ``Object``
|
||||||
|
type.
|
||||||
|
|
||||||
|
|
||||||
.. contents:: Contents
|
.. contents:: Contents
|
||||||
:local:
|
:local:
|
||||||
|
|
||||||
In the first place Git is a key-value storage system. The keys are called
|
|
||||||
OIDs, for Object id, and the values stored are called Objects.
|
|
||||||
|
|
||||||
Oids
|
Object lookup
|
||||||
=================
|
=================
|
||||||
|
|
||||||
The oid is the `SHA-1 <http://en.wikipedia.org/wiki/SHA-1>`_ hash of an
|
In the previous chapter we learnt about Object IDs. With an oid we can ask the
|
||||||
object. It is 20 bytes long:
|
repository to get the associated object. To do that the ``Repository`` class
|
||||||
|
implementes a subset of the mapping interface.
|
||||||
|
|
||||||
- When we represent an oid as a 20 bytes Python string, we say it is a raw
|
.. method:: Repository.get(oid, default=None)
|
||||||
oid.
|
|
||||||
|
|
||||||
- When we represent an oid as a 40 chars Python string, we sayt it is a hex
|
Return the Git object for the given *oid*, returns the *default* value if
|
||||||
oid.
|
there's no object in the repository with that oid. The oid can be an Oid
|
||||||
|
object, or an hexadecimal string.
|
||||||
|
|
||||||
However, most of the time we will use the Oid type. We can explicetly create
|
Example::
|
||||||
an Oid object from its raw or hexadecimal form::
|
|
||||||
|
|
||||||
>>> hex = "cff3ceaefc955f0dbe1957017db181bc49913781"
|
>>> from pygit2 import Repository
|
||||||
>>> oid1 = Oid(hex=hex)
|
>>> repo = Repository('path/to/pygit2')
|
||||||
|
>>> obj = repo.get("101715bf37440d32291bde4f58c3142bcf7d8adb")
|
||||||
|
>>> obj
|
||||||
|
<_pygit2.Commit object at 0x7ff27a6b60f0>
|
||||||
|
|
||||||
>>> from binascii import unhexlify
|
.. method:: Repository[oid]
|
||||||
>>> raw = unhexlify(hex)
|
|
||||||
>>> oid2 = Oid(raw=raw)
|
|
||||||
|
|
||||||
>>> print oid1 == oid2
|
Return the Git object for the given oid, raise ``KeyError`` if there's no
|
||||||
|
object in the repository with that oid. The oid can be an Oid object, or
|
||||||
|
an hexadecimal string.
|
||||||
|
|
||||||
|
.. method:: oid in Repository
|
||||||
|
|
||||||
|
Returns True if there is an object in the Repository with that oid, False
|
||||||
|
if there is not. The oid can be an Oid object, or an hexadecimal string.
|
||||||
|
|
||||||
|
|
||||||
|
The Object base type
|
||||||
|
====================
|
||||||
|
|
||||||
|
The Object type is a base type, it is not possible to make instances of it, in
|
||||||
|
any way.
|
||||||
|
|
||||||
|
It is the base type of the ``Blob``, ``Tree``, ``Commit`` and ``Tag`` types, so
|
||||||
|
it is possible to check whether a Python value is an Object or not::
|
||||||
|
|
||||||
|
>>> from pygit2 import Object
|
||||||
|
>>> commit = repository.revparse_single('HEAD')
|
||||||
|
>>> print isinstance(commit, Object)
|
||||||
True
|
True
|
||||||
|
|
||||||
And in the opposite direction, we can get the raw or hexadecimal form from
|
All Objects are immutable, they cannot be modified once they are created::
|
||||||
an Oid object:
|
|
||||||
|
|
||||||
.. autoattribute:: pygit2.Oid.raw
|
>>> commit.message = u"foobar"
|
||||||
.. autoattribute:: pygit2.Oid.hex
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
AttributeError: attribute 'message' of '_pygit2.Commit' objects is not writable
|
||||||
|
|
||||||
The Oid type supports:
|
Derived types (blobs, trees, etc.) don't have a constructor, this means they
|
||||||
|
cannot be created with the common idiom::
|
||||||
|
|
||||||
- rich comparisons, not just for equality, also: lesser-than, lesser-or-equal,
|
>>> from pygit2 import Blob
|
||||||
etc.
|
>>> blob = Blob("data")
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
TypeError: cannot create '_pygit2.Blob' instances
|
||||||
|
|
||||||
- hashing, so Oid objects can be used as keys in a dictionary
|
New objects are created using an specific API we will see later.
|
||||||
|
|
||||||
|
|
||||||
Python 2 and Python 3
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
There is a difference on how the library handles hex oids, depending on
|
|
||||||
whether we are using Python 2 or 3.
|
|
||||||
|
|
||||||
- In Python 2, we can represent an hexadecimal oid using a bytes string
|
|
||||||
(``str``) or a text string (``unicode``)
|
|
||||||
|
|
||||||
- In Python 3, hexadecimal oids can only be represented using unicode
|
|
||||||
strings.
|
|
||||||
|
|
||||||
|
|
||||||
Objects
|
|
||||||
=================
|
|
||||||
|
|
||||||
There are four types (commits, trees, blobs and tags), for each type pygit2
|
|
||||||
has a Python class::
|
|
||||||
|
|
||||||
>>> # Show commits and trees
|
|
||||||
>>> commit
|
|
||||||
<pygit2.Commit object at 0x7f9d2f3000b0>
|
|
||||||
>>> commit.tree
|
|
||||||
<pygit2.Tree object at 0x7f9d2f3000f0>
|
|
||||||
|
|
||||||
These four classes (``Commit``, ``Tree``, ``Blob`` and ``Tag``) inherit from
|
|
||||||
the ``Object`` base class, which provides shared behaviour. A Git object is
|
|
||||||
identified by a unique *object id*, which is a binary byte string; this is
|
|
||||||
often represented as an hexadecimal text string::
|
|
||||||
|
|
||||||
>>> commit.oid
|
|
||||||
b'x\xde\xb5W\x8d\x01<\xdb\xdf\x08o\xa1\xd1\xa3\xe7\xd9\x82\xe8\x88\x8f'
|
|
||||||
>>> commit.hex
|
|
||||||
'78deb5578d013cdbdf086fa1d1a3e7d982e8888f'
|
|
||||||
|
|
||||||
The API of pygit2 accepts both the raw object id and its hexadecimal
|
|
||||||
representation, the difference is done based on its type (a byte or a text
|
|
||||||
string).
|
|
||||||
|
|
||||||
Objects can not be modified once they have been created.
|
|
||||||
|
|
||||||
This is the common interface for all Git objects:
|
This is the common interface for all Git objects:
|
||||||
|
|
||||||
@@ -96,6 +84,126 @@ This is the common interface for all Git objects:
|
|||||||
.. automethod:: pygit2.Object.read_raw
|
.. automethod:: pygit2.Object.read_raw
|
||||||
|
|
||||||
|
|
||||||
|
Blobs
|
||||||
|
=================
|
||||||
|
|
||||||
|
A blob is just a raw byte string. They are the Git equivalent to files in
|
||||||
|
a filesytem.
|
||||||
|
|
||||||
|
This is their API:
|
||||||
|
|
||||||
|
.. autoattribute:: pygit2.Blob.data
|
||||||
|
|
||||||
|
Example, print the contents of the ``.gitignore`` file::
|
||||||
|
|
||||||
|
>>> blob = repo["d8022420bf6db02e906175f64f66676df539f2fd"]
|
||||||
|
>>> print blob.data
|
||||||
|
MANIFEST
|
||||||
|
build
|
||||||
|
dist
|
||||||
|
|
||||||
|
.. autoattribute:: pygit2.Blob.size
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
>>> print blob.size
|
||||||
|
130
|
||||||
|
|
||||||
|
Creating blobs
|
||||||
|
--------------
|
||||||
|
|
||||||
|
There are a number of methods in the repository to create new blobs, and add
|
||||||
|
them to the Git object database:
|
||||||
|
|
||||||
|
.. automethod:: pygit2.Repository.create_blob
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
>>> oid = repo.create_blob('foo bar') # Creates blob from bytes string
|
||||||
|
>>> blob = repo[oid]
|
||||||
|
>>> blob.data
|
||||||
|
'foo bar'
|
||||||
|
|
||||||
|
.. automethod:: pygit2.Repository.create_blob_fromworkdir
|
||||||
|
.. automethod:: pygit2.Repository.create_blob_fromdisk
|
||||||
|
|
||||||
|
There are also some functions to calculate the oid for a byte string without
|
||||||
|
creating the blob object:
|
||||||
|
|
||||||
|
.. autofunction:: pygit2.hash
|
||||||
|
.. autofunction:: pygit2.hashfile
|
||||||
|
|
||||||
|
|
||||||
|
Trees
|
||||||
|
=================
|
||||||
|
|
||||||
|
A tree is a sorted collection of tree entries. It is similar to a folder or
|
||||||
|
directory in a file system. Each entry points to another tree or a blob. A
|
||||||
|
tree can be iterated, and partially implements the sequence and mapping
|
||||||
|
interfaces.
|
||||||
|
|
||||||
|
.. method:: Tree[name]
|
||||||
|
|
||||||
|
Return the TreeEntry object for the given *name*. Raise ``KeyError`` if
|
||||||
|
there is not a tree entry with that name.
|
||||||
|
|
||||||
|
.. method:: name in Tree
|
||||||
|
|
||||||
|
Return True if there is a tree entry with the given name, False otherwise.
|
||||||
|
|
||||||
|
.. method:: len(Tree)
|
||||||
|
|
||||||
|
Return the number of entries in the tree.
|
||||||
|
|
||||||
|
.. method:: iter(Tree)
|
||||||
|
|
||||||
|
Return an iterator over the entries of the tree.
|
||||||
|
|
||||||
|
.. automethod:: pygit2.Tree.diff
|
||||||
|
|
||||||
|
Tree entries
|
||||||
|
------------
|
||||||
|
|
||||||
|
.. autoattribute:: pygit2.TreeEntry.name
|
||||||
|
.. autoattribute:: pygit2.TreeEntry.oid
|
||||||
|
.. autoattribute:: pygit2.TreeEntry.hex
|
||||||
|
.. autoattribute:: pygit2.TreeEntry.filemode
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
>>> tree = commit.tree
|
||||||
|
>>> len(tree) # Number of entries
|
||||||
|
6
|
||||||
|
|
||||||
|
>>> for entry in tree: # Iteration
|
||||||
|
... print(entry.hex, entry.name)
|
||||||
|
...
|
||||||
|
7151ca7cd3e59f3eab19c485cfbf3cb30928d7fa .gitignore
|
||||||
|
c36f4cf1e38ec1bb9d9ad146ed572b89ecfc9f18 COPYING
|
||||||
|
32b30b90b062f66957d6790c3c155c289c34424e README.md
|
||||||
|
c87dae4094b3a6d10e08bc6c5ef1f55a7e448659 pygit2.c
|
||||||
|
85a67270a49ef16cdd3d328f06a3e4b459f09b27 setup.py
|
||||||
|
3d8985bbec338eb4d47c5b01b863ee89d044bd53 test
|
||||||
|
|
||||||
|
>>> entry = tree['pygit2.c'] # Get an entry by name
|
||||||
|
>>> entry
|
||||||
|
<pygit2.TreeEntry object at 0xcc10f0>
|
||||||
|
|
||||||
|
>>> blob = repo[entry.oid] # Get the object the entry points to
|
||||||
|
>>> blob
|
||||||
|
<pygit2.Blob object at 0xcc12d0>
|
||||||
|
|
||||||
|
Creating trees
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
.. automethod:: pygit2.Repository.TreeBuilder
|
||||||
|
|
||||||
|
.. automethod:: pygit2.TreeBuilder.insert
|
||||||
|
.. automethod:: pygit2.TreeBuilder.remove
|
||||||
|
.. automethod:: pygit2.TreeBuilder.clear
|
||||||
|
.. automethod:: pygit2.TreeBuilder.write
|
||||||
|
|
||||||
|
|
||||||
Commits
|
Commits
|
||||||
=================
|
=================
|
||||||
|
|
||||||
@@ -147,82 +255,6 @@ repository with the following parameters::
|
|||||||
'#\xe4<u\xfe\xd6\x17\xa0\xe6\xa2\x8b\xb6\xdc35$\xcf-\x8b~'
|
'#\xe4<u\xfe\xd6\x17\xa0\xe6\xa2\x8b\xb6\xdc35$\xcf-\x8b~'
|
||||||
|
|
||||||
|
|
||||||
Trees
|
|
||||||
=================
|
|
||||||
|
|
||||||
A tree is a sorted collection of tree entries. It is similar to a folder or
|
|
||||||
directory in a file system. Each entry points to another tree or a blob. A
|
|
||||||
tree can be iterated, and partially implements the sequence and mapping
|
|
||||||
interfaces::
|
|
||||||
|
|
||||||
>>> # Number of entries
|
|
||||||
>>> tree = commit.tree
|
|
||||||
>>> len(tree)
|
|
||||||
6
|
|
||||||
|
|
||||||
>>> # Iteration
|
|
||||||
>>> for entry in tree:
|
|
||||||
... print(entry.hex, entry.name)
|
|
||||||
...
|
|
||||||
7151ca7cd3e59f3eab19c485cfbf3cb30928d7fa .gitignore
|
|
||||||
c36f4cf1e38ec1bb9d9ad146ed572b89ecfc9f18 COPYING
|
|
||||||
32b30b90b062f66957d6790c3c155c289c34424e README.md
|
|
||||||
c87dae4094b3a6d10e08bc6c5ef1f55a7e448659 pygit2.c
|
|
||||||
85a67270a49ef16cdd3d328f06a3e4b459f09b27 setup.py
|
|
||||||
3d8985bbec338eb4d47c5b01b863ee89d044bd53 test
|
|
||||||
|
|
||||||
>>> # Get an entry by name
|
|
||||||
>>> entry = tree['pygit2.c']
|
|
||||||
>>> entry
|
|
||||||
<pygit2.TreeEntry object at 0xcc10f0>
|
|
||||||
|
|
||||||
>>> # Get the object the entry points to
|
|
||||||
>>> blob = repo[entry.oid]
|
|
||||||
>>> blob
|
|
||||||
<pygit2.Blob object at 0xcc12d0>
|
|
||||||
|
|
||||||
.. automethod:: pygit2.Tree.diff
|
|
||||||
|
|
||||||
.. autoattribute:: pygit2.TreeEntry.name
|
|
||||||
.. autoattribute:: pygit2.TreeEntry.oid
|
|
||||||
.. autoattribute:: pygit2.TreeEntry.hex
|
|
||||||
.. autoattribute:: pygit2.TreeEntry.filemode
|
|
||||||
|
|
||||||
|
|
||||||
Creating trees
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
.. automethod:: pygit2.Repository.TreeBuilder
|
|
||||||
|
|
||||||
.. automethod:: pygit2.TreeBuilder.insert
|
|
||||||
.. automethod:: pygit2.TreeBuilder.remove
|
|
||||||
.. automethod:: pygit2.TreeBuilder.clear
|
|
||||||
.. automethod:: pygit2.TreeBuilder.write
|
|
||||||
|
|
||||||
|
|
||||||
Blobs
|
|
||||||
=================
|
|
||||||
|
|
||||||
A blob is equivalent to a file in a file system.::
|
|
||||||
|
|
||||||
>>> # create a blob out of memory
|
|
||||||
>>> oid = repo.create_blob('foo bar')
|
|
||||||
>>> blob = repo[oid]
|
|
||||||
>>> blob.data
|
|
||||||
'foo bar'
|
|
||||||
>>> oid
|
|
||||||
'\x96\xc9\x06um{\x91\xc4S"a|\x92\x95\xe4\xa8\rR\xd1\xc5'
|
|
||||||
|
|
||||||
.. autoattribute:: pygit2.Blob.data
|
|
||||||
.. autoattribute:: pygit2.Blob.size
|
|
||||||
|
|
||||||
Creating blobs
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
.. automethod:: pygit2.Repository.create_blob
|
|
||||||
.. automethod:: pygit2.Repository.create_blob_fromworkdir
|
|
||||||
.. automethod:: pygit2.Repository.create_blob_fromdisk
|
|
||||||
|
|
||||||
Tags
|
Tags
|
||||||
=================
|
=================
|
||||||
|
|
||||||
|
84
docs/oid.rst
Normal file
84
docs/oid.rst
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
**********************************************************************
|
||||||
|
Object IDs
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
In the first place Git is a key-value storage system. The keys are called
|
||||||
|
OIDs, for Object ID, and the values stored are called Objects.
|
||||||
|
|
||||||
|
.. contents:: Contents
|
||||||
|
:local:
|
||||||
|
|
||||||
|
|
||||||
|
The three forms of an object id
|
||||||
|
===============================
|
||||||
|
|
||||||
|
The oid is the `SHA-1 <http://en.wikipedia.org/wiki/SHA-1>`_ hash of an
|
||||||
|
object. It is 20 bytes long.
|
||||||
|
|
||||||
|
These are the three forms of an oid in pygit2:
|
||||||
|
|
||||||
|
Raw oid
|
||||||
|
A raw oid is represented as a Python byte string of 20 bytes length.
|
||||||
|
This form can only be used to create an Oid object.
|
||||||
|
|
||||||
|
Hex oid
|
||||||
|
A hex oid is represented as a Python string of 40 hexadecimal chars. This
|
||||||
|
form can be used to create Oid objects, just like raw oids. Also, the pygit2
|
||||||
|
API directly accepts hex oids everywhere.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
In Python 3 hexadecimal oids are represented using the ``str`` type.
|
||||||
|
In Python 2 both ``str`` and ``unicode`` are accepted.
|
||||||
|
|
||||||
|
Oid object
|
||||||
|
An ``Oid`` object can be built from the raw or hexadecimal representations
|
||||||
|
(see below). The pygit2 API always returns, and accepts, ``Oid`` objects.
|
||||||
|
|
||||||
|
This is the preferred way to represent an Oid, with the hexadecimal form
|
||||||
|
being used for interaction with the user.
|
||||||
|
|
||||||
|
|
||||||
|
The Oid type
|
||||||
|
============
|
||||||
|
|
||||||
|
.. c:type:: pygit2.Oid(raw=None, hex=None)
|
||||||
|
|
||||||
|
The constructor expects either a raw or a hex oid, but not both.
|
||||||
|
|
||||||
|
An Oid object is created from the hexadecimal form this way::
|
||||||
|
|
||||||
|
>>> from pygit2 import Oid
|
||||||
|
|
||||||
|
>>> hex = "cff3ceaefc955f0dbe1957017db181bc49913781"
|
||||||
|
>>> oid1 = Oid(hex=hex)
|
||||||
|
|
||||||
|
An Oid object is created from the raw form this way::
|
||||||
|
|
||||||
|
>>> from binascii import unhexlify
|
||||||
|
>>> from pygit2 import Oid
|
||||||
|
|
||||||
|
>>> raw = unhexlify("cff3ceaefc955f0dbe1957017db181bc49913781")
|
||||||
|
>>> oid2 = Oid(raw=raw)
|
||||||
|
|
||||||
|
An the other way around, from an Oid object we can get the hexadecimal and raw
|
||||||
|
forms.
|
||||||
|
|
||||||
|
.. autoattribute:: pygit2.Oid.hex
|
||||||
|
.. autoattribute:: pygit2.Oid.raw
|
||||||
|
|
||||||
|
The Oid type supports:
|
||||||
|
|
||||||
|
- rich comparisons, not just for equality, also: lesser-than, lesser-or-equal,
|
||||||
|
etc.
|
||||||
|
|
||||||
|
- hashing, so Oid objects can be used as keys in a dictionary.
|
||||||
|
|
||||||
|
|
||||||
|
Constants
|
||||||
|
=========
|
||||||
|
|
||||||
|
.. py:data:: GIT_OID_RAWSZ
|
||||||
|
.. py:data:: GIT_OID_HEXSZ
|
||||||
|
.. py:data:: GIT_OID_HEX_ZERO
|
||||||
|
.. py:data:: GIT_OID_MINPREFIXLEN
|
@@ -5,40 +5,59 @@ The repository
|
|||||||
Everything starts either by creating a new repository, or by opening an
|
Everything starts either by creating a new repository, or by opening an
|
||||||
existing one.
|
existing one.
|
||||||
|
|
||||||
|
.. contents:: Contents
|
||||||
|
:local:
|
||||||
|
|
||||||
Creating a repository
|
|
||||||
|
Functions
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
.. autofunction:: pygit2.init_repository
|
.. autofunction:: pygit2.init_repository
|
||||||
|
|
||||||
This is how to create non-bare repository::
|
Example::
|
||||||
|
|
||||||
>>> from pygit2 import init_repository
|
>>> from pygit2 import init_repository
|
||||||
>>> repo = init_repository('test')
|
>>> repo = init_repository('test') # Creates a non-bare repository
|
||||||
|
>>> repo = init_repository('test', bare=True) # Creates a bare repository
|
||||||
|
|
||||||
And this is how to create a bare repository::
|
.. autofunction:: pygit2.clone_repository
|
||||||
|
|
||||||
>>> from pygit2 import init_repository
|
Example::
|
||||||
>>> repo = init_repository('test', bare=True)
|
|
||||||
|
|
||||||
But one can also do::
|
>>> from pygit2 import clone_repository
|
||||||
|
>>> repo_url = 'git://github.com/libgit2/pygit2.git'
|
||||||
|
>>> repo_path = '/path/to/create/repository'
|
||||||
|
>>> repo = clone_repository(repo_url, repo_path) # Clones a non-bare repository
|
||||||
|
>>> repo = clone_repository(repo_url, repo_path, bare=True) # Clones a bare repository
|
||||||
|
|
||||||
|
|
||||||
|
.. autofunction:: pygit2.discover_repository
|
||||||
|
|
||||||
>>> from pygit2 import init_repository
|
|
||||||
>>> repo = init_repository('test', True)
|
|
||||||
|
|
||||||
|
|
||||||
The Repository class
|
The Repository class
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
To open an existing repository::
|
.. py:class:: pygit2.Repository(path)
|
||||||
|
|
||||||
|
The Repository constructor only takes one argument, the path of the
|
||||||
|
repository to open.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
>>> from pygit2 import Repository
|
>>> from pygit2 import Repository
|
||||||
>>> repo = Repository('pygit2/.git')
|
>>> repo = Repository('pygit2/.git')
|
||||||
|
|
||||||
|
The API of the Repository class is quite large. Since this documentation is
|
||||||
|
orgaized by features, the related bits are explained in the related chapters,
|
||||||
|
for instance the :py:meth:`pygit2.Repository.checkout` method are explained in
|
||||||
|
the Checkout section.
|
||||||
|
|
||||||
|
Below there are some general attributes and methods:
|
||||||
|
|
||||||
.. autoattribute:: pygit2.Repository.path
|
.. autoattribute:: pygit2.Repository.path
|
||||||
.. autoattribute:: pygit2.Repository.workdir
|
.. autoattribute:: pygit2.Repository.workdir
|
||||||
.. autoattribute:: pygit2.Repository.is_bare
|
.. autoattribute:: pygit2.Repository.is_bare
|
||||||
.. autoattribute:: pygit2.Repository.is_empty
|
.. autoattribute:: pygit2.Repository.is_empty
|
||||||
.. automethod:: pygit2.Repository.read
|
.. automethod:: pygit2.Repository.read
|
||||||
.. automethod:: pygit2.Repository.write
|
.. automethod:: pygit2.Repository.write
|
||||||
.. automethod:: pygit2.Repository.merge_base
|
|
||||||
|
@@ -1,14 +0,0 @@
|
|||||||
**********************************************************************
|
|
||||||
Utilities
|
|
||||||
**********************************************************************
|
|
||||||
|
|
||||||
.. autofunction:: pygit2.discover_repository
|
|
||||||
|
|
||||||
.. autofunction:: pygit2.hash
|
|
||||||
|
|
||||||
.. autofunction:: pygit2.hashfile
|
|
||||||
|
|
||||||
.. automodule:: pygit2.utils
|
|
||||||
:members:
|
|
||||||
:show-inheritance:
|
|
||||||
:undoc-members:
|
|
@@ -40,15 +40,50 @@ import pygit2.utils
|
|||||||
|
|
||||||
def init_repository(path, bare=False):
|
def init_repository(path, bare=False):
|
||||||
"""
|
"""
|
||||||
Creates a new Git repository in the given path.
|
Creates a new Git repository in the given *path*.
|
||||||
|
|
||||||
Arguments:
|
If *bare* is True the repository will be bare, i.e. it will not have a
|
||||||
|
working copy.
|
||||||
path
|
|
||||||
Path where to create the repository.
|
|
||||||
|
|
||||||
bare
|
|
||||||
Whether the repository will be bare or not.
|
|
||||||
"""
|
"""
|
||||||
_pygit2.init_repository(path, bare)
|
_pygit2.init_repository(path, bare)
|
||||||
return Repository(path)
|
return Repository(path)
|
||||||
|
|
||||||
|
|
||||||
|
def clone_repository(
|
||||||
|
url, path, bare=False, remote_name="origin",
|
||||||
|
push_url=None, fetch_spec=None,
|
||||||
|
push_spec=None, checkout_branch=None):
|
||||||
|
"""
|
||||||
|
Clones a new Git repository from *url* in the given *path*.
|
||||||
|
|
||||||
|
**bare** indicates whether a bare git repository should be created.
|
||||||
|
|
||||||
|
**remote_name** is the name given to the "origin" remote.
|
||||||
|
The default is "origin".
|
||||||
|
|
||||||
|
**push_url** is a URL to be used for pushing.
|
||||||
|
None means use the *url* parameter.
|
||||||
|
|
||||||
|
**fetch_spec** defines the the default fetch spec.
|
||||||
|
None results in the same behavior as *GIT_REMOTE_DEFAULT_FETCH*.
|
||||||
|
|
||||||
|
**push_spec** is the fetch specification to be used for pushing.
|
||||||
|
None means use the same spec as for *fetch_spec*.
|
||||||
|
|
||||||
|
**checkout_branch** gives the name of the branch to checkout.
|
||||||
|
None means use the remote's *HEAD*.
|
||||||
|
|
||||||
|
Returns a Repository class pointing to the newly cloned repository.
|
||||||
|
|
||||||
|
If you wish to use the repo, you need to do a checkout for one of
|
||||||
|
the available branches, like this:
|
||||||
|
|
||||||
|
>>> repo = repo.clone_repository("url", "path")
|
||||||
|
>>> repo.checkout(branch) # i.e.: refs/heads/master
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
_pygit2.clone_repository(
|
||||||
|
url, path, bare, remote_name, push_url,
|
||||||
|
fetch_spec, push_spec, checkout_branch)
|
||||||
|
return Repository(path)
|
||||||
|
@@ -42,7 +42,8 @@ Blob_size__get__(Blob *self)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Blob_data__doc__,
|
PyDoc_STRVAR(Blob_data__doc__,
|
||||||
"Raw data. This is the same as Blob.read_raw()");
|
"The contents of the blob, a bytes string. This is the same as\n"
|
||||||
|
"Blob.read_raw()");
|
||||||
|
|
||||||
PyGetSetDef Blob_getseters[] = {
|
PyGetSetDef Blob_getseters[] = {
|
||||||
GETTER(Blob, size),
|
GETTER(Blob, size),
|
||||||
|
26
src/commit.c
26
src/commit.c
@@ -31,6 +31,7 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "signature.h"
|
#include "signature.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
|
#include "object.h"
|
||||||
|
|
||||||
extern PyTypeObject TreeType;
|
extern PyTypeObject TreeType;
|
||||||
|
|
||||||
@@ -149,32 +150,43 @@ Commit_tree__get__(Commit *commit)
|
|||||||
PyDoc_STRVAR(Commit_parents__doc__, "The list of parent commits.");
|
PyDoc_STRVAR(Commit_parents__doc__, "The list of parent commits.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Commit_parents__get__(Commit *commit)
|
Commit_parents__get__(Commit *self)
|
||||||
{
|
{
|
||||||
|
git_repository *repo;
|
||||||
unsigned int i, parent_count;
|
unsigned int i, parent_count;
|
||||||
const git_oid *parent_oid;
|
const git_oid *parent_oid;
|
||||||
PyObject *obj;
|
git_commit *parent;
|
||||||
|
int err;
|
||||||
|
PyObject *py_parent;
|
||||||
PyObject *list;
|
PyObject *list;
|
||||||
|
|
||||||
parent_count = git_commit_parentcount(commit->commit);
|
parent_count = git_commit_parentcount(self->commit);
|
||||||
list = PyList_New(parent_count);
|
list = PyList_New(parent_count);
|
||||||
if (!list)
|
if (!list)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
repo = git_object_owner((git_object*)self->commit);
|
||||||
for (i=0; i < parent_count; i++) {
|
for (i=0; i < parent_count; i++) {
|
||||||
parent_oid = git_commit_parent_id(commit->commit, i);
|
parent_oid = git_commit_parent_id(self->commit, i);
|
||||||
if (parent_oid == NULL) {
|
if (parent_oid == NULL) {
|
||||||
Py_DECREF(list);
|
Py_DECREF(list);
|
||||||
Error_set(GIT_ENOTFOUND);
|
Error_set(GIT_ENOTFOUND);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
obj = lookup_object(commit->repo, parent_oid, GIT_OBJ_COMMIT);
|
|
||||||
if (obj == NULL) {
|
err = git_commit_lookup(&parent, repo, parent_oid);
|
||||||
|
if (err < 0) {
|
||||||
|
Py_DECREF(list);
|
||||||
|
return Error_set_oid(err, parent_oid, GIT_OID_HEXSZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
py_parent = wrap_object((git_object*)parent, self->repo);
|
||||||
|
if (py_parent == NULL) {
|
||||||
Py_DECREF(list);
|
Py_DECREF(list);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyList_SET_ITEM(list, i, obj);
|
PyList_SET_ITEM(list, i, py_parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
|
@@ -358,10 +358,10 @@ Index_read_tree(Index *self, PyObject *value)
|
|||||||
git_oid oid;
|
git_oid oid;
|
||||||
git_tree *tree;
|
git_tree *tree;
|
||||||
int err;
|
int err;
|
||||||
Py_ssize_t len;
|
size_t len;
|
||||||
|
|
||||||
len = py_str_to_git_oid(value, &oid);
|
len = py_oid_to_git_oid(value, &oid);
|
||||||
if (len < 0)
|
if (len == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err = git_tree_lookup_prefix(&tree, self->repo->repo, &oid, len);
|
err = git_tree_lookup_prefix(&tree, self->repo->repo, &oid, len);
|
||||||
@@ -378,7 +378,7 @@ Index_read_tree(Index *self, PyObject *value)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Index_write_tree__doc__,
|
PyDoc_STRVAR(Index_write_tree__doc__,
|
||||||
"write_tree() -> str\n"
|
"write_tree() -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Create a tree object from the index file, return its oid.");
|
"Create a tree object from the index file, return its oid.");
|
||||||
|
|
||||||
|
12
src/object.c
12
src/object.c
@@ -50,7 +50,7 @@ Object_dealloc(Object* self)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Object_oid__doc__,
|
PyDoc_STRVAR(Object_oid__doc__,
|
||||||
"The object id, a byte string 20 bytes long.");
|
"The object id, an instance of the Oid type.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Object_oid__get__(Object *self)
|
Object_oid__get__(Object *self)
|
||||||
@@ -65,7 +65,8 @@ Object_oid__get__(Object *self)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Object_hex__doc__,
|
PyDoc_STRVAR(Object_hex__doc__,
|
||||||
"Hexadecimal representation of the object id, a text string 40 chars long.");
|
"Hexadecimal representation of the object id. This is a shortcut for\n"
|
||||||
|
"Object.oid.hex");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Object_hex__get__(Object *self)
|
Object_hex__get__(Object *self)
|
||||||
@@ -91,19 +92,22 @@ Object_type__get__(Object *self)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Object_read_raw__doc__,
|
PyDoc_STRVAR(Object_read_raw__doc__,
|
||||||
|
"read_raw()\n"
|
||||||
|
"\n"
|
||||||
"Returns the byte string with the raw contents of the of the object.");
|
"Returns the byte string with the raw contents of the of the object.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Object_read_raw(Object *self)
|
Object_read_raw(Object *self)
|
||||||
{
|
{
|
||||||
|
git_repository *repo;
|
||||||
const git_oid *oid;
|
const git_oid *oid;
|
||||||
git_odb_object *obj;
|
git_odb_object *obj;
|
||||||
PyObject *aux;
|
PyObject *aux;
|
||||||
|
|
||||||
|
repo = git_object_owner(self->obj);
|
||||||
oid = git_object_id(self->obj);
|
oid = git_object_id(self->obj);
|
||||||
assert(oid);
|
|
||||||
|
|
||||||
obj = Repository_read_raw(self->repo->repo, oid, GIT_OID_HEXSZ);
|
obj = Repository_read_raw(repo, oid, GIT_OID_HEXSZ);
|
||||||
if (obj == NULL)
|
if (obj == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
81
src/oid.c
81
src/oid.c
@@ -45,8 +45,8 @@ git_oid_to_python(const git_oid *oid)
|
|||||||
return (PyObject*)py_oid;
|
return (PyObject*)py_oid;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_ssize_t
|
size_t
|
||||||
_oid_from_hex(PyObject *py_oid, git_oid *oid)
|
py_hex_to_git_oid (PyObject *py_oid, git_oid *oid)
|
||||||
{
|
{
|
||||||
PyObject *py_hex;
|
PyObject *py_hex;
|
||||||
int err;
|
int err;
|
||||||
@@ -58,15 +58,15 @@ _oid_from_hex(PyObject *py_oid, git_oid *oid)
|
|||||||
if (PyBytes_Check(py_oid)) {
|
if (PyBytes_Check(py_oid)) {
|
||||||
err = PyBytes_AsStringAndSize(py_oid, &hex, &len);
|
err = PyBytes_AsStringAndSize(py_oid, &hex, &len);
|
||||||
if (err)
|
if (err)
|
||||||
return -1;
|
return 0;
|
||||||
|
|
||||||
err = git_oid_fromstrn(oid, hex, len);
|
err = git_oid_fromstrn(oid, hex, len);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
PyErr_SetObject(Error_type(err), py_oid);
|
PyErr_SetObject(Error_type(err), py_oid);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return (size_t)len;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -74,31 +74,31 @@ _oid_from_hex(PyObject *py_oid, git_oid *oid)
|
|||||||
if (PyUnicode_Check(py_oid)) {
|
if (PyUnicode_Check(py_oid)) {
|
||||||
py_hex = PyUnicode_AsASCIIString(py_oid);
|
py_hex = PyUnicode_AsASCIIString(py_oid);
|
||||||
if (py_hex == NULL)
|
if (py_hex == NULL)
|
||||||
return -1;
|
return 0;
|
||||||
|
|
||||||
err = PyBytes_AsStringAndSize(py_hex, &hex, &len);
|
err = PyBytes_AsStringAndSize(py_hex, &hex, &len);
|
||||||
if (err) {
|
if (err) {
|
||||||
Py_DECREF(py_hex);
|
Py_DECREF(py_hex);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = git_oid_fromstrn(oid, hex, len);
|
err = git_oid_fromstrn(oid, hex, len);
|
||||||
Py_DECREF(py_hex);
|
Py_DECREF(py_hex);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
PyErr_SetObject(Error_type(err), py_oid);
|
PyErr_SetObject(Error_type(err), py_oid);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return len;
|
return (size_t)len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Type error */
|
/* Type error */
|
||||||
PyErr_SetObject(PyExc_TypeError, py_oid);
|
PyErr_SetObject(PyExc_TypeError, py_oid);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_ssize_t
|
size_t
|
||||||
py_str_to_git_oid(PyObject *py_oid, git_oid *oid)
|
py_oid_to_git_oid(PyObject *py_oid, git_oid *oid)
|
||||||
{
|
{
|
||||||
/* Oid */
|
/* Oid */
|
||||||
if (PyObject_TypeCheck(py_oid, (PyTypeObject*)&OidType)) {
|
if (PyObject_TypeCheck(py_oid, (PyTypeObject*)&OidType)) {
|
||||||
@@ -107,41 +107,43 @@ py_str_to_git_oid(PyObject *py_oid, git_oid *oid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Hex */
|
/* Hex */
|
||||||
return _oid_from_hex(py_oid, oid);
|
return py_hex_to_git_oid(py_oid, oid);
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_ssize_t
|
int
|
||||||
py_str_to_git_oid_expand(git_repository *repo, PyObject *py_str, git_oid *oid)
|
py_oid_to_git_oid_expand(git_repository *repo, PyObject *py_str, git_oid *oid)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
Py_ssize_t len;
|
size_t len;
|
||||||
git_odb *odb;
|
git_odb *odb = NULL;
|
||||||
git_odb_object *obj;
|
git_odb_object *obj = NULL;
|
||||||
|
|
||||||
len = py_str_to_git_oid(py_str, oid);
|
len = py_oid_to_git_oid(py_str, oid);
|
||||||
|
if (len == 0)
|
||||||
if (len == GIT_OID_HEXSZ || len < 0)
|
|
||||||
return len;
|
|
||||||
|
|
||||||
err = git_repository_odb(&odb, repo);
|
|
||||||
if (err < 0) {
|
|
||||||
Error_set(err);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
if (len == GIT_OID_HEXSZ)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Short oid */
|
||||||
|
err = git_repository_odb(&odb, repo);
|
||||||
|
if (err < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
err = git_odb_read_prefix(&obj, odb, oid, len);
|
err = git_odb_read_prefix(&obj, odb, oid, len);
|
||||||
if (err < 0) {
|
if (err < 0)
|
||||||
git_odb_free(odb);
|
goto error;
|
||||||
Error_set(err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
git_oid_cpy(oid, git_odb_object_id(obj));
|
git_oid_cpy(oid, git_odb_object_id(obj));
|
||||||
|
|
||||||
git_odb_object_free(obj);
|
git_odb_object_free(obj);
|
||||||
git_odb_free(odb);
|
git_odb_free(odb);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
git_odb_object_free(obj);
|
||||||
|
git_odb_free(odb);
|
||||||
|
Error_set(err);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
@@ -197,8 +199,8 @@ Oid_init(Oid *self, PyObject *args, PyObject *kw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Case 2: hex */
|
/* Case 2: hex */
|
||||||
len = _oid_from_hex(hex, &self->oid);
|
len = py_hex_to_git_oid(hex, &self->oid);
|
||||||
if (len < 0)
|
if (len == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -246,6 +248,9 @@ Oid_richcompare(PyObject *o1, PyObject *o2, int op)
|
|||||||
case Py_GE:
|
case Py_GE:
|
||||||
res = (cmp >= 0) ? Py_True: Py_False;
|
res = (cmp >= 0) ? Py_True: Py_False;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
PyErr_Format(PyExc_RuntimeError, "Unexpected '%d' op", op);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_INCREF(res);
|
Py_INCREF(res);
|
||||||
@@ -253,7 +258,7 @@ Oid_richcompare(PyObject *o1, PyObject *o2, int op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Oid_raw__doc__, "Raw oid.");
|
PyDoc_STRVAR(Oid_raw__doc__, "Raw oid, a 20 bytes string.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Oid_raw__get__(Oid *self)
|
Oid_raw__get__(Oid *self)
|
||||||
@@ -262,7 +267,7 @@ Oid_raw__get__(Oid *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Oid_hex__doc__, "Hex oid.");
|
PyDoc_STRVAR(Oid_hex__doc__, "Hex oid, a 40 chars long string (type str).");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Oid_hex__get__(Oid *self)
|
Oid_hex__get__(Oid *self)
|
||||||
|
@@ -32,8 +32,8 @@
|
|||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <git2.h>
|
#include <git2.h>
|
||||||
|
|
||||||
Py_ssize_t py_str_to_git_oid(PyObject *py_str, git_oid *oid);
|
size_t py_oid_to_git_oid(PyObject *py_str, git_oid *oid);
|
||||||
Py_ssize_t py_str_to_git_oid_expand(git_repository *repo, PyObject *py_str,
|
int py_oid_to_git_oid_expand(git_repository *repo, PyObject *py_str,
|
||||||
git_oid *oid);
|
git_oid *oid);
|
||||||
PyObject* git_oid_to_python(const git_oid *oid);
|
PyObject* git_oid_to_python(const git_oid *oid);
|
||||||
PyObject* git_oid_to_py_str(const git_oid *oid);
|
PyObject* git_oid_to_py_str(const git_oid *oid);
|
||||||
|
73
src/pygit2.c
73
src/pygit2.c
@@ -97,6 +97,69 @@ init_repository(PyObject *self, PyObject *args) {
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PyDoc_STRVAR(clone_repository__doc__,
|
||||||
|
"clone_repository(url, path, bare, remote_name, push_url,"
|
||||||
|
"fetch_spec, push_spec, checkout_branch)\n"
|
||||||
|
"\n"
|
||||||
|
"Clones a Git repository in the given url to the given path "
|
||||||
|
"with the specified options.\n"
|
||||||
|
"\n"
|
||||||
|
"Arguments:\n"
|
||||||
|
"\n"
|
||||||
|
"url\n"
|
||||||
|
" Git repository remote url.\n"
|
||||||
|
"path\n"
|
||||||
|
" Path where to create the repository.\n"
|
||||||
|
"bare\n"
|
||||||
|
" If 'bare' is not 0, then a bare git repository will be created.\n"
|
||||||
|
"remote_name\n"
|
||||||
|
" The name given to the 'origin' remote. The default is 'origin'.\n"
|
||||||
|
"push_url\n"
|
||||||
|
" URL to be used for pushing.\n"
|
||||||
|
"fetch_spec\n"
|
||||||
|
" The fetch specification to be used for fetching. None results in "
|
||||||
|
"the same behavior as GIT_REMOTE_DEFAULT_FETCH.\n"
|
||||||
|
"push_spec\n"
|
||||||
|
" The fetch specification to be used for pushing. None means use the "
|
||||||
|
"same spec as for 'fetch_spec'\n"
|
||||||
|
"checkout_branch\n"
|
||||||
|
" The name of the branch to checkout. None means use the remote's "
|
||||||
|
"HEAD.\n");
|
||||||
|
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
clone_repository(PyObject *self, PyObject *args) {
|
||||||
|
git_repository *repo;
|
||||||
|
const char *url;
|
||||||
|
const char *path;
|
||||||
|
unsigned int bare;
|
||||||
|
const char *remote_name, *push_url, *fetch_spec;
|
||||||
|
const char *push_spec, *checkout_branch;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "zzIzzzzz",
|
||||||
|
&url, &path, &bare, &remote_name, &push_url,
|
||||||
|
&fetch_spec, &push_spec, &checkout_branch))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
git_clone_options opts = {
|
||||||
|
.version=1,
|
||||||
|
.bare=bare,
|
||||||
|
.remote_name=remote_name,
|
||||||
|
.pushurl=push_url,
|
||||||
|
.fetch_spec=fetch_spec,
|
||||||
|
.push_spec=push_spec,
|
||||||
|
.checkout_branch=checkout_branch
|
||||||
|
};
|
||||||
|
|
||||||
|
err = git_clone(&repo, url, path, &opts);
|
||||||
|
if (err < 0)
|
||||||
|
return Error_set_str(err, path);
|
||||||
|
|
||||||
|
git_repository_free(repo);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(discover_repository__doc__,
|
PyDoc_STRVAR(discover_repository__doc__,
|
||||||
"discover_repository(path[, across_fs[, ceiling_dirs]]) -> str\n"
|
"discover_repository(path[, across_fs[, ceiling_dirs]]) -> str\n"
|
||||||
@@ -124,9 +187,9 @@ discover_repository(PyObject *self, PyObject *args)
|
|||||||
};
|
};
|
||||||
|
|
||||||
PyDoc_STRVAR(hashfile__doc__,
|
PyDoc_STRVAR(hashfile__doc__,
|
||||||
"hashfile(path) -> bytes\n"
|
"hashfile(path) -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Returns the oid of a new blob from a file path without actually writing \n"
|
"Returns the oid of a new blob from a file path without actually writing\n"
|
||||||
"to the odb.");
|
"to the odb.");
|
||||||
PyObject *
|
PyObject *
|
||||||
hashfile(PyObject *self, PyObject *args)
|
hashfile(PyObject *self, PyObject *args)
|
||||||
@@ -146,9 +209,9 @@ hashfile(PyObject *self, PyObject *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(hash__doc__,
|
PyDoc_STRVAR(hash__doc__,
|
||||||
"hash(data) -> bytes\n"
|
"hash(data) -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Returns the oid of a new blob from a string without actually writing to \n"
|
"Returns the oid of a new blob from a string without actually writing to\n"
|
||||||
"the odb.");
|
"the odb.");
|
||||||
PyObject *
|
PyObject *
|
||||||
hash(PyObject *self, PyObject *args)
|
hash(PyObject *self, PyObject *args)
|
||||||
@@ -172,6 +235,8 @@ hash(PyObject *self, PyObject *args)
|
|||||||
|
|
||||||
PyMethodDef module_methods[] = {
|
PyMethodDef module_methods[] = {
|
||||||
{"init_repository", init_repository, METH_VARARGS, init_repository__doc__},
|
{"init_repository", init_repository, METH_VARARGS, init_repository__doc__},
|
||||||
|
{"clone_repository", clone_repository, METH_VARARGS,
|
||||||
|
clone_repository__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__},
|
||||||
|
@@ -107,6 +107,7 @@ PyTypeObject RefLogIterType = {
|
|||||||
void
|
void
|
||||||
Reference_dealloc(Reference *self)
|
Reference_dealloc(Reference *self)
|
||||||
{
|
{
|
||||||
|
Py_CLEAR(self->repo);
|
||||||
git_reference_free(self->reference);
|
git_reference_free(self->reference);
|
||||||
PyObject_Del(self);
|
PyObject_Del(self);
|
||||||
}
|
}
|
||||||
@@ -191,7 +192,7 @@ Reference_resolve(Reference *self, PyObject *args)
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
return Error_set(err);
|
return Error_set(err);
|
||||||
|
|
||||||
return wrap_reference(c_reference);
|
return wrap_reference(c_reference, self->repo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -226,7 +227,6 @@ Reference_target__set__(Reference *self, PyObject *py_target)
|
|||||||
git_oid oid;
|
git_oid oid;
|
||||||
char *c_name;
|
char *c_name;
|
||||||
int err;
|
int err;
|
||||||
Py_ssize_t len;
|
|
||||||
git_reference *new_ref;
|
git_reference *new_ref;
|
||||||
git_repository *repo;
|
git_repository *repo;
|
||||||
|
|
||||||
@@ -235,11 +235,9 @@ Reference_target__set__(Reference *self, PyObject *py_target)
|
|||||||
/* Case 1: Direct */
|
/* Case 1: Direct */
|
||||||
if (GIT_REF_OID == git_reference_type(self->reference)) {
|
if (GIT_REF_OID == git_reference_type(self->reference)) {
|
||||||
repo = git_reference_owner(self->reference);
|
repo = git_reference_owner(self->reference);
|
||||||
len = py_str_to_git_oid_expand(repo, py_target, &oid);
|
err = py_oid_to_git_oid_expand(repo, py_target, &oid);
|
||||||
if (len < 0) {
|
if (err < 0)
|
||||||
err = (int)len;
|
return err;
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = git_reference_set_target(&new_ref, self->reference, &oid);
|
err = git_reference_set_target(&new_ref, self->reference, &oid);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
@@ -464,13 +462,18 @@ PyTypeObject ReferenceType = {
|
|||||||
|
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
wrap_reference(git_reference * c_reference)
|
wrap_reference(git_reference * c_reference, Repository *repo)
|
||||||
{
|
{
|
||||||
Reference *py_reference=NULL;
|
Reference *py_reference=NULL;
|
||||||
|
|
||||||
py_reference = PyObject_New(Reference, &ReferenceType);
|
py_reference = PyObject_New(Reference, &ReferenceType);
|
||||||
if (py_reference)
|
if (py_reference) {
|
||||||
py_reference->reference = c_reference;
|
py_reference->reference = c_reference;
|
||||||
|
if (repo) {
|
||||||
|
py_reference->repo = repo;
|
||||||
|
Py_INCREF(repo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (PyObject *)py_reference;
|
return (PyObject *)py_reference;
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,6 @@ PyObject* Reference_get_name(Reference *self);
|
|||||||
PyObject* Reference_get_oid(Reference *self);
|
PyObject* Reference_get_oid(Reference *self);
|
||||||
PyObject* Reference_get_hex(Reference *self);
|
PyObject* Reference_get_hex(Reference *self);
|
||||||
PyObject* Reference_get_type(Reference *self);
|
PyObject* Reference_get_type(Reference *self);
|
||||||
PyObject* wrap_reference(git_reference * c_reference);
|
PyObject* wrap_reference(git_reference *c_reference, Repository *repo);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
117
src/repository.c
117
src/repository.c
@@ -65,20 +65,6 @@ int_to_loose_object_type(int type_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
|
||||||
lookup_object(Repository *repo, const git_oid *oid, git_otype type)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
git_object *obj;
|
|
||||||
|
|
||||||
err = git_object_lookup_prefix(&obj, repo->repo, oid, GIT_OID_HEXSZ,
|
|
||||||
type);
|
|
||||||
if (err < 0)
|
|
||||||
return Error_set_oid(err, oid, GIT_OID_HEXSZ);
|
|
||||||
|
|
||||||
return wrap_object(obj, repo);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
Repository_init(Repository *self, PyObject *args, PyObject *kwds)
|
Repository_init(Repository *self, PyObject *args, PyObject *kwds)
|
||||||
{
|
{
|
||||||
@@ -182,7 +168,7 @@ Repository_head__get__(Repository *self)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return wrap_reference(head);
|
return wrap_reference(head, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -268,12 +254,12 @@ PyObject *
|
|||||||
Repository_git_object_lookup_prefix(Repository *self, PyObject *key)
|
Repository_git_object_lookup_prefix(Repository *self, PyObject *key)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
Py_ssize_t len;
|
size_t len;
|
||||||
git_oid oid;
|
git_oid oid;
|
||||||
git_object *obj;
|
git_object *obj;
|
||||||
|
|
||||||
len = py_str_to_git_oid(key, &oid);
|
len = py_oid_to_git_oid(key, &oid);
|
||||||
if (len < 0)
|
if (len == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err = git_object_lookup_prefix(&obj, self->repo, &oid, len, GIT_OBJ_ANY);
|
err = git_object_lookup_prefix(&obj, self->repo, &oid, len, GIT_OBJ_ANY);
|
||||||
@@ -353,11 +339,11 @@ Repository_read(Repository *self, PyObject *py_hex)
|
|||||||
{
|
{
|
||||||
git_oid oid;
|
git_oid oid;
|
||||||
git_odb_object *obj;
|
git_odb_object *obj;
|
||||||
Py_ssize_t len;
|
size_t len;
|
||||||
PyObject* tuple;
|
PyObject* tuple;
|
||||||
|
|
||||||
len = py_str_to_git_oid(py_hex, &oid);
|
len = py_oid_to_git_oid(py_hex, &oid);
|
||||||
if (len < 0)
|
if (len == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
obj = Repository_read_raw(self->repo, &oid, len);
|
obj = Repository_read_raw(self->repo, &oid, len);
|
||||||
@@ -380,11 +366,11 @@ Repository_read(Repository *self, PyObject *py_hex)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_write__doc__,
|
PyDoc_STRVAR(Repository_write__doc__,
|
||||||
"write(type, data) -> oid\n"
|
"write(type, data) -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Write raw object data into the repository. First arg is the object type,\n"
|
"Write raw object data into the repository. First arg is the object\n"
|
||||||
"the second one a buffer with data. Return the object id (sha) of of the\n"
|
"type, the second one a buffer with data. Return the Oid of the created\n"
|
||||||
"created object.");
|
"object.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Repository_write(Repository *self, PyObject *args)
|
Repository_write(Repository *self, PyObject *args)
|
||||||
@@ -519,7 +505,7 @@ Repository_config__get__(Repository *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_merge_base__doc__,
|
PyDoc_STRVAR(Repository_merge_base__doc__,
|
||||||
"merge_base(oid, oid) -> commit\n"
|
"merge_base(oid, oid) -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Find as good common ancestors as possible for a merge.");
|
"Find as good common ancestors as possible for a merge.");
|
||||||
|
|
||||||
@@ -536,11 +522,11 @@ Repository_merge_base(Repository *self, PyObject *args)
|
|||||||
if (!PyArg_ParseTuple(args, "OO", &value1, &value2))
|
if (!PyArg_ParseTuple(args, "OO", &value1, &value2))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err = py_str_to_git_oid_expand(self->repo, value1, &oid1);
|
err = py_oid_to_git_oid_expand(self->repo, value1, &oid1);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err = py_str_to_git_oid_expand(self->repo, value2, &oid2);
|
err = py_oid_to_git_oid_expand(self->repo, value2, &oid2);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -562,7 +548,6 @@ Repository_walk(Repository *self, PyObject *args)
|
|||||||
PyObject *value;
|
PyObject *value;
|
||||||
unsigned int sort;
|
unsigned int sort;
|
||||||
int err;
|
int err;
|
||||||
Py_ssize_t len;
|
|
||||||
git_oid oid;
|
git_oid oid;
|
||||||
git_revwalk *walk;
|
git_revwalk *walk;
|
||||||
Walker *py_walker;
|
Walker *py_walker;
|
||||||
@@ -579,10 +564,10 @@ Repository_walk(Repository *self, PyObject *args)
|
|||||||
|
|
||||||
/* Push */
|
/* Push */
|
||||||
if (value != Py_None) {
|
if (value != Py_None) {
|
||||||
len = py_str_to_git_oid_expand(self->repo, value, &oid);
|
err = py_oid_to_git_oid_expand(self->repo, value, &oid);
|
||||||
if (len < 0) {
|
if (err < 0) {
|
||||||
git_revwalk_free(walk);
|
git_revwalk_free(walk);
|
||||||
return Error_set((int)len);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = git_revwalk_push(walk, &oid);
|
err = git_revwalk_push(walk, &oid);
|
||||||
@@ -606,9 +591,10 @@ Repository_walk(Repository *self, PyObject *args)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_create_blob__doc__,
|
PyDoc_STRVAR(Repository_create_blob__doc__,
|
||||||
"create_blob(data) -> bytes\n"
|
"create_blob(data) -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Create a new blob from memory.");
|
"Create a new blob from a bytes string. The blob is added to the Git\n"
|
||||||
|
"object database. Returns the oid of the blob.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Repository_create_blob(Repository *self, PyObject *args)
|
Repository_create_blob(Repository *self, PyObject *args)
|
||||||
@@ -630,9 +616,11 @@ Repository_create_blob(Repository *self, PyObject *args)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_create_blob_fromworkdir__doc__,
|
PyDoc_STRVAR(Repository_create_blob_fromworkdir__doc__,
|
||||||
"create_blob_fromworkdir(path) -> bytes\n"
|
"create_blob_fromworkdir(path) -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Create a new blob from a file within the working directory (raise an error otherwise).");
|
"Create a new blob from a file within the working directory. The given\n"
|
||||||
|
"path must be relative to the working directory, if it is not an error\n"
|
||||||
|
"is raised.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Repository_create_blob_fromworkdir(Repository *self, PyObject *args)
|
Repository_create_blob_fromworkdir(Repository *self, PyObject *args)
|
||||||
@@ -653,7 +641,7 @@ Repository_create_blob_fromworkdir(Repository *self, PyObject *args)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_create_blob_fromdisk__doc__,
|
PyDoc_STRVAR(Repository_create_blob_fromdisk__doc__,
|
||||||
"create_blob_fromdisk(path) -> bytes\n"
|
"create_blob_fromdisk(path) -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Create a new blob from a file anywhere (no working directory check).");
|
"Create a new blob from a file anywhere (no working directory check).");
|
||||||
|
|
||||||
@@ -676,9 +664,9 @@ Repository_create_blob_fromdisk(Repository *self, PyObject *args)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_create_commit__doc__,
|
PyDoc_STRVAR(Repository_create_commit__doc__,
|
||||||
"create_commit(reference, author, committer, message, tree, parents[, encoding]) -> bytes\n"
|
"create_commit(reference, author, committer, message, tree, parents[, encoding]) -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Create a new commit object, return its SHA.");
|
"Create a new commit object, return its oid.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Repository_create_commit(Repository *self, PyObject *args)
|
Repository_create_commit(Repository *self, PyObject *args)
|
||||||
@@ -694,7 +682,7 @@ Repository_create_commit(Repository *self, PyObject *args)
|
|||||||
int parent_count;
|
int parent_count;
|
||||||
git_commit **parents = NULL;
|
git_commit **parents = NULL;
|
||||||
int err = 0, i = 0;
|
int err = 0, i = 0;
|
||||||
Py_ssize_t len;
|
size_t len;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "zO!O!OOO!|s",
|
if (!PyArg_ParseTuple(args, "zO!O!OOO!|s",
|
||||||
&update_ref,
|
&update_ref,
|
||||||
@@ -706,8 +694,8 @@ Repository_create_commit(Repository *self, PyObject *args)
|
|||||||
&encoding))
|
&encoding))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
len = py_str_to_git_oid(py_oid, &oid);
|
len = py_oid_to_git_oid(py_oid, &oid);
|
||||||
if (len < 0)
|
if (len == 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
message = py_str_to_c_str(py_message, encoding);
|
message = py_str_to_c_str(py_message, encoding);
|
||||||
@@ -728,13 +716,15 @@ Repository_create_commit(Repository *self, PyObject *args)
|
|||||||
}
|
}
|
||||||
for (; i < parent_count; i++) {
|
for (; i < parent_count; i++) {
|
||||||
py_parent = PyList_GET_ITEM(py_parents, i);
|
py_parent = PyList_GET_ITEM(py_parents, i);
|
||||||
len = py_str_to_git_oid(py_parent, &oid);
|
len = py_oid_to_git_oid(py_parent, &oid);
|
||||||
if (len < 0)
|
if (len == 0)
|
||||||
goto out;
|
goto out;
|
||||||
if (git_commit_lookup_prefix(&parents[i], self->repo, &oid,
|
err = git_commit_lookup_prefix(&parents[i], self->repo, &oid, len);
|
||||||
(unsigned int)len))
|
if (err < 0) {
|
||||||
|
Error_set(err);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = git_commit_create(&oid, self->repo, update_ref,
|
err = git_commit_create(&oid, self->repo, update_ref,
|
||||||
py_author->signature, py_committer->signature,
|
py_author->signature, py_committer->signature,
|
||||||
@@ -760,9 +750,9 @@ out:
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_create_tag__doc__,
|
PyDoc_STRVAR(Repository_create_tag__doc__,
|
||||||
"create_tag(name, oid, type, tagger, message) -> bytes\n"
|
"create_tag(name, oid, type, tagger, message) -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Create a new tag object, return its SHA.");
|
"Create a new tag object, return its oid.");
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
Repository_create_tag(Repository *self, PyObject *args)
|
Repository_create_tag(Repository *self, PyObject *args)
|
||||||
@@ -773,7 +763,7 @@ Repository_create_tag(Repository *self, PyObject *args)
|
|||||||
git_oid oid;
|
git_oid oid;
|
||||||
git_object *target = NULL;
|
git_object *target = NULL;
|
||||||
int err, target_type;
|
int err, target_type;
|
||||||
Py_ssize_t len;
|
size_t len;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "sOiO!s",
|
if (!PyArg_ParseTuple(args, "sOiO!s",
|
||||||
&tag_name,
|
&tag_name,
|
||||||
@@ -783,12 +773,12 @@ Repository_create_tag(Repository *self, PyObject *args)
|
|||||||
&message))
|
&message))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
len = py_str_to_git_oid(py_oid, &oid);
|
len = py_oid_to_git_oid(py_oid, &oid);
|
||||||
if (len < 0)
|
if (len == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err = git_object_lookup_prefix(&target, self->repo, &oid,
|
err = git_object_lookup_prefix(&target, self->repo, &oid, len,
|
||||||
(unsigned int)len, target_type);
|
target_type);
|
||||||
err = err < 0 ? err : git_tag_create(&oid, self->repo, tag_name, target,
|
err = err < 0 ? err : git_tag_create(&oid, self->repo, tag_name, target,
|
||||||
py_tagger->signature, message, 0);
|
py_tagger->signature, message, 0);
|
||||||
git_object_free(target);
|
git_object_free(target);
|
||||||
@@ -869,7 +859,7 @@ Repository_lookup_reference(Repository *self, PyObject *py_name)
|
|||||||
free(c_name);
|
free(c_name);
|
||||||
|
|
||||||
/* 3- Make an instance of Reference and return it */
|
/* 3- Make an instance of Reference and return it */
|
||||||
return wrap_reference(c_reference);
|
return wrap_reference(c_reference, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_create_reference_direct__doc__,
|
PyDoc_STRVAR(Repository_create_reference_direct__doc__,
|
||||||
@@ -896,20 +886,19 @@ Repository_create_reference_direct(Repository *self, PyObject *args,
|
|||||||
char *c_name;
|
char *c_name;
|
||||||
git_oid oid;
|
git_oid oid;
|
||||||
int err, force;
|
int err, force;
|
||||||
Py_ssize_t len;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "sOi", &c_name, &py_obj, &force))
|
if (!PyArg_ParseTuple(args, "sOi", &c_name, &py_obj, &force))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
len = py_str_to_git_oid_expand(self->repo, py_obj, &oid);
|
err = py_oid_to_git_oid_expand(self->repo, py_obj, &oid);
|
||||||
if (len < 0)
|
if (err < 0)
|
||||||
return Error_set((int)len);
|
return NULL;
|
||||||
|
|
||||||
err = git_reference_create(&c_reference, self->repo, c_name, &oid, force);
|
err = git_reference_create(&c_reference, self->repo, c_name, &oid, force);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return Error_set(err);
|
return Error_set(err);
|
||||||
|
|
||||||
return wrap_reference(c_reference);
|
return wrap_reference(c_reference, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_create_reference_symbolic__doc__,
|
PyDoc_STRVAR(Repository_create_reference_symbolic__doc__,
|
||||||
@@ -943,7 +932,7 @@ Repository_create_reference_symbolic(Repository *self, PyObject *args,
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
return Error_set(err);
|
return Error_set(err);
|
||||||
|
|
||||||
return wrap_reference(c_reference);
|
return wrap_reference(c_reference, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1024,7 +1013,6 @@ Repository_TreeBuilder(Repository *self, PyObject *args)
|
|||||||
git_tree *tree = NULL;
|
git_tree *tree = NULL;
|
||||||
git_tree *must_free = NULL;
|
git_tree *must_free = NULL;
|
||||||
int err;
|
int err;
|
||||||
Py_ssize_t len;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "|O", &py_src))
|
if (!PyArg_ParseTuple(args, "|O", &py_src))
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1038,8 +1026,8 @@ Repository_TreeBuilder(Repository *self, PyObject *args)
|
|||||||
}
|
}
|
||||||
tree = py_tree->tree;
|
tree = py_tree->tree;
|
||||||
} else {
|
} else {
|
||||||
len = py_str_to_git_oid_expand(self->repo, py_src, &oid);
|
err = py_oid_to_git_oid_expand(self->repo, py_src, &oid);
|
||||||
if (len < 0)
|
if (err < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err = git_tree_lookup(&tree, self->repo, &oid);
|
err = git_tree_lookup(&tree, self->repo, &oid);
|
||||||
@@ -1220,12 +1208,11 @@ Repository_notes(Repository *self, PyObject *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Error_set(err);
|
return Error_set(err);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(Repository_create_note__doc__,
|
PyDoc_STRVAR(Repository_create_note__doc__,
|
||||||
"create_note(message, author, committer, annotated_id [,ref, force]) -> ID\n"
|
"create_note(message, author, committer, annotated_id [,ref, force]) -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Create a new note for an object, return its SHA-ID."
|
"Create a new note for an object, return its SHA-ID."
|
||||||
"If no ref is given 'refs/notes/commits' will be used.");
|
"If no ref is given 'refs/notes/commits' will be used.");
|
||||||
|
@@ -290,7 +290,7 @@ Tree_diff_to_workdir(Tree *self, PyObject *args)
|
|||||||
if (!PyArg_ParseTuple(args, "|i", &opts.flags))
|
if (!PyArg_ParseTuple(args, "|i", &opts.flags))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
repo = self->repo->repo;
|
repo = git_tree_owner(self->tree);
|
||||||
err = git_diff_tree_to_workdir(&diff, repo, self->tree, &opts);
|
err = git_diff_tree_to_workdir(&diff, repo, self->tree, &opts);
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
@@ -321,7 +321,7 @@ Tree_diff_to_index(Tree *self, PyObject *args, PyObject *kwds)
|
|||||||
if (!PyArg_ParseTuple(args, "O!|i", &IndexType, &py_idx, &opts.flags))
|
if (!PyArg_ParseTuple(args, "O!|i", &IndexType, &py_idx, &opts.flags))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
repo = self->repo->repo;
|
repo = git_tree_owner(self->tree);
|
||||||
err = git_diff_tree_to_index(&diff, repo, self->tree, py_idx->index, &opts);
|
err = git_diff_tree_to_index(&diff, repo, self->tree, py_idx->index, &opts);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return Error_set(err);
|
return Error_set(err);
|
||||||
@@ -354,7 +354,7 @@ Tree_diff_to_tree(Tree *self, PyObject *args, PyObject *kwds)
|
|||||||
&swap))
|
&swap))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
repo = self->repo->repo;
|
repo = git_tree_owner(self->tree);
|
||||||
to = (py_tree == NULL) ? NULL : py_tree->tree;
|
to = (py_tree == NULL) ? NULL : py_tree->tree;
|
||||||
from = self->tree;
|
from = self->tree;
|
||||||
if (swap > 0) {
|
if (swap > 0) {
|
||||||
|
@@ -53,7 +53,7 @@ PyObject *
|
|||||||
TreeBuilder_insert(TreeBuilder *self, PyObject *args)
|
TreeBuilder_insert(TreeBuilder *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *py_oid;
|
PyObject *py_oid;
|
||||||
Py_ssize_t len;
|
size_t len;
|
||||||
int err, attr;
|
int err, attr;
|
||||||
git_oid oid;
|
git_oid oid;
|
||||||
const char *fname;
|
const char *fname;
|
||||||
@@ -61,8 +61,8 @@ TreeBuilder_insert(TreeBuilder *self, PyObject *args)
|
|||||||
if (!PyArg_ParseTuple(args, "sOi", &fname, &py_oid, &attr))
|
if (!PyArg_ParseTuple(args, "sOi", &fname, &py_oid, &attr))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
len = py_str_to_git_oid(py_oid, &oid);
|
len = py_oid_to_git_oid(py_oid, &oid);
|
||||||
if (len < 0)
|
if (len == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
err = git_treebuilder_insert(NULL, self->bld, fname, &oid, attr);
|
err = git_treebuilder_insert(NULL, self->bld, fname, &oid, attr);
|
||||||
@@ -74,7 +74,7 @@ TreeBuilder_insert(TreeBuilder *self, PyObject *args)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(TreeBuilder_write__doc__,
|
PyDoc_STRVAR(TreeBuilder_write__doc__,
|
||||||
"write() -> bytes\n"
|
"write() -> Oid\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Write the tree to the given repository.");
|
"Write the tree to the given repository.");
|
||||||
|
|
||||||
|
@@ -158,10 +158,7 @@ typedef struct {
|
|||||||
/* git_reference, git_reflog */
|
/* git_reference, git_reflog */
|
||||||
SIMPLE_TYPE(Walker, git_revwalk, walk)
|
SIMPLE_TYPE(Walker, git_revwalk, walk)
|
||||||
|
|
||||||
typedef struct {
|
SIMPLE_TYPE(Reference, git_reference, reference)
|
||||||
PyObject_HEAD
|
|
||||||
git_reference *reference;
|
|
||||||
} Reference;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
@@ -192,6 +189,4 @@ typedef struct {
|
|||||||
SIMPLE_TYPE(Remote, git_remote, remote)
|
SIMPLE_TYPE(Remote, git_remote, remote)
|
||||||
|
|
||||||
|
|
||||||
PyObject* lookup_object(Repository *repo, const git_oid *oid, git_otype type);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -79,7 +79,8 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Utilities */
|
/* Utilities */
|
||||||
#define to_unicode(x, encoding, errors) to_unicode_n(x, strlen(x), encoding, errors)
|
#define to_unicode(x, encoding, errors)\
|
||||||
|
to_unicode_n(x, strlen(x), encoding, errors)
|
||||||
|
|
||||||
PYGIT2_FN_UNUSED
|
PYGIT2_FN_UNUSED
|
||||||
Py_LOCAL_INLINE(PyObject*)
|
Py_LOCAL_INLINE(PyObject*)
|
||||||
@@ -150,8 +151,8 @@ char * py_str_to_c_str(PyObject *value, const char *encoding);
|
|||||||
|
|
||||||
/* Helpers to make type init shorter. */
|
/* Helpers to make type init shorter. */
|
||||||
#define INIT_TYPE(type, base, new) \
|
#define INIT_TYPE(type, base, new) \
|
||||||
if (base != NULL) type.tp_base = base; \
|
type.tp_base = base; \
|
||||||
if (new != NULL) type.tp_new = new; \
|
type.tp_new = new; \
|
||||||
if (PyType_Ready(&type) < 0) return NULL;
|
if (PyType_Ready(&type) < 0) return NULL;
|
||||||
|
|
||||||
#define ADD_TYPE(module, type) \
|
#define ADD_TYPE(module, type) \
|
||||||
|
14
src/walker.c
14
src/walker.c
@@ -53,12 +53,11 @@ PyObject *
|
|||||||
Walker_hide(Walker *self, PyObject *py_hex)
|
Walker_hide(Walker *self, PyObject *py_hex)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
Py_ssize_t len;
|
|
||||||
git_oid oid;
|
git_oid oid;
|
||||||
|
|
||||||
len = py_str_to_git_oid_expand(self->repo->repo, py_hex, &oid);
|
err = py_oid_to_git_oid_expand(self->repo->repo, py_hex, &oid);
|
||||||
if (len < 0)
|
if (err < 0)
|
||||||
return Error_set((int)len);
|
return NULL;
|
||||||
|
|
||||||
err = git_revwalk_hide(self->walk, &oid);
|
err = git_revwalk_hide(self->walk, &oid);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
@@ -77,12 +76,11 @@ PyObject *
|
|||||||
Walker_push(Walker *self, PyObject *py_hex)
|
Walker_push(Walker *self, PyObject *py_hex)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
Py_ssize_t len;
|
|
||||||
git_oid oid;
|
git_oid oid;
|
||||||
|
|
||||||
len = py_str_to_git_oid_expand(self->repo->repo, py_hex, &oid);
|
err = py_oid_to_git_oid_expand(self->repo->repo, py_hex, &oid);
|
||||||
if (len < 0)
|
if (err < 0)
|
||||||
return Error_set((int)len);
|
return NULL;
|
||||||
|
|
||||||
err = git_revwalk_push(self->walk, &oid);
|
err = git_revwalk_push(self->walk, &oid);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@@ -40,7 +40,10 @@ from os.path import join, realpath
|
|||||||
|
|
||||||
# Import from pygit2
|
# Import from pygit2
|
||||||
from pygit2 import GIT_OBJ_ANY, GIT_OBJ_BLOB, GIT_OBJ_COMMIT
|
from pygit2 import GIT_OBJ_ANY, GIT_OBJ_BLOB, GIT_OBJ_COMMIT
|
||||||
from pygit2 import init_repository, discover_repository, Reference, hashfile
|
from pygit2 import (
|
||||||
|
init_repository, clone_repository, discover_repository,
|
||||||
|
Reference, hashfile
|
||||||
|
)
|
||||||
from pygit2 import Oid
|
from pygit2 import Oid
|
||||||
import pygit2
|
import pygit2
|
||||||
from . import utils
|
from . import utils
|
||||||
@@ -101,7 +104,7 @@ class RepositoryTest(utils.BareRepoTestCase):
|
|||||||
self.assertFalse('a' * 20 in self.repo)
|
self.assertFalse('a' * 20 in self.repo)
|
||||||
|
|
||||||
def test_iterable(self):
|
def test_iterable(self):
|
||||||
l = [ obj for obj in self.repo ]
|
l = [obj for obj in self.repo]
|
||||||
oid = Oid(hex=BLOB_HEX)
|
oid = Oid(hex=BLOB_HEX)
|
||||||
self.assertTrue(oid in l)
|
self.assertTrue(oid in l)
|
||||||
|
|
||||||
@@ -135,7 +138,8 @@ class RepositoryTest(utils.BareRepoTestCase):
|
|||||||
commit = self.repo[commit_sha_prefix]
|
commit = self.repo[commit_sha_prefix]
|
||||||
self.assertEqual(commit_sha, commit.hex)
|
self.assertEqual(commit_sha, commit.hex)
|
||||||
self.assertEqual(GIT_OBJ_COMMIT, commit.type)
|
self.assertEqual(GIT_OBJ_COMMIT, commit.type)
|
||||||
self.assertEqual(('Second test data commit.\n\n'
|
self.assertEqual(
|
||||||
|
('Second test data commit.\n\n'
|
||||||
'This commit has some additional text.\n'),
|
'This commit has some additional text.\n'),
|
||||||
commit.message)
|
commit.message)
|
||||||
self.assertRaises(ValueError, self.repo.__getitem__, too_short_prefix)
|
self.assertRaises(ValueError, self.repo.__getitem__, too_short_prefix)
|
||||||
@@ -272,6 +276,7 @@ class InitRepositoryTest(utils.NoRepoTestCase):
|
|||||||
repo = init_repository(self._temp_dir, bare=True)
|
repo = init_repository(self._temp_dir, bare=True)
|
||||||
self.assertTrue(repo.is_bare)
|
self.assertTrue(repo.is_bare)
|
||||||
|
|
||||||
|
|
||||||
class DiscoverRepositoryTest(utils.NoRepoTestCase):
|
class DiscoverRepositoryTest(utils.NoRepoTestCase):
|
||||||
def test_discover_repo(self):
|
def test_discover_repo(self):
|
||||||
repo = init_repository(self._temp_dir, False)
|
repo = init_repository(self._temp_dir, False)
|
||||||
@@ -279,6 +284,7 @@ class DiscoverRepositoryTest(utils.NoRepoTestCase):
|
|||||||
os.makedirs(subdir)
|
os.makedirs(subdir)
|
||||||
self.assertEqual(repo.path, discover_repository(subdir))
|
self.assertEqual(repo.path, discover_repository(subdir))
|
||||||
|
|
||||||
|
|
||||||
class EmptyRepositoryTest(utils.EmptyRepoTestCase):
|
class EmptyRepositoryTest(utils.EmptyRepoTestCase):
|
||||||
|
|
||||||
def test_is_empty(self):
|
def test_is_empty(self):
|
||||||
@@ -292,5 +298,69 @@ class EmptyRepositoryTest(utils.EmptyRepoTestCase):
|
|||||||
self.assertFalse(self.repo.head_is_detached)
|
self.assertFalse(self.repo.head_is_detached)
|
||||||
|
|
||||||
|
|
||||||
|
class CloneRepositoryTest(utils.NoRepoTestCase):
|
||||||
|
def test_clone_repository(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(repo_path, self._temp_dir)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
self.assertFalse(repo.is_bare)
|
||||||
|
|
||||||
|
def test_clone_bare_repository(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(repo_path, self._temp_dir, bare=True)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
self.assertTrue(repo.is_bare)
|
||||||
|
|
||||||
|
def test_clone_remote_name(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(
|
||||||
|
repo_path, self._temp_dir, remote_name="custom_remote"
|
||||||
|
)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
self.assertEqual(repo.remotes[0].name, "custom_remote")
|
||||||
|
|
||||||
|
def test_clone_push_url(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(
|
||||||
|
repo_path, self._temp_dir, push_url="custom_push_url"
|
||||||
|
)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
# FIXME: When pygit2 supports retrieving the pushurl parameter,
|
||||||
|
# enable this test
|
||||||
|
# self.assertEqual(repo.remotes[0].pushurl, "custom_push_url")
|
||||||
|
|
||||||
|
def test_clone_fetch_spec(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(
|
||||||
|
repo_path, self._temp_dir, fetch_spec="refs/heads/test"
|
||||||
|
)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
# FIXME: When pygit2 retrieve the fetchspec we passed to git clone.
|
||||||
|
# fetchspec seems to be going through, but the Repository class is
|
||||||
|
# not getting it.
|
||||||
|
# self.assertEqual(repo.remotes[0].fetchspec, "refs/heads/test")
|
||||||
|
|
||||||
|
def test_clone_push_spec(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(
|
||||||
|
repo_path, self._temp_dir, push_spec="refs/heads/test"
|
||||||
|
)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
# FIXME: When pygit2 supports retrieving the pushspec parameter,
|
||||||
|
# enable this test
|
||||||
|
# not sure how to test this either... couldn't find pushspec
|
||||||
|
# self.assertEqual(repo.remotes[0].fetchspec, "refs/heads/test")
|
||||||
|
|
||||||
|
def test_clone_checkout_branch(self):
|
||||||
|
repo_path = "./test/data/testrepo.git/"
|
||||||
|
repo = clone_repository(
|
||||||
|
repo_path, self._temp_dir, checkout_branch="test"
|
||||||
|
)
|
||||||
|
self.assertFalse(repo.is_empty)
|
||||||
|
# FIXME: When pygit2 supports retrieving the current branch,
|
||||||
|
# enable this test
|
||||||
|
# self.assertEqual(repo.remotes[0].current_branch, "test")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Reference in New Issue
Block a user