From 1b49de3c2c52e29c78f870826b6334abdadc0295 Mon Sep 17 00:00:00 2001 From: Lars Hjemli Date: Sun, 13 May 2007 11:24:23 +0200 Subject: Add shared diff-handling functions This adds a standard interface for tree diffing. Signed-off-by: Lars Hjemli --- cgit.h | 5 +++++ shared.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/cgit.h b/cgit.h index b7f8827..24b02d7 100644 --- a/cgit.h +++ b/cgit.h @@ -19,6 +19,7 @@ typedef void (*configfn)(const char *name, const char *value); +typedef void (*filepair_fn)(struct diff_filepair *pair); struct cacheitem { char *name; @@ -116,6 +117,10 @@ extern int chk_positive(int result, char *msg); extern int hextoint(char c); extern void *cgit_free_commitinfo(struct commitinfo *info); +extern void cgit_diff_tree(const unsigned char *old_sha1, + const unsigned char *new_sha1, + filepair_fn fn); +extern void cgit_diff_commit(struct commit *commit, filepair_fn fn); extern char *fmt(const char *format,...); diff --git a/shared.c b/shared.c index 19d2df0..f8a17b6 100644 --- a/shared.c +++ b/shared.c @@ -74,8 +74,8 @@ struct repoinfo *add_repo(const char *url) cgit_repolist.length = 8; else cgit_repolist.length *= 2; - cgit_repolist.repos = xrealloc(cgit_repolist.repos, - cgit_repolist.length * + cgit_repolist.repos = xrealloc(cgit_repolist.repos, + cgit_repolist.length * sizeof(struct repoinfo)); } @@ -195,3 +195,46 @@ int hextoint(char c) return -1; } +void cgit_diff_tree_cb(struct diff_queue_struct *q, + struct diff_options *options, void *data) +{ + int i; + + for (i = 0; i < q->nr; i++) { + if (q->queue[i]->status == 'U') + continue; + ((filepair_fn)data)(q->queue[i]); + } +} + +void cgit_diff_tree(const unsigned char *old_sha1, + const unsigned char *new_sha1, + filepair_fn fn) +{ + struct diff_options opt; + int ret; + + diff_setup(&opt); + opt.output_format = DIFF_FORMAT_CALLBACK; + opt.detect_rename = 1; + opt.recursive = 1; + opt.format_callback = cgit_diff_tree_cb; + opt.format_callback_data = fn; + diff_setup_done(&opt); + + if (old_sha1) + ret = diff_tree_sha1(old_sha1, new_sha1, "", &opt); + else + ret = diff_root_tree_sha1(new_sha1, "", &opt); + diffcore_std(&opt); + diff_flush(&opt); +} + +void cgit_diff_commit(struct commit *commit, filepair_fn fn) +{ + unsigned char *old_sha1 = NULL; + + if (commit->parents) + old_sha1 = commit->parents->item->object.sha1; + cgit_diff_tree(old_sha1, commit->object.sha1, fn); +} -- cgit v1.2.3-24-g4f1b