From 6ce71a279961fa17316bf581c1507306689be6bb Mon Sep 17 00:00:00 2001 From: Nico von Geyso Date: Mon, 20 May 2013 13:57:40 +0200 Subject: [PATCH] Added: support for context_lines and interhunk_lines for diffs --- pygit2/repository.py | 34 +++++++++++++++++++---- src/index.c | 36 ++++++++++++++++++++---- src/tree.c | 65 ++++++++++++++++++++++++++++++++++++-------- 3 files changed, 112 insertions(+), 23 deletions(-) diff --git a/pygit2/repository.py b/pygit2/repository.py index 5427462..d62d08a 100644 --- a/pygit2/repository.py +++ b/pygit2/repository.py @@ -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): diff --git a/src/index.c b/src/index.c index b756a09..3b637a8 100644 --- a/src/index.c +++ b/src/index.c @@ -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); diff --git a/src/tree.c b/src/tree.c index b8dee9b..58e27a1 100644 --- a/src/tree.c +++ b/src/tree.c @@ -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);