[PATCH] add diff-filter option

Tommy Wu wu.tommy at gmail.com
Thu Oct 21 08:45:44 UTC 2021


This patch add diff-filter option. This new option is used to
specify an external command which will be executed when displaying diff
content. Diff content will be written to STDIN of the filter and STDOUT from
the filter will be included verbatim in the html output from cgit.
---
 cgit.c       | 6 ++++++
 cgit.h       | 4 +++-
 cgitrc.5.txt | 7 +++++++
 filter.c     | 3 +++
 shared.c     | 5 +++++
 5 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/cgit.c b/cgit.c
index 08d81a1..039f98b 100644
--- a/cgit.c
+++ b/cgit.c
@@ -112,6 +112,8 @@ static void repo_config(struct cgit_repo *repo,
const char *name, const char *va
  repo->about_filter = cgit_new_filter(value, ABOUT);
  else if (!strcmp(name, "commit-filter"))
  repo->commit_filter = cgit_new_filter(value, COMMIT);
+ else if (!strcmp(name, "diff-filter"))
+ repo->diff_filter = cgit_new_filter(value, DIFF);
  else if (!strcmp(name, "source-filter"))
  repo->source_filter = cgit_new_filter(value, SOURCE);
  else if (!strcmp(name, "email-filter"))
@@ -221,6 +223,8 @@ static void config_cb(const char *name, const char *value)
  ctx.cfg.about_filter = cgit_new_filter(value, ABOUT);
  else if (!strcmp(name, "commit-filter"))
  ctx.cfg.commit_filter = cgit_new_filter(value, COMMIT);
+ else if (!strcmp(name, "diff-filter"))
+ ctx.cfg.diff_filter = cgit_new_filter(value, DIFF);
  else if (!strcmp(name, "email-filter"))
  ctx.cfg.email_filter = cgit_new_filter(value, EMAIL);
  else if (!strcmp(name, "owner-filter"))
@@ -828,6 +832,8 @@ static void print_repo(FILE *f, struct cgit_repo *repo)
  cgit_fprintf_filter(repo->about_filter, f, "repo.about-filter=");
  if (repo->commit_filter && repo->commit_filter != ctx.cfg.commit_filter)
  cgit_fprintf_filter(repo->commit_filter, f, "repo.commit-filter=");
+ if (repo->diff_filter && repo->diff_filter != ctx.cfg.diff_filter)
+ cgit_fprintf_filter(repo->diff_filter, f, "repo.diff-filter=");
  if (repo->source_filter && repo->source_filter != ctx.cfg.source_filter)
  cgit_fprintf_filter(repo->source_filter, f, "repo.source-filter=");
  if (repo->email_filter && repo->email_filter != ctx.cfg.email_filter)
diff --git a/cgit.h b/cgit.h
index 69b5c13..5b03c0d 100644
--- a/cgit.h
+++ b/cgit.h
@@ -58,7 +58,7 @@ typedef enum {
 } diff_type;

 typedef enum {
- ABOUT, COMMIT, SOURCE, EMAIL, AUTH, OWNER
+ ABOUT, COMMIT, DIFF, SOURCE, EMAIL, AUTH, OWNER
 } filter_type;

 struct cgit_filter {
@@ -107,6 +107,7 @@ struct cgit_repo {
  time_t mtime;
  struct cgit_filter *about_filter;
  struct cgit_filter *commit_filter;
+ struct cgit_filter *diff_filter;
  struct cgit_filter *source_filter;
  struct cgit_filter *email_filter;
  struct cgit_filter *owner_filter;
@@ -266,6 +267,7 @@ struct cgit_config {
  struct string_list mimetypes;
  struct cgit_filter *about_filter;
  struct cgit_filter *commit_filter;
+ struct cgit_filter *diff_filter;
  struct cgit_filter *source_filter;
  struct cgit_filter *email_filter;
  struct cgit_filter *owner_filter;
diff --git a/cgitrc.5.txt b/cgitrc.5.txt
index 33a6a8c..8b0fd96 100644
--- a/cgitrc.5.txt
+++ b/cgitrc.5.txt
@@ -128,6 +128,13 @@ css::
  Url which specifies the css document to include in all cgit pages.
  Default value: "/cgit.css".

+diff-filter::
+ Specifies a command which will be invoked to format diff content.
+ The command will get the diff content on its STDIN and the STDOUT
+ from the command will be included verbatim as the diff contents, i.e.
+ this can be used to implement e.g. fallback encoding like gitweb.
+ Default value: none. See also: "FILTER API".
+
 email-filter::
  Specifies a command which will be invoked to format names and email
  address of committers, authors, and taggers, as represented in various
diff --git a/filter.c b/filter.c
index 70f5b74..71c8828 100644
--- a/filter.c
+++ b/filter.c
@@ -26,6 +26,7 @@ void cgit_cleanup_filters(void)
  int i;
  reap_filter(ctx.cfg.about_filter);
  reap_filter(ctx.cfg.commit_filter);
+ reap_filter(ctx.cfg.diff_filter);
  reap_filter(ctx.cfg.source_filter);
  reap_filter(ctx.cfg.email_filter);
  reap_filter(ctx.cfg.owner_filter);
@@ -33,6 +34,7 @@ void cgit_cleanup_filters(void)
  for (i = 0; i < cgit_repolist.count; ++i) {
  reap_filter(cgit_repolist.repos[i].about_filter);
  reap_filter(cgit_repolist.repos[i].commit_filter);
+ reap_filter(cgit_repolist.repos[i].diff_filter);
  reap_filter(cgit_repolist.repos[i].source_filter);
  reap_filter(cgit_repolist.repos[i].email_filter);
  reap_filter(cgit_repolist.repos[i].owner_filter);
@@ -438,6 +440,7 @@ struct cgit_filter *cgit_new_filter(const char
*cmd, filter_type filtertype)
  break;

  case COMMIT:
+ case DIFF:
  default:
  argument_count = 0;
  break;
diff --git a/shared.c b/shared.c
index 8115469..4c0e144 100644
--- a/shared.c
+++ b/shared.c
@@ -73,6 +73,7 @@ struct cgit_repo *cgit_add_repo(const char *url)
  ret->mtime = -1;
  ret->about_filter = ctx.cfg.about_filter;
  ret->commit_filter = ctx.cfg.commit_filter;
+ ret->diff_filter = ctx.cfg.diff_filter;
  ret->source_filter = ctx.cfg.source_filter;
  ret->email_filter = ctx.cfg.email_filter;
  ret->owner_filter = ctx.cfg.owner_filter;
@@ -328,7 +329,11 @@ int cgit_diff_files(const struct object_id *old_oid,
  emit_params.flags = XDL_EMIT_FUNCNAMES;
  emit_cb.out_line = filediff_cb;
  emit_cb.priv = fn;
+ if (ctx.repo->diff_filter)
+ cgit_open_filter(ctx.repo->diff_filter);
  xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb);
+ if (ctx.repo->diff_filter)
+ cgit_close_filter(ctx.repo->diff_filter);
  if (file1.size)
  free(file1.ptr);
  if (file2.size)
-- 
2.30.2


More information about the CGit mailing list