docs: review, in progress
This commit is contained in:
parent
d6c1d49ef6
commit
101715bf37
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:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:maxdepth: 1
|
||||
|
||||
install
|
||||
|
||||
Usage guide:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:maxdepth: 1
|
||||
|
||||
general
|
||||
repository
|
||||
oid
|
||||
objects
|
||||
references
|
||||
revparse
|
||||
log
|
||||
working-copy
|
||||
diff
|
||||
merge
|
||||
config
|
||||
remotes
|
||||
errors
|
||||
|
||||
More:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
utils
|
||||
|
||||
|
||||
Indices and tables
|
||||
|
@ -1,8 +1,5 @@
|
||||
**********************************************************************
|
||||
Errors
|
||||
Merge
|
||||
**********************************************************************
|
||||
|
||||
.. autoexception:: pygit2.GitError
|
||||
:members:
|
||||
:show-inheritance:
|
||||
:undoc-members:
|
||||
.. automethod:: pygit2.Repository.merge_base
|
226
docs/objects.rst
226
docs/objects.rst
@ -2,91 +2,46 @@
|
||||
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
|
||||
: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
|
||||
=================
|
||||
|
||||
The oid is the `SHA-1 <http://en.wikipedia.org/wiki/SHA-1>`_ hash of an
|
||||
object. It is 20 bytes long:
|
||||
|
||||
- When we represent an oid as a 20 bytes Python string, we say it is a raw
|
||||
oid.
|
||||
|
||||
- When we represent an oid as a 40 chars Python string, we sayt it is a hex
|
||||
oid.
|
||||
|
||||
However, most of the time we will use the Oid type. We can explicetly create
|
||||
an Oid object from its raw or hexadecimal form::
|
||||
|
||||
>>> hex = "cff3ceaefc955f0dbe1957017db181bc49913781"
|
||||
>>> oid1 = Oid(hex=hex)
|
||||
|
||||
>>> from binascii import unhexlify
|
||||
>>> raw = unhexlify(hex)
|
||||
>>> oid2 = Oid(raw=raw)
|
||||
|
||||
>>> print oid1 == oid2
|
||||
True
|
||||
|
||||
And in the opposite direction, we can get the raw or hexadecimal form from
|
||||
an Oid object:
|
||||
|
||||
.. autoattribute:: pygit2.Oid.raw
|
||||
.. autoattribute:: pygit2.Oid.hex
|
||||
|
||||
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
|
||||
|
||||
|
||||
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::
|
||||
The Object type is a base type, it is not possible to make instances of it, in
|
||||
any way.
|
||||
|
||||
>>> # Show commits and trees
|
||||
>>> commit
|
||||
<pygit2.Commit object at 0x7f9d2f3000b0>
|
||||
>>> commit.tree
|
||||
<pygit2.Tree object at 0x7f9d2f3000f0>
|
||||
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::
|
||||
|
||||
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::
|
||||
>>> from pygit2 import Object
|
||||
>>> commit = repository.revparse_single('HEAD')
|
||||
>>> print isinstance(commit, Object)
|
||||
True
|
||||
|
||||
>>> commit.oid
|
||||
b'x\xde\xb5W\x8d\x01<\xdb\xdf\x08o\xa1\xd1\xa3\xe7\xd9\x82\xe8\x88\x8f'
|
||||
>>> commit.hex
|
||||
'78deb5578d013cdbdf086fa1d1a3e7d982e8888f'
|
||||
All Objects are immutable, they cannot be modified once they are created::
|
||||
|
||||
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).
|
||||
>>> commit.message = u"foobar"
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
AttributeError: attribute 'message' of '_pygit2.Commit' objects is not writable
|
||||
|
||||
Objects can not be modified once they have been created.
|
||||
Derived types (blobs, trees, etc.) don't have a constructor, this means they
|
||||
cannot be created with the common idiom::
|
||||
|
||||
>>> from pygit2 import Blob
|
||||
>>> blob = Blob("data")
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in <module>
|
||||
TypeError: cannot create '_pygit2.Blob' instances
|
||||
|
||||
New objects are created using an specific API we will see later.
|
||||
|
||||
This is the common interface for all Git objects:
|
||||
|
||||
@ -96,55 +51,38 @@ This is the common interface for all Git objects:
|
||||
.. automethod:: pygit2.Object.read_raw
|
||||
|
||||
|
||||
Commits
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Blobs
|
||||
=================
|
||||
|
||||
A commit is a snapshot of the working dir with meta informations like author,
|
||||
committer and others.
|
||||
A blob is equivalent to a file in a file system.::
|
||||
|
||||
.. autoattribute:: pygit2.Commit.author
|
||||
.. autoattribute:: pygit2.Commit.committer
|
||||
.. autoattribute:: pygit2.Commit.message
|
||||
.. autoattribute:: pygit2.Commit.message_encoding
|
||||
.. autoattribute:: pygit2.Commit.tree
|
||||
.. autoattribute:: pygit2.Commit.parents
|
||||
.. autoattribute:: pygit2.Commit.commit_time
|
||||
.. autoattribute:: pygit2.Commit.commit_time_offset
|
||||
>>> # 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
|
||||
|
||||
Signatures
|
||||
-------------
|
||||
To create new blobs use the Repository API:
|
||||
|
||||
The author and committer attributes of commit objects are ``Signature``
|
||||
objects::
|
||||
.. automethod:: pygit2.Repository.create_blob
|
||||
.. automethod:: pygit2.Repository.create_blob_fromworkdir
|
||||
.. automethod:: pygit2.Repository.create_blob_fromdisk
|
||||
|
||||
>>> commit.author
|
||||
<pygit2.Signature object at 0x7f75e9b1f5f8>
|
||||
It is also possible to get the oid for a blob without really adding it to
|
||||
the Git object database:
|
||||
|
||||
.. autoattribute:: pygit2.Signature.name
|
||||
.. autoattribute:: pygit2.Signature.email
|
||||
.. autoattribute:: pygit2.Signature.time
|
||||
.. autoattribute:: pygit2.Signature.offset
|
||||
|
||||
|
||||
Creating commits
|
||||
----------------
|
||||
|
||||
.. automethod:: pygit2.Repository.create_commit
|
||||
|
||||
Commits can be created by calling the ``create_commit`` method of the
|
||||
repository with the following parameters::
|
||||
|
||||
>>> author = Signature('Alice Author', 'alice@authors.tld')
|
||||
>>> committer = Signature('Cecil Committer', 'cecil@committers.tld')
|
||||
>>> tree = repo.TreeBuilder().write()
|
||||
>>> repo.create_commit(
|
||||
... 'refs/heads/master', # the name of the reference to update
|
||||
... author, committer, 'one line commit message\n\ndetailed commit message',
|
||||
... tree, # binary string representing the tree object ID
|
||||
... [] # list of binary strings representing parents of the new commit
|
||||
... )
|
||||
'#\xe4<u\xfe\xd6\x17\xa0\xe6\xa2\x8b\xb6\xdc35$\xcf-\x8b~'
|
||||
.. autofunction:: pygit2.hash
|
||||
.. autofunction:: pygit2.hashfile
|
||||
|
||||
|
||||
Trees
|
||||
@ -200,28 +138,56 @@ Creating trees
|
||||
.. automethod:: pygit2.TreeBuilder.write
|
||||
|
||||
|
||||
Blobs
|
||||
Commits
|
||||
=================
|
||||
|
||||
A blob is equivalent to a file in a file system.::
|
||||
A commit is a snapshot of the working dir with meta informations like author,
|
||||
committer and others.
|
||||
|
||||
>>> # 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.Commit.author
|
||||
.. autoattribute:: pygit2.Commit.committer
|
||||
.. autoattribute:: pygit2.Commit.message
|
||||
.. autoattribute:: pygit2.Commit.message_encoding
|
||||
.. autoattribute:: pygit2.Commit.tree
|
||||
.. autoattribute:: pygit2.Commit.parents
|
||||
.. autoattribute:: pygit2.Commit.commit_time
|
||||
.. autoattribute:: pygit2.Commit.commit_time_offset
|
||||
|
||||
.. autoattribute:: pygit2.Blob.data
|
||||
.. autoattribute:: pygit2.Blob.size
|
||||
|
||||
Creating blobs
|
||||
--------------------
|
||||
Signatures
|
||||
-------------
|
||||
|
||||
The author and committer attributes of commit objects are ``Signature``
|
||||
objects::
|
||||
|
||||
>>> commit.author
|
||||
<pygit2.Signature object at 0x7f75e9b1f5f8>
|
||||
|
||||
.. autoattribute:: pygit2.Signature.name
|
||||
.. autoattribute:: pygit2.Signature.email
|
||||
.. autoattribute:: pygit2.Signature.time
|
||||
.. autoattribute:: pygit2.Signature.offset
|
||||
|
||||
|
||||
Creating commits
|
||||
----------------
|
||||
|
||||
.. automethod:: pygit2.Repository.create_commit
|
||||
|
||||
Commits can be created by calling the ``create_commit`` method of the
|
||||
repository with the following parameters::
|
||||
|
||||
>>> author = Signature('Alice Author', 'alice@authors.tld')
|
||||
>>> committer = Signature('Cecil Committer', 'cecil@committers.tld')
|
||||
>>> tree = repo.TreeBuilder().write()
|
||||
>>> repo.create_commit(
|
||||
... 'refs/heads/master', # the name of the reference to update
|
||||
... author, committer, 'one line commit message\n\ndetailed commit message',
|
||||
... tree, # binary string representing the tree object ID
|
||||
... [] # list of binary strings representing parents of the new commit
|
||||
... )
|
||||
'#\xe4<u\xfe\xd6\x17\xa0\xe6\xa2\x8b\xb6\xdc35$\xcf-\x8b~'
|
||||
|
||||
.. automethod:: pygit2.Repository.create_blob
|
||||
.. automethod:: pygit2.Repository.create_blob_fromworkdir
|
||||
.. automethod:: pygit2.Repository.create_blob_fromdisk
|
||||
|
||||
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,51 @@ The repository
|
||||
Everything starts either by creating a new repository, or by opening an
|
||||
existing one.
|
||||
|
||||
.. contents:: Contents
|
||||
:local:
|
||||
|
||||
|
||||
Creating a repository
|
||||
===================================
|
||||
|
||||
.. autofunction:: pygit2.init_repository
|
||||
|
||||
This is how to create non-bare repository::
|
||||
Example::
|
||||
|
||||
>>> from pygit2 import init_repository
|
||||
>>> repo = init_repository('test')
|
||||
|
||||
And this is how to create a bare repository::
|
||||
|
||||
>>> from pygit2 import init_repository
|
||||
>>> repo = init_repository('test', bare=True)
|
||||
|
||||
But one can also do::
|
||||
|
||||
>>> from pygit2 import init_repository
|
||||
>>> repo = init_repository('test', True)
|
||||
>>> repo = init_repository('test') # Creates a non-bare repository
|
||||
>>> repo = init_repository('test', bare=True) # Creates a bare repository
|
||||
|
||||
|
||||
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
|
||||
>>> 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.workdir
|
||||
.. autoattribute:: pygit2.Repository.is_bare
|
||||
.. autoattribute:: pygit2.Repository.is_empty
|
||||
.. automethod:: pygit2.Repository.read
|
||||
.. automethod:: pygit2.Repository.write
|
||||
.. automethod:: pygit2.Repository.merge_base
|
||||
|
||||
|
||||
Utilities
|
||||
=========
|
||||
|
||||
.. autofunction:: pygit2.discover_repository
|
||||
|
@ -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,10 @@ import pygit2.utils
|
||||
|
||||
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:
|
||||
|
||||
path
|
||||
Path where to create the repository.
|
||||
|
||||
bare
|
||||
Whether the repository will be bare or not.
|
||||
If *bare* is True the repository will be bare, i.e. it will not have a
|
||||
working copy.
|
||||
"""
|
||||
_pygit2.init_repository(path, bare)
|
||||
return Repository(path)
|
||||
|
@ -50,7 +50,7 @@ Object_dealloc(Object* self)
|
||||
|
||||
|
||||
PyDoc_STRVAR(Object_oid__doc__,
|
||||
"The object id, a byte string 20 bytes long.");
|
||||
"The object id, an instance of the Oid type.");
|
||||
|
||||
PyObject *
|
||||
Object_oid__get__(Object *self)
|
||||
@ -65,7 +65,8 @@ Object_oid__get__(Object *self)
|
||||
|
||||
|
||||
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 *
|
||||
Object_hex__get__(Object *self)
|
||||
@ -91,6 +92,8 @@ Object_type__get__(Object *self)
|
||||
|
||||
|
||||
PyDoc_STRVAR(Object_read_raw__doc__,
|
||||
"read_raw()\n"
|
||||
"\n"
|
||||
"Returns the byte string with the raw contents of the of the object.");
|
||||
|
||||
PyObject *
|
||||
|
@ -253,7 +253,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 *
|
||||
Oid_raw__get__(Oid *self)
|
||||
@ -262,7 +262,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 *
|
||||
Oid_hex__get__(Oid *self)
|
||||
|
@ -124,9 +124,9 @@ discover_repository(PyObject *self, PyObject *args)
|
||||
};
|
||||
|
||||
PyDoc_STRVAR(hashfile__doc__,
|
||||
"hashfile(path) -> bytes\n"
|
||||
"hashfile(path) -> Oid\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.");
|
||||
PyObject *
|
||||
hashfile(PyObject *self, PyObject *args)
|
||||
@ -146,9 +146,9 @@ hashfile(PyObject *self, PyObject *args)
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(hash__doc__,
|
||||
"hash(data) -> bytes\n"
|
||||
"hash(data) -> Oid\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.");
|
||||
PyObject *
|
||||
hash(PyObject *self, PyObject *args)
|
||||
|
@ -366,11 +366,11 @@ Repository_read(Repository *self, PyObject *py_hex)
|
||||
|
||||
|
||||
PyDoc_STRVAR(Repository_write__doc__,
|
||||
"write(type, data) -> oid\n"
|
||||
"write(type, data) -> Oid\n"
|
||||
"\n"
|
||||
"Write raw object data into the repository. First arg is the object type,\n"
|
||||
"the second one a buffer with data. Return the object id (sha) of of the\n"
|
||||
"created object.");
|
||||
"Write raw object data into the repository. First arg is the object\n"
|
||||
"type, the second one a buffer with data. Return the Oid of the created\n"
|
||||
"object.");
|
||||
|
||||
PyObject *
|
||||
Repository_write(Repository *self, PyObject *args)
|
||||
|
Loading…
Reference in New Issue
Block a user