Added: support for context_lines and interhunk_lines for diffs

This commit is contained in:
Nico von Geyso
2013-05-20 13:57:40 +02:00
parent 35d8bc4fc4
commit 6ce71a2799
3 changed files with 112 additions and 23 deletions

View File

@@ -27,6 +27,7 @@
# Import from the Standard Library
from string import hexdigits
from collections import OrderedDict
# Import from pygit2
from utils import text_type
@@ -134,12 +135,29 @@ class Repository(_Repository):
#
# Diff
#
def diff(self, a=None, b=None, cached=False, flags=0):
def diff(self, a=None, b=None, cached=False, flags=0, context_lines=3,
interhunk_lines=0):
"""
Show changes between the working tree and the index or a tree,
changes between the index and a tree, changes between two trees, or
changes between two blobs.
Keyword arguments:
cached
use staged changes instead of workdir
flag
a GIT_DIFF_* constant
context_lines
the number of unchanged lines that define the boundary
of a hunk (and to display before and after)\n"
interhunk_lines
the maximum number of unchanged lines between hunk
boundaries before the hunks will be merged into a one
Examples::
# Changes in the working tree not yet staged for the next commit
@@ -174,20 +192,26 @@ class Repository(_Repository):
a = treeish_to_tree(a) or a
b = treeish_to_tree(b) or b
opts = OrderedDict([
('flags', flags),
('context_lines', context_lines),
('interhunk_lines', interhunk_lines)
])
# Case 1: Diff tree to tree
if isinstance(a, Tree) and isinstance(b, Tree):
return a.diff_to_tree(b, flags=flags)
return a.diff_to_tree(b, **opts)
# Case 2: Index to workdir
elif a is None and b is None:
return self.index.diff_to_workdir()
return self.index.diff_to_workdir(*opts.values())
# Case 3: Diff tree to index or workdir
elif isinstance(a, Tree) and b is None:
if cached:
return a.diff_to_index(self.index, flags=flags)
return a.diff_to_index(self.index, **opts)
else:
return a.diff_to_workdir(flags)
return a.diff_to_workdir(*opts.values())
# Case 4: Diff blob to blob
if isinstance(a, Blob) and isinstance(b, Blob):

View File

@@ -116,10 +116,20 @@ Index_clear(Index *self)
PyDoc_STRVAR(Index_diff_to_workdir__doc__,
"diff_to_workdir() -> Diff\n"
"diff_to_workdir([flag, context_lines, interhunk_lines]) -> Diff\n"
"\n"
"Return a :py:class:`~pygit2.Diff` object with the differences between the\n"
"index and the working copy.\n");
"index and the working copy.\n"
"\n"
"Arguments:\n"
"\n"
"flag: a GIT_DIFF_* constant.\n"
"\n"
"context_lines: the number of unchanged lines that define the boundary\n"
" of a hunk (and to display before and after)\n"
"\n"
"interhunk_lines: the maximum number of unchanged lines between hunk\n"
" boundaries before the hunks will be merged into a one.\n");
PyObject *
Index_diff_to_workdir(Index *self, PyObject *args)
@@ -128,7 +138,8 @@ Index_diff_to_workdir(Index *self, PyObject *args)
git_diff_list *diff;
int err;
if (!PyArg_ParseTuple(args, "|i", &opts.flags))
if (!PyArg_ParseTuple(args, "|IHH", &opts.flags, &opts.context_lines,
&opts.interhunk_lines))
return NULL;
err = git_diff_index_to_workdir(
@@ -144,10 +155,22 @@ Index_diff_to_workdir(Index *self, PyObject *args)
}
PyDoc_STRVAR(Index_diff_to_tree__doc__,
"diff_to_tree(tree) -> Diff\n"
"diff_to_tree(tree [, flag, context_lines, interhunk_lines]) -> Diff\n"
"\n"
"Return a :py:class:`~pygit2.Diff` object with the differences between the\n"
"index and the given tree.\n");
"index and the given tree.\n"
"\n"
"Arguments:\n"
"\n"
"tree: the tree to diff.\n"
"\n"
"flag: a GIT_DIFF_* constant.\n"
"\n"
"context_lines: the number of unchanged lines that define the boundary\n"
" of a hunk (and to display before and after)\n"
"\n"
"interhunk_lines: the maximum number of unchanged lines between hunk\n"
" boundaries before the hunks will be merged into a one.\n");
PyObject *
Index_diff_to_tree(Index *self, PyObject *args)
@@ -159,7 +182,8 @@ Index_diff_to_tree(Index *self, PyObject *args)
Tree *py_tree = NULL;
if (!PyArg_ParseTuple(args, "O!|i", &TreeType, &py_tree, &opts.flags))
if (!PyArg_ParseTuple(args, "O!|IHH", &TreeType, &py_tree, &opts.flags,
&opts.context_lines, &opts.interhunk_lines))
return NULL;
repo = git_tree_owner(py_tree->tree);

View File

@@ -272,9 +272,19 @@ Tree_getitem(Tree *self, PyObject *value)
PyDoc_STRVAR(Tree_diff_to_workdir__doc__,
"diff_to_workdir([flags]) -> Diff\n"
"diff_to_workdir([flags, context_lines, interhunk_lines]) -> Diff\n"
"\n"
"Show the changes between the tree and the workdir.\n");
"Show the changes between the :py:class:`~pygit2.Tree` and the workdir.\n"
"\n"
"Arguments:\n"
"\n"
"flag: a GIT_DIFF_* constant.\n"
"\n"
"context_lines: the number of unchanged lines that define the boundary\n"
" of a hunk (and to display before and after)\n"
"\n"
"interhunk_lines: the maximum number of unchanged lines between hunk\n"
" boundaries before the hunks will be merged into a one.\n");
PyObject *
Tree_diff_to_workdir(Tree *self, PyObject *args)
@@ -287,7 +297,8 @@ Tree_diff_to_workdir(Tree *self, PyObject *args)
Diff *py_diff;
PyObject *py_obj = NULL;
if (!PyArg_ParseTuple(args, "|i", &opts.flags))
if (!PyArg_ParseTuple(args, "|IHH", &opts.flags, &opts.context_lines,
&opts.interhunk_lines))
return NULL;
repo = git_tree_owner(self->tree);
@@ -301,9 +312,21 @@ Tree_diff_to_workdir(Tree *self, PyObject *args)
PyDoc_STRVAR(Tree_diff_to_index__doc__,
"diff_to_index(index, [flags]) -> Diff\n"
"diff_to_index(index, [flags, context_lines, interhunk_lines]) -> Diff\n"
"\n"
"Show the changes between the index and a given tree.\n");
"Show the changes between the index and a given :py:class:`~pygit2.Tree`.\n"
"\n"
"Arguments:\n"
"\n"
"tree: the :py:class:`~pygit2.Tree` to diff.\n"
"\n"
"flag: a GIT_DIFF_* constant.\n"
"\n"
"context_lines: the number of unchanged lines that define the boundary\n"
" of a hunk (and to display before and after)\n"
"\n"
"interhunk_lines: the maximum number of unchanged lines between hunk\n"
" boundaries before the hunks will be merged into a one.\n");
PyObject *
Tree_diff_to_index(Tree *self, PyObject *args, PyObject *kwds)
@@ -318,7 +341,9 @@ Tree_diff_to_index(Tree *self, PyObject *args, PyObject *kwds)
Diff *py_diff;
Index *py_idx = NULL;
if (!PyArg_ParseTuple(args, "O!|i", &IndexType, &py_idx, &opts.flags))
if (!PyArg_ParseTuple(args, "O!|IHH", &IndexType, &py_idx, &opts.flags,
&opts.context_lines,
&opts.interhunk_lines))
return NULL;
repo = git_tree_owner(self->tree);
@@ -331,10 +356,24 @@ Tree_diff_to_index(Tree *self, PyObject *args, PyObject *kwds)
PyDoc_STRVAR(Tree_diff_to_tree__doc__,
"diff_to_tree([tree, flags, swap]) -> Diff\n"
"diff_to_tree([tree, flags, context_lines, interhunk_lines, swap]) -> Diff\n"
"\n"
"Show the changes between two trees. If no tree is given the empty tree will"
"be used instead.\n");
"Show the changes between two trees\n"
"\n"
"Arguments:\n"
"\n"
"tree: the :py:class:`~pygit2.Tree` to diff. If no tree is given the empty\n"
" tree will be used instead.\n"
"\n"
"flag: a GIT_DIFF_* constant.\n"
"\n"
"context_lines: the number of unchanged lines that define the boundary\n"
" of a hunk (and to display before and after)\n"
"\n"
"interhunk_lines: the maximum number of unchanged lines between hunk\n"
" boundaries before the hunks will be merged into a one.\n"
"\n"
"swap: instead of diffing a to b. Diff b to a.\n");
PyObject *
Tree_diff_to_tree(Tree *self, PyObject *args, PyObject *kwds)
@@ -344,14 +383,16 @@ Tree_diff_to_tree(Tree *self, PyObject *args, PyObject *kwds)
git_tree *from, *to, *tmp;
git_repository* repo;
int err, swap = 0;
char *keywords[] = {"obj", "flags", "swap", NULL};
char *keywords[] = {"obj", "flags", "context_lines", "interhunk_lines",
"swap", NULL};
Diff *py_diff;
Tree *py_tree = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!ii", keywords,
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!IHHi", keywords,
&TreeType, &py_tree, &opts.flags,
&swap))
&opts.context_lines,
&opts.interhunk_lines, &swap))
return NULL;
repo = git_tree_owner(self->tree);