diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/shared.c27
-rw-r--r--source/shared.h5
-rw-r--r--source/ui-diff.c7
3 files changed, 26 insertions, 13 deletions
diff --git a/source/shared.c b/source/shared.c
index 1b610a0..78dc3f4 100644
--- a/source/shared.c
+++ b/source/shared.c
@@ -451,11 +451,24 @@ int cgit_diff_files(const struct object_id *old_oid, const struct object_id *new
return 0;
}
+void cgit_diff_limit_path(struct diff_options *opt, const char *prefix)
+{
+ struct pathspec_item *item;
+
+ item = xcalloc(1, sizeof(*item));
+ item->match = xstrdup(prefix);
+ item->len = strlen(prefix);
+ // nowildcard_len matching len makes git treat the path as literal
+ // rather than as a glob.
+ item->nowildcard_len = item->len;
+ opt->pathspec.nr = 1;
+ opt->pathspec.items = item;
+}
+
void cgit_diff_tree(const struct object_id *old_oid, const struct object_id *new_oid,
filepair_fn fn, const char *prefix, int ignorews)
{
struct diff_options opt;
- struct pathspec_item *item;
repo_diff_setup(the_repository, &opt);
opt.output_format = DIFF_FORMAT_CALLBACK;
@@ -466,16 +479,8 @@ void cgit_diff_tree(const struct object_id *old_oid, const struct object_id *new
DIFF_XDL_SET(&opt, IGNORE_WHITESPACE);
opt.format_callback = cgit_diff_tree_cb;
opt.format_callback_data = fn;
- if (prefix) {
- item = xcalloc(1, sizeof(*item));
- item->match = xstrdup(prefix);
- item->len = strlen(prefix);
- // nowildcard_len matching len makes git treat the path as
- // literal rather than as a glob.
- item->nowildcard_len = item->len;
- opt.pathspec.nr = 1;
- opt.pathspec.items = item;
- }
+ if (prefix)
+ cgit_diff_limit_path(&opt, prefix);
diff_setup_done(&opt);
if (old_oid && !is_null_oid(old_oid))
diff --git a/source/shared.h b/source/shared.h
index 9e39389..d61c1f1 100644
--- a/source/shared.h
+++ b/source/shared.h
@@ -60,6 +60,11 @@ extern int cgit_diff_files(const struct object_id *old_oid, const struct object_
unsigned long *old_size, unsigned long *new_size, int *binary, int context, int ignorews,
linediff_fn fn);
+/*
+ * Limit a diff to the paths below prefix, which is taken literally.
+ */
+extern void cgit_diff_limit_path(struct diff_options *opt, const char *prefix);
+
extern void cgit_diff_tree(const struct object_id *old_oid, const struct object_id *new_oid,
filepair_fn fn, const char *prefix, int ignorews);
extern void cgit_diff_commit(struct commit *commit, filepair_fn fn, const char *prefix);
diff --git a/source/ui-diff.c b/source/ui-diff.c
index 5c9cd1c..a5202b5 100644
--- a/source/ui-diff.c
+++ b/source/ui-diff.c
@@ -535,13 +535,16 @@ static void filepair_cb(struct diff_filepair *pair)
end_file();
}
-static void print_raw_patch(const struct object_id *old_tree_oid, const struct object_id *new_tree_oid)
+static void print_raw_patch(const struct object_id *old_tree_oid, const struct object_id *new_tree_oid,
+ const char *prefix)
{
struct diff_options diffopt;
repo_diff_setup(the_repository, &diffopt);
diffopt.output_format = DIFF_FORMAT_PATCH;
diffopt.flags.recursive = 1;
+ if (prefix)
+ cgit_diff_limit_path(&diffopt, prefix);
diff_setup_done(&diffopt);
ctx.page.mimetype = "text/plain";
@@ -683,7 +686,7 @@ void cgit_print_diff(const char *new_rev, const char *old_rev, const char *prefi
cap_diffs = !path || prefix_is_dir(old_tree_oid, new_tree_oid, path);
if (raw) {
- print_raw_patch(old_tree_oid, new_tree_oid);
+ print_raw_patch(old_tree_oid, new_tree_oid, path);
return;
}