mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-30 22:24:56 +00:00
Merge pull request #2066 from libgit2/rb/builtin-diff-drivers
Add built in diff drivers
This commit is contained in:
commit
a1a9d0bd48
@ -39,27 +39,34 @@
|
|||||||
# but has otherwise not contributed to git.)
|
# but has otherwise not contributed to git.)
|
||||||
#
|
#
|
||||||
ok Adam Simpkins <adam@adamsimpkins.net> (http transport)
|
ok Adam Simpkins <adam@adamsimpkins.net> (http transport)
|
||||||
|
ok Adrian Johnson <ajohnson@redneon.com>
|
||||||
|
ok Alexey Shumkin <alex.crezoff@gmail.com>
|
||||||
ok Andreas Ericsson <ae@op5.se>
|
ok Andreas Ericsson <ae@op5.se>
|
||||||
ok Boyd Lynn Gerber <gerberb@zenez.com>
|
ok Boyd Lynn Gerber <gerberb@zenez.com>
|
||||||
|
ok Brandon Casey <drafnel@gmail.com>
|
||||||
ok Brian Downing <bdowning@lavos.net>
|
ok Brian Downing <bdowning@lavos.net>
|
||||||
ok Brian Gernhardt <benji@silverinsanity.com>
|
ok Brian Gernhardt <benji@silverinsanity.com>
|
||||||
ok Christian Couder <chriscool@tuxfamily.org>
|
ok Christian Couder <chriscool@tuxfamily.org>
|
||||||
ok Daniel Barkalow <barkalow@iabervon.org>
|
ok Daniel Barkalow <barkalow@iabervon.org>
|
||||||
ok Florian Forster <octo@verplant.org>
|
ok Florian Forster <octo@verplant.org>
|
||||||
|
ok Gustaf Hendeby <hendeby@isy.liu.se>
|
||||||
ok Holger Weiss <holger@zedat.fu-berlin.de>
|
ok Holger Weiss <holger@zedat.fu-berlin.de>
|
||||||
ok Jeff King <peff@peff.net>
|
ok Jeff King <peff@peff.net>
|
||||||
ok Johannes Schindelin <Johannes.Schindelin@gmx.de>
|
ok Johannes Schindelin <Johannes.Schindelin@gmx.de>
|
||||||
ok Johannes Sixt <j6t@kdbg.org>
|
ok Johannes Sixt <j6t@kdbg.org>
|
||||||
|
ask Jonathan Nieder <jrnieder@gmail.com>
|
||||||
ok Junio C Hamano <gitster@pobox.com>
|
ok Junio C Hamano <gitster@pobox.com>
|
||||||
ok Kristian Høgsberg <krh@redhat.com>
|
ok Kristian Høgsberg <krh@redhat.com>
|
||||||
ok Linus Torvalds <torvalds@linux-foundation.org>
|
ok Linus Torvalds <torvalds@linux-foundation.org>
|
||||||
ok Lukas Sandström <lukass@etek.chalmers.se>
|
ok Lukas Sandström <lukass@etek.chalmers.se>
|
||||||
ok Matthieu Moy <Matthieu.Moy@imag.fr>
|
ok Matthieu Moy <Matthieu.Moy@imag.fr>
|
||||||
|
ok Michael Haggerty <mhagger@alum.mit.edu>
|
||||||
ign Mike McCormack <mike@codeweavers.com> (imap-send)
|
ign Mike McCormack <mike@codeweavers.com> (imap-send)
|
||||||
ok Nicolas Pitre <nico@fluxnic.net> <nico@cam.org>
|
ok Nicolas Pitre <nico@fluxnic.net> <nico@cam.org>
|
||||||
ok Paolo Bonzini <bonzini@gnu.org>
|
ok Paolo Bonzini <bonzini@gnu.org>
|
||||||
ok Paul Kocher <paul@cryptography.com>
|
ok Paul Kocher <paul@cryptography.com>
|
||||||
ok Peter Hagervall <hager@cs.umu.se>
|
ok Peter Hagervall <hager@cs.umu.se>
|
||||||
|
ok Petr Onderka <gsvick@gmail.com>
|
||||||
ok Pierre Habouzit <madcoder@debian.org>
|
ok Pierre Habouzit <madcoder@debian.org>
|
||||||
ok Pieter de Bie <pdebie@ai.rug.nl>
|
ok Pieter de Bie <pdebie@ai.rug.nl>
|
||||||
ok René Scharfe <rene.scharfe@lsrfire.ath.cx>
|
ok René Scharfe <rene.scharfe@lsrfire.ath.cx>
|
||||||
@ -68,4 +75,5 @@ ok Sebastian Schuberth <sschuberth@gmail.com>
|
|||||||
ok Shawn O. Pearce <spearce@spearce.org>
|
ok Shawn O. Pearce <spearce@spearce.org>
|
||||||
ok Steffen Prohaska <prohaska@zib.de>
|
ok Steffen Prohaska <prohaska@zib.de>
|
||||||
ok Sven Verdoolaege <skimo@kotnet.org>
|
ok Sven Verdoolaege <skimo@kotnet.org>
|
||||||
|
ask Thomas Rast <tr@thomasrast.ch> (ok before 6-Oct-2013)
|
||||||
ok Torsten Bögershausen <tboegi@web.de>
|
ok Torsten Bögershausen <tboegi@web.de>
|
||||||
|
@ -26,10 +26,13 @@ typedef enum {
|
|||||||
DIFF_DRIVER_PATTERNLIST = 3,
|
DIFF_DRIVER_PATTERNLIST = 3,
|
||||||
} git_diff_driver_t;
|
} git_diff_driver_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
regex_t re;
|
||||||
|
int flags;
|
||||||
|
} git_diff_driver_pattern;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
DIFF_CONTEXT_FIND_NORMAL = 0,
|
REG_NEGATE = (1 << 15) /* get out of the way of existing flags */
|
||||||
DIFF_CONTEXT_FIND_ICASE = (1 << 0),
|
|
||||||
DIFF_CONTEXT_FIND_EXT = (1 << 1),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* data for finding function context for a given file type */
|
/* data for finding function context for a given file type */
|
||||||
@ -37,11 +40,13 @@ struct git_diff_driver {
|
|||||||
git_diff_driver_t type;
|
git_diff_driver_t type;
|
||||||
uint32_t binary_flags;
|
uint32_t binary_flags;
|
||||||
uint32_t other_flags;
|
uint32_t other_flags;
|
||||||
git_array_t(regex_t) fn_patterns;
|
git_array_t(git_diff_driver_pattern) fn_patterns;
|
||||||
regex_t word_pattern;
|
regex_t word_pattern;
|
||||||
char name[GIT_FLEX_ARRAY];
|
char name[GIT_FLEX_ARRAY];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "userdiff.h"
|
||||||
|
|
||||||
struct git_diff_driver_registry {
|
struct git_diff_driver_registry {
|
||||||
git_strmap *drivers;
|
git_strmap *drivers;
|
||||||
};
|
};
|
||||||
@ -81,34 +86,59 @@ void git_diff_driver_registry_free(git_diff_driver_registry *reg)
|
|||||||
git__free(reg);
|
git__free(reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int diff_driver_add_funcname(
|
static int diff_driver_add_patterns(
|
||||||
git_diff_driver *drv, const char *name, int regex_flags)
|
git_diff_driver *drv, const char *regex_str, int regex_flags)
|
||||||
{
|
{
|
||||||
int error;
|
int error = 0;
|
||||||
regex_t re, *re_ptr;
|
const char *scan, *end;
|
||||||
|
git_diff_driver_pattern *pat = NULL;
|
||||||
|
git_buf buf = GIT_BUF_INIT;
|
||||||
|
|
||||||
if ((error = regcomp(&re, name, regex_flags)) != 0) {
|
for (scan = regex_str; scan; scan = end) {
|
||||||
/* TODO: warning about bad regex instead of failure */
|
/* get pattern to fill in */
|
||||||
error = giterr_set_regex(&re, error);
|
if ((pat = git_array_alloc(drv->fn_patterns)) == NULL) {
|
||||||
regfree(&re);
|
error = -1;
|
||||||
return error;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
re_ptr = git_array_alloc(drv->fn_patterns);
|
pat->flags = regex_flags;
|
||||||
GITERR_CHECK_ALLOC(re_ptr);
|
if (*scan == '!') {
|
||||||
|
pat->flags |= REG_NEGATE;
|
||||||
|
++scan;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(re_ptr, &re, sizeof(re));
|
if ((end = strchr(scan, '\n')) != NULL) {
|
||||||
return 0;
|
error = git_buf_set(&buf, scan, end - scan);
|
||||||
|
end++;
|
||||||
|
} else {
|
||||||
|
error = git_buf_sets(&buf, scan);
|
||||||
|
}
|
||||||
|
if (error < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((error = regcomp(&pat->re, buf.ptr, regex_flags)) < 0) {
|
||||||
|
/* if regex fails to compile, warn? fail? */
|
||||||
|
error = giterr_set_regex(&pat->re, error);
|
||||||
|
regfree(&pat->re);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error && pat != NULL)
|
||||||
|
(void)git_array_pop(drv->fn_patterns); /* release last item */
|
||||||
|
git_buf_free(&buf);
|
||||||
|
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int diff_driver_xfuncname(const git_config_entry *entry, void *payload)
|
static int diff_driver_xfuncname(const git_config_entry *entry, void *payload)
|
||||||
{
|
{
|
||||||
return diff_driver_add_funcname(payload, entry->value, REG_EXTENDED);
|
return diff_driver_add_patterns(payload, entry->value, REG_EXTENDED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int diff_driver_funcname(const git_config_entry *entry, void *payload)
|
static int diff_driver_funcname(const git_config_entry *entry, void *payload)
|
||||||
{
|
{
|
||||||
return diff_driver_add_funcname(payload, entry->value, 0);
|
return diff_driver_add_patterns(payload, entry->value, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static git_diff_driver_registry *git_repository_driver_registry(
|
static git_diff_driver_registry *git_repository_driver_registry(
|
||||||
@ -128,12 +158,65 @@ static git_diff_driver_registry *git_repository_driver_registry(
|
|||||||
return repo->diff_drivers;
|
return repo->diff_drivers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int git_diff_driver_builtin(
|
||||||
|
git_diff_driver **out,
|
||||||
|
git_diff_driver_registry *reg,
|
||||||
|
const char *driver_name)
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
git_diff_driver_definition *ddef = NULL;
|
||||||
|
git_diff_driver *drv = NULL;
|
||||||
|
size_t namelen, idx;
|
||||||
|
|
||||||
|
for (idx = 0; idx < ARRAY_SIZE(builtin_defs); ++idx) {
|
||||||
|
if (!strcasecmp(driver_name, builtin_defs[idx].name)) {
|
||||||
|
ddef = &builtin_defs[idx];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ddef)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
namelen = strlen(ddef->name);
|
||||||
|
|
||||||
|
drv = git__calloc(1, sizeof(git_diff_driver) + namelen + 1);
|
||||||
|
GITERR_CHECK_ALLOC(drv);
|
||||||
|
|
||||||
|
drv->type = DIFF_DRIVER_PATTERNLIST;
|
||||||
|
memcpy(drv->name, ddef->name, namelen);
|
||||||
|
|
||||||
|
if (ddef->fns &&
|
||||||
|
(error = diff_driver_add_patterns(
|
||||||
|
drv, ddef->fns, ddef->flags | REG_EXTENDED)) < 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (ddef->words &&
|
||||||
|
(error = regcomp(
|
||||||
|
&drv->word_pattern, ddef->words, ddef->flags | REG_EXTENDED)))
|
||||||
|
{
|
||||||
|
error = giterr_set_regex(&drv->word_pattern, error);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
git_strmap_insert(reg->drivers, drv->name, drv, error);
|
||||||
|
if (error > 0)
|
||||||
|
error = 0;
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (error && drv)
|
||||||
|
git_diff_driver_free(drv);
|
||||||
|
else
|
||||||
|
*out = drv;
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
static int git_diff_driver_load(
|
static int git_diff_driver_load(
|
||||||
git_diff_driver **out, git_repository *repo, const char *driver_name)
|
git_diff_driver **out, git_repository *repo, const char *driver_name)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
git_diff_driver_registry *reg;
|
git_diff_driver_registry *reg;
|
||||||
git_diff_driver *drv;
|
git_diff_driver *drv = NULL;
|
||||||
size_t namelen = strlen(driver_name);
|
size_t namelen = strlen(driver_name);
|
||||||
khiter_t pos;
|
khiter_t pos;
|
||||||
git_config *cfg;
|
git_config *cfg;
|
||||||
@ -141,21 +224,19 @@ static int git_diff_driver_load(
|
|||||||
const git_config_entry *ce;
|
const git_config_entry *ce;
|
||||||
bool found_driver = false;
|
bool found_driver = false;
|
||||||
|
|
||||||
reg = git_repository_driver_registry(repo);
|
if ((reg = git_repository_driver_registry(repo)) == NULL)
|
||||||
if (!reg)
|
|
||||||
return -1;
|
return -1;
|
||||||
else {
|
|
||||||
pos = git_strmap_lookup_index(reg->drivers, driver_name);
|
pos = git_strmap_lookup_index(reg->drivers, driver_name);
|
||||||
if (git_strmap_valid_index(reg->drivers, pos)) {
|
if (git_strmap_valid_index(reg->drivers, pos)) {
|
||||||
*out = git_strmap_value_at(reg->drivers, pos);
|
*out = git_strmap_value_at(reg->drivers, pos);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* if you can't read config for repo, just use default driver */
|
/* if you can't read config for repo, just use default driver */
|
||||||
if (git_repository_config__weakptr(&cfg, repo) < 0) {
|
if (git_repository_config__weakptr(&cfg, repo) < 0) {
|
||||||
giterr_clear();
|
giterr_clear();
|
||||||
return GIT_ENOTFOUND;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
drv = git__calloc(1, sizeof(git_diff_driver) + namelen + 1);
|
drv = git__calloc(1, sizeof(git_diff_driver) + namelen + 1);
|
||||||
@ -178,7 +259,7 @@ static int git_diff_driver_load(
|
|||||||
found_driver = true;
|
found_driver = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* diff.<driver>.binary unspecified, so just continue */
|
/* diff.<driver>.binary unspecified or "auto", so just continue */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,14 +315,18 @@ static int git_diff_driver_load(
|
|||||||
git_strmap_insert(reg->drivers, drv->name, drv, error);
|
git_strmap_insert(reg->drivers, drv->name, drv, error);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
error = 0;
|
||||||
|
|
||||||
*out = drv;
|
*out = drv;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
git_buf_free(&name);
|
git_buf_free(&name);
|
||||||
|
|
||||||
if (!*out)
|
if (!*out) {
|
||||||
*out = &global_drivers[DIFF_DRIVER_AUTO];
|
int error2 = git_diff_driver_builtin(out, reg, driver_name);
|
||||||
|
if (!error)
|
||||||
|
error = error2;
|
||||||
|
}
|
||||||
|
|
||||||
if (drv && drv != *out)
|
if (drv && drv != *out)
|
||||||
git_diff_driver_free(drv);
|
git_diff_driver_free(drv);
|
||||||
@ -256,14 +341,13 @@ int git_diff_driver_lookup(
|
|||||||
const char *value;
|
const char *value;
|
||||||
|
|
||||||
assert(out);
|
assert(out);
|
||||||
|
*out = NULL;
|
||||||
|
|
||||||
if (!repo || !path || !strlen(path))
|
if (!repo || !path || !strlen(path))
|
||||||
goto use_auto;
|
/* just use the auto value */;
|
||||||
|
else if ((error = git_attr_get(&value, repo, 0, path, "diff")) < 0)
|
||||||
if ((error = git_attr_get(&value, repo, 0, path, "diff")) < 0)
|
/* return error below */;
|
||||||
return error;
|
else if (GIT_ATTR_UNSPECIFIED(value))
|
||||||
|
|
||||||
if (GIT_ATTR_UNSPECIFIED(value))
|
|
||||||
/* just use the auto value */;
|
/* just use the auto value */;
|
||||||
else if (GIT_ATTR_FALSE(value))
|
else if (GIT_ATTR_FALSE(value))
|
||||||
*out = &global_drivers[DIFF_DRIVER_BINARY];
|
*out = &global_drivers[DIFF_DRIVER_BINARY];
|
||||||
@ -272,17 +356,16 @@ int git_diff_driver_lookup(
|
|||||||
|
|
||||||
/* otherwise look for driver information in config and build driver */
|
/* otherwise look for driver information in config and build driver */
|
||||||
else if ((error = git_diff_driver_load(out, repo, value)) < 0) {
|
else if ((error = git_diff_driver_load(out, repo, value)) < 0) {
|
||||||
if (error != GIT_ENOTFOUND)
|
if (error == GIT_ENOTFOUND) {
|
||||||
return error;
|
error = 0;
|
||||||
else
|
|
||||||
giterr_clear();
|
giterr_clear();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use_auto:
|
|
||||||
if (!*out)
|
if (!*out)
|
||||||
*out = &global_drivers[DIFF_DRIVER_AUTO];
|
*out = &global_drivers[DIFF_DRIVER_AUTO];
|
||||||
|
|
||||||
return 0;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void git_diff_driver_free(git_diff_driver *driver)
|
void git_diff_driver_free(git_diff_driver *driver)
|
||||||
@ -293,7 +376,7 @@ void git_diff_driver_free(git_diff_driver *driver)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < git_array_size(driver->fn_patterns); ++i)
|
for (i = 0; i < git_array_size(driver->fn_patterns); ++i)
|
||||||
regfree(git_array_get(driver->fn_patterns, i));
|
regfree(& git_array_get(driver->fn_patterns, i)->re);
|
||||||
git_array_clear(driver->fn_patterns);
|
git_array_clear(driver->fn_patterns);
|
||||||
|
|
||||||
regfree(&driver->word_pattern);
|
regfree(&driver->word_pattern);
|
||||||
@ -330,24 +413,35 @@ int git_diff_driver_content_is_binary(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int diff_context_line__simple(
|
static int diff_context_line__simple(
|
||||||
git_diff_driver *driver, const char *line, size_t line_len)
|
git_diff_driver *driver, git_buf *line)
|
||||||
{
|
{
|
||||||
|
char firstch = line->ptr[0];
|
||||||
GIT_UNUSED(driver);
|
GIT_UNUSED(driver);
|
||||||
GIT_UNUSED(line_len);
|
return (git__isalpha(firstch) || firstch == '_' || firstch == '$');
|
||||||
return (git__isalpha(*line) || *line == '_' || *line == '$');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int diff_context_line__pattern_match(
|
static int diff_context_line__pattern_match(
|
||||||
git_diff_driver *driver, const char *line, size_t line_len)
|
git_diff_driver *driver, git_buf *line)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i, maxi = git_array_size(driver->fn_patterns);
|
||||||
|
regmatch_t pmatch[2];
|
||||||
|
|
||||||
GIT_UNUSED(line_len);
|
for (i = 0; i < maxi; ++i) {
|
||||||
|
git_diff_driver_pattern *pat = git_array_get(driver->fn_patterns, i);
|
||||||
|
|
||||||
|
if (!regexec(&pat->re, line->ptr, 2, pmatch, 0)) {
|
||||||
|
if (pat->flags & REG_NEGATE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* use pmatch data to trim line data */
|
||||||
|
i = (pmatch[1].rm_so >= 0) ? 1 : 0;
|
||||||
|
git_buf_consume(line, git_buf_cstr(line) + pmatch[i].rm_so);
|
||||||
|
git_buf_truncate(line, pmatch[i].rm_eo - pmatch[i].rm_so);
|
||||||
|
git_buf_rtrim(line);
|
||||||
|
|
||||||
for (i = 0; i < git_array_size(driver->fn_patterns); ++i) {
|
|
||||||
if (!regexec(git_array_get(driver->fn_patterns, i), line, 0, NULL, 0))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -368,8 +462,7 @@ static long diff_context_find(
|
|||||||
if (!ctxt->line.size)
|
if (!ctxt->line.size)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!ctxt->match_line ||
|
if (!ctxt->match_line || !ctxt->match_line(ctxt->driver, &ctxt->line))
|
||||||
!ctxt->match_line(ctxt->driver, ctxt->line.ptr, ctxt->line.size))
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (out_size > (long)ctxt->line.size)
|
if (out_size > (long)ctxt->line.size)
|
||||||
|
@ -31,7 +31,7 @@ typedef long (*git_diff_find_context_fn)(
|
|||||||
const char *, long, char *, long, void *);
|
const char *, long, char *, long, void *);
|
||||||
|
|
||||||
typedef int (*git_diff_find_context_line)(
|
typedef int (*git_diff_find_context_line)(
|
||||||
git_diff_driver *, const char *, size_t);
|
git_diff_driver *, git_buf *);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
git_diff_driver *driver;
|
git_diff_driver *driver;
|
||||||
|
210
src/userdiff.h
Normal file
210
src/userdiff.h
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||||
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDE_userdiff_h__
|
||||||
|
#define INCLUDE_userdiff_h__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file isolates the built in diff driver function name patterns.
|
||||||
|
* Most of these patterns are taken from Git (with permission from the
|
||||||
|
* original authors for relicensing to libgit2).
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
const char *fns;
|
||||||
|
const char *words;
|
||||||
|
int flags;
|
||||||
|
} git_diff_driver_definition;
|
||||||
|
|
||||||
|
#define WORD_DEFAULT "|[^[:space:]]|[\xc0-\xff][\x80-\xbf]+"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These builtin driver definition macros have same signature as in core
|
||||||
|
* git userdiff.c so that the data can be extracted verbatim
|
||||||
|
*/
|
||||||
|
#define PATTERNS(NAME, FN_PATS, WORD_PAT) \
|
||||||
|
{ NAME, FN_PATS, WORD_PAT WORD_DEFAULT, 0 }
|
||||||
|
#define IPATTERN(NAME, FN_PATS, WORD_PAT) \
|
||||||
|
{ NAME, FN_PATS, WORD_PAT WORD_DEFAULT, REG_ICASE }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The table of diff driver patterns
|
||||||
|
*
|
||||||
|
* Function name patterns are a list of newline separated patterns that
|
||||||
|
* match a function declaration (i.e. the line you want in the hunk header),
|
||||||
|
* or a negative pattern prefixed with a '!' to reject a pattern (such as
|
||||||
|
* rejecting goto labels in C code).
|
||||||
|
*
|
||||||
|
* Word boundary patterns are just a simple pattern that will be OR'ed with
|
||||||
|
* the default value above (i.e. whitespace or non-ASCII characters).
|
||||||
|
*/
|
||||||
|
static git_diff_driver_definition builtin_defs[] = {
|
||||||
|
|
||||||
|
IPATTERN("ada",
|
||||||
|
"!^(.*[ \t])?(is new|renames|is separate)([ \t].*)?$\n"
|
||||||
|
"!^[ \t]*with[ \t].*$\n"
|
||||||
|
"^[ \t]*((procedure|function)[ \t]+.*)$\n"
|
||||||
|
"^[ \t]*((package|protected|task)[ \t]+.*)$",
|
||||||
|
/* -- */
|
||||||
|
"[a-zA-Z][a-zA-Z0-9_]*"
|
||||||
|
"|[0-9][-+0-9#_.eE]"
|
||||||
|
"|=>|\\.\\.|\\*\\*|:=|/=|>=|<=|<<|>>|<>"),
|
||||||
|
|
||||||
|
IPATTERN("fortran",
|
||||||
|
"!^([C*]|[ \t]*!)\n"
|
||||||
|
"!^[ \t]*MODULE[ \t]+PROCEDURE[ \t]\n"
|
||||||
|
"^[ \t]*((END[ \t]+)?(PROGRAM|MODULE|BLOCK[ \t]+DATA"
|
||||||
|
"|([^'\" \t]+[ \t]+)*(SUBROUTINE|FUNCTION))[ \t]+[A-Z].*)$",
|
||||||
|
/* -- */
|
||||||
|
"[a-zA-Z][a-zA-Z0-9_]*"
|
||||||
|
"|\\.([Ee][Qq]|[Nn][Ee]|[Gg][TtEe]|[Ll][TtEe]|[Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]|[Aa][Nn][Dd]|[Oo][Rr]|[Nn]?[Ee][Qq][Vv]|[Nn][Oo][Tt])\\."
|
||||||
|
/* numbers and format statements like 2E14.4, or ES12.6, 9X.
|
||||||
|
* Don't worry about format statements without leading digits since
|
||||||
|
* they would have been matched above as a variable anyway. */
|
||||||
|
"|[-+]?[0-9.]+([AaIiDdEeFfLlTtXx][Ss]?[-+]?[0-9.]*)?(_[a-zA-Z0-9][a-zA-Z0-9_]*)?"
|
||||||
|
"|//|\\*\\*|::|[/<>=]="),
|
||||||
|
|
||||||
|
PATTERNS("html", "^[ \t]*(<[Hh][1-6][ \t].*>.*)$",
|
||||||
|
"[^<>= \t]+"),
|
||||||
|
|
||||||
|
PATTERNS("java",
|
||||||
|
"!^[ \t]*(catch|do|for|if|instanceof|new|return|switch|throw|while)\n"
|
||||||
|
"^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$",
|
||||||
|
/* -- */
|
||||||
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
|
"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
|
||||||
|
"|[-+*/<>%&^|=!]="
|
||||||
|
"|--|\\+\\+|<<=?|>>>?=?|&&|\\|\\|"),
|
||||||
|
|
||||||
|
PATTERNS("matlab",
|
||||||
|
"^[[:space:]]*((classdef|function)[[:space:]].*)$|^%%[[:space:]].*$",
|
||||||
|
"[a-zA-Z_][a-zA-Z0-9_]*|[-+0-9.e]+|[=~<>]=|\\.[*/\\^']|\\|\\||&&"),
|
||||||
|
|
||||||
|
PATTERNS("objc",
|
||||||
|
/* Negate C statements that can look like functions */
|
||||||
|
"!^[ \t]*(do|for|if|else|return|switch|while)\n"
|
||||||
|
/* Objective-C methods */
|
||||||
|
"^[ \t]*([-+][ \t]*\\([ \t]*[A-Za-z_][A-Za-z_0-9* \t]*\\)[ \t]*[A-Za-z_].*)$\n"
|
||||||
|
/* C functions */
|
||||||
|
"^[ \t]*(([A-Za-z_][A-Za-z_0-9]*[ \t]+)+[A-Za-z_][A-Za-z_0-9]*[ \t]*\\([^;]*)$\n"
|
||||||
|
/* Objective-C class/protocol definitions */
|
||||||
|
"^(@(implementation|interface|protocol)[ \t].*)$",
|
||||||
|
/* -- */
|
||||||
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
|
"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
|
||||||
|
"|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"),
|
||||||
|
|
||||||
|
PATTERNS("pascal",
|
||||||
|
"^(((class[ \t]+)?(procedure|function)|constructor|destructor|interface|"
|
||||||
|
"implementation|initialization|finalization)[ \t]*.*)$"
|
||||||
|
"\n"
|
||||||
|
"^(.*=[ \t]*(class|record).*)$",
|
||||||
|
/* -- */
|
||||||
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
|
"|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+"
|
||||||
|
"|<>|<=|>=|:=|\\.\\."),
|
||||||
|
|
||||||
|
PATTERNS("perl",
|
||||||
|
"^package .*\n"
|
||||||
|
"^sub [[:alnum:]_':]+[ \t]*"
|
||||||
|
"(\\([^)]*\\)[ \t]*)?" /* prototype */
|
||||||
|
/*
|
||||||
|
* Attributes. A regex can't count nested parentheses,
|
||||||
|
* so just slurp up whatever we see, taking care not
|
||||||
|
* to accept lines like "sub foo; # defined elsewhere".
|
||||||
|
*
|
||||||
|
* An attribute could contain a semicolon, but at that
|
||||||
|
* point it seems reasonable enough to give up.
|
||||||
|
*/
|
||||||
|
"(:[^;#]*)?"
|
||||||
|
"(\\{[ \t]*)?" /* brace can come here or on the next line */
|
||||||
|
"(#.*)?$\n" /* comment */
|
||||||
|
"^(BEGIN|END|INIT|CHECK|UNITCHECK|AUTOLOAD|DESTROY)[ \t]*"
|
||||||
|
"(\\{[ \t]*)?" /* brace can come here or on the next line */
|
||||||
|
"(#.*)?$\n"
|
||||||
|
"^=head[0-9] .*", /* POD */
|
||||||
|
/* -- */
|
||||||
|
"[[:alpha:]_'][[:alnum:]_']*"
|
||||||
|
"|0[xb]?[0-9a-fA-F_]*"
|
||||||
|
/* taking care not to interpret 3..5 as (3.)(.5) */
|
||||||
|
"|[0-9a-fA-F_]+(\\.[0-9a-fA-F_]+)?([eE][-+]?[0-9_]+)?"
|
||||||
|
"|=>|-[rwxoRWXOezsfdlpSugkbctTBMAC>]|~~|::"
|
||||||
|
"|&&=|\\|\\|=|//=|\\*\\*="
|
||||||
|
"|&&|\\|\\||//|\\+\\+|--|\\*\\*|\\.\\.\\.?"
|
||||||
|
"|[-+*/%.^&<>=!|]="
|
||||||
|
"|=~|!~"
|
||||||
|
"|<<|<>|<=>|>>"),
|
||||||
|
|
||||||
|
PATTERNS("python", "^[ \t]*((class|def)[ \t].*)$",
|
||||||
|
/* -- */
|
||||||
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
|
"|[-+0-9.e]+[jJlL]?|0[xX]?[0-9a-fA-F]+[lL]?"
|
||||||
|
"|[-+*/<>%&^|=!]=|//=?|<<=?|>>=?|\\*\\*=?"),
|
||||||
|
|
||||||
|
PATTERNS("ruby", "^[ \t]*((class|module|def)[ \t].*)$",
|
||||||
|
/* -- */
|
||||||
|
"(@|@@|\\$)?[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
|
"|[-+0-9.e]+|0[xXbB]?[0-9a-fA-F]+|\\?(\\\\C-)?(\\\\M-)?."
|
||||||
|
"|//=?|[-+*/<>%&^|=!]=|<<=?|>>=?|===|\\.{1,3}|::|[!=]~"),
|
||||||
|
|
||||||
|
PATTERNS("bibtex", "(@[a-zA-Z]{1,}[ \t]*\\{{0,1}[ \t]*[^ \t\"@',\\#}{~%]*).*$",
|
||||||
|
"[={}\"]|[^={}\" \t]+"),
|
||||||
|
|
||||||
|
PATTERNS("tex", "^(\\\\((sub)*section|chapter|part)\\*{0,1}\\{.*)$",
|
||||||
|
"\\\\[a-zA-Z@]+|\\\\.|[a-zA-Z0-9\x80-\xff]+"),
|
||||||
|
|
||||||
|
PATTERNS("cpp",
|
||||||
|
/* Jump targets or access declarations */
|
||||||
|
"!^[ \t]*[A-Za-z_][A-Za-z_0-9]*:.*$\n"
|
||||||
|
/* C/++ functions/methods at top level */
|
||||||
|
"^([A-Za-z_][A-Za-z_0-9]*([ \t*]+[A-Za-z_][A-Za-z_0-9]*([ \t]*::[ \t]*[^[:space:]]+)?){1,}[ \t]*\\([^;]*)$\n"
|
||||||
|
/* compound type at top level */
|
||||||
|
"^((struct|class|enum)[^;]*)$",
|
||||||
|
/* -- */
|
||||||
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
|
"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
|
||||||
|
"|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"),
|
||||||
|
|
||||||
|
PATTERNS("csharp",
|
||||||
|
/* Keywords */
|
||||||
|
"!^[ \t]*(do|while|for|if|else|instanceof|new|return|switch|case|throw|catch|using)\n"
|
||||||
|
/* Methods and constructors */
|
||||||
|
"^[ \t]*(((static|public|internal|private|protected|new|virtual|sealed|override|unsafe)[ \t]+)*[][<>@.~_[:alnum:]]+[ \t]+[<>@._[:alnum:]]+[ \t]*\\(.*\\))[ \t]*$\n"
|
||||||
|
/* Properties */
|
||||||
|
"^[ \t]*(((static|public|internal|private|protected|new|virtual|sealed|override|unsafe)[ \t]+)*[][<>@.~_[:alnum:]]+[ \t]+[@._[:alnum:]]+)[ \t]*$\n"
|
||||||
|
/* Type definitions */
|
||||||
|
"^[ \t]*(((static|public|internal|private|protected|new|unsafe|sealed|abstract|partial)[ \t]+)*(class|enum|interface|struct)[ \t]+.*)$\n"
|
||||||
|
/* Namespace */
|
||||||
|
"^[ \t]*(namespace[ \t]+.*)$",
|
||||||
|
/* -- */
|
||||||
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
|
"|[-+0-9.e]+[fFlL]?|0[xXbB]?[0-9a-fA-F]+[lL]?"
|
||||||
|
"|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"),
|
||||||
|
|
||||||
|
PATTERNS("php",
|
||||||
|
"^[ \t]*(((public|private|protected|static|final)[ \t]+)*((class|function)[ \t].*))$",
|
||||||
|
/* -- */
|
||||||
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
|
"|[-+0-9.e]+[fFlL]?|0[xX]?[0-9a-fA-F]+[lL]?"
|
||||||
|
"|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"),
|
||||||
|
|
||||||
|
PATTERNS("javascript",
|
||||||
|
"^[ \t]*(function[ \t][a-zA-Z_][^\{]*)\n"
|
||||||
|
"^[ \t]*(var[ \t]+[a-zA-Z_][a-zA-Z0-9_]*[ \t]*=[ \t]*function[ \t\(][^\{]*)\n"
|
||||||
|
"^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*[ \t]*:[ \t]*function[ \t\(][^\{]*)",
|
||||||
|
/* -- */
|
||||||
|
"[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
|
"|[-+0-9.e]+[fFlL]?|0[xX]?[0-9a-fA-F]+[lL]?"
|
||||||
|
"|[-+*/<>%&^|=!]=|--|\\+\\+|<<=?|>>=?|&&|\\|\\||::|->"),
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef IPATTERN
|
||||||
|
#undef PATTERNS
|
||||||
|
#undef WORD_DEFAULT
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -861,15 +861,15 @@ void test_diff_blob__using_path_and_attributes(void)
|
|||||||
cl_git_pass(git_config_set_bool(cfg, "diff.iam_binary.binary", 1));
|
cl_git_pass(git_config_set_bool(cfg, "diff.iam_binary.binary", 1));
|
||||||
cl_git_pass(git_config_set_bool(cfg, "diff.iam_text.binary", 0));
|
cl_git_pass(git_config_set_bool(cfg, "diff.iam_text.binary", 0));
|
||||||
cl_git_pass(git_config_set_string(
|
cl_git_pass(git_config_set_string(
|
||||||
cfg, "diff.iam_alphactx.xfuncname", "^[A-Za-z]"));
|
cfg, "diff.iam_alphactx.xfuncname", "^[A-Za-z].*$"));
|
||||||
cl_git_pass(git_config_set_bool(cfg, "diff.iam_textalpha.binary", 0));
|
cl_git_pass(git_config_set_bool(cfg, "diff.iam_textalpha.binary", 0));
|
||||||
cl_git_pass(git_config_set_string(
|
cl_git_pass(git_config_set_string(
|
||||||
cfg, "diff.iam_textalpha.xfuncname", "^[A-Za-z]"));
|
cfg, "diff.iam_textalpha.xfuncname", "^[A-Za-z].*$"));
|
||||||
cl_git_pass(git_config_set_string(
|
cl_git_pass(git_config_set_string(
|
||||||
cfg, "diff.iam_numctx.funcname", "^[0-9]"));
|
cfg, "diff.iam_numctx.funcname", "^[0-9][0-9]*"));
|
||||||
cl_git_pass(git_config_set_bool(cfg, "diff.iam_textnum.binary", 0));
|
cl_git_pass(git_config_set_bool(cfg, "diff.iam_textnum.binary", 0));
|
||||||
cl_git_pass(git_config_set_string(
|
cl_git_pass(git_config_set_string(
|
||||||
cfg, "diff.iam_textnum.funcname", "^[0-9]"));
|
cfg, "diff.iam_textnum.funcname", "^[0-9][0-9]*"));
|
||||||
git_config_free(cfg);
|
git_config_free(cfg);
|
||||||
|
|
||||||
cl_git_append2file(
|
cl_git_append2file(
|
||||||
|
@ -15,6 +15,23 @@ void test_diff_drivers__cleanup(void)
|
|||||||
g_repo = NULL;
|
g_repo = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void overwrite_filemode(const char *expected, git_buf *actual)
|
||||||
|
{
|
||||||
|
size_t offset;
|
||||||
|
char *found;
|
||||||
|
|
||||||
|
found = strstr(expected, "100644");
|
||||||
|
if (!found)
|
||||||
|
return;
|
||||||
|
|
||||||
|
offset = ((const char *)found) - expected;
|
||||||
|
if (actual->size < offset + 6)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (memcmp(&actual->ptr[offset], "100644", 6) != 0)
|
||||||
|
memcpy(&actual->ptr[offset], "100644", 6);
|
||||||
|
}
|
||||||
|
|
||||||
void test_diff_drivers__patterns(void)
|
void test_diff_drivers__patterns(void)
|
||||||
{
|
{
|
||||||
git_config *cfg;
|
git_config *cfg;
|
||||||
@ -22,7 +39,7 @@ void test_diff_drivers__patterns(void)
|
|||||||
git_tree *one;
|
git_tree *one;
|
||||||
git_diff *diff;
|
git_diff *diff;
|
||||||
git_patch *patch;
|
git_patch *patch;
|
||||||
git_buf buf = GIT_BUF_INIT;
|
git_buf actual = GIT_BUF_INIT;
|
||||||
const char *expected0 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\n--- a/untimely.txt\n+++ b/untimely.txt\n@@ -22,3 +22,5 @@ Comes through the blood of the vanguards who\n dreamed--too soon--it had sounded.\r\n \r\n -- Rudyard Kipling\r\n+\r\n+Some new stuff\r\n";
|
const char *expected0 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\n--- a/untimely.txt\n+++ b/untimely.txt\n@@ -22,3 +22,5 @@ Comes through the blood of the vanguards who\n dreamed--too soon--it had sounded.\r\n \r\n -- Rudyard Kipling\r\n+\r\n+Some new stuff\r\n";
|
||||||
const char *expected1 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\nBinary files a/untimely.txt and b/untimely.txt differ\n";
|
const char *expected1 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\nBinary files a/untimely.txt and b/untimely.txt differ\n";
|
||||||
const char *expected2 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\n--- a/untimely.txt\n+++ b/untimely.txt\n@@ -22,3 +22,5 @@ Heaven delivers on earth the Hour that cannot be\n dreamed--too soon--it had sounded.\r\n \r\n -- Rudyard Kipling\r\n+\r\n+Some new stuff\r\n";
|
const char *expected2 = "diff --git a/untimely.txt b/untimely.txt\nindex 9a69d96..57fd0cf 100644\n--- a/untimely.txt\n+++ b/untimely.txt\n@@ -22,3 +22,5 @@ Heaven delivers on earth the Hour that cannot be\n dreamed--too soon--it had sounded.\r\n \r\n -- Rudyard Kipling\r\n+\r\n+Some new stuff\r\n";
|
||||||
@ -45,10 +62,10 @@ void test_diff_drivers__patterns(void)
|
|||||||
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
|
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
|
||||||
|
|
||||||
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
||||||
cl_git_pass(git_patch_to_buf(&buf, patch));
|
cl_git_pass(git_patch_to_buf(&actual, patch));
|
||||||
cl_assert_equal_s(expected0, buf.ptr);
|
cl_assert_equal_s(expected0, actual.ptr);
|
||||||
|
|
||||||
git_buf_free(&buf);
|
git_buf_free(&actual);
|
||||||
git_patch_free(patch);
|
git_patch_free(patch);
|
||||||
git_diff_free(diff);
|
git_diff_free(diff);
|
||||||
|
|
||||||
@ -60,10 +77,10 @@ void test_diff_drivers__patterns(void)
|
|||||||
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
|
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
|
||||||
|
|
||||||
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
||||||
cl_git_pass(git_patch_to_buf(&buf, patch));
|
cl_git_pass(git_patch_to_buf(&actual, patch));
|
||||||
cl_assert_equal_s(expected1, buf.ptr);
|
cl_assert_equal_s(expected1, actual.ptr);
|
||||||
|
|
||||||
git_buf_free(&buf);
|
git_buf_free(&actual);
|
||||||
git_patch_free(patch);
|
git_patch_free(patch);
|
||||||
git_diff_free(diff);
|
git_diff_free(diff);
|
||||||
|
|
||||||
@ -75,10 +92,10 @@ void test_diff_drivers__patterns(void)
|
|||||||
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
|
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
|
||||||
|
|
||||||
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
||||||
cl_git_pass(git_patch_to_buf(&buf, patch));
|
cl_git_pass(git_patch_to_buf(&actual, patch));
|
||||||
cl_assert_equal_s(expected0, buf.ptr);
|
cl_assert_equal_s(expected0, actual.ptr);
|
||||||
|
|
||||||
git_buf_free(&buf);
|
git_buf_free(&actual);
|
||||||
git_patch_free(patch);
|
git_patch_free(patch);
|
||||||
git_diff_free(diff);
|
git_diff_free(diff);
|
||||||
|
|
||||||
@ -92,10 +109,10 @@ void test_diff_drivers__patterns(void)
|
|||||||
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
|
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
|
||||||
|
|
||||||
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
||||||
cl_git_pass(git_patch_to_buf(&buf, patch));
|
cl_git_pass(git_patch_to_buf(&actual, patch));
|
||||||
cl_assert_equal_s(expected1, buf.ptr);
|
cl_assert_equal_s(expected1, actual.ptr);
|
||||||
|
|
||||||
git_buf_free(&buf);
|
git_buf_free(&actual);
|
||||||
git_patch_free(patch);
|
git_patch_free(patch);
|
||||||
git_diff_free(diff);
|
git_diff_free(diff);
|
||||||
|
|
||||||
@ -106,17 +123,17 @@ void test_diff_drivers__patterns(void)
|
|||||||
|
|
||||||
cl_git_pass(git_repository_config(&cfg, g_repo));
|
cl_git_pass(git_repository_config(&cfg, g_repo));
|
||||||
cl_git_pass(git_config_set_bool(cfg, "diff.kipling0.binary", 0));
|
cl_git_pass(git_config_set_bool(cfg, "diff.kipling0.binary", 0));
|
||||||
cl_git_pass(git_config_set_string(cfg, "diff.kipling0.xfuncname", "^H"));
|
cl_git_pass(git_config_set_string(cfg, "diff.kipling0.xfuncname", "^H.*$"));
|
||||||
git_config_free(cfg);
|
git_config_free(cfg);
|
||||||
|
|
||||||
cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
|
cl_git_pass(git_diff_tree_to_workdir(&diff, g_repo, one, NULL));
|
||||||
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
|
cl_assert_equal_i(1, (int)git_diff_num_deltas(diff));
|
||||||
|
|
||||||
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
||||||
cl_git_pass(git_patch_to_buf(&buf, patch));
|
cl_git_pass(git_patch_to_buf(&actual, patch));
|
||||||
cl_assert_equal_s(expected2, buf.ptr);
|
cl_assert_equal_s(expected2, actual.ptr);
|
||||||
|
|
||||||
git_buf_free(&buf);
|
git_buf_free(&actual);
|
||||||
git_patch_free(patch);
|
git_patch_free(patch);
|
||||||
git_diff_free(diff);
|
git_diff_free(diff);
|
||||||
|
|
||||||
@ -129,7 +146,7 @@ void test_diff_drivers__long_lines(void)
|
|||||||
git_index *idx;
|
git_index *idx;
|
||||||
git_diff *diff;
|
git_diff *diff;
|
||||||
git_patch *patch;
|
git_patch *patch;
|
||||||
git_buf buf = GIT_BUF_INIT;
|
git_buf actual = GIT_BUF_INIT;
|
||||||
const char *expected = "diff --git a/longlines.txt b/longlines.txt\nindex c1ce6ef..0134431 100644\n--- a/longlines.txt\n+++ b/longlines.txt\n@@ -3,3 +3,5 @@ Phasellus eget erat odio. Praesent at est iaculis, ultricies augue vel, dignissi\n Nam eget dolor fermentum, aliquet nisl at, convallis tellus. Pellentesque rhoncus erat enim, id porttitor elit euismod quis.\n Mauris sollicitudin magna odio, non egestas libero vehicula ut. Etiam et quam velit. Fusce eget libero rhoncus, ultricies felis sit amet, egestas purus.\n Aliquam in semper tellus. Pellentesque adipiscing rutrum velit, quis malesuada lacus consequat eget.\n+newline\n+newline\n";
|
const char *expected = "diff --git a/longlines.txt b/longlines.txt\nindex c1ce6ef..0134431 100644\n--- a/longlines.txt\n+++ b/longlines.txt\n@@ -3,3 +3,5 @@ Phasellus eget erat odio. Praesent at est iaculis, ultricies augue vel, dignissi\n Nam eget dolor fermentum, aliquet nisl at, convallis tellus. Pellentesque rhoncus erat enim, id porttitor elit euismod quis.\n Mauris sollicitudin magna odio, non egestas libero vehicula ut. Etiam et quam velit. Fusce eget libero rhoncus, ultricies felis sit amet, egestas purus.\n Aliquam in semper tellus. Pellentesque adipiscing rutrum velit, quis malesuada lacus consequat eget.\n+newline\n+newline\n";
|
||||||
|
|
||||||
g_repo = cl_git_sandbox_init("empty_standard_repo");
|
g_repo = cl_git_sandbox_init("empty_standard_repo");
|
||||||
@ -145,18 +162,91 @@ void test_diff_drivers__long_lines(void)
|
|||||||
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, NULL));
|
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, NULL));
|
||||||
cl_assert_equal_sz(1, git_diff_num_deltas(diff));
|
cl_assert_equal_sz(1, git_diff_num_deltas(diff));
|
||||||
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
||||||
cl_git_pass(git_patch_to_buf(&buf, patch));
|
cl_git_pass(git_patch_to_buf(&actual, patch));
|
||||||
|
|
||||||
/* if chmod not supported, overwrite mode bits since anything is possible */
|
/* if chmod not supported, overwrite mode bits since anything is possible */
|
||||||
if (!cl_is_chmod_supported()) {
|
overwrite_filemode(expected, &actual);
|
||||||
if (buf.size > 72 && memcmp(&buf.ptr[66], "100644", 6) != 0)
|
|
||||||
memcpy(&buf.ptr[66], "100644", 6);
|
|
||||||
}
|
|
||||||
|
|
||||||
cl_assert_equal_s(expected, buf.ptr);
|
cl_assert_equal_s(expected, actual.ptr);
|
||||||
|
|
||||||
git_buf_free(&buf);
|
git_buf_free(&actual);
|
||||||
git_patch_free(patch);
|
git_patch_free(patch);
|
||||||
git_diff_free(diff);
|
git_diff_free(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_diff_drivers__builtins(void)
|
||||||
|
{
|
||||||
|
git_diff *diff;
|
||||||
|
git_patch *patch;
|
||||||
|
git_buf file = GIT_BUF_INIT, actual = GIT_BUF_INIT, expected = GIT_BUF_INIT;
|
||||||
|
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
|
||||||
|
git_vector files = GIT_VECTOR_INIT;
|
||||||
|
size_t i;
|
||||||
|
char *path, *extension;
|
||||||
|
|
||||||
|
g_repo = cl_git_sandbox_init("userdiff");
|
||||||
|
|
||||||
|
cl_git_pass(git_path_dirload("userdiff/files", 9, 0, 0, &files));
|
||||||
|
|
||||||
|
opts.interhunk_lines = 1;
|
||||||
|
opts.context_lines = 1;
|
||||||
|
opts.pathspec.count = 1;
|
||||||
|
|
||||||
|
git_vector_foreach(&files, i, path) {
|
||||||
|
if (git__prefixcmp(path, "files/file."))
|
||||||
|
continue;
|
||||||
|
extension = path + strlen("files/file.");
|
||||||
|
opts.pathspec.strings = &path;
|
||||||
|
|
||||||
|
/* do diff with no special driver */
|
||||||
|
|
||||||
|
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
|
||||||
|
cl_assert_equal_sz(1, git_diff_num_deltas(diff));
|
||||||
|
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
||||||
|
cl_git_pass(git_patch_to_buf(&actual, patch));
|
||||||
|
|
||||||
|
git_buf_sets(&expected, "userdiff/expected/nodriver/diff.");
|
||||||
|
git_buf_puts(&expected, extension);
|
||||||
|
cl_git_pass(git_futils_readbuffer(&expected, expected.ptr));
|
||||||
|
|
||||||
|
overwrite_filemode(expected.ptr, &actual);
|
||||||
|
|
||||||
|
cl_assert_equal_s(expected.ptr, actual.ptr);
|
||||||
|
|
||||||
|
git_buf_clear(&actual);
|
||||||
|
git_patch_free(patch);
|
||||||
|
git_diff_free(diff);
|
||||||
|
|
||||||
|
/* do diff with driver */
|
||||||
|
|
||||||
|
{
|
||||||
|
FILE *fp = fopen("userdiff/.gitattributes", "w");
|
||||||
|
fprintf(fp, "*.%s diff=%s\n", extension, extension);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
|
||||||
|
cl_assert_equal_sz(1, git_diff_num_deltas(diff));
|
||||||
|
cl_git_pass(git_patch_from_diff(&patch, diff, 0));
|
||||||
|
cl_git_pass(git_patch_to_buf(&actual, patch));
|
||||||
|
|
||||||
|
git_buf_sets(&expected, "userdiff/expected/driver/diff.");
|
||||||
|
git_buf_puts(&expected, extension);
|
||||||
|
cl_git_pass(git_futils_readbuffer(&expected, expected.ptr));
|
||||||
|
|
||||||
|
overwrite_filemode(expected.ptr, &actual);
|
||||||
|
|
||||||
|
cl_assert_equal_s(expected.ptr, actual.ptr);
|
||||||
|
|
||||||
|
git_buf_clear(&actual);
|
||||||
|
git_patch_free(patch);
|
||||||
|
git_diff_free(diff);
|
||||||
|
|
||||||
|
git__free(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
git_buf_free(&file);
|
||||||
|
git_buf_free(&actual);
|
||||||
|
git_buf_free(&expected);
|
||||||
|
git_vector_free(&files);
|
||||||
|
}
|
||||||
|
BIN
tests/resources/userdiff/.gitted/HEAD
Normal file
BIN
tests/resources/userdiff/.gitted/HEAD
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/.gitted/config
Normal file
BIN
tests/resources/userdiff/.gitted/config
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/.gitted/description
Normal file
BIN
tests/resources/userdiff/.gitted/description
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/.gitted/index
Normal file
BIN
tests/resources/userdiff/.gitted/index
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/.gitted/info/refs
Normal file
BIN
tests/resources/userdiff/.gitted/info/refs
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/.gitted/objects/info/packs
Normal file
BIN
tests/resources/userdiff/.gitted/objects/info/packs
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
tests/resources/userdiff/.gitted/packed-refs
Normal file
BIN
tests/resources/userdiff/.gitted/packed-refs
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/after/file.html
Normal file
BIN
tests/resources/userdiff/after/file.html
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/after/file.javascript
Normal file
BIN
tests/resources/userdiff/after/file.javascript
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/after/file.php
Normal file
BIN
tests/resources/userdiff/after/file.php
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/before/file.html
Normal file
BIN
tests/resources/userdiff/before/file.html
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/before/file.javascript
Normal file
BIN
tests/resources/userdiff/before/file.javascript
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/before/file.php
Normal file
BIN
tests/resources/userdiff/before/file.php
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/expected/driver/diff.html
Normal file
BIN
tests/resources/userdiff/expected/driver/diff.html
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/expected/driver/diff.javascript
Normal file
BIN
tests/resources/userdiff/expected/driver/diff.javascript
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/expected/driver/diff.php
Normal file
BIN
tests/resources/userdiff/expected/driver/diff.php
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/expected/nodriver/diff.html
Normal file
BIN
tests/resources/userdiff/expected/nodriver/diff.html
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/expected/nodriver/diff.javascript
Normal file
BIN
tests/resources/userdiff/expected/nodriver/diff.javascript
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/expected/nodriver/diff.php
Normal file
BIN
tests/resources/userdiff/expected/nodriver/diff.php
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/files/file.html
Normal file
BIN
tests/resources/userdiff/files/file.html
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/files/file.javascript
Normal file
BIN
tests/resources/userdiff/files/file.javascript
Normal file
Binary file not shown.
BIN
tests/resources/userdiff/files/file.php
Normal file
BIN
tests/resources/userdiff/files/file.php
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user